diff --git a/cc/cc.go b/cc/cc.go index c9f00e248..ddff2b03d 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -1076,6 +1076,10 @@ func (c *Module) CcLibraryInterface() bool { return false } +func (c *Module) RustLibraryInterface() bool { + return false +} + func (c *Module) IsFuzzModule() bool { if _, ok := c.compiler.(*fuzzBinary); ok { return true diff --git a/cc/fuzz.go b/cc/fuzz.go index c897501e8..636ad855b 100644 --- a/cc/fuzz.go +++ b/cc/fuzz.go @@ -535,6 +535,17 @@ func CollectAllSharedDependencies(ctx android.ModuleContext) (android.RuleBuilde }) ctx.WalkDeps(func(child, parent android.Module) bool { + + // If this is a Rust module which is not rust_ffi_shared, we still want to bundle any transitive + // shared dependencies (even for rust_ffi_static) + if rustmod, ok := child.(LinkableInterface); ok && rustmod.RustLibraryInterface() && !rustmod.Shared() { + if recursed[ctx.OtherModuleName(child)] { + return false + } + recursed[ctx.OtherModuleName(child)] = true + return true + } + if !IsValidSharedDependency(child) { return false } diff --git a/cc/linkable.go b/cc/linkable.go index 557f5d2b3..976a38201 100644 --- a/cc/linkable.go +++ b/cc/linkable.go @@ -100,6 +100,9 @@ type LinkableInterface interface { CcLibrary() bool CcLibraryInterface() bool + // RustLibraryInterface returns true if this is a Rust library module + RustLibraryInterface() bool + // BaseModuleName returns the android.ModuleBase.BaseModuleName() value for this module. BaseModuleName() string diff --git a/rust/fuzz_test.go b/rust/fuzz_test.go index 7fa9f5c8f..0aecf617e 100644 --- a/rust/fuzz_test.go +++ b/rust/fuzz_test.go @@ -19,6 +19,7 @@ import ( "testing" "android/soong/android" + "android/soong/cc" ) func TestRustFuzz(t *testing.T) { @@ -59,3 +60,68 @@ func TestRustFuzz(t *testing.T) { t.Errorf("rust_fuzz dependent library does not contain the expected flags (sancov-module, cfg fuzzing).") } } + +func TestRustFuzzDepBundling(t *testing.T) { + ctx := testRust(t, ` + cc_library { + name: "libcc_transitive_dep", + } + cc_library { + name: "libcc_direct_dep", + } + rust_library { + name: "libtest_fuzzing", + crate_name: "test_fuzzing", + srcs: ["foo.rs"], + shared_libs: ["libcc_transitive_dep"], + } + rust_fuzz { + name: "fuzz_libtest", + srcs: ["foo.rs"], + rustlibs: ["libtest_fuzzing"], + shared_libs: ["libcc_direct_dep"], + } + `) + + fuzz_libtest := ctx.ModuleForTests("fuzz_libtest", "android_arm64_armv8-a_fuzzer").Module().(*Module) + + if !strings.Contains(fuzz_libtest.FuzzSharedLibraries().String(), ":libcc_direct_dep.so") { + t.Errorf("rust_fuzz does not contain the expected bundled direct shared libs ('libcc_direct_dep'): %#v", fuzz_libtest.FuzzSharedLibraries().String()) + } + if !strings.Contains(fuzz_libtest.FuzzSharedLibraries().String(), ":libcc_transitive_dep.so") { + t.Errorf("rust_fuzz does not contain the expected bundled transitive shared libs ('libcc_transitive_dep'): %#v", fuzz_libtest.FuzzSharedLibraries().String()) + } +} + +func TestCCFuzzDepBundling(t *testing.T) { + ctx := testRust(t, ` + cc_library { + name: "libcc_transitive_dep", + } + rust_ffi { + name: "libtest_fuzzing", + 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_libs: ["libtest_fuzzing"], + } + + `) + + fuzz_shared_libtest := ctx.ModuleForTests("fuzz_shared_libtest", "android_arm64_armv8-a_fuzzer").Module().(cc.LinkableInterface) + fuzz_static_libtest := ctx.ModuleForTests("fuzz_static_libtest", "android_arm64_armv8-a_fuzzer").Module().(cc.LinkableInterface) + + if !strings.Contains(fuzz_shared_libtest.FuzzSharedLibraries().String(), ":libcc_transitive_dep.so") { + t.Errorf("cc_fuzz does not contain the expected bundled transitive shared libs from rust_ffi_shared ('libcc_transitive_dep'): %#v", fuzz_shared_libtest.FuzzSharedLibraries().String()) + } + if !strings.Contains(fuzz_static_libtest.FuzzSharedLibraries().String(), ":libcc_transitive_dep.so") { + t.Errorf("cc_fuzz does not contain the expected bundled transitive shared libs from rust_ffi_static ('libcc_transitive_dep'): %#v", fuzz_static_libtest.FuzzSharedLibraries().String()) + } +} diff --git a/rust/rust.go b/rust/rust.go index 4324ecbb9..e524c9fb6 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -631,6 +631,15 @@ func (mod *Module) CcLibraryInterface() bool { return false } +func (mod *Module) RustLibraryInterface() bool { + if mod.compiler != nil { + if _, ok := mod.compiler.(libraryInterface); ok { + return true + } + } + return false +} + func (mod *Module) IsFuzzModule() bool { if _, ok := mod.compiler.(*fuzzDecorator); ok { return true