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
This commit is contained in:
@@ -150,15 +150,11 @@ func TestDepsTracking(t *testing.T) {
|
||||
host_supported: true,
|
||||
name: "cc_stubs_dep",
|
||||
}
|
||||
rust_ffi_host_static {
|
||||
cc_library_host_static {
|
||||
name: "libstatic",
|
||||
srcs: ["foo.rs"],
|
||||
crate_name: "static",
|
||||
}
|
||||
rust_ffi_host_static {
|
||||
cc_library_host_static {
|
||||
name: "libwholestatic",
|
||||
srcs: ["foo.rs"],
|
||||
crate_name: "wholestatic",
|
||||
}
|
||||
rust_ffi_host_shared {
|
||||
name: "libshared",
|
||||
@@ -435,6 +431,105 @@ func TestRustAliases(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRustRlibs(t *testing.T) {
|
||||
ctx := testRust(t, `
|
||||
rust_ffi_rlib {
|
||||
name: "libbar",
|
||||
crate_name: "bar",
|
||||
srcs: ["src/lib.rs"],
|
||||
export_include_dirs: ["bar_includes"]
|
||||
}
|
||||
|
||||
rust_ffi_rlib {
|
||||
name: "libfoo",
|
||||
crate_name: "foo",
|
||||
srcs: ["src/lib.rs"],
|
||||
export_include_dirs: ["foo_includes"]
|
||||
}
|
||||
|
||||
cc_library_shared {
|
||||
name: "libcc_shared",
|
||||
srcs:["foo.c"],
|
||||
static_rlibs: ["libbar"],
|
||||
}
|
||||
|
||||
cc_library_static {
|
||||
name: "libcc_static",
|
||||
srcs:["foo.c"],
|
||||
static_rlibs: ["libfoo"],
|
||||
}
|
||||
|
||||
cc_binary {
|
||||
name: "ccBin",
|
||||
srcs:["foo.c"],
|
||||
static_rlibs: ["libbar"],
|
||||
static_libs: ["libcc_static"],
|
||||
}
|
||||
`)
|
||||
|
||||
libbar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_rlib_rlib-std").Rule("rustc")
|
||||
libcc_shared_rustc := ctx.ModuleForTests("libcc_shared", "android_arm64_armv8-a_shared").Rule("rustc")
|
||||
libcc_shared_ld := ctx.ModuleForTests("libcc_shared", "android_arm64_armv8-a_shared").Rule("ld")
|
||||
libcc_shared_cc := ctx.ModuleForTests("libcc_shared", "android_arm64_armv8-a_shared").Rule("cc")
|
||||
ccbin_rustc := ctx.ModuleForTests("ccBin", "android_arm64_armv8-a").Rule("rustc")
|
||||
ccbin_ld := ctx.ModuleForTests("ccBin", "android_arm64_armv8-a").Rule("ld")
|
||||
ccbin_cc := ctx.ModuleForTests("ccBin", "android_arm64_armv8-a").Rule("cc")
|
||||
|
||||
if !strings.Contains(libbar.Args["rustcFlags"], "crate-type=rlib") {
|
||||
t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", "rlib", libbar.Args["rustcFlags"])
|
||||
}
|
||||
|
||||
// Make sure there's a rustc command, and it's producing a staticlib
|
||||
if !strings.Contains(libcc_shared_rustc.Args["rustcFlags"], "crate-type=staticlib") {
|
||||
t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v",
|
||||
"staticlib", libcc_shared_rustc.Args["rustcFlags"])
|
||||
}
|
||||
|
||||
// Make sure the static lib is included in the ld command
|
||||
if !strings.Contains(libcc_shared_ld.Args["libFlags"], "generated_rust_staticlib/liblibcc_shared_rust_staticlib.a") {
|
||||
t.Errorf("missing generated static library in linker step libFlags %#v, libFlags: %#v",
|
||||
"libcc_shared.generated_rust_staticlib.a", libcc_shared_ld.Args["libFlags"])
|
||||
}
|
||||
|
||||
// Make sure the static lib includes are in the cc command
|
||||
if !strings.Contains(libcc_shared_cc.Args["cFlags"], "-Ibar_includes") {
|
||||
t.Errorf("missing rlibs includes, expecting %#v, cFlags: %#v",
|
||||
"-Ibar_includes", libcc_shared_cc.Args["cFlags"])
|
||||
}
|
||||
|
||||
// Make sure there's a rustc command, and it's producing a staticlib
|
||||
if !strings.Contains(ccbin_rustc.Args["rustcFlags"], "crate-type=staticlib") {
|
||||
t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", "staticlib", ccbin_rustc.Args["rustcFlags"])
|
||||
}
|
||||
|
||||
// Make sure the static lib is included in the cc command
|
||||
if !strings.Contains(ccbin_ld.Args["libFlags"], "generated_rust_staticlib/libccBin_rust_staticlib.a") {
|
||||
t.Errorf("missing generated static library in linker step libFlags, expecting %#v, libFlags: %#v",
|
||||
"ccBin.generated_rust_staticlib.a", ccbin_ld.Args["libFlags"])
|
||||
}
|
||||
|
||||
// Make sure the static lib includes are in the ld command
|
||||
if !strings.Contains(ccbin_cc.Args["cFlags"], "-Ibar_includes") {
|
||||
t.Errorf("missing rlibs includes, expecting %#v, cFlags: %#v",
|
||||
"-Ibar_includes", ccbin_cc.Args)
|
||||
}
|
||||
|
||||
// Make sure that direct dependencies and indirect 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"])
|
||||
}
|
||||
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"])
|
||||
}
|
||||
|
||||
// Test indirect includes propagation
|
||||
if !strings.Contains(ccbin_cc.Args["cFlags"], "-Ifoo_includes") {
|
||||
t.Errorf("missing rlibs includes, expecting %#v, cFlags: %#v",
|
||||
"-Ifoo_includes", ccbin_cc.Args)
|
||||
}
|
||||
}
|
||||
|
||||
func assertString(t *testing.T, got, expected string) {
|
||||
t.Helper()
|
||||
if got != expected {
|
||||
|
Reference in New Issue
Block a user