summaryrefslogtreecommitdiff
path: root/cc/builder.go
diff options
context:
space:
mode:
Diffstat (limited to 'cc/builder.go')
-rw-r--r--cc/builder.go51
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,