rust: Add stub support for rust_ffi modules
This adds stubs support for rust_ffi and rust_ffi_shared modules. Usage
should match current cc usage. The stubs generator leveraged is the cc
stubs generator.
Bug: 203478530
Test: m blueprint_tests
Change-Id: I043b9714a357cd5fe17c183ccdf86900f5172e0e
diff --git a/cc/builder.go b/cc/builder.go
index 56b7139..5325116 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -851,6 +851,25 @@
return strings.Join(lines, "\n")
}
+func BuildRustStubs(ctx android.ModuleContext, outputFile android.ModuleOutPath,
+ crtBegin, crtEnd android.Paths, stubObjs Objects, ccFlags Flags) {
+
+ // Instantiate paths
+ sharedLibs := android.Paths{}
+ staticLibs := android.Paths{}
+ lateStaticLibs := android.Paths{}
+ wholeStaticLibs := android.Paths{}
+ deps := android.Paths{}
+ implicitOutputs := android.WritablePaths{}
+ validations := android.Paths{}
+ groupLate := false
+
+ builderFlags := flagsToBuilderFlags(ccFlags)
+ transformObjToDynamicBinary(ctx, stubObjs.objFiles, sharedLibs, staticLibs,
+ lateStaticLibs, wholeStaticLibs, deps, crtBegin, crtEnd,
+ groupLate, builderFlags, outputFile, implicitOutputs, validations)
+}
+
// 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,
diff --git a/cc/cc.go b/cc/cc.go
index 0db5c40..57b5e3c 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -160,6 +160,8 @@
Installable *bool
// RelativeInstallPath returns the relative install path for this module.
RelativeInstallPath string
+ // TODO(b/362509506): remove this once all apex_exclude uses are switched to stubs.
+ RustApexExclude bool
}
var LinkableInfoProvider = blueprint.NewProvider[*LinkableInfo]()
@@ -943,6 +945,11 @@
return depTag == runtimeDepTag
}
+func ExcludeInApexDepTag(depTag blueprint.DependencyTag) bool {
+ ccLibDepTag, ok := depTag.(libraryDependencyTag)
+ return ok && ccLibDepTag.excludeInApex
+}
+
// Module contains the properties and members used by all C/C++ module types, and implements
// the blueprint.Module interface. It delegates to compiler, linker, and installer interfaces
// to construct the output file. Behavior can be customized with a Customizer, or "decorator",
@@ -1529,6 +1536,10 @@
return false
}
+func (c *Module) RustApexExclude() bool {
+ return false
+}
+
func (c *Module) IsStubsImplementationRequired() bool {
if lib := c.library; lib != nil {
return lib.IsStubsImplementationRequired()
@@ -2360,6 +2371,8 @@
OnlyInRecovery: mod.OnlyInRecovery(),
Installable: mod.Installable(),
RelativeInstallPath: mod.RelativeInstallPath(),
+ // TODO(b/362509506): remove this once all apex_exclude uses are switched to stubs.
+ RustApexExclude: mod.RustApexExclude(),
}
}
@@ -3354,9 +3367,12 @@
depFile = sharedLibraryInfo.TableOfContents
if !sharedLibraryInfo.IsStubs {
- depPaths.directImplementationDeps = append(depPaths.directImplementationDeps, android.OutputFileForModule(ctx, dep, ""))
- if info, ok := android.OtherModuleProvider(ctx, dep, ImplementationDepInfoProvider); ok {
- depPaths.transitiveImplementationDeps = append(depPaths.transitiveImplementationDeps, info.ImplementationDeps)
+ // TODO(b/362509506): remove this additional check once all apex_exclude uses are switched to stubs.
+ if !linkableInfo.RustApexExclude {
+ depPaths.directImplementationDeps = append(depPaths.directImplementationDeps, android.OutputFileForModule(ctx, dep, ""))
+ if info, ok := android.OtherModuleProvider(ctx, dep, ImplementationDepInfoProvider); ok {
+ depPaths.transitiveImplementationDeps = append(depPaths.transitiveImplementationDeps, info.ImplementationDeps)
+ }
}
}
diff --git a/cc/compiler.go b/cc/compiler.go
index 1899f59..3730bbe 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -360,7 +360,7 @@
}
}
-func addTargetFlags(ctx android.ModuleContext, flags Flags, tc config.Toolchain, version string, bpf bool) Flags {
+func AddTargetFlags(ctx android.ModuleContext, flags Flags, tc config.Toolchain, version string, bpf bool) Flags {
target := "-target " + tc.ClangTriple()
if ctx.Os().Class == android.Device {
if version == "" || version == "current" {
@@ -536,7 +536,7 @@
flags.Local.ConlyFlags = config.ClangFilterUnknownCflags(flags.Local.ConlyFlags)
flags.Local.LdFlags = config.ClangFilterUnknownCflags(flags.Local.LdFlags)
- flags = addTargetFlags(ctx, flags, tc, ctx.minSdkVersion(), Bool(compiler.Properties.Bpf_target))
+ flags = AddTargetFlags(ctx, flags, tc, ctx.minSdkVersion(), Bool(compiler.Properties.Bpf_target))
hod := "Host"
if ctx.Os().Class == android.Device {
diff --git a/cc/coverage.go b/cc/coverage.go
index 4e058bd..c8ff82b 100644
--- a/cc/coverage.go
+++ b/cc/coverage.go
@@ -354,7 +354,7 @@
}
}
-func parseSymbolFileForAPICoverage(ctx android.ModuleContext, symbolFile string) android.ModuleOutPath {
+func ParseSymbolFileForAPICoverage(ctx android.ModuleContext, symbolFile string) android.ModuleOutPath {
apiLevelsJson := android.GetApiLevelsJson(ctx)
symbolFilePath := android.PathForModuleSrc(ctx, symbolFile)
outputFile := ctx.Module().(LinkableInterface).BaseModuleName() + ".xml"
diff --git a/cc/library.go b/cc/library.go
index 7b225ec..950ea91 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -460,7 +460,7 @@
return props
}
-func commonLibraryLinkerFlags(ctx android.ModuleContext, flags Flags,
+func CommonLibraryLinkerFlags(ctx android.ModuleContext, flags Flags,
toolchain config.Toolchain, libName string) Flags {
mod, ok := ctx.Module().(LinkableInterface)
@@ -511,7 +511,7 @@
// shared library).
func (library *libraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
flags = library.baseLinker.linkerFlags(ctx, flags)
- flags = commonLibraryLinkerFlags(ctx, flags, ctx.toolchain(), library.getLibName(ctx))
+ flags = CommonLibraryLinkerFlags(ctx, flags, ctx.toolchain(), library.getLibName(ctx))
if library.static() {
flags.Local.CFlags = append(flags.Local.CFlags, library.StaticProperties.Static.Cflags.GetOrDefault(ctx, nil)...)
} else if library.shared() {
@@ -558,7 +558,7 @@
flags.Local.CommonFlags = removeInclude(flags.Local.CommonFlags)
flags.Local.CFlags = removeInclude(flags.Local.CFlags)
- flags = addStubLibraryCompilerFlags(flags)
+ flags = AddStubLibraryCompilerFlags(flags)
}
return flags
}
@@ -735,7 +735,7 @@
nativeAbiResult.VersionScript)
// Parse symbol file to get API list for coverage
if library.StubsVersion() == "current" && ctx.PrimaryArch() && !ctx.inRecovery() && !ctx.inProduct() && !ctx.inVendor() {
- library.apiListCoverageXmlPath = parseSymbolFileForAPICoverage(ctx, symbolFile)
+ library.apiListCoverageXmlPath = ParseSymbolFileForAPICoverage(ctx, symbolFile)
}
return objs
@@ -2360,10 +2360,6 @@
// setStubsVersions normalizes the versions in the Stubs.Versions property into MutatedProperties.AllStubsVersions.
func setStubsVersions(mctx android.BaseModuleContext, module VersionedLinkableInterface) {
- // TODO(ivanlozano) remove this when Rust supports stubs
- if module.RustLibraryInterface() {
- return
- }
if !module.BuildSharedVariant() || !canBeVersionVariant(module) {
return
}
@@ -2385,10 +2381,6 @@
return []string{""}
}
if m, ok := ctx.Module().(VersionedLinkableInterface); ok {
- // TODO(ivanlozano) remove this when Rust supports stubs
- if m.RustLibraryInterface() {
- return []string{""}
- }
if m.CcLibraryInterface() && canBeVersionVariant(m) {
setStubsVersions(ctx, m)
return append(slices.Clone(m.VersionedInterface().AllStubsVersions()), "")
@@ -2439,11 +2431,6 @@
m, ok := ctx.Module().(VersionedLinkableInterface)
if library := moduleVersionedInterface(ctx.Module()); library != nil && canBeVersionVariant(m) {
- // TODO(ivanlozano) remove this when Rust supports stubs
- if m.RustLibraryInterface() {
- return
- }
-
isLLNDK := m.IsLlndk()
isVendorPublicLibrary := m.IsVendorPublicLibrary()
diff --git a/cc/linkable.go b/cc/linkable.go
index d0fda64..337b459 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -84,6 +84,10 @@
SetMinSdkVersion(version string)
ApexSdkVersion() android.ApiLevel
ImplementationModuleNameForMake(ctx android.BaseModuleContext) string
+
+ // RustApexExclude returns ApexExclude() for Rust modules; always returns false for all non-Rust modules.
+ // TODO(b/362509506): remove this once all apex_exclude uses are switched to stubs.
+ RustApexExclude() bool
}
// LinkableInterface is an interface for a type of module that is linkable in a C++ library.
diff --git a/cc/linker.go b/cc/linker.go
index 20c2f4a..f854937 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -471,7 +471,7 @@
// ModuleContext extends BaseModuleContext
// BaseModuleContext should know if LLD is used?
-func commonLinkerFlags(ctx android.ModuleContext, flags Flags, useClangLld bool,
+func CommonLinkerFlags(ctx android.ModuleContext, flags Flags, useClangLld bool,
toolchain config.Toolchain, allow_undefined_symbols bool) Flags {
hod := "Host"
if ctx.Os().Class == android.Device {
@@ -480,7 +480,7 @@
mod, ok := ctx.Module().(LinkableInterface)
if !ok {
- ctx.ModuleErrorf("trying to add commonLinkerFlags to non-LinkableInterface module.")
+ ctx.ModuleErrorf("trying to add CommonLinkerFlags to non-LinkableInterface module.")
return flags
}
if useClangLld {
@@ -531,7 +531,7 @@
toolchain := ctx.toolchain()
allow_undefined_symbols := Bool(linker.Properties.Allow_undefined_symbols)
- flags = commonLinkerFlags(ctx, flags, linker.useClangLld(ctx), toolchain,
+ flags = CommonLinkerFlags(ctx, flags, linker.useClangLld(ctx), toolchain,
allow_undefined_symbols)
if !toolchain.Bionic() && ctx.Os() != android.LinuxMusl {
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 4321beb..1f0fc07 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -236,7 +236,7 @@
pctx.StaticVariable("StubLibraryCompilerFlags", strings.Join(stubLibraryCompilerFlags, " "))
}
-func addStubLibraryCompilerFlags(flags Flags) Flags {
+func AddStubLibraryCompilerFlags(flags Flags) Flags {
flags.Global.CFlags = append(flags.Global.CFlags, stubLibraryCompilerFlags...)
// All symbols in the stubs library should be visible.
if inList("-fvisibility=hidden", flags.Local.CFlags) {
@@ -247,7 +247,7 @@
func (stub *stubDecorator) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
flags = stub.baseCompiler.compilerFlags(ctx, flags, deps)
- return addStubLibraryCompilerFlags(flags)
+ return AddStubLibraryCompilerFlags(flags)
}
type NdkApiOutputs struct {
@@ -510,7 +510,7 @@
}
}
if c.apiLevel.IsCurrent() && ctx.PrimaryArch() {
- c.parsedCoverageXmlPath = parseSymbolFileForAPICoverage(ctx, symbolFile)
+ c.parsedCoverageXmlPath = ParseSymbolFileForAPICoverage(ctx, symbolFile)
}
return objs
}
diff --git a/cc/stub_library.go b/cc/stub_library.go
index 2291153..9d7b5bc 100644
--- a/cc/stub_library.go
+++ b/cc/stub_library.go
@@ -59,10 +59,6 @@
vendorStubLibraryMap := make(map[string]bool)
ctx.VisitAllModules(func(module android.Module) {
if m, ok := module.(VersionedLinkableInterface); ok {
- // TODO(ivanlozano) remove this when Rust supports stubs
- if m.RustLibraryInterface() {
- return
- }
if IsStubTarget(android.OtherModuleProviderOrDefault(ctx, m, LinkableInfoProvider)) {
if name := getInstalledFileName(ctx, m); name != "" {
stubLibraryMap[name] = true