cc/rust: Alias ffi rlib variant for static_libs
Alias the rlib variant to "link: static". This allows declaring
rust_ffi_rlib modules in static_libs. This effectively removes any
distinction between rust_ffi_static and rust_ffi_rlib. Removing the
functionality for building Rust staticlib modules will be cleaned up in
a follow-on CL.
This should have the effect of changing the default linkage for all rust
modules in static_libs from linking individual staticlibs to building a
single staticlib that includes all rust_ffi rlib dependencies.
This removes the static_rlibs property, as we're now handling
the choice dynamically. This also makes rlibs only propagate through
cc_library_static modules if the rlib is included in
whole_static_lib. This both mirrors the expected behavior of
cc libraries and helps control which version of a crate ends up in the
final link (e.g. libdoh_ffi vs libdoh_ffi_for_test).
Bug: 254469782
Test: m
Test: m blueprint_tests
Change-Id: I2925f67f6dc9329dae3dcccafb8560900ac8a6fc
diff --git a/cc/builder.go b/cc/builder.go
index 8719d4f..367bda3 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -798,9 +798,12 @@
// 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
+ // This should only be reachable if a module defines Rust deps in static_libs 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()))
+ panic(fmt.Errorf(
+ "TransformRlibstoStaticlib is not set and rust deps are defined in static_libs for %s",
+ ctx.ModuleName()))
+
} else if len(rlibDeps) == 0 {
return nil
}
@@ -829,6 +832,7 @@
func genRustStaticlibSrcFile(crateNames []string) string {
lines := []string{
"// @Soong generated Source",
+ "#![no_std]", // pre-emptively set no_std to support both std and no_std.
}
for _, crate := range crateNames {
lines = append(lines, fmt.Sprintf("extern crate %s;", crate))
diff --git a/cc/cc.go b/cc/cc.go
index d8fe319..9a2540d 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -99,7 +99,6 @@
StaticLibs, LateStaticLibs, WholeStaticLibs []string
HeaderLibs []string
RuntimeLibs []string
- Rlibs []string
// UnexportedStaticLibs are static libraries that are also passed to -Wl,--exclude-libs= to
// prevent automatically exporting symbols.
@@ -746,11 +745,6 @@
return d.Kind == staticLibraryDependency
}
-// rlib returns true if the libraryDependencyTag is tagging an rlib dependency.
-func (d libraryDependencyTag) rlib() bool {
- return d.Kind == rlibLibraryDependency
-}
-
func (d libraryDependencyTag) LicenseAnnotations() []android.LicenseAnnotation {
if d.shared() {
return []android.LicenseAnnotation{android.LicenseAnnotationSharedDependency}
@@ -917,6 +911,8 @@
hideApexVariantFromMake bool
logtagsPaths android.Paths
+
+ WholeRustStaticlib bool
}
func (c *Module) AddJSONData(d *map[string]interface{}) {
@@ -1192,6 +1188,16 @@
panic(fmt.Errorf("BuildSharedVariant called on non-library module: %q", c.BaseModuleName()))
}
+func (c *Module) BuildRlibVariant() bool {
+ // cc modules can never build rlib variants
+ return false
+}
+
+func (c *Module) IsRustFFI() bool {
+ // cc modules are not Rust modules
+ return false
+}
+
func (c *Module) Module() android.Module {
return c
}
@@ -2267,7 +2273,6 @@
deps.WholeStaticLibs = android.LastUniqueStrings(deps.WholeStaticLibs)
deps.StaticLibs = android.LastUniqueStrings(deps.StaticLibs)
- deps.Rlibs = android.LastUniqueStrings(deps.Rlibs)
deps.LateStaticLibs = android.LastUniqueStrings(deps.LateStaticLibs)
deps.SharedLibs = android.LastUniqueStrings(deps.SharedLibs)
deps.LateSharedLibs = android.LastUniqueStrings(deps.LateSharedLibs)
@@ -2562,28 +2567,20 @@
}
for _, lib := range deps.StaticLibs {
+ // Some dependencies listed in static_libs might actually be rust_ffi rlib variants.
depTag := libraryDependencyTag{Kind: staticLibraryDependency}
+
if inList(lib, deps.ReexportStaticLibHeaders) {
depTag.reexportFlags = true
}
if inList(lib, deps.ExcludeLibsForApex) {
depTag.excludeInApex = true
}
-
actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "static"},
}, depTag, lib)
}
- for _, lib := range deps.Rlibs {
- depTag := libraryDependencyTag{Kind: rlibLibraryDependency}
- actx.AddVariationDependencies([]blueprint.Variation{
- {Mutator: "link", Variation: ""},
- {Mutator: "rust_libraries", Variation: "rlib"},
- {Mutator: "rust_stdlinkage", Variation: "rlib-std"},
- }, depTag, lib)
- }
-
// staticUnwinderDep is treated as staticDep for Q apexes
// so that native libraries/binaries are linked with static unwinder
// because Q libc doesn't have unwinder APIs
@@ -3171,78 +3168,86 @@
panic(fmt.Errorf("unexpected library dependency order %d", libDepTag.Order))
}
- case libDepTag.rlib():
- rlibDep := RustRlibDep{LibPath: linkFile.Path(), CrateName: ccDep.CrateName(), LinkDirs: ccDep.ExportedCrateLinkDirs()}
- depPaths.ReexportedRustRlibDeps = append(depPaths.ReexportedRustRlibDeps, rlibDep)
- depPaths.RustRlibDeps = append(depPaths.RustRlibDeps, rlibDep)
- depPaths.IncludeDirs = append(depPaths.IncludeDirs, depExporterInfo.IncludeDirs...)
- depPaths.ReexportedDirs = append(depPaths.ReexportedDirs, depExporterInfo.IncludeDirs...)
-
case libDepTag.static():
- staticLibraryInfo, isStaticLib := android.OtherModuleProvider(ctx, dep, StaticLibraryInfoProvider)
- if !isStaticLib {
- if !ctx.Config().AllowMissingDependencies() {
- ctx.ModuleErrorf("module %q is not a static library", depName)
- } else {
- ctx.AddMissingDependencies([]string{depName})
- }
- return
- }
+ if ccDep.RustLibraryInterface() {
+ rlibDep := RustRlibDep{LibPath: linkFile.Path(), CrateName: ccDep.CrateName(), LinkDirs: ccDep.ExportedCrateLinkDirs()}
+ depPaths.RustRlibDeps = append(depPaths.RustRlibDeps, rlibDep)
+ depPaths.IncludeDirs = append(depPaths.IncludeDirs, depExporterInfo.IncludeDirs...)
+ if libDepTag.wholeStatic {
+ depPaths.ReexportedDirs = append(depPaths.ReexportedDirs, depExporterInfo.IncludeDirs...)
+ depPaths.ReexportedRustRlibDeps = append(depPaths.ReexportedRustRlibDeps, rlibDep)
- // Stubs lib doesn't link to the static lib dependencies. Don't set
- // linkFile, depFile, and ptr.
- if c.IsStubs() {
- break
- }
-
- linkFile = android.OptionalPathForPath(staticLibraryInfo.StaticLibrary)
- if libDepTag.wholeStatic {
- ptr = &depPaths.WholeStaticLibs
- if len(staticLibraryInfo.Objects.objFiles) > 0 {
- depPaths.WholeStaticLibObjs = depPaths.WholeStaticLibObjs.Append(staticLibraryInfo.Objects)
- } else {
- // This case normally catches prebuilt static
- // libraries, but it can also occur when
- // AllowMissingDependencies is on and the
- // dependencies has no sources of its own
- // but has a whole_static_libs dependency
- // on a missing library. We want to depend
- // on the .a file so that there is something
- // in the dependency tree that contains the
- // error rule for the missing transitive
- // dependency.
- depPaths.WholeStaticLibsFromPrebuilts = append(depPaths.WholeStaticLibsFromPrebuilts, linkFile.Path())
+ // If whole_static, track this as we want to make sure that in a final linkage for a shared library,
+ // exported functions from the rust generated staticlib still exported.
+ if c.CcLibrary() && c.Shared() {
+ c.WholeRustStaticlib = true
+ }
}
- depPaths.WholeStaticLibsFromPrebuilts = append(depPaths.WholeStaticLibsFromPrebuilts,
- staticLibraryInfo.WholeStaticLibsFromPrebuilts...)
+
} else {
- switch libDepTag.Order {
- case earlyLibraryDependency:
- panic(fmt.Errorf("early static libs not suppported"))
- case normalLibraryDependency:
- // static dependencies will be handled separately so they can be ordered
- // using transitive dependencies.
- ptr = nil
- directStaticDeps = append(directStaticDeps, staticLibraryInfo)
- case lateLibraryDependency:
- ptr = &depPaths.LateStaticLibs
- default:
- panic(fmt.Errorf("unexpected library dependency order %d", libDepTag.Order))
+ staticLibraryInfo, isStaticLib := android.OtherModuleProvider(ctx, dep, StaticLibraryInfoProvider)
+ if !isStaticLib {
+ if !ctx.Config().AllowMissingDependencies() {
+ ctx.ModuleErrorf("module %q is not a static library", depName)
+ } else {
+ ctx.AddMissingDependencies([]string{depName})
+ }
+ return
}
- }
- // We re-export the Rust static_rlibs so rlib dependencies don't need to be redeclared by cc_library_static dependents.
- // E.g. libfoo (cc_library_static) depends on libfoo.ffi (a rust_ffi rlib), libbar depending on libfoo shouldn't have to also add libfoo.ffi to static_rlibs.
- depPaths.ReexportedRustRlibDeps = append(depPaths.ReexportedRustRlibDeps, depExporterInfo.RustRlibDeps...)
- depPaths.RustRlibDeps = append(depPaths.RustRlibDeps, depExporterInfo.RustRlibDeps...)
+ // Stubs lib doesn't link to the static lib dependencies. Don't set
+ // linkFile, depFile, and ptr.
+ if c.IsStubs() {
+ break
+ }
- if libDepTag.unexportedSymbols {
- depPaths.LdFlags = append(depPaths.LdFlags,
- "-Wl,--exclude-libs="+staticLibraryInfo.StaticLibrary.Base())
+ linkFile = android.OptionalPathForPath(staticLibraryInfo.StaticLibrary)
+ if libDepTag.wholeStatic {
+ ptr = &depPaths.WholeStaticLibs
+ if len(staticLibraryInfo.Objects.objFiles) > 0 {
+ depPaths.WholeStaticLibObjs = depPaths.WholeStaticLibObjs.Append(staticLibraryInfo.Objects)
+ } else {
+ // This case normally catches prebuilt static
+ // libraries, but it can also occur when
+ // AllowMissingDependencies is on and the
+ // dependencies has no sources of its own
+ // but has a whole_static_libs dependency
+ // on a missing library. We want to depend
+ // on the .a file so that there is something
+ // in the dependency tree that contains the
+ // error rule for the missing transitive
+ // dependency.
+ depPaths.WholeStaticLibsFromPrebuilts = append(depPaths.WholeStaticLibsFromPrebuilts, linkFile.Path())
+ }
+ depPaths.WholeStaticLibsFromPrebuilts = append(depPaths.WholeStaticLibsFromPrebuilts,
+ staticLibraryInfo.WholeStaticLibsFromPrebuilts...)
+ } else {
+ switch libDepTag.Order {
+ case earlyLibraryDependency:
+ panic(fmt.Errorf("early static libs not supported"))
+ case normalLibraryDependency:
+ // static dependencies will be handled separately so they can be ordered
+ // using transitive dependencies.
+ ptr = nil
+ directStaticDeps = append(directStaticDeps, staticLibraryInfo)
+ case lateLibraryDependency:
+ ptr = &depPaths.LateStaticLibs
+ default:
+ panic(fmt.Errorf("unexpected library dependency order %d", libDepTag.Order))
+ }
+ }
+
+ // Collect any exported Rust rlib deps from static libraries which have been included as whole_static_libs
+ depPaths.RustRlibDeps = append(depPaths.RustRlibDeps, depExporterInfo.RustRlibDeps...)
+
+ if libDepTag.unexportedSymbols {
+ depPaths.LdFlags = append(depPaths.LdFlags,
+ "-Wl,--exclude-libs="+staticLibraryInfo.StaticLibrary.Base())
+ }
}
}
- if libDepTag.static() && !libDepTag.wholeStatic {
+ if libDepTag.static() && !libDepTag.wholeStatic && !ccDep.RustLibraryInterface() {
if !ccDep.CcLibraryInterface() || !ccDep.Static() {
ctx.ModuleErrorf("module %q not a static library", depName)
return
@@ -3329,12 +3334,14 @@
c.Properties.AndroidMkSharedLibs = append(
c.Properties.AndroidMkSharedLibs, makeLibName)
case libDepTag.static():
- if libDepTag.wholeStatic {
- c.Properties.AndroidMkWholeStaticLibs = append(
- c.Properties.AndroidMkWholeStaticLibs, makeLibName)
- } else {
- c.Properties.AndroidMkStaticLibs = append(
- c.Properties.AndroidMkStaticLibs, makeLibName)
+ if !ccDep.RustLibraryInterface() {
+ if libDepTag.wholeStatic {
+ c.Properties.AndroidMkWholeStaticLibs = append(
+ c.Properties.AndroidMkWholeStaticLibs, makeLibName)
+ } else {
+ c.Properties.AndroidMkStaticLibs = append(
+ c.Properties.AndroidMkStaticLibs, makeLibName)
+ }
}
}
} else if !c.IsStubs() {
diff --git a/cc/compiler.go b/cc/compiler.go
index d8446fb..a3347b0 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -796,9 +796,6 @@
// be added to the include path using -I
Local_include_dirs []string `android:"arch_variant,variant_prepend"`
- // list of Rust static libraries.
- Static_rlibs []string `android:"arch_variant,variant_prepend"`
-
// list of static libraries that provide headers for this binding.
Static_libs []string `android:"arch_variant,variant_prepend"`
diff --git a/cc/library.go b/cc/library.go
index e49f50c..4373b46 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -1135,8 +1135,12 @@
linkerDeps = append(linkerDeps, deps.SharedLibsDeps...)
linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
- if generatedLib := generateRustStaticlib(ctx, deps.RustRlibDeps); generatedLib != nil {
- deps.StaticLibs = append(deps.StaticLibs, generatedLib)
+ if generatedLib := generateRustStaticlib(ctx, deps.RustRlibDeps); generatedLib != nil && !library.buildStubs() {
+ if ctx.Module().(*Module).WholeRustStaticlib {
+ deps.WholeStaticLibs = append(deps.WholeStaticLibs, generatedLib)
+ } else {
+ deps.StaticLibs = append(deps.StaticLibs, generatedLib)
+ }
}
transformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs,
@@ -2149,7 +2153,6 @@
modules := mctx.CreateLocalVariations(variations...)
static := modules[0].(LinkableInterface)
shared := modules[1].(LinkableInterface)
-
static.SetStatic()
shared.SetShared()
@@ -2173,6 +2176,12 @@
mctx.CreateLocalVariations(variations...)
mctx.AliasVariation(variations[0])
}
+ if library.BuildRlibVariant() && library.IsRustFFI() && !buildStatic {
+ // Rust modules do not build static libs, but rlibs are used as if they
+ // were via `static_libs`. Thus we need to alias the BuildRlibVariant
+ // to "static" for Rust FFI libraries.
+ mctx.CreateAliasVariation("static", "")
+ }
}
}
diff --git a/cc/linkable.go b/cc/linkable.go
index 2309fe8..1672366 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -94,12 +94,16 @@
SelectedStl() string
BuildStaticVariant() bool
+ BuildRlibVariant() bool
BuildSharedVariant() bool
SetStatic()
SetShared()
IsPrebuilt() bool
Toc() android.OptionalPath
+ // IsRustFFI returns true if this is a Rust FFI library.
+ IsRustFFI() bool
+
// IsFuzzModule returns true if this a *_fuzz module.
IsFuzzModule() bool
diff --git a/cc/linker.go b/cc/linker.go
index 1675df6..d2974c2 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -39,9 +39,6 @@
// the dependency's .a file will be linked into this module using -Wl,--whole-archive.
Whole_static_libs []string `android:"arch_variant,variant_prepend"`
- // list of Rust libs that should be statically linked into this module.
- Static_rlibs []string `android:"arch_variant"`
-
// list of modules that should be statically linked into this module.
Static_libs []string `android:"arch_variant,variant_prepend"`
@@ -127,10 +124,6 @@
// variant of the C/C++ module.
Header_libs []string
- // list of Rust libs that should be statically linked to build vendor or product
- // variant.
- Static_rlibs []string
-
// list of shared libs that should not be used to build vendor or
// product variant of the C/C++ module.
Exclude_shared_libs []string
@@ -159,10 +152,6 @@
// variant of the C/C++ module.
Static_libs []string
- // list of Rust libs that should be statically linked to build the recovery
- // variant.
- Static_rlibs []string
-
// list of shared libs that should not be used to build
// the recovery variant of the C/C++ module.
Exclude_shared_libs []string
@@ -184,10 +173,6 @@
// variant of the C/C++ module.
Static_libs []string
- // list of Rust libs that should be statically linked to build the ramdisk
- // variant.
- Static_rlibs []string
-
// list of shared libs that should not be used to build
// the ramdisk variant of the C/C++ module.
Exclude_shared_libs []string
@@ -205,10 +190,6 @@
// the vendor ramdisk variant of the C/C++ module.
Exclude_shared_libs []string
- // list of Rust libs that should be statically linked to build the vendor ramdisk
- // variant.
- Static_rlibs []string
-
// list of static libs that should not be used to build
// the vendor ramdisk variant of the C/C++ module.
Exclude_static_libs []string
@@ -224,10 +205,6 @@
// variants.
Shared_libs []string
- // list of Rust libs that should be statically linked to build the vendor ramdisk
- // variant.
- Static_rlibs []string
-
// list of ehader libs that only should be used to build platform variant of
// the C/C++ module.
Header_libs []string
@@ -322,7 +299,6 @@
deps.WholeStaticLibs = append(deps.WholeStaticLibs, linker.Properties.Whole_static_libs...)
deps.HeaderLibs = append(deps.HeaderLibs, linker.Properties.Header_libs...)
deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Static_libs...)
- deps.Rlibs = append(deps.Rlibs, linker.Properties.Static_rlibs...)
deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Shared_libs...)
deps.RuntimeLibs = append(deps.RuntimeLibs, linker.Properties.Runtime_libs...)
@@ -366,7 +342,6 @@
deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Vendor.Exclude_static_libs)
deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Vendor.Exclude_static_libs)
deps.RuntimeLibs = removeListFromList(deps.RuntimeLibs, linker.Properties.Target.Vendor.Exclude_runtime_libs)
- deps.Rlibs = append(deps.Rlibs, linker.Properties.Target.Vendor.Static_rlibs...)
}
if ctx.inProduct() {
@@ -380,7 +355,6 @@
deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Product.Exclude_static_libs)
deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Product.Exclude_static_libs)
deps.RuntimeLibs = removeListFromList(deps.RuntimeLibs, linker.Properties.Target.Product.Exclude_runtime_libs)
- deps.Rlibs = append(deps.Rlibs, linker.Properties.Target.Product.Static_rlibs...)
}
if ctx.inRecovery() {
@@ -394,7 +368,6 @@
deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Recovery.Exclude_static_libs)
deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Recovery.Exclude_static_libs)
deps.RuntimeLibs = removeListFromList(deps.RuntimeLibs, linker.Properties.Target.Recovery.Exclude_runtime_libs)
- deps.Rlibs = append(deps.Rlibs, linker.Properties.Target.Recovery.Static_rlibs...)
}
if ctx.inRamdisk() {
@@ -405,7 +378,6 @@
deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Ramdisk.Exclude_static_libs)
deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Ramdisk.Exclude_static_libs)
deps.RuntimeLibs = removeListFromList(deps.RuntimeLibs, linker.Properties.Target.Ramdisk.Exclude_runtime_libs)
- deps.Rlibs = append(deps.Rlibs, linker.Properties.Target.Ramdisk.Static_rlibs...)
}
if ctx.inVendorRamdisk() {
@@ -415,7 +387,6 @@
deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Vendor_ramdisk.Exclude_static_libs)
deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Vendor_ramdisk.Exclude_static_libs)
deps.RuntimeLibs = removeListFromList(deps.RuntimeLibs, linker.Properties.Target.Vendor_ramdisk.Exclude_runtime_libs)
- deps.Rlibs = append(deps.Rlibs, linker.Properties.Target.Vendor_ramdisk.Static_rlibs...)
}
if !ctx.useSdk() {