diff options
author | 2024-05-13 21:03:34 -0400 | |
---|---|---|
committer | 2024-05-16 13:00:43 -0400 | |
commit | 0a468a4f3b1c9dea9b31ca51cebd3db58d65e771 (patch) | |
tree | 9ee8007e83b660eb7bb4affcbf6584ea3fdab82e /rust/library_test.go | |
parent | 28ed8f4f83551ca651dd3831eb5b0a23567f5fa6 (diff) |
rust: made-to-order rust staticlibs
Whenever any two Rust static libraries are included
as static libraries anywhere in a CC dependency tree, we sometimes
get duplicate symbol errors. To avoid this, we no longer
directly link multiple rust static libs to CC modules.
Instead, we build rust_ffi_rlib modules and produce the actual
static library that gets linked against the CC module based on
that CC module's full list of Rust rlib dependencies.
This introduces a new static_rlibs property for cc modules to
define the rust_ffi_rlib dependencies, which are then used to
generate the module above.
This CL is intended to deprecate rust_ffi_static. It leaves
rust_ffi_static and rust_ffi static variants in place until
the remaining rust_ffi_static declarations and uses can be
removed. In the meantime, rust_ffi_static produces
rust_ffi_rlib variants as well to make the transition easier.
Bug: 254469782
Test: m # with no changes
Test: m libapexsupport # with static_rlibs
Test: m libunwindstack # with static_rlibs
Test: m netsimd # with static_rlibs, no duplicate symbols
Test: m blueprint_tests # New Soong tests
Change-Id: I47e27ac967ef0cad46d398ebf59d8275929ae28a
Diffstat (limited to 'rust/library_test.go')
-rw-r--r-- | rust/library_test.go | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/rust/library_test.go b/rust/library_test.go index 7275b66c1..1133c28ed 100644 --- a/rust/library_test.go +++ b/rust/library_test.go @@ -37,9 +37,10 @@ func TestLibraryVariants(t *testing.T) { }`) // 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") - libfooStatic := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_static").Rule("rustc") + libfooFFIRlib := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_rlib_rlib-std").Rule("rustc") libfooShared := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_shared").Rule("rustc") rlibCrateType := "rlib" @@ -62,6 +63,11 @@ func TestLibraryVariants(t *testing.T) { 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"]) + } + // Test crate type for C shared libraries is correct. if !strings.Contains(libfooShared.Args["rustcFlags"], "crate-type="+sharedCrateType) { t.Errorf("missing crate-type for shared variant, expecting %#v, got rustcFlags: %#v", sharedCrateType, libfooShared.Args["rustcFlags"]) @@ -182,15 +188,20 @@ func TestSharedLibraryToc(t *testing.T) { func TestStaticLibraryLinkage(t *testing.T) { ctx := testRust(t, ` - rust_ffi_static { + rust_ffi { name: "libfoo", srcs: ["foo.rs"], crate_name: "foo", }`) - libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static") + 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) } @@ -198,6 +209,12 @@ func TestStaticLibraryLinkage(t *testing.T) { func TestNativeDependencyOfRlib(t *testing.T) { ctx := testRust(t, ` + rust_ffi_rlib { + name: "libffi_rlib", + crate_name: "ffi_rlib", + rlibs: ["librust_rlib"], + srcs: ["foo.rs"], + } rust_ffi_static { name: "libffi_static", crate_name: "ffi_static", @@ -224,10 +241,12 @@ func TestNativeDependencyOfRlib(t *testing.T) { 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, } @@ -290,27 +309,28 @@ func TestAutoDeps(t *testing.T) { 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} { + for _, static := range []android.TestingModule{libfooRlib, libfooStatic, libfooFFIRlib} { if !android.InList("libbar.rlib-std", static.Module().(*Module).Properties.AndroidMkRlibs) { - t.Errorf("libbar not present as rlib dependency in static lib") + t.Errorf("libbar not present as rlib dependency in static lib: %s", static.Module().Name()) } if android.InList("libbar", static.Module().(*Module).Properties.AndroidMkDylibs) { - t.Errorf("libbar present as dynamic dependency in static lib") + t.Errorf("libbar present as dynamic dependency in static lib: %s", static.Module().Name()) } } for _, dyn := range []android.TestingModule{libfooDylib, libfooShared} { if !android.InList("libbar", dyn.Module().(*Module).Properties.AndroidMkDylibs) { - t.Errorf("libbar not present as dynamic dependency in dynamic lib") + t.Errorf("libbar not present as dynamic dependency in dynamic lib: %s", dyn.Module().Name()) } if android.InList("libbar", dyn.Module().(*Module).Properties.AndroidMkRlibs) { - t.Errorf("libbar present as rlib dependency in dynamic lib") + t.Errorf("libbar present as rlib dependency in dynamic lib: %s", dyn.Module().Name()) } if !android.InList("librlib_only", dyn.Module().(*Module).Properties.AndroidMkRlibs) { - t.Errorf("librlib_only should be selected by rustlibs as an rlib.") + t.Errorf("librlib_only should be selected by rustlibs as an rlib: %s.", dyn.Module().Name()) } } } @@ -375,6 +395,7 @@ func TestLibstdLinkage(t *testing.T) { 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. libbarRlibStd := ctx.ModuleForTests("libbar.prefer_rlib", "android_arm64_armv8-a_shared").Module().(*Module) @@ -398,6 +419,12 @@ func TestLibstdLinkage(t *testing.T) { 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") + } + if !android.InList("libfoo.rlib-std", libbarFFIRlib.Properties.AndroidMkRlibs) { + t.Errorf("Device rust_ffi_rlib does not link dependent rustlib rlib-std variant") + } if !android.InList("libstd", libbarRlibStd.Properties.AndroidMkRlibs) { t.Errorf("rust_ffi with prefer_rlib does not link libstd as an rlib") } |