diff options
Diffstat (limited to 'rust')
| -rw-r--r-- | rust/binary.go | 3 | ||||
| -rw-r--r-- | rust/builder_test.go | 20 | ||||
| -rw-r--r-- | rust/fuzz_test.go | 10 | ||||
| -rw-r--r-- | rust/image.go | 28 | ||||
| -rw-r--r-- | rust/image_test.go | 24 | ||||
| -rw-r--r-- | rust/library.go | 52 | ||||
| -rw-r--r-- | rust/library_test.go | 72 | ||||
| -rw-r--r-- | rust/rust.go | 128 | ||||
| -rw-r--r-- | rust/rust_test.go | 22 | ||||
| -rw-r--r-- | rust/test_test.go | 17 | ||||
| -rw-r--r-- | rust/testing.go | 4 |
11 files changed, 228 insertions, 152 deletions
diff --git a/rust/binary.go b/rust/binary.go index 996951366..cba29a023 100644 --- a/rust/binary.go +++ b/rust/binary.go @@ -134,6 +134,9 @@ func (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps Path ret := buildOutput{outputFile: outputFile} crateRootPath := crateRootPath(ctx, binary) + // Ensure link dirs are not duplicated + deps.linkDirs = android.FirstUniqueStrings(deps.linkDirs) + flags.RustFlags = append(flags.RustFlags, deps.depFlags...) flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...) flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...) diff --git a/rust/builder_test.go b/rust/builder_test.go index c093ac4df..ae5ccde27 100644 --- a/rust/builder_test.go +++ b/rust/builder_test.go @@ -65,6 +65,11 @@ func TestCompilationOutputFiles(t *testing.T) { crate_name: "rust_ffi", srcs: ["lib.rs"], } + rust_ffi_static { + name: "librust_ffi_static", + crate_name: "rust_ffi", + srcs: ["lib.rs"], + } `) testcases := []struct { testName string @@ -118,14 +123,14 @@ func TestCompilationOutputFiles(t *testing.T) { }, }, { - testName: "rust_ffi static", - moduleName: "librust_ffi", - variant: "android_arm64_armv8-a_static", + testName: "rust_ffi_static rlib", + moduleName: "librust_ffi_static", + variant: "android_arm64_armv8-a_rlib_rlib-std", expectedFiles: []string{ - "out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_static/librust_ffi.a", - "out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_static/librust_ffi.a.clippy", - "out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_static/meta_lic", - "out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_static/rustdoc.timestamp", + "out/soong/.intermediates/librust_ffi_static/android_arm64_armv8-a_rlib_rlib-std/librust_ffi_static.rlib", + "out/soong/.intermediates/librust_ffi_static/android_arm64_armv8-a_rlib_rlib-std/librust_ffi_static.rlib.clippy", + "out/soong/.intermediates/librust_ffi_static/android_arm64_armv8-a_rlib_rlib-std/meta_lic", + "out/soong/.intermediates/librust_ffi_static/android_arm64_armv8-a_rlib_rlib-std/rustdoc.timestamp", }, }, { @@ -148,6 +153,7 @@ func TestCompilationOutputFiles(t *testing.T) { "out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_shared/unstripped/librust_ffi.so", "out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_shared/unstripped/librust_ffi.so.toc", "out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_shared/meta_lic", + "out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_shared/rustdoc.timestamp", "out/soong/target/product/test_device/system/lib64/librust_ffi.so", }, }, diff --git a/rust/fuzz_test.go b/rust/fuzz_test.go index 0d4622a7e..6cb8b9319 100644 --- a/rust/fuzz_test.go +++ b/rust/fuzz_test.go @@ -114,17 +114,23 @@ func TestCCFuzzDepBundling(t *testing.T) { srcs: ["foo.rs"], shared_libs: ["libcc_transitive_dep"], } + rust_ffi_static { + name: "libtest_fuzzing_static", + crate_name: "test_fuzzing", + srcs: ["foo.rs"], + shared_libs: ["libcc_transitive_dep"], + } cc_fuzz { name: "fuzz_shared_libtest", shared_libs: ["libtest_fuzzing"], } cc_fuzz { name: "fuzz_static_libtest", - static_rlibs: ["libtest_fuzzing"], + static_libs: ["libtest_fuzzing"], } cc_fuzz { name: "fuzz_staticffi_libtest", - static_libs: ["libtest_fuzzing"], + static_libs: ["libtest_fuzzing_static"], } `) diff --git a/rust/image.go b/rust/image.go index fec6d92d8..26929b1ac 100644 --- a/rust/image.go +++ b/rust/image.go @@ -77,6 +77,14 @@ func (mod *Module) SetCoreVariantNeeded(b bool) { mod.Properties.CoreVariantNeeded = b } +func (mod *Module) SetProductVariantNeeded(b bool) { + mod.Properties.ProductVariantNeeded = b +} + +func (mod *Module) SetVendorVariantNeeded(b bool) { + mod.Properties.VendorVariantNeeded = b +} + func (mod *Module) SnapshotVersion(mctx android.BaseModuleContext) string { if snapshot, ok := mod.compiler.(cc.SnapshotInterface); ok { return snapshot.Version() @@ -86,6 +94,14 @@ func (mod *Module) SnapshotVersion(mctx android.BaseModuleContext) string { } } +func (mod *Module) VendorVariantNeeded(ctx android.BaseModuleContext) bool { + return mod.Properties.VendorVariantNeeded +} + +func (mod *Module) ProductVariantNeeded(ctx android.BaseModuleContext) bool { + return mod.Properties.ProductVariantNeeded +} + func (mod *Module) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { return mod.Properties.VendorRamdiskVariantNeeded } @@ -184,12 +200,12 @@ func (mod *Module) HasNonSystemVariants() bool { } func (mod *Module) InProduct() bool { - return mod.Properties.ImageVariation == cc.ProductVariation + return mod.Properties.ImageVariation == android.ProductVariation } // Returns true if the module is "vendor" variant. Usually these modules are installed in /vendor func (mod *Module) InVendor() bool { - return mod.Properties.ImageVariation == cc.VendorVariation + return mod.Properties.ImageVariation == android.VendorVariation } // Returns true if the module is "vendor" or "product" variant. @@ -202,13 +218,13 @@ func (mod *Module) SetImageVariation(ctx android.BaseModuleContext, variant stri mod.MakeAsPlatform() } else if variant == android.RecoveryVariation { mod.MakeAsPlatform() - } else if strings.HasPrefix(variant, cc.VendorVariation) { - mod.Properties.ImageVariation = cc.VendorVariation + } else if strings.HasPrefix(variant, android.VendorVariation) { + mod.Properties.ImageVariation = android.VendorVariation if strings.HasPrefix(variant, cc.VendorVariationPrefix) { mod.Properties.VndkVersion = strings.TrimPrefix(variant, cc.VendorVariationPrefix) } - } else if strings.HasPrefix(variant, cc.ProductVariation) { - mod.Properties.ImageVariation = cc.ProductVariation + } else if strings.HasPrefix(variant, android.ProductVariation) { + mod.Properties.ImageVariation = android.ProductVariation if strings.HasPrefix(variant, cc.ProductVariationPrefix) { mod.Properties.VndkVersion = strings.TrimPrefix(variant, cc.ProductVariationPrefix) } diff --git a/rust/image_test.go b/rust/image_test.go index 71e271c89..d84eb10c5 100644 --- a/rust/image_test.go +++ b/rust/image_test.go @@ -22,18 +22,20 @@ import ( "android/soong/cc" ) -// Test that cc modules can link against vendor_available rust_ffi_rlib/rust_ffi_static libraries. +// Test that cc modules can depend on vendor_available rust_ffi_rlib/rust_ffi_static libraries. func TestVendorLinkage(t *testing.T) { ctx := testRust(t, ` cc_binary { name: "fizz_vendor_available", - static_libs: ["libfoo_vendor_static"], - static_rlibs: ["libfoo_vendor"], + static_libs: [ + "libfoo_vendor", + "libfoo_vendor_static" + ], vendor_available: true, } cc_binary { name: "fizz_soc_specific", - static_rlibs: ["libfoo_vendor"], + static_libs: ["libfoo_vendor"], soc_specific: true, } rust_ffi_rlib { @@ -52,8 +54,8 @@ func TestVendorLinkage(t *testing.T) { vendorBinary := ctx.ModuleForTests("fizz_vendor_available", "android_vendor_arm64_armv8-a").Module().(*cc.Module) - if !android.InList("libfoo_vendor_static.vendor", vendorBinary.Properties.AndroidMkStaticLibs) { - t.Errorf("vendorBinary should have a dependency on libfoo_vendor_static.vendor: %#v", vendorBinary.Properties.AndroidMkStaticLibs) + if android.InList("libfoo_vendor_static.vendor", vendorBinary.Properties.AndroidMkStaticLibs) { + t.Errorf("vendorBinary should not have a staticlib dependency on libfoo_vendor_static.vendor: %#v", vendorBinary.Properties.AndroidMkStaticLibs) } } @@ -110,8 +112,10 @@ func TestVendorRamdiskLinkage(t *testing.T) { ctx := testRust(t, ` cc_library_shared { name: "libcc_vendor_ramdisk", - static_rlibs: ["libfoo_vendor_ramdisk"], - static_libs: ["libfoo_static_vendor_ramdisk"], + static_libs: [ + "libfoo_vendor_ramdisk", + "libfoo_static_vendor_ramdisk" + ], system_shared_libs: [], vendor_ramdisk_available: true, } @@ -131,8 +135,8 @@ func TestVendorRamdiskLinkage(t *testing.T) { vendorRamdiskLibrary := ctx.ModuleForTests("libcc_vendor_ramdisk", "android_vendor_ramdisk_arm64_armv8-a_shared").Module().(*cc.Module) - if !android.InList("libfoo_static_vendor_ramdisk.vendor_ramdisk", vendorRamdiskLibrary.Properties.AndroidMkStaticLibs) { - t.Errorf("libcc_vendor_ramdisk should have a dependency on libfoo_static_vendor_ramdisk") + if android.InList("libfoo_static_vendor_ramdisk.vendor_ramdisk", vendorRamdiskLibrary.Properties.AndroidMkStaticLibs) { + t.Errorf("libcc_vendor_ramdisk should not have a dependency on the libfoo_static_vendor_ramdisk static library") } } diff --git a/rust/library.go b/rust/library.go index 2a21263bd..96c02c832 100644 --- a/rust/library.go +++ b/rust/library.go @@ -43,9 +43,9 @@ func init() { android.RegisterModuleType("rust_ffi_host_rlib", RustFFIRlibHostFactory) // TODO: Remove when all instances of rust_ffi_static have been switched to rust_ffi_rlib - // Alias rust_ffi_static to the combined rust_ffi_rlib factory - android.RegisterModuleType("rust_ffi_static", RustFFIStaticRlibFactory) - android.RegisterModuleType("rust_ffi_host_static", RustFFIStaticRlibHostFactory) + // Alias rust_ffi_static to the rust_ffi_rlib factory + android.RegisterModuleType("rust_ffi_static", RustFFIRlibFactory) + android.RegisterModuleType("rust_ffi_host_static", RustFFIRlibHostFactory) } type VariantLibraryProperties struct { @@ -353,7 +353,7 @@ func RustFFISharedHostFactory() android.Module { // type "rlib"). func RustFFIRlibHostFactory() android.Module { module, library := NewRustLibrary(android.HostSupported) - library.BuildOnlyRlibStatic() + library.BuildOnlyRlib() library.isFFI = true return module.Init() @@ -368,30 +368,12 @@ func RustFFIRlibFactory() android.Module { return module.Init() } -// rust_ffi_static produces a staticlib and an rlib variant -func RustFFIStaticRlibFactory() android.Module { - module, library := NewRustLibrary(android.HostAndDeviceSupported) - library.BuildOnlyRlibStatic() - - library.isFFI = true - return module.Init() -} - -// rust_ffi_static_host produces a staticlib and an rlib variant for the host -func RustFFIStaticRlibHostFactory() android.Module { - module, library := NewRustLibrary(android.HostSupported) - library.BuildOnlyRlibStatic() - - library.isFFI = true - return module.Init() -} - func (library *libraryDecorator) BuildOnlyFFI() { library.MutatedProperties.BuildDylib = false // we build rlibs for later static ffi linkage. library.MutatedProperties.BuildRlib = true library.MutatedProperties.BuildShared = true - library.MutatedProperties.BuildStatic = true + library.MutatedProperties.BuildStatic = false library.isFFI = true } @@ -417,14 +399,6 @@ func (library *libraryDecorator) BuildOnlyRlib() { library.MutatedProperties.BuildStatic = false } -func (library *libraryDecorator) BuildOnlyRlibStatic() { - library.MutatedProperties.BuildDylib = false - library.MutatedProperties.BuildRlib = true - library.MutatedProperties.BuildShared = false - library.MutatedProperties.BuildStatic = true - library.isFFI = true -} - func (library *libraryDecorator) BuildOnlyStatic() { library.MutatedProperties.BuildRlib = false library.MutatedProperties.BuildDylib = false @@ -766,10 +740,13 @@ func LibraryMutator(mctx android.BottomUpMutatorContext) { // The order of the variations (modules) matches the variant names provided. Iterate // through the new variation modules and set their mutated properties. + var emptyVariant = false + var rlibVariant = false for i, v := range modules { switch variants[i] { case rlibVariation: v.(*Module).compiler.(libraryInterface).setRlib() + rlibVariant = true case dylibVariation: v.(*Module).compiler.(libraryInterface).setDylib() if v.(*Module).ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation { @@ -784,11 +761,19 @@ func LibraryMutator(mctx android.BottomUpMutatorContext) { // Disable the compilation steps. v.(*Module).compiler.SetDisabled() case "": - // if there's an empty variant, alias it so it is the default variant - mctx.AliasVariation("") + emptyVariant = true } } + if rlibVariant && library.isFFILibrary() { + // If an rlib variant is set and this is an FFI library, make it the + // default variant so CC can link against it appropriately. + mctx.AliasVariation(rlibVariation) + } else if emptyVariant { + // If there's an empty variant, alias it so it is the default variant + mctx.AliasVariation("") + } + // If a source variant is created, add an inter-variant dependency // between the other variants and the source variant. if sourceVariant { @@ -817,6 +802,7 @@ func LibstdMutator(mctx android.BottomUpMutatorContext) { rlib := modules[0].(*Module) rlib.compiler.(libraryInterface).setRlibStd() rlib.Properties.RustSubName += RlibStdlibSuffix + mctx.AliasVariation("rlib-std") } else { variants := []string{"rlib-std", "dylib-std"} modules := mctx.CreateLocalVariations(variants...) diff --git a/rust/library_test.go b/rust/library_test.go index 1133c28ed..35a420cd5 100644 --- a/rust/library_test.go +++ b/rust/library_test.go @@ -34,10 +34,14 @@ func TestLibraryVariants(t *testing.T) { name: "libfoo.ffi", srcs: ["foo.rs"], crate_name: "foo" + } + rust_ffi_host_static { + name: "libfoo.ffi_static", + srcs: ["foo.rs"], + crate_name: "foo" }`) // Test all variants are being built. - libfooStatic := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_static").Rule("rustc") libfooRlib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_rlib_rlib-std").Rule("rustc") libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc") libfooFFIRlib := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_rlib_rlib-std").Rule("rustc") @@ -46,7 +50,6 @@ func TestLibraryVariants(t *testing.T) { rlibCrateType := "rlib" dylibCrateType := "dylib" sharedCrateType := "cdylib" - staticCrateType := "staticlib" // Test crate type for rlib is correct. if !strings.Contains(libfooRlib.Args["rustcFlags"], "crate-type="+rlibCrateType) { @@ -58,11 +61,6 @@ func TestLibraryVariants(t *testing.T) { t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", dylibCrateType, libfooDylib.Args["rustcFlags"]) } - // Test crate type for C static libraries is correct. - if !strings.Contains(libfooStatic.Args["rustcFlags"], "crate-type="+staticCrateType) { - t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", staticCrateType, libfooStatic.Args["rustcFlags"]) - } - // Test crate type for FFI rlibs is correct if !strings.Contains(libfooFFIRlib.Args["rustcFlags"], "crate-type="+rlibCrateType) { t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", rlibCrateType, libfooFFIRlib.Args["rustcFlags"]) @@ -188,23 +186,18 @@ func TestSharedLibraryToc(t *testing.T) { func TestStaticLibraryLinkage(t *testing.T) { ctx := testRust(t, ` - rust_ffi { + rust_ffi_static { name: "libfoo", srcs: ["foo.rs"], crate_name: "foo", }`) libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_rlib_rlib-std") - libfooStatic := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static") if !android.InList("libstd", libfoo.Module().(*Module).Properties.AndroidMkRlibs) { t.Errorf("Static libstd rlib expected to be a dependency of Rust rlib libraries. Rlib deps are: %#v", libfoo.Module().(*Module).Properties.AndroidMkDylibs) } - if !android.InList("libstd", libfooStatic.Module().(*Module).Properties.AndroidMkRlibs) { - t.Errorf("Static libstd rlib expected to be a dependency of Rust static libraries. Rlib deps are: %#v", - libfoo.Module().(*Module).Properties.AndroidMkDylibs) - } } func TestNativeDependencyOfRlib(t *testing.T) { @@ -215,39 +208,31 @@ func TestNativeDependencyOfRlib(t *testing.T) { rlibs: ["librust_rlib"], srcs: ["foo.rs"], } - rust_ffi_static { - name: "libffi_static", - crate_name: "ffi_static", - rlibs: ["librust_rlib"], - srcs: ["foo.rs"], - } rust_library_rlib { name: "librust_rlib", crate_name: "rust_rlib", srcs: ["foo.rs"], - shared_libs: ["shared_cc_dep"], - static_libs: ["static_cc_dep"], + shared_libs: ["libshared_cc_dep"], + static_libs: ["libstatic_cc_dep"], } cc_library_shared { - name: "shared_cc_dep", + name: "libshared_cc_dep", srcs: ["foo.cpp"], } cc_library_static { - name: "static_cc_dep", + name: "libstatic_cc_dep", srcs: ["foo.cpp"], } `) rustRlibRlibStd := ctx.ModuleForTests("librust_rlib", "android_arm64_armv8-a_rlib_rlib-std") rustRlibDylibStd := ctx.ModuleForTests("librust_rlib", "android_arm64_armv8-a_rlib_dylib-std") - ffiStatic := ctx.ModuleForTests("libffi_static", "android_arm64_armv8-a_static") ffiRlib := ctx.ModuleForTests("libffi_rlib", "android_arm64_armv8-a_rlib_rlib-std") modules := []android.TestingModule{ rustRlibRlibStd, rustRlibDylibStd, ffiRlib, - ffiStatic, } // librust_rlib specifies -L flag to cc deps output directory on rustc command @@ -258,17 +243,17 @@ func TestNativeDependencyOfRlib(t *testing.T) { // TODO: We could consider removing these flags for _, module := range modules { if !strings.Contains(module.Rule("rustc").Args["libFlags"], - "-L out/soong/.intermediates/shared_cc_dep/android_arm64_armv8-a_shared/") { + "-L out/soong/.intermediates/libshared_cc_dep/android_arm64_armv8-a_shared/") { t.Errorf( - "missing -L flag for shared_cc_dep, rustcFlags: %#v", - rustRlibRlibStd.Rule("rustc").Args["libFlags"], + "missing -L flag for libshared_cc_dep of %s, rustcFlags: %#v", + module.Module().Name(), rustRlibRlibStd.Rule("rustc").Args["libFlags"], ) } if !strings.Contains(module.Rule("rustc").Args["libFlags"], - "-L out/soong/.intermediates/static_cc_dep/android_arm64_armv8-a_static/") { + "-L out/soong/.intermediates/libstatic_cc_dep/android_arm64_armv8-a_static/") { t.Errorf( - "missing -L flag for static_cc_dep, rustcFlags: %#v", - rustRlibRlibStd.Rule("rustc").Args["libFlags"], + "missing -L flag for libstatic_cc_dep of %s, rustcFlags: %#v", + module.Module().Name(), rustRlibRlibStd.Rule("rustc").Args["libFlags"], ) } } @@ -305,15 +290,23 @@ func TestAutoDeps(t *testing.T) { "libbar", "librlib_only", ], + } + rust_ffi_host_static { + name: "libfoo.ffi.static", + srcs: ["foo.rs"], + crate_name: "foo", + rustlibs: [ + "libbar", + "librlib_only", + ], }`) libfooRlib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_rlib_rlib-std") libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib") libfooFFIRlib := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_rlib_rlib-std") - libfooStatic := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_static") libfooShared := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_shared") - for _, static := range []android.TestingModule{libfooRlib, libfooStatic, libfooFFIRlib} { + for _, static := range []android.TestingModule{libfooRlib, libfooFFIRlib} { if !android.InList("libbar.rlib-std", static.Module().(*Module).Properties.AndroidMkRlibs) { t.Errorf("libbar not present as rlib dependency in static lib: %s", static.Module().Name()) } @@ -381,6 +374,12 @@ func TestLibstdLinkage(t *testing.T) { crate_name: "bar", rustlibs: ["libfoo"], } + rust_ffi_static { + name: "libbar_static", + srcs: ["foo.rs"], + crate_name: "bar", + rustlibs: ["libfoo"], + } rust_ffi { name: "libbar.prefer_rlib", srcs: ["foo.rs"], @@ -394,7 +393,6 @@ func TestLibstdLinkage(t *testing.T) { libfooRlibDynamic := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_rlib_dylib-std").Module().(*Module) libbarShared := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module().(*Module) - libbarStatic := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_static").Module().(*Module) libbarFFIRlib := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_rlib_rlib-std").Module().(*Module) // prefer_rlib works the same for both rust_library and rust_ffi, so a single check is sufficient here. @@ -413,12 +411,6 @@ func TestLibstdLinkage(t *testing.T) { if !android.InList("libstd", libbarShared.Properties.AndroidMkDylibs) { t.Errorf("Device rust_ffi_shared does not link libstd as an dylib") } - if !android.InList("libstd", libbarStatic.Properties.AndroidMkRlibs) { - t.Errorf("Device rust_ffi_static does not link libstd as an rlib") - } - if !android.InList("libfoo.rlib-std", libbarStatic.Properties.AndroidMkRlibs) { - t.Errorf("Device rust_ffi_static does not link dependent rustlib rlib-std variant") - } if !android.InList("libstd", libbarFFIRlib.Properties.AndroidMkRlibs) { t.Errorf("Device rust_ffi_rlib does not link libstd as an rlib") } diff --git a/rust/rust.go b/rust/rust.go index 7cd9df4c7..6b7b2fbae 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -16,6 +16,7 @@ package rust import ( "fmt" + "strconv" "strings" "android/soong/bloaty" @@ -80,6 +81,8 @@ type BaseProperties struct { RustSubName string `blueprint:"mutated"` // Set by imageMutator + ProductVariantNeeded bool `blueprint:"mutated"` + VendorVariantNeeded bool `blueprint:"mutated"` CoreVariantNeeded bool `blueprint:"mutated"` VendorRamdiskVariantNeeded bool `blueprint:"mutated"` RamdiskVariantNeeded bool `blueprint:"mutated"` @@ -206,27 +209,6 @@ func (mod *Module) IsPrebuilt() bool { return false } -func (mod *Module) OutputFiles(tag string) (android.Paths, error) { - switch tag { - case "": - if mod.sourceProvider != nil && (mod.compiler == nil || mod.compiler.Disabled()) { - return mod.sourceProvider.Srcs(), nil - } else { - if mod.OutputFile().Valid() { - return android.Paths{mod.OutputFile().Path()}, nil - } - return android.Paths{}, nil - } - case "unstripped": - if mod.compiler != nil { - return android.PathsIfNonNil(mod.compiler.unstrippedOutputFilePath()), nil - } - return nil, nil - default: - return nil, fmt.Errorf("unsupported module reference tag %q", tag) - } -} - func (mod *Module) SelectedStl() string { return "" } @@ -438,7 +420,7 @@ type PathDeps struct { depFlags []string depLinkFlags []string - // linkDirs are link paths passed via -L to rustc. linkObjects are objects passed directly to the linker. + // linkDirs are link paths passed via -L to rustc. linkObjects are objects passed directly to the linker // Both of these are exported and propagate to dependencies. linkDirs []string linkObjects []string @@ -460,9 +442,6 @@ type PathDeps struct { // Paths to generated source files SrcDeps android.Paths srcProviderFiles android.Paths - - // Used by Generated Libraries - depExportedRlibs []cc.RustRlibDep } type RustLibraries []RustLibrary @@ -483,6 +462,7 @@ type xref interface { type flagExporter struct { linkDirs []string + ccLinkDirs []string linkObjects []string } @@ -676,6 +656,24 @@ func (mod *Module) BuildStaticVariant() bool { panic(fmt.Errorf("BuildStaticVariant called on non-library module: %q", mod.BaseModuleName())) } +func (mod *Module) BuildRlibVariant() bool { + if mod.compiler != nil { + if library, ok := mod.compiler.(libraryInterface); ok { + return library.buildRlib() + } + } + panic(fmt.Errorf("BuildRlibVariant called on non-library module: %q", mod.BaseModuleName())) +} + +func (mod *Module) IsRustFFI() bool { + if mod.compiler != nil { + if library, ok := mod.compiler.(libraryInterface); ok { + return library.isFFILibrary() + } + } + return false +} + func (mod *Module) BuildSharedVariant() bool { if mod.compiler != nil { if library, ok := mod.compiler.(libraryInterface); ok { @@ -986,6 +984,61 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { if mod.testModule { android.SetProvider(ctx, testing.TestModuleProviderKey, testing.TestModuleProviderData{}) } + + mod.setOutputFiles(ctx) + + buildComplianceMetadataInfo(ctx, mod, deps) +} + +func (mod *Module) setOutputFiles(ctx ModuleContext) { + if mod.sourceProvider != nil && (mod.compiler == nil || mod.compiler.Disabled()) { + ctx.SetOutputFiles(mod.sourceProvider.Srcs(), "") + } else if mod.OutputFile().Valid() { + ctx.SetOutputFiles(android.Paths{mod.OutputFile().Path()}, "") + } else { + ctx.SetOutputFiles(android.Paths{}, "") + } + if mod.compiler != nil { + ctx.SetOutputFiles(android.PathsIfNonNil(mod.compiler.unstrippedOutputFilePath()), "unstripped") + } +} + +func buildComplianceMetadataInfo(ctx *moduleContext, mod *Module, deps PathDeps) { + // Dump metadata that can not be done in android/compliance-metadata.go + metadataInfo := ctx.ComplianceMetadataInfo() + metadataInfo.SetStringValue(android.ComplianceMetadataProp.IS_STATIC_LIB, strconv.FormatBool(mod.Static())) + metadataInfo.SetStringValue(android.ComplianceMetadataProp.BUILT_FILES, mod.outputFile.String()) + + // Static libs + staticDeps := ctx.GetDirectDepsWithTag(rlibDepTag) + staticDepNames := make([]string, 0, len(staticDeps)) + for _, dep := range staticDeps { + staticDepNames = append(staticDepNames, dep.Name()) + } + ccStaticDeps := ctx.GetDirectDepsWithTag(cc.StaticDepTag(false)) + for _, dep := range ccStaticDeps { + staticDepNames = append(staticDepNames, dep.Name()) + } + + staticDepPaths := make([]string, 0, len(deps.StaticLibs)+len(deps.RLibs)) + // C static libraries + for _, dep := range deps.StaticLibs { + staticDepPaths = append(staticDepPaths, dep.String()) + } + // Rust static libraries + for _, dep := range deps.RLibs { + staticDepPaths = append(staticDepPaths, dep.Path.String()) + } + metadataInfo.SetListValue(android.ComplianceMetadataProp.STATIC_DEPS, android.FirstUniqueStrings(staticDepNames)) + metadataInfo.SetListValue(android.ComplianceMetadataProp.STATIC_DEP_FILES, android.FirstUniqueStrings(staticDepPaths)) + + // C Whole static libs + ccWholeStaticDeps := ctx.GetDirectDepsWithTag(cc.StaticDepTag(true)) + wholeStaticDepNames := make([]string, 0, len(ccWholeStaticDeps)) + for _, dep := range ccStaticDeps { + wholeStaticDepNames = append(wholeStaticDepNames, dep.Name()) + } + metadataInfo.SetListValue(android.ComplianceMetadataProp.STATIC_DEPS, android.FirstUniqueStrings(staticDepNames)) } func (mod *Module) deps(ctx DepsContext) Deps { @@ -1200,7 +1253,6 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { ctx.VisitDirectDeps(func(dep android.Module) { depName := ctx.OtherModuleName(dep) depTag := ctx.OtherModuleDependencyTag(dep) - if _, exists := skipModuleList[depName]; exists { return } @@ -1213,8 +1265,8 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { //Handle Rust Modules makeLibName := rustMakeLibName(ctx, mod, rustDep, depName+rustDep.Properties.RustSubName) - switch depTag { - case dylibDepTag: + switch { + case depTag == dylibDepTag: dylib, ok := rustDep.compiler.(libraryInterface) if !ok || !dylib.dylib() { ctx.ModuleErrorf("mod %q not an dylib library", depName) @@ -1224,8 +1276,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { mod.Properties.AndroidMkDylibs = append(mod.Properties.AndroidMkDylibs, makeLibName) mod.Properties.SnapshotDylibs = append(mod.Properties.SnapshotDylibs, cc.BaseLibName(depName)) - case rlibDepTag: - + case depTag == rlibDepTag: rlib, ok := rustDep.compiler.(libraryInterface) if !ok || !rlib.rlib() { ctx.ModuleErrorf("mod %q not an rlib library", makeLibName) @@ -1240,16 +1291,25 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...) depPaths.exportedLinkDirs = append(depPaths.exportedLinkDirs, linkPathFromFilePath(rustDep.OutputFile().Path())) - case procMacroDepTag: + case depTag == procMacroDepTag: directProcMacroDeps = append(directProcMacroDeps, rustDep) mod.Properties.AndroidMkProcMacroLibs = append(mod.Properties.AndroidMkProcMacroLibs, makeLibName) // proc_macro link dirs need to be exported, so collect those here. depPaths.exportedLinkDirs = append(depPaths.exportedLinkDirs, linkPathFromFilePath(rustDep.OutputFile().Path())) - case sourceDepTag: + case depTag == sourceDepTag: if _, ok := mod.sourceProvider.(*protobufDecorator); ok { collectIncludedProtos(mod, rustDep) } + case cc.IsStaticDepTag(depTag): + // Rust FFI rlibs should not be declared in a Rust modules + // "static_libs" list as we can't handle them properly at the + // moment (for example, they only produce an rlib-std variant). + // Instead, a normal rust_library variant should be used. + ctx.PropertyErrorf("static_libs", + "found '%s' in static_libs; use a rust_library module in rustlibs instead of a rust_ffi module in static_libs", + depName) + } transitiveAndroidMkSharedLibs = append(transitiveAndroidMkSharedLibs, rustDep.transitiveAndroidMkSharedLibs) @@ -1469,7 +1529,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { var srcProviderDepFiles android.Paths for _, dep := range directSrcProvidersDeps { - srcs, _ := dep.OutputFiles("") + srcs := android.OutputFilesForModule(ctx, dep, "") srcProviderDepFiles = append(srcProviderDepFiles, srcs...) } for _, dep := range directSrcDeps { @@ -1856,5 +1916,3 @@ var Bool = proptools.Bool var BoolDefault = proptools.BoolDefault var String = proptools.String var StringPtr = proptools.StringPtr - -var _ android.OutputFileProducer = (*Module)(nil) diff --git a/rust/rust_test.go b/rust/rust_test.go index 8b96df8b3..0d005d0a2 100644 --- a/rust/rust_test.go +++ b/rust/rust_test.go @@ -447,23 +447,30 @@ func TestRustRlibs(t *testing.T) { export_include_dirs: ["foo_includes"] } + rust_ffi_rlib { + name: "libbuzz", + crate_name: "buzz", + srcs: ["src/lib.rs"], + export_include_dirs: ["buzz_includes"] + } + cc_library_shared { name: "libcc_shared", srcs:["foo.c"], - static_rlibs: ["libbar"], + static_libs: ["libbar"], } cc_library_static { name: "libcc_static", srcs:["foo.c"], - static_rlibs: ["libfoo"], + static_libs: ["libbuzz"], + whole_static_libs: ["libfoo"], } cc_binary { name: "ccBin", srcs:["foo.c"], - static_rlibs: ["libbar"], - static_libs: ["libcc_static"], + static_libs: ["libcc_static", "libbar"], } `) @@ -514,10 +521,13 @@ func TestRustRlibs(t *testing.T) { "-Ibar_includes", ccbin_cc.Args) } - // Make sure that direct dependencies and indirect dependencies are + // Make sure that direct dependencies and indirect whole static dependencies are // propagating correctly to the generated rlib. if !strings.Contains(ccbin_rustc.Args["libFlags"], "--extern foo=") { - t.Errorf("Missing indirect dependency libfoo when writing generated Rust staticlib: %#v", ccbin_rustc.Args["libFlags"]) + t.Errorf("Missing indirect whole_static_lib dependency libfoo when writing generated Rust staticlib: %#v", ccbin_rustc.Args["libFlags"]) + } + if strings.Contains(ccbin_rustc.Args["libFlags"], "--extern buzz=") { + t.Errorf("Indirect static_lib dependency libbuzz found when writing generated Rust staticlib: %#v", ccbin_rustc.Args["libFlags"]) } if !strings.Contains(ccbin_rustc.Args["libFlags"], "--extern bar=") { t.Errorf("Missing direct dependency libbar when writing generated Rust staticlib: %#v", ccbin_rustc.Args["libFlags"]) diff --git a/rust/test_test.go b/rust/test_test.go index 6d0ebcf28..dc796c8a4 100644 --- a/rust/test_test.go +++ b/rust/test_test.go @@ -106,12 +106,9 @@ func TestDataLibs(t *testing.T) { ctx := testRust(t, bp) - module := ctx.ModuleForTests("main_test", "android_arm64_armv8-a").Module() - testBinary := module.(*Module).compiler.(*testDecorator) - outputFiles, err := module.(android.OutputFileProducer).OutputFiles("") - if err != nil { - t.Fatalf("Expected rust_test to produce output files, error: %s", err) - } + testingModule := ctx.ModuleForTests("main_test", "android_arm64_armv8-a") + testBinary := testingModule.Module().(*Module).compiler.(*testDecorator) + outputFiles := testingModule.OutputFiles(t, "") if len(outputFiles) != 1 { t.Fatalf("expected exactly one output file. output files: [%s]", outputFiles) } @@ -168,12 +165,10 @@ func TestDataLibsRelativeInstallPath(t *testing.T) { ` ctx := testRust(t, bp) - module := ctx.ModuleForTests("main_test", "android_arm64_armv8-a").Module() + testingModule := ctx.ModuleForTests("main_test", "android_arm64_armv8-a") + module := testingModule.Module() testBinary := module.(*Module).compiler.(*testDecorator) - outputFiles, err := module.(android.OutputFileProducer).OutputFiles("") - if err != nil { - t.Fatalf("Expected rust_test to produce output files, error: %s", err) - } + outputFiles := testingModule.OutputFiles(t, "") if len(outputFiles) != 1 { t.Fatalf("expected exactly one output file. output files: [%s]", outputFiles) } diff --git a/rust/testing.go b/rust/testing.go index f31c59188..6ee49a971 100644 --- a/rust/testing.go +++ b/rust/testing.go @@ -189,11 +189,11 @@ func registerRequiredBuildComponentsForTest(ctx android.RegistrationContext) { ctx.RegisterModuleType("rust_ffi", RustFFIFactory) ctx.RegisterModuleType("rust_ffi_shared", RustFFISharedFactory) ctx.RegisterModuleType("rust_ffi_rlib", RustFFIRlibFactory) - ctx.RegisterModuleType("rust_ffi_static", RustFFIStaticRlibFactory) + ctx.RegisterModuleType("rust_ffi_static", RustFFIRlibFactory) ctx.RegisterModuleType("rust_ffi_host", RustFFIHostFactory) ctx.RegisterModuleType("rust_ffi_host_shared", RustFFISharedHostFactory) ctx.RegisterModuleType("rust_ffi_host_rlib", RustFFIRlibHostFactory) - ctx.RegisterModuleType("rust_ffi_host_static", RustFFIStaticRlibHostFactory) + ctx.RegisterModuleType("rust_ffi_host_static", RustFFIRlibHostFactory) ctx.RegisterModuleType("rust_proc_macro", ProcMacroFactory) ctx.RegisterModuleType("rust_protobuf", RustProtobufFactory) ctx.RegisterModuleType("rust_protobuf_host", RustProtobufHostFactory) |