summaryrefslogtreecommitdiff
path: root/rust/rust.go
diff options
context:
space:
mode:
Diffstat (limited to 'rust/rust.go')
-rw-r--r--rust/rust.go216
1 files changed, 196 insertions, 20 deletions
diff --git a/rust/rust.go b/rust/rust.go
index 861090bcd..5e9b7af17 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -162,9 +162,36 @@ type BaseProperties struct {
// Make this module available when building for recovery
Recovery_available *bool
- // Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX).
+ // The API level that this module is built against. The APIs of this API level will be
+ // visible at build time, but use of any APIs newer than min_sdk_version will render the
+ // module unloadable on older devices. In the future it will be possible to weakly-link new
+ // APIs, making the behavior match Java: such modules will load on older devices, but
+ // calling new APIs on devices that do not support them will result in a crash.
+ //
+ // This property has the same behavior as sdk_version does for Java modules. For those
+ // familiar with Android Gradle, the property behaves similarly to how compileSdkVersion
+ // does for Java code.
+ //
+ // In addition, setting this property causes two variants to be built, one for the platform
+ // and one for apps.
+ Sdk_version *string
+
+ // Minimum OS API level supported by this C or C++ module. This property becomes the value
+ // of the __ANDROID_API__ macro. When the C or C++ module is included in an APEX or an APK,
+ // this property is also used to ensure that the min_sdk_version of the containing module is
+ // not older (i.e. less) than this module's min_sdk_version. When not set, this property
+ // defaults to the value of sdk_version. When this is set to "apex_inherit", this tracks
+ // min_sdk_version of the containing APEX. When the module
+ // is not built for an APEX, "apex_inherit" defaults to sdk_version.
Min_sdk_version *string
+ // Variant is an SDK variant created by sdkMutator
+ IsSdkVariant bool `blueprint:"mutated"`
+
+ // Set by factories of module types that can only be referenced from variants compiled against
+ // the SDK.
+ AlwaysSdk bool `blueprint:"mutated"`
+
HideFromMake bool `blueprint:"mutated"`
PreventInstall bool `blueprint:"mutated"`
@@ -209,6 +236,9 @@ type Module struct {
apexSdkVersion android.ApiLevel
transitiveAndroidMkSharedLibs depset.DepSet[string]
+
+ // Shared flags among stubs build rules of this module
+ sharedFlags cc.SharedFlags
}
func (mod *Module) Header() bool {
@@ -374,7 +404,8 @@ func (mod *Module) IsVndkPrebuiltLibrary() bool {
}
func (mod *Module) IsVendorPublicLibrary() bool {
- return mod.VendorProperties.IsVendorPublicLibrary
+ // Rust modules do not currently support vendor_public_library
+ return false
}
func (mod *Module) SdkAndPlatformVariantVisibleToMake() bool {
@@ -383,10 +414,12 @@ func (mod *Module) SdkAndPlatformVariantVisibleToMake() bool {
}
func (c *Module) IsVndkPrivate() bool {
+ // Rust modules do not currently support VNDK variants
return false
}
func (c *Module) IsLlndk() bool {
+ // Rust modules do not currently support LLNDK variants
return false
}
@@ -395,35 +428,34 @@ func (mod *Module) KernelHeadersDecorator() bool {
}
func (m *Module) NeedsLlndkVariants() bool {
+ // Rust modules do not currently support LLNDK variants
return false
}
func (m *Module) NeedsVendorPublicLibraryVariants() bool {
+ // Rust modules do not currently support vendor_public_library
return false
}
func (mod *Module) HasLlndkStubs() bool {
+ // Rust modules do not currently support LLNDK stubs
return false
}
-func (mod *Module) StubsVersion() string {
- panic(fmt.Errorf("StubsVersion called on non-versioned module: %q", mod.BaseModuleName()))
-}
-
func (mod *Module) SdkVersion() string {
- return ""
+ return String(mod.Properties.Sdk_version)
}
func (mod *Module) AlwaysSdk() bool {
- return false
+ return mod.Properties.AlwaysSdk
}
func (mod *Module) IsSdkVariant() bool {
- return false
+ return mod.Properties.IsSdkVariant
}
func (mod *Module) SplitPerApiLevel() bool {
- return false
+ return cc.CanUseSdk(mod) && mod.IsCrt()
}
func (mod *Module) XrefRustFiles() android.Paths {
@@ -561,6 +593,9 @@ func (mod *Module) ExportedCrateLinkDirs() []string {
func (mod *Module) PreventInstall() bool {
return mod.Properties.PreventInstall
}
+func (c *Module) ForceDisableSanitizers() {
+ c.sanitize.Properties.ForceDisable = true
+}
func (mod *Module) MarkAsCoverageVariant(coverage bool) {
mod.coverage.Properties.IsCoverageVariant = coverage
@@ -743,11 +778,51 @@ func (mod *Module) IsNdk(config android.Config) bool {
return false
}
+func (mod *Module) IsStubs() bool {
+ if lib, ok := mod.compiler.(libraryInterface); ok {
+ return lib.BuildStubs()
+ }
+ return false
+}
+
func (mod *Module) HasStubsVariants() bool {
+ if lib, ok := mod.compiler.(libraryInterface); ok {
+ return lib.HasStubsVariants()
+ }
return false
}
-func (mod *Module) IsStubs() bool {
+func (mod *Module) ApexSdkVersion() android.ApiLevel {
+ return mod.apexSdkVersion
+}
+
+func (mod *Module) RustApexExclude() bool {
+ return mod.ApexExclude()
+}
+
+func (mod *Module) getSharedFlags() *cc.SharedFlags {
+ shared := &mod.sharedFlags
+ if shared.FlagsMap == nil {
+ shared.NumSharedFlags = 0
+ shared.FlagsMap = make(map[string]string)
+ }
+ return shared
+}
+
+func (mod *Module) ImplementationModuleNameForMake(ctx android.BaseModuleContext) string {
+ name := mod.BaseModuleName()
+ if versioned, ok := mod.compiler.(cc.VersionedInterface); ok {
+ name = versioned.ImplementationModuleName(name)
+ }
+ return name
+}
+
+func (mod *Module) Multilib() string {
+ return mod.Arch().ArchType.Multilib
+}
+
+func (mod *Module) IsCrt() bool {
+ // Rust does not currently provide any crt modules.
return false
}
@@ -771,6 +846,7 @@ func (ctx moduleContext) apexVariationName() string {
}
var _ cc.LinkableInterface = (*Module)(nil)
+var _ cc.VersionedLinkableInterface = (*Module)(nil)
func (mod *Module) Init() android.Module {
mod.AddProperties(&mod.Properties)
@@ -881,6 +957,25 @@ func (mod *Module) nativeCoverage() bool {
return mod.compiler != nil && mod.compiler.nativeCoverage()
}
+func (mod *Module) SetStl(s string) {
+ // STL is a CC concept; do nothing for Rust
+}
+
+func (mod *Module) SetSdkVersion(s string) {
+ mod.Properties.Sdk_version = StringPtr(s)
+}
+
+func (mod *Module) SetMinSdkVersion(s string) {
+ mod.Properties.Min_sdk_version = StringPtr(s)
+}
+
+func (mod *Module) VersionedInterface() cc.VersionedInterface {
+ if _, ok := mod.compiler.(cc.VersionedInterface); ok {
+ return mod.compiler.(cc.VersionedInterface)
+ }
+ return nil
+}
+
func (mod *Module) EverInstallable() bool {
return mod.compiler != nil &&
// Check to see whether the module is actually ever installable.
@@ -1025,11 +1120,15 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
ctx.Phony("rust", ctx.RustModule().OutputFile().Path())
}
- linkableInfo := cc.CreateCommonLinkableInfo(mod)
+ linkableInfo := cc.CreateCommonLinkableInfo(ctx, mod)
linkableInfo.Static = mod.Static()
linkableInfo.Shared = mod.Shared()
linkableInfo.CrateName = mod.CrateName()
linkableInfo.ExportedCrateLinkDirs = mod.ExportedCrateLinkDirs()
+ if lib, ok := mod.compiler.(cc.VersionedInterface); ok {
+ linkableInfo.StubsVersion = lib.StubsVersion()
+ }
+
android.SetProvider(ctx, cc.LinkableInfoProvider, linkableInfo)
rustInfo := &RustInfo{
@@ -1064,6 +1163,21 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
}
android.SetProvider(ctx, RustInfoProvider, rustInfo)
+ ccInfo := &cc.CcInfo{
+ IsPrebuilt: mod.IsPrebuilt(),
+ }
+
+ // Define the linker info if compiler != nil because Rust currently
+ // does compilation and linking in one step. If this changes in the future,
+ // move this as appropriate.
+ ccInfo.LinkerInfo = &cc.LinkerInfo{
+ WholeStaticLibs: mod.compiler.baseCompilerProps().Whole_static_libs,
+ StaticLibs: mod.compiler.baseCompilerProps().Static_libs,
+ SharedLibs: mod.compiler.baseCompilerProps().Shared_libs,
+ }
+
+ android.SetProvider(ctx, cc.CcInfoProvider, ccInfo)
+
mod.setOutputFiles(ctx)
buildComplianceMetadataInfo(ctx, mod, deps)
@@ -1225,6 +1339,21 @@ func (mod *Module) begin(ctx BaseModuleContext) {
if mod.sanitize != nil {
mod.sanitize.begin(ctx)
}
+
+ if mod.UseSdk() && mod.IsSdkVariant() {
+ sdkVersion := ""
+ if ctx.Device() {
+ sdkVersion = mod.SdkVersion()
+ }
+ version, err := cc.NativeApiLevelFromUser(ctx, sdkVersion)
+ if err != nil {
+ ctx.PropertyErrorf("sdk_version", err.Error())
+ mod.Properties.Sdk_version = nil
+ } else {
+ mod.Properties.Sdk_version = StringPtr(version.String())
+ }
+ }
+
}
func (mod *Module) Prebuilt() *android.Prebuilt {
@@ -1500,9 +1629,12 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
sharedLibraryInfo, exportedInfo := cc.ChooseStubOrImpl(ctx, dep)
if !sharedLibraryInfo.IsStubs {
- depPaths.directImplementationDeps = append(depPaths.directImplementationDeps, android.OutputFileForModule(ctx, dep, ""))
- if info, ok := android.OtherModuleProvider(ctx, dep, cc.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, cc.ImplementationDepInfoProvider); ok {
+ depPaths.transitiveImplementationDeps = append(depPaths.transitiveImplementationDeps, info.ImplementationDeps)
+ }
}
}
@@ -1558,7 +1690,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
}
}
- if srcDep, ok := android.OtherModuleProvider(ctx, dep, android.SourceFilesInfoKey); ok {
+ if srcDep, ok := android.OtherModuleProvider(ctx, dep, android.SourceFilesInfoProvider); ok {
if android.IsSourceDepTagWithOutputTag(depTag, "") {
// These are usually genrules which don't have per-target variants.
directSrcDeps = append(directSrcDeps, srcDep)
@@ -1871,7 +2003,7 @@ func (mod *Module) HostToolPath() android.OptionalPath {
var _ android.ApexModule = (*Module)(nil)
// If a module is marked for exclusion from apexes, don't provide apex variants.
-// TODO(b/362509506): remove this once stubs are properly supported by rust_ffi targets.
+// TODO(b/362509506): remove this once all apex_exclude usages are removed.
func (m *Module) CanHaveApexVariants() bool {
if m.ApexExclude() {
return false
@@ -1908,6 +2040,13 @@ func (mod *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVer
}
// Implements android.ApexModule
+func (mod *Module) AlwaysRequiresPlatformApexVariant() bool {
+ // stub libraries and native bridge libraries are always available to platform
+ // TODO(b/362509506): remove the ApexExclude() check once all apex_exclude uses are switched to stubs.
+ return mod.IsStubs() || mod.Target().NativeBridge == android.NativeBridgeEnabled || mod.ApexExclude()
+}
+
+// Implements android.ApexModule
func (mod *Module) OutgoingDepIsInSameApex(depTag blueprint.DependencyTag) bool {
if depTag == procMacroDepTag || depTag == customBindgenDepTag {
return false
@@ -1920,18 +2059,55 @@ func (mod *Module) OutgoingDepIsInSameApex(depTag blueprint.DependencyTag) bool
return false
}
+ if depTag == cc.StubImplDepTag {
+ // We don't track from an implementation library to its stubs.
+ return false
+ }
+
+ if cc.ExcludeInApexDepTag(depTag) {
+ return false
+ }
+
+ // TODO(b/362509506): remove once all apex_exclude uses are switched to stubs.
+ if mod.ApexExclude() {
+ return false
+ }
+
return true
}
func (mod *Module) IncomingDepIsInSameApex(depTag blueprint.DependencyTag) bool {
- return !mod.ApexExclude()
+ // TODO(b/362509506): remove once all apex_exclude uses are switched to stubs.
+ if mod.ApexExclude() {
+ return false
+ }
+
+ if mod.HasStubsVariants() {
+ if cc.IsSharedDepTag(depTag) {
+ // dynamic dep to a stubs lib crosses APEX boundary
+ return false
+ }
+ if cc.IsRuntimeDepTag(depTag) {
+ // runtime dep to a stubs lib also crosses APEX boundary
+ return false
+ }
+ if cc.IsHeaderDepTag(depTag) {
+ return false
+ }
+ }
+ return true
}
// Overrides ApexModule.IsInstallabeToApex()
func (mod *Module) IsInstallableToApex() bool {
+ // TODO(b/362509506): remove once all apex_exclude uses are switched to stubs.
+ if mod.ApexExclude() {
+ return false
+ }
+
if mod.compiler != nil {
- if lib, ok := mod.compiler.(libraryInterface); ok && (lib.shared() || lib.dylib()) {
- return true
+ if lib, ok := mod.compiler.(libraryInterface); ok {
+ return (lib.shared() || lib.dylib()) && !lib.BuildStubs()
}
if _, ok := mod.compiler.(*binaryDecorator); ok {
return true