diff options
Diffstat (limited to 'rust')
-rw-r--r-- | rust/builder.go | 17 | ||||
-rw-r--r-- | rust/library.go | 9 | ||||
-rw-r--r-- | rust/rust.go | 23 | ||||
-rw-r--r-- | rust/rust_test.go | 75 |
4 files changed, 112 insertions, 12 deletions
diff --git a/rust/builder.go b/rust/builder.go index 8a869aad8..1b6a6c117 100644 --- a/rust/builder.go +++ b/rust/builder.go @@ -171,7 +171,7 @@ func TransformSrctoRlib(ctx ModuleContext, mainSrc android.Path, deps PathDeps, return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "rlib")) } -// TransformRlibstoStaticlib is assumed to be called from the cc module, and +// TransformRlibstoStaticlib is assumed to be callable from the cc module, and // thus needs to reconstruct the common set of flags which need to be passed // to the rustc compiler. func TransformRlibstoStaticlib(ctx android.ModuleContext, mainSrc android.Path, deps []cc.RustRlibDep, @@ -185,7 +185,7 @@ func TransformRlibstoStaticlib(ctx android.ModuleContext, mainSrc android.Path, rustPathDeps.linkDirs = append(rustPathDeps.linkDirs, rlibDep.LinkDirs...) } - ccModule := ctx.(cc.ModuleContext).Module().(*cc.Module) + mod := ctx.Module().(cc.LinkableInterface) toolchain := config.FindToolchain(ctx.Os(), ctx.Arch()) t := transformProperties{ // Crate name can be a predefined value as this is a staticlib and @@ -195,10 +195,10 @@ func TransformRlibstoStaticlib(ctx android.ModuleContext, mainSrc android.Path, crateName: "generated_rust_staticlib", is64Bit: toolchain.Is64Bit(), targetTriple: toolchain.RustTriple(), - bootstrap: ccModule.Bootstrap(), - inRecovery: ccModule.InRecovery(), - inRamdisk: ccModule.InRamdisk(), - inVendorRamdisk: ccModule.InVendorRamdisk(), + bootstrap: mod.Bootstrap(), + inRecovery: mod.InRecovery(), + inRamdisk: mod.InRamdisk(), + inVendorRamdisk: mod.InVendorRamdisk(), // crateType indicates what type of crate to build crateType: "staticlib", @@ -402,6 +402,11 @@ func transformSrctoCrate(ctx android.ModuleContext, main android.Path, deps Path linkFlags = append(linkFlags, dynamicLinker) } + if generatedLib := cc.GenerateRustStaticlib(ctx, deps.ccRlibDeps); generatedLib != nil { + deps.StaticLibs = append(deps.StaticLibs, generatedLib) + linkFlags = append(linkFlags, generatedLib.String()) + } + libFlags := makeLibFlags(deps) // Collect dependencies diff --git a/rust/library.go b/rust/library.go index 14d908cb6..bc7baf666 100644 --- a/rust/library.go +++ b/rust/library.go @@ -737,12 +737,15 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa if library.rlib() { library.flagExporter.exportStaticLibs(deps.staticLibObjects...) } - // Since we have FFI rlibs, we need to collect their includes as well if library.static() || library.shared() || library.rlib() || library.stubs() { - android.SetProvider(ctx, cc.FlagExporterInfoProvider, cc.FlagExporterInfo{ + ccExporter := cc.FlagExporterInfo{ IncludeDirs: android.FirstUniquePaths(library.includeDirs), - }) + } + if library.rlib() { + ccExporter.RustRlibDeps = append(ccExporter.RustRlibDeps, deps.reexportedCcRlibDeps...) + } + android.SetProvider(ctx, cc.FlagExporterInfoProvider, ccExporter) } if library.shared() || library.stubs() { diff --git a/rust/rust.go b/rust/rust.go index dfd39f739..b73f79b0b 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -495,6 +495,10 @@ type PathDeps struct { depFlags []string depLinkFlags []string + // track cc static-libs that have Rlib dependencies + reexportedCcRlibDeps []cc.RustRlibDep + ccRlibDeps []cc.RustRlibDep + // 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 @@ -1531,6 +1535,13 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { } } + if !mod.Rlib() { + depPaths.ccRlibDeps = append(depPaths.ccRlibDeps, exportedInfo.RustRlibDeps...) + } else { + // rlibs need to reexport these + depPaths.reexportedCcRlibDeps = append(depPaths.reexportedCcRlibDeps, exportedInfo.RustRlibDeps...) + } + case depTag == procMacroDepTag: directProcMacroDeps = append(directProcMacroDeps, linkableInfo) mod.Properties.AndroidMkProcMacroLibs = append(mod.Properties.AndroidMkProcMacroLibs, makeLibName) @@ -1651,8 +1662,8 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { } else { // Otherwise add to staticLibObjects, which only propagate through rlibs to their dependents. depPaths.staticLibObjects = append(depPaths.staticLibObjects, ccLibPath.String()) - } + depPaths.linkDirs = append(depPaths.linkDirs, linkPath) exportedInfo, _ := android.OtherModuleProvider(ctx, dep, cc.FlagExporterInfoProvider) @@ -1660,6 +1671,14 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...) depPaths.depClangFlags = append(depPaths.depClangFlags, exportedInfo.Flags...) depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, exportedInfo.GeneratedHeaders...) + + if !mod.Rlib() { + // rlibs don't need to build the generated static library, so they don't need to track these. + depPaths.ccRlibDeps = append(depPaths.ccRlibDeps, exportedInfo.RustRlibDeps...) + } else { + depPaths.reexportedCcRlibDeps = append(depPaths.reexportedCcRlibDeps, exportedInfo.RustRlibDeps...) + } + directStaticLibDeps = append(directStaticLibDeps, linkableInfo) // Record baseLibName for snapshots. @@ -1815,6 +1834,8 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { depPaths.depIncludePaths = android.FirstUniquePaths(depPaths.depIncludePaths) depPaths.depSystemIncludePaths = android.FirstUniquePaths(depPaths.depSystemIncludePaths) depPaths.depLinkFlags = android.FirstUniqueStrings(depPaths.depLinkFlags) + depPaths.reexportedCcRlibDeps = android.FirstUniqueFunc(depPaths.reexportedCcRlibDeps, cc.EqRustRlibDeps) + depPaths.ccRlibDeps = android.FirstUniqueFunc(depPaths.ccRlibDeps, cc.EqRustRlibDeps) return depPaths } diff --git a/rust/rust_test.go b/rust/rust_test.go index 4390f556e..2e016f0c7 100644 --- a/rust/rust_test.go +++ b/rust/rust_test.go @@ -449,12 +449,26 @@ func TestRustFFIRlibs(t *testing.T) { } rust_ffi_static { + name: "libfoo_from_rlib", + crate_name: "foo_from_rlib", + srcs: ["src/lib.rs"], + export_include_dirs: ["foo_includes"] + } + + rust_ffi_static { name: "libbuzz", crate_name: "buzz", srcs: ["src/lib.rs"], export_include_dirs: ["buzz_includes"] } + rust_ffi_static { + name: "libbuzz_from_rlib", + crate_name: "buzz_from_rlib", + srcs: ["src/lib.rs"], + export_include_dirs: ["buzz_includes"] + } + cc_library_shared { name: "libcc_shared", srcs:["foo.c"], @@ -468,12 +482,34 @@ func TestRustFFIRlibs(t *testing.T) { whole_static_libs: ["libfoo"], } + cc_library_static { + name: "libcc_static_from_rlib", + srcs:["foo.c"], + static_libs: ["libbuzz_from_rlib"], + whole_static_libs: ["libfoo_from_rlib"], + } + cc_binary { name: "ccBin", srcs:["foo.c"], static_libs: ["libcc_static", "libbar"], } - `) + + rust_library { + name: "librs", + srcs:["src/foo.rs"], + crate_name: "rs", + static_libs: ["libcc_static_from_rlib"], + } + + rust_binary { + name: "rsBin", + srcs:["src/foo.rs"], + crate_name: "rsBin", + rlibs: ["librs", "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") @@ -482,6 +518,9 @@ func TestRustFFIRlibs(t *testing.T) { 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") + rustbin_genlib := ctx.ModuleForTests("rsBin", "android_arm64_armv8-a").Output("generated_rust_staticlib/librustlibs.a") + rustbin := ctx.ModuleForTests("rsBin", "android_arm64_armv8-a").Output("unstripped/rsBin") + librs_rlib := ctx.ModuleForTests("librs", "android_arm64_armv8-a_rlib_dylib-std").MaybeOutput("generated_rust_staticlib/librustlibs.a") 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"]) @@ -513,7 +552,7 @@ func TestRustFFIRlibs(t *testing.T) { // Make sure the static lib is included in the cc command if !strings.Contains(ccbin_ld.Args["libFlags"], "generated_rust_staticlib/librustlibs.a") { t.Errorf("missing generated static library in linker step libFlags, expecting %#v, libFlags: %#v", - "ccBin.generated_rust_staticlib.a", ccbin_ld.Args["libFlags"]) + "generated_rust_staticlib/librustlibs.a", ccbin_ld.Args["libFlags"]) } // Make sure the static lib includes are in the ld command @@ -534,11 +573,43 @@ func TestRustFFIRlibs(t *testing.T) { t.Errorf("Missing direct dependency libbar when writing generated Rust staticlib: %#v", ccbin_rustc.Args["libFlags"]) } + // Make sure the static lib is included in the rustc command + if !strings.Contains(rustbin.Args["linkFlags"], "generated_rust_staticlib/librustlibs.a") { + t.Errorf("missing generated static library in linker step libFlags in Rust module, expecting %#v, libFlags: %#v", + "generated_rust_staticlib/librustlibs.a", rustbin.Args["libFlags"]) + } + + // Make sure that direct dependencies and indirect whole static dependencies are + // propagating correctly for the rlib -> cc_library_static -> rust_* generated library example. + if !strings.Contains(rustbin_genlib.Args["libFlags"], "--extern foo=") { + t.Errorf("Missing indirect whole_static_lib dependency libfoo from cc static_lib when writing generated Rust staticlib: %#v", rustbin_genlib.Args["libFlags"]) + } + if strings.Contains(rustbin_genlib.Args["libFlags"], "--extern buzz=") { + t.Errorf("Indirect rlib dependency libbuzz from cc static_lib found when writing generated Rust staticlib: %#v", rustbin_genlib.Args["libFlags"]) + } + if strings.Contains(rustbin_genlib.Args["libFlags"], "--extern bar=") { + t.Errorf("Direct rlib dependency libbar getting included in the generated Rust staticlib: %#v", rustbin_genlib.Args["libFlags"]) + } + if !strings.Contains(rustbin_genlib.Args["libFlags"], "--extern foo_from_rlib=") { + t.Errorf("Missing indirect whole_static_lib dependency libfoo_from_rlib from cc static_lib when writing generated Rust staticlib: %#v", rustbin_genlib.Args["libFlags"]) + } + if strings.Contains(rustbin_genlib.Args["libFlags"], "--extern buzz_from_rlib=") { + // While static-libs propagate for rust modules, this is not the + // expected behavior for cc modules. Thus, libbuzz_from_rlib would + // be expected to have to be re-declared as a direct rlib dependency. + t.Errorf("Indirect rlib dependency libbuzz_from_rlib from cc static_lib found when writing generated Rust staticlib: %#v", rustbin_genlib.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) } + + // Make sure we're not generating superfluous mto staticlibs. + if librs_rlib.Rule != nil { + t.Error("rlibs should not be generating mto staticlibs", "rlib", libbar.Args["rustcFlags"]) + } } func assertString(t *testing.T, got, expected string) { |