diff options
Diffstat (limited to 'rust/rust.go')
-rw-r--r-- | rust/rust.go | 216 |
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 |