Merge "rust: Pass cc static libs to rustc."
diff --git a/rust/binary.go b/rust/binary.go
index 0334acc..df48916 100644
--- a/rust/binary.go
+++ b/rust/binary.go
@@ -119,6 +119,7 @@
outputFile := android.PathForModuleOut(ctx, fileName)
flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
+ flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...)
flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...)
TransformSrcToBinary(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
diff --git a/rust/compiler.go b/rust/compiler.go
index c921824..586063e 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -96,7 +96,11 @@
// list of C shared library dependencies
Shared_libs []string `android:"arch_variant"`
- // list of C static library dependencies
+ // list of C static library dependencies. Note, static libraries prefixed by "lib" will be passed to rustc
+ // along with "-lstatic=<name>". This will bundle the static library into rlib/static libraries so dependents do
+ // not need to also declare the static library as a dependency. Static libraries which are not prefixed by "lib"
+ // cannot be passed to rustc with this flag and will not be bundled into rlib/static libraries, and thus must
+ // be redeclared in dependents.
Static_libs []string `android:"arch_variant"`
// crate name, required for modules which produce Rust libraries: rust_library, rust_ffi and SourceProvider
diff --git a/rust/library.go b/rust/library.go
index b5749a2..7ff13ec 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -443,6 +443,7 @@
}
flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
+ flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...)
flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...)
if library.dylib() {
@@ -482,7 +483,6 @@
if library.rlib() || library.dylib() {
library.flagExporter.exportLinkDirs(deps.linkDirs...)
- library.flagExporter.exportDepFlags(deps.depFlags...)
library.flagExporter.exportLinkObjects(deps.linkObjects...)
}
diff --git a/rust/rust.go b/rust/rust.go
index 504b7a9..e1af776 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -280,10 +280,15 @@
SharedLibDeps android.Paths
StaticLibs android.Paths
ProcMacros RustLibraries
- linkDirs []string
- depFlags []string
- linkObjects []string
- //ReexportedDeps android.Paths
+
+ // depFlags and depLinkFlags are rustc and linker (clang) flags.
+ depFlags []string
+ depLinkFlags []string
+
+ // 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
+ linkObjects []string
// Used by bindgen modules which call clang
depClangFlags []string
@@ -328,12 +333,10 @@
type exportedFlagsProducer interface {
exportLinkDirs(...string)
- exportDepFlags(...string)
exportLinkObjects(...string)
}
type flagExporter struct {
- depFlags []string
linkDirs []string
linkObjects []string
}
@@ -342,17 +345,12 @@
flagExporter.linkDirs = android.FirstUniqueStrings(append(flagExporter.linkDirs, dirs...))
}
-func (flagExporter *flagExporter) exportDepFlags(flags ...string) {
- flagExporter.depFlags = android.FirstUniqueStrings(append(flagExporter.depFlags, flags...))
-}
-
func (flagExporter *flagExporter) exportLinkObjects(flags ...string) {
flagExporter.linkObjects = android.FirstUniqueStrings(append(flagExporter.linkObjects, flags...))
}
func (flagExporter *flagExporter) setProvider(ctx ModuleContext) {
ctx.SetProvider(FlagExporterInfoProvider, FlagExporterInfo{
- Flags: flagExporter.depFlags,
LinkDirs: flagExporter.linkDirs,
LinkObjects: flagExporter.linkObjects,
})
@@ -898,8 +896,21 @@
exportDep := false
switch {
case cc.IsStaticDepTag(depTag):
- depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
+ // Link cc static libraries using "-lstatic" so rustc can reason about how to handle these
+ // (for example, bundling them into rlibs).
+ //
+ // rustc does not support linking libraries with the "-l" flag unless they are prefixed by "lib".
+ // If we need to link a library that isn't prefixed by "lib", we'll just link to it directly through
+ // linkObjects; such a library may need to be redeclared by static dependents.
+ if libName, ok := libNameFromFilePath(linkObject.Path()); ok {
+ depPaths.depFlags = append(depPaths.depFlags, "-lstatic="+libName)
+ }
+
+ // Add this to linkObjects to pass the library directly to the linker as well. This propagates
+ // to dependencies to avoid having to redeclare static libraries for dependents of the dylib variant.
depPaths.linkObjects = append(depPaths.linkObjects, linkObject.String())
+ depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
+
exportedInfo := ctx.OtherModuleProvider(dep, cc.FlagExporterInfoProvider).(cc.FlagExporterInfo)
depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...)
depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...)
@@ -1213,6 +1224,16 @@
return false
}
+// If a library file has a "lib" prefix, extract the library name without the prefix.
+func libNameFromFilePath(filepath android.Path) (string, bool) {
+ libName := strings.TrimSuffix(filepath.Base(), filepath.Ext())
+ if strings.HasPrefix(libName, "lib") {
+ libName = libName[3:]
+ return libName, true
+ }
+ return "", false
+}
+
var Bool = proptools.Bool
var BoolDefault = proptools.BoolDefault
var String = proptools.String
diff --git a/rust/rust_test.go b/rust/rust_test.go
index abc9af9..a32c6a7 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -230,6 +230,7 @@
}
`)
module := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Module().(*Module)
+ rustc := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Rule("rustc")
// Since dependencies are added to AndroidMk* properties, we can check these to see if they've been picked up.
if !android.InList("libdylib", module.Properties.AndroidMkDylibs) {
@@ -251,6 +252,11 @@
if !android.InList("libstatic", module.Properties.AndroidMkStaticLibs) {
t.Errorf("Static library dependency not detected (dependency missing from AndroidMkStaticLibs)")
}
+
+ if !strings.Contains(rustc.Args["rustcFlags"], "-lstatic=static") {
+ t.Errorf("-lstatic flag not being passed to rustc for static library")
+ }
+
}
func TestSourceProviderDeps(t *testing.T) {