diff options
Diffstat (limited to 'cc/builder.go')
-rw-r--r-- | cc/builder.go | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/cc/builder.go b/cc/builder.go index e78b8c0de..3eed1f266 100644 --- a/cc/builder.go +++ b/cc/builder.go @@ -19,6 +19,7 @@ package cc // functions. import ( + "fmt" "path/filepath" "runtime" "strconv" @@ -330,6 +331,15 @@ var ( CommandDeps: []string{"$cxxExtractor", "$kytheVnames"}, }, "cFlags") + + // Function pointer for producting staticlibs from rlibs. Corresponds to + // rust.TransformRlibstoStaticlib(), initialized in soong-rust (rust/builder.go init()) + // + // This is required since soong-rust depends on soong-cc, so soong-cc cannot depend on soong-rust + // without resulting in a circular dependency. Setting this function pointer in soong-rust allows + // soong-cc to call into this particular function. + TransformRlibstoStaticlib (func(ctx android.ModuleContext, mainSrc android.Path, deps []RustRlibDep, + outputFile android.WritablePath) android.Path) = nil ) func PwdPrefix() string { @@ -774,6 +784,47 @@ func transformObjToStaticLib(ctx android.ModuleContext, } } +// Generate a Rust staticlib from a list of rlibDeps. Returns nil if TransformRlibstoStaticlib is nil or rlibDeps is empty. +func generateRustStaticlib(ctx android.ModuleContext, rlibDeps []RustRlibDep) android.Path { + if TransformRlibstoStaticlib == nil && len(rlibDeps) > 0 { + // This should only be reachable if a module defines static_rlibs and + // soong-rust hasn't been loaded alongside soong-cc (e.g. in soong-cc tests). + panic(fmt.Errorf("TransformRlibstoStaticlib is not set and static_rlibs is defined in %s", ctx.ModuleName())) + } else if len(rlibDeps) == 0 { + return nil + } + + output := android.PathForModuleOut(ctx, "generated_rust_staticlib", "lib"+ctx.ModuleName()+"_rust_staticlib.a") + stemFile := output.ReplaceExtension(ctx, "rs") + crateNames := []string{} + + // Collect crate names + for _, lib := range rlibDeps { + // Exclude libstd so this can support no_std builds. + if lib.CrateName != "libstd" { + crateNames = append(crateNames, lib.CrateName) + } + } + + // Deduplicate any crateNames just to be safe + crateNames = android.FirstUniqueStrings(crateNames) + + // Write the source file + android.WriteFileRule(ctx, stemFile, genRustStaticlibSrcFile(crateNames)) + + return TransformRlibstoStaticlib(ctx, stemFile, rlibDeps, output) +} + +func genRustStaticlibSrcFile(crateNames []string) string { + lines := []string{ + "// @Soong generated Source", + } + for _, crate := range crateNames { + lines = append(lines, fmt.Sprintf("extern crate %s;", crate)) + } + return strings.Join(lines, "\n") +} + // Generate a rule for compiling multiple .o files, plus static libraries, whole static libraries, // and shared libraries, to a shared library (.so) or dynamic executable func transformObjToDynamicBinary(ctx android.ModuleContext, |