diff options
59 files changed, 1177 insertions, 707 deletions
diff --git a/Android.bp b/Android.bp index 6c4066160..523f55c4b 100644 --- a/Android.bp +++ b/Android.bp @@ -147,6 +147,16 @@ all_apex_contributions { // Framework guests. cc_defaults { name: "cc_baremetal_defaults", + arch: { + arm64: { + cflags: [ + // Prevent the compiler from optimizing code using SVE, as the + // baremetal environment might not have configured the hardware. + "-Xclang -target-feature", + "-Xclang -sve", + ], + }, + }, defaults_visibility: ["//visibility:public"], } diff --git a/android/androidmk.go b/android/androidmk.go index 7d6b05673..c081ba372 100644 --- a/android/androidmk.go +++ b/android/androidmk.go @@ -165,7 +165,7 @@ type AndroidMkExtraEntriesContext interface { type androidMkExtraEntriesContext struct { ctx fillInEntriesContext - mod blueprint.Module + mod Module } func (a *androidMkExtraEntriesContext) Provider(provider blueprint.AnyProviderKey) (any, bool) { @@ -352,8 +352,8 @@ func (d *distCopies) Strings() (ret []string) { } // Compute the contributions that the module makes to the dist. -func (a *AndroidMkEntries) getDistContributions(mod blueprint.Module) *distContributions { - amod := mod.(Module).base() +func (a *AndroidMkEntries) getDistContributions(mod Module) *distContributions { + amod := mod.base() name := amod.BaseModuleName() // Collate the set of associated tag/paths available for copying to the dist. @@ -390,7 +390,7 @@ func (a *AndroidMkEntries) getDistContributions(mod blueprint.Module) *distContr // Collate the contributions this module makes to the dist. distContributions := &distContributions{} - if !exemptFromRequiredApplicableLicensesProperty(mod.(Module)) { + if !exemptFromRequiredApplicableLicensesProperty(mod) { distContributions.licenseMetadataFile = info.LicenseMetadataFile } @@ -501,7 +501,7 @@ func generateDistContributionsForMake(distContributions *distContributions) []st // Compute the list of Make strings to declare phony goals and dist-for-goals // calls from the module's dist and dists properties. -func (a *AndroidMkEntries) GetDistForGoals(mod blueprint.Module) []string { +func (a *AndroidMkEntries) GetDistForGoals(mod Module) []string { distContributions := a.getDistContributions(mod) if distContributions == nil { return nil @@ -522,11 +522,10 @@ type fillInEntriesContext interface { HasMutatorFinished(mutatorName string) bool } -func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint.Module) { +func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod Module) { a.entryContext = ctx a.EntryMap = make(map[string][]string) - amod := mod.(Module) - base := amod.base() + base := mod.base() name := base.BaseModuleName() if a.OverrideName != "" { name = a.OverrideName @@ -535,10 +534,10 @@ func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint if a.Include == "" { a.Include = "$(BUILD_PREBUILT)" } - a.Required = append(a.Required, amod.RequiredModuleNames(ctx)...) - a.Required = append(a.Required, amod.VintfFragmentModuleNames(ctx)...) - a.Host_required = append(a.Host_required, amod.HostRequiredModuleNames()...) - a.Target_required = append(a.Target_required, amod.TargetRequiredModuleNames()...) + a.Required = append(a.Required, mod.RequiredModuleNames(ctx)...) + a.Required = append(a.Required, mod.VintfFragmentModuleNames(ctx)...) + a.Host_required = append(a.Host_required, mod.HostRequiredModuleNames()...) + a.Target_required = append(a.Target_required, mod.TargetRequiredModuleNames()...) for _, distString := range a.GetDistForGoals(mod) { fmt.Fprintln(&a.header, distString) @@ -554,7 +553,7 @@ func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint a.AddStrings("LOCAL_REQUIRED_MODULES", a.Required...) a.AddStrings("LOCAL_HOST_REQUIRED_MODULES", a.Host_required...) a.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", a.Target_required...) - a.AddStrings("LOCAL_SOONG_MODULE_TYPE", ctx.ModuleType(amod)) + a.AddStrings("LOCAL_SOONG_MODULE_TYPE", ctx.ModuleType(mod)) // If the install rule was generated by Soong tell Make about it. info := OtherModuleProviderOrDefault(ctx, mod, InstallFilesProvider) @@ -718,10 +717,10 @@ func AndroidMkSingleton() Singleton { type androidMkSingleton struct{} -func allModulesSorted(ctx SingletonContext) []blueprint.Module { - var allModules []blueprint.Module +func allModulesSorted(ctx SingletonContext) []Module { + var allModules []Module - ctx.VisitAllModulesBlueprint(func(module blueprint.Module) { + ctx.VisitAllModules(func(module Module) { allModules = append(allModules, module) }) @@ -776,20 +775,9 @@ func (so *soongOnlyAndroidMkSingleton) GenerateBuildActions(ctx SingletonContext // In soong-only mode, we don't do most of the androidmk stuff. But disted files are still largely // defined through the androidmk mechanisms, so this function is an alternate implementation of // the androidmk singleton that just focuses on getting the dist contributions -func (so *soongOnlyAndroidMkSingleton) soongOnlyBuildActions(ctx SingletonContext, mods []blueprint.Module) { +func (so *soongOnlyAndroidMkSingleton) soongOnlyBuildActions(ctx SingletonContext, mods []Module) { allDistContributions, moduleInfoJSONs := getSoongOnlyDataFromMods(ctx, mods) - for _, provider := range append(makeVarsInitProviders, *getSingletonMakevarsProviders(ctx.Config())...) { - mctx := &makeVarsContext{ - SingletonContext: ctx, - pctx: provider.pctx, - } - provider.call(mctx) - if contribution := distsToDistContributions(mctx.dists); contribution != nil { - allDistContributions = append(allDistContributions, *contribution) - } - } - singletonDists := getSingletonDists(ctx.Config()) singletonDists.lock.Lock() if contribution := distsToDistContributions(singletonDists.dists); contribution != nil { @@ -897,7 +885,7 @@ func distsToDistContributions(dists []dist) *distContributions { // getSoongOnlyDataFromMods gathers data from the given modules needed in soong-only builds. // Currently, this is the dist contributions, and the module-info.json contents. -func getSoongOnlyDataFromMods(ctx fillInEntriesContext, mods []blueprint.Module) ([]distContributions, []*ModuleInfoJSON) { +func getSoongOnlyDataFromMods(ctx fillInEntriesContext, mods []Module) ([]distContributions, []*ModuleInfoJSON) { var allDistContributions []distContributions var moduleInfoJSONs []*ModuleInfoJSON for _, mod := range mods { @@ -907,7 +895,7 @@ func getSoongOnlyDataFromMods(ctx fillInEntriesContext, mods []blueprint.Module) } } - if amod, ok := mod.(Module); ok && shouldSkipAndroidMkProcessing(ctx, amod.base()) { + if shouldSkipAndroidMkProcessing(ctx, mod.base()) { continue } if info, ok := OtherModuleProvider(ctx, mod, AndroidMkInfoProvider); ok { @@ -966,37 +954,12 @@ func getSoongOnlyDataFromMods(ctx fillInEntriesContext, mods []blueprint.Module) } } } - if x, ok := mod.(ModuleMakeVarsProvider); ok { - mctx := &makeVarsContext{ - SingletonContext: ctx.(SingletonContext), - config: ctx.Config(), - pctx: pctx, - } - if !x.Enabled(ctx) { - continue - } - x.MakeVars(mctx) - if contribution := distsToDistContributions(mctx.dists); contribution != nil { - allDistContributions = append(allDistContributions, *contribution) - } - } - if x, ok := mod.(SingletonMakeVarsProvider); ok { - mctx := &makeVarsContext{ - SingletonContext: ctx.(SingletonContext), - config: ctx.Config(), - pctx: pctx, - } - x.MakeVars(mctx) - if contribution := distsToDistContributions(mctx.dists); contribution != nil { - allDistContributions = append(allDistContributions, *contribution) - } - } } } return allDistContributions, moduleInfoJSONs } -func translateAndroidMk(ctx SingletonContext, absMkFile string, moduleInfoJSONPath WritablePath, mods []blueprint.Module) error { +func translateAndroidMk(ctx SingletonContext, absMkFile string, moduleInfoJSONPath WritablePath, mods []Module) error { buf := &bytes.Buffer{} var moduleInfoJSONs []*ModuleInfoJSON @@ -1011,8 +974,8 @@ func translateAndroidMk(ctx SingletonContext, absMkFile string, moduleInfoJSONPa return err } - if amod, ok := mod.(Module); ok && ctx.PrimaryModule(amod) == amod { - typeStats[ctx.ModuleType(amod)] += 1 + if ctx.PrimaryModule(mod) == mod { + typeStats[ctx.ModuleType(mod)] += 1 } } @@ -1056,7 +1019,7 @@ func writeModuleInfoJSON(ctx SingletonContext, moduleInfoJSONs []*ModuleInfoJSON return nil } -func translateAndroidMkModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON, mod blueprint.Module) error { +func translateAndroidMkModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON, mod Module) error { defer func() { if r := recover(); r != nil { panic(fmt.Errorf("%s in translateAndroidMkModule for module %s variant %s", @@ -1087,7 +1050,7 @@ func translateAndroidMkModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs return err } -func (data *AndroidMkData) fillInData(ctx fillInEntriesContext, mod blueprint.Module) { +func (data *AndroidMkData) fillInData(ctx fillInEntriesContext, mod Module) { // Get the preamble content through AndroidMkEntries logic. data.Entries = AndroidMkEntries{ Class: data.Class, @@ -1110,9 +1073,9 @@ func (data *AndroidMkData) fillInData(ctx fillInEntriesContext, mod blueprint.Mo // A support func for the deprecated AndroidMkDataProvider interface. Use AndroidMkEntryProvider // instead. func translateAndroidModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON, - mod blueprint.Module, provider AndroidMkDataProvider) error { + mod Module, provider AndroidMkDataProvider) error { - amod := mod.(Module).base() + amod := mod.base() if shouldSkipAndroidMkProcessing(ctx, amod) { return nil } @@ -1124,7 +1087,7 @@ func translateAndroidModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs * } data.fillInData(ctx, mod) - aconfigUpdateAndroidMkData(ctx, mod.(Module), &data) + aconfigUpdateAndroidMkData(ctx, mod, &data) prefix := "" if amod.ArchSpecific() { @@ -1205,13 +1168,13 @@ func WriteAndroidMkData(w io.Writer, data AndroidMkData) { } func translateAndroidMkEntriesModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON, - mod blueprint.Module, provider AndroidMkEntriesProvider) error { - if shouldSkipAndroidMkProcessing(ctx, mod.(Module).base()) { + mod Module, provider AndroidMkEntriesProvider) error { + if shouldSkipAndroidMkProcessing(ctx, mod.base()) { return nil } entriesList := provider.AndroidMkEntries() - aconfigUpdateAndroidMkEntries(ctx, mod.(Module), &entriesList) + aconfigUpdateAndroidMkEntries(ctx, mod, &entriesList) moduleInfoJSON, providesModuleInfoJSON := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider) @@ -1371,15 +1334,15 @@ type AndroidMkProviderInfoProducer interface { var AndroidMkInfoProvider = blueprint.NewProvider[*AndroidMkProviderInfo]() func translateAndroidMkEntriesInfoModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON, - mod blueprint.Module, providerInfo *AndroidMkProviderInfo) error { - if shouldSkipAndroidMkProcessing(ctx, mod.(Module).base()) { + mod Module, providerInfo *AndroidMkProviderInfo) error { + if shouldSkipAndroidMkProcessing(ctx, mod.base()) { return nil } // Deep copy the provider info since we need to modify the info later info := deepCopyAndroidMkProviderInfo(providerInfo) - aconfigUpdateAndroidMkInfos(ctx, mod.(Module), &info) + aconfigUpdateAndroidMkInfos(ctx, mod, &info) // Any new or special cases here need review to verify correct propagation of license information. info.PrimaryInfo.fillInEntries(ctx, mod) @@ -1515,13 +1478,12 @@ func (a *AndroidMkInfo) AddCompatibilityTestSuites(suites ...string) { a.AddStrings("LOCAL_COMPATIBILITY_SUITE", suites...) } -func (a *AndroidMkInfo) fillInEntries(ctx fillInEntriesContext, mod blueprint.Module) { +func (a *AndroidMkInfo) fillInEntries(ctx fillInEntriesContext, mod Module) { helperInfo := AndroidMkInfo{ EntryMap: make(map[string][]string), } - amod := mod.(Module) - base := amod.base() + base := mod.base() name := base.BaseModuleName() if a.OverrideName != "" { name = a.OverrideName @@ -1530,10 +1492,10 @@ func (a *AndroidMkInfo) fillInEntries(ctx fillInEntriesContext, mod blueprint.Mo if a.Include == "" { a.Include = "$(BUILD_PREBUILT)" } - a.Required = append(a.Required, amod.RequiredModuleNames(ctx)...) - a.Required = append(a.Required, amod.VintfFragmentModuleNames(ctx)...) - a.Host_required = append(a.Host_required, amod.HostRequiredModuleNames()...) - a.Target_required = append(a.Target_required, amod.TargetRequiredModuleNames()...) + a.Required = append(a.Required, mod.RequiredModuleNames(ctx)...) + a.Required = append(a.Required, mod.VintfFragmentModuleNames(ctx)...) + a.Host_required = append(a.Host_required, mod.HostRequiredModuleNames()...) + a.Target_required = append(a.Target_required, mod.TargetRequiredModuleNames()...) for _, distString := range a.GetDistForGoals(ctx, mod) { a.HeaderStrings = append(a.HeaderStrings, distString) @@ -1549,7 +1511,7 @@ func (a *AndroidMkInfo) fillInEntries(ctx fillInEntriesContext, mod blueprint.Mo helperInfo.AddStrings("LOCAL_REQUIRED_MODULES", a.Required...) helperInfo.AddStrings("LOCAL_HOST_REQUIRED_MODULES", a.Host_required...) helperInfo.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", a.Target_required...) - helperInfo.AddStrings("LOCAL_SOONG_MODULE_TYPE", ctx.ModuleType(amod)) + helperInfo.AddStrings("LOCAL_SOONG_MODULE_TYPE", ctx.ModuleType(mod)) // If the install rule was generated by Soong tell Make about it. info := OtherModuleProviderOrDefault(ctx, mod, InstallFilesProvider) @@ -1690,7 +1652,7 @@ func (a *AndroidMkInfo) write(w io.Writer) { // Compute the list of Make strings to declare phony goals and dist-for-goals // calls from the module's dist and dists properties. -func (a *AndroidMkInfo) GetDistForGoals(ctx fillInEntriesContext, mod blueprint.Module) []string { +func (a *AndroidMkInfo) GetDistForGoals(ctx fillInEntriesContext, mod Module) []string { distContributions := a.getDistContributions(ctx, mod) if distContributions == nil { return nil @@ -1700,8 +1662,8 @@ func (a *AndroidMkInfo) GetDistForGoals(ctx fillInEntriesContext, mod blueprint. } // Compute the contributions that the module makes to the dist. -func (a *AndroidMkInfo) getDistContributions(ctx fillInEntriesContext, mod blueprint.Module) *distContributions { - amod := mod.(Module).base() +func (a *AndroidMkInfo) getDistContributions(ctx fillInEntriesContext, mod Module) *distContributions { + amod := mod.base() name := amod.BaseModuleName() // Collate the set of associated tag/paths available for copying to the dist. @@ -1738,7 +1700,7 @@ func (a *AndroidMkInfo) getDistContributions(ctx fillInEntriesContext, mod bluep // Collate the contributions this module makes to the dist. distContributions := &distContributions{} - if !exemptFromRequiredApplicableLicensesProperty(mod.(Module)) { + if !exemptFromRequiredApplicableLicensesProperty(mod) { distContributions.licenseMetadataFile = info.LicenseMetadataFile } diff --git a/android/apex.go b/android/apex.go index 780d091bf..91fa2c718 100644 --- a/android/apex.go +++ b/android/apex.go @@ -282,11 +282,8 @@ type ApexModule interface { // check-platform-availability mutator in the apex package. SetNotAvailableForPlatform() - // Returns nil (success) if this module should support the given sdk version. Returns an - // error if not. No default implementation is provided for this method. A module type - // implementing this interface should provide an implementation. A module supports an sdk - // version when the module's min_sdk_version is equal to or less than the given sdk version. - ShouldSupportSdkVersion(ctx BaseModuleContext, sdkVersion ApiLevel) error + // Returns the min sdk version that the module supports, . + MinSdkVersionSupported(ctx BaseModuleContext) ApiLevel // Returns true if this module needs a unique variation per apex, effectively disabling the // deduping. This is turned on when, for example if use_apex_name_macro is set so that each @@ -729,22 +726,21 @@ func CheckMinSdkVersion(ctx ModuleContext, minSdkVersion ApiLevel, walk WalkPayl if !IsDepInSameApex(ctx, from, to) { return false } - if m, ok := to.(ModuleWithMinSdkVersionCheck); ok { - // This dependency performs its own min_sdk_version check, just make sure it sets min_sdk_version - // to trigger the check. - if !m.MinSdkVersion(ctx).Specified() { - ctx.OtherModuleErrorf(m, "must set min_sdk_version") + if info, ok := OtherModuleProvider(ctx, to, CommonModuleInfoKey); ok && info.ModuleWithMinSdkVersionCheck { + if info.MinSdkVersion.ApiLevel == nil || !info.MinSdkVersion.ApiLevel.Specified() { + // This dependency performs its own min_sdk_version check, just make sure it sets min_sdk_version + // to trigger the check. + ctx.OtherModuleErrorf(to, "must set min_sdk_version") } return false } - if err := to.ShouldSupportSdkVersion(ctx, minSdkVersion); err != nil { - toName := ctx.OtherModuleName(to) + if err := ShouldSupportSdkVersion(ctx, to, minSdkVersion); err != nil { ctx.OtherModuleErrorf(to, "should support min_sdk_version(%v) for %q: %v."+ "\n\nDependency path: %s\n\n"+ "Consider adding 'min_sdk_version: %q' to %q", minSdkVersion, ctx.ModuleName(), err.Error(), ctx.GetPathString(false), - minSdkVersion, toName) + minSdkVersion, ctx.OtherModuleName(to)) return false } return true @@ -757,6 +753,24 @@ type MinSdkVersionFromValueContext interface { ModuleErrorContext } +// Returns nil (success) if this module should support the given sdk version. Returns an +// error if not. No default implementation is provided for this method. A module type +// implementing this interface should provide an implementation. A module supports an sdk +// version when the module's min_sdk_version is equal to or less than the given sdk version. +func ShouldSupportSdkVersion(ctx BaseModuleContext, module Module, sdkVersion ApiLevel) error { + info, ok := OtherModuleProvider(ctx, module, CommonModuleInfoKey) + if !ok || info.MinSdkVersionSupported.IsNone() { + return fmt.Errorf("min_sdk_version is not specified") + } + minVer := info.MinSdkVersionSupported + + if minVer.GreaterThan(sdkVersion) { + return fmt.Errorf("newer SDK(%v)", minVer) + } + + return nil +} + // Construct ApiLevel object from min_sdk_version string value func MinSdkVersionFromValue(ctx MinSdkVersionFromValueContext, value string) ApiLevel { if value == "" { diff --git a/android/api_levels.go b/android/api_levels.go index b4fa251bc..c042eebee 100644 --- a/android/api_levels.go +++ b/android/api_levels.go @@ -252,6 +252,9 @@ var NoneApiLevel = ApiLevel{ isPreview: true, } +// A special ApiLevel that all modules should at least support. +var MinApiLevel = ApiLevel{number: 1} + // Sentinel ApiLevel to validate that an apiLevel is either an int or a recognized codename. var InvalidApiLevel = NewInvalidApiLevel("invalid") @@ -465,6 +468,7 @@ func getApiLevelsMapReleasedVersions() (map[string]int, error) { "Tiramisu": 33, "UpsideDownCake": 34, "VanillaIceCream": 35, + "Baklava": 36, }, nil } diff --git a/android/base_module_context.go b/android/base_module_context.go index 2c47e1583..5e05f547a 100644 --- a/android/base_module_context.go +++ b/android/base_module_context.go @@ -91,6 +91,11 @@ type BaseModuleContext interface { // This method shouldn't be used directly, prefer the type-safe android.OtherModuleProvider instead. otherModuleProvider(m blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) + // OtherModuleHasProvider returns true if the module has the given provider set. This + // can avoid copying the provider if the caller only cares about the existence of + // the provider. + OtherModuleHasProvider(m blueprint.Module, provider blueprint.AnyProviderKey) bool + // OtherModuleIsAutoGenerated returns true if the module is auto generated by another module // instead of being defined in Android.bp file. OtherModuleIsAutoGenerated(m blueprint.Module) bool @@ -303,6 +308,10 @@ func (b *baseModuleContext) otherModuleProvider(m blueprint.Module, provider blu return b.bp.OtherModuleProvider(getWrappedModule(m), provider) } +func (b *baseModuleContext) OtherModuleHasProvider(m blueprint.Module, provider blueprint.AnyProviderKey) bool { + return b.bp.OtherModuleHasProvider(getWrappedModule(m), provider) +} + func (b *baseModuleContext) OtherModuleIsAutoGenerated(m blueprint.Module) bool { return b.bp.OtherModuleIsAutoGenerated(m) } diff --git a/android/config.go b/android/config.go index acaad60ad..3867c1197 100644 --- a/android/config.go +++ b/android/config.go @@ -394,6 +394,17 @@ type partialCompileFlags struct { // Add others as needed. } +// These are the flags when `SOONG_PARTIAL_COMPILE` is empty or not set. +var defaultPartialCompileFlags = partialCompileFlags{ + Enabled: false, +} + +// These are the flags when `SOONG_PARTIAL_COMPILE=true`. +var enabledPartialCompileFlags = partialCompileFlags{ + Enabled: true, + Use_d8: true, +} + type deviceConfig struct { config *config OncePer @@ -427,11 +438,6 @@ type jsonConfigurable interface { // To add a new feature to the list, add the field in the struct // `partialCompileFlags` above, and then add the name of the field in the // switch statement below. -var defaultPartialCompileFlags = partialCompileFlags{ - // Set any opt-out flags here. Opt-in flags are off by default. - Enabled: false, -} - func (c *config) parsePartialCompileFlags(isEngBuild bool) (partialCompileFlags, error) { if !isEngBuild { return partialCompileFlags{}, nil @@ -472,8 +478,7 @@ func (c *config) parsePartialCompileFlags(isEngBuild bool) (partialCompileFlags, } switch tok { case "true": - ret = defaultPartialCompileFlags - ret.Enabled = true + ret = enabledPartialCompileFlags case "false": // Set everything to false. ret = partialCompileFlags{} diff --git a/android/config_test.go b/android/config_test.go index 4bdf05f0e..3d8686041 100644 --- a/android/config_test.go +++ b/android/config_test.go @@ -239,10 +239,10 @@ func TestPartialCompile(t *testing.T) { }{ {"", true, defaultPartialCompileFlags}, {"false", true, partialCompileFlags{}}, - {"true", true, defaultPartialCompileFlags.updateEnabled(true)}, + {"true", true, enabledPartialCompileFlags}, {"true", false, partialCompileFlags{}}, - {"true,use_d8", true, defaultPartialCompileFlags.updateEnabled(true).updateUseD8(true)}, - {"true,-use_d8", true, defaultPartialCompileFlags.updateEnabled(true).updateUseD8(false)}, + {"true,use_d8", true, enabledPartialCompileFlags.updateUseD8(true)}, + {"true,-use_d8", true, enabledPartialCompileFlags.updateUseD8(false)}, {"use_d8,false", true, partialCompileFlags{}}, {"false,+use_d8", true, partialCompileFlags{}.updateUseD8(true)}, } diff --git a/android/makevars.go b/android/makevars.go index 45fd0d065..2931d0bed 100644 --- a/android/makevars.go +++ b/android/makevars.go @@ -65,24 +65,6 @@ type BaseMakeVarsContext interface { // dependencies to be added to it. Phony can be called on the same name multiple // times to add additional dependencies. Phony(names string, deps ...Path) - - // DistForGoal creates a rule to copy one or more Paths to the artifacts - // directory on the build server when the specified goal is built. - DistForGoal(goal string, paths ...Path) - - // DistForGoalWithFilename creates a rule to copy a Path to the artifacts - // directory on the build server with the given filename when the specified - // goal is built. - DistForGoalWithFilename(goal string, path Path, filename string) - - // DistForGoals creates a rule to copy one or more Paths to the artifacts - // directory on the build server when any of the specified goals are built. - DistForGoals(goals []string, paths ...Path) - - // DistForGoalsWithFilename creates a rule to copy a Path to the artifacts - // directory on the build server with the given filename when any of the - // specified goals are built. - DistForGoalsWithFilename(goals []string, path Path, filename string) } // MakeVarsContext contains the set of functions available for MakeVarsProvider @@ -198,11 +180,9 @@ var makeVarsInitProviders []makeVarsProvider type makeVarsContext struct { SingletonContext - config Config pctx PackageContext vars []makeVarsVariable phonies []phony - dists []dist } var _ MakeVarsContext = &makeVarsContext{} @@ -263,7 +243,6 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) { vars = append(vars, mctx.vars...) phonies = append(phonies, mctx.phonies...) - dists = append(dists, mctx.dists...) } singletonDists := getSingletonDists(ctx.Config()) @@ -281,7 +260,6 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) { vars = append(vars, mctx.vars...) phonies = append(phonies, mctx.phonies...) - dists = append(dists, mctx.dists...) } if m.ExportedToMake() { @@ -328,19 +306,12 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) { sort.Slice(phonies, func(i, j int) bool { return phonies[i].name < phonies[j].name }) - lessArr := func(a, b []string) bool { - if len(a) == len(b) { - for i := range a { - if a[i] < b[i] { - return true - } - } - return false - } - return len(a) < len(b) - } sort.Slice(dists, func(i, j int) bool { - return lessArr(dists[i].goals, dists[j].goals) || lessArr(dists[i].paths.Strings(), dists[j].paths.Strings()) + goals := slices.Compare(dists[i].goals, dists[j].goals) + if goals != 0 { + return goals < 0 + } + return slices.Compare(dists[i].paths.Strings(), dists[j].paths.Strings()) < 0 }) outBytes := s.writeVars(vars) @@ -618,13 +589,6 @@ func (c *makeVarsContext) addPhony(name string, deps []string) { c.phonies = append(c.phonies, phony{name, deps}) } -func (c *makeVarsContext) addDist(goals []string, paths []distCopy) { - c.dists = append(c.dists, dist{ - goals: goals, - paths: paths, - }) -} - func (c *makeVarsContext) Strict(name, ninjaStr string) { c.addVariable(name, ninjaStr, true, false) } @@ -648,26 +612,3 @@ func (c *makeVarsContext) CheckRaw(name, value string) { func (c *makeVarsContext) Phony(name string, deps ...Path) { c.addPhony(name, Paths(deps).Strings()) } - -func (c *makeVarsContext) DistForGoal(goal string, paths ...Path) { - c.DistForGoals([]string{goal}, paths...) -} - -func (c *makeVarsContext) DistForGoalWithFilename(goal string, path Path, filename string) { - c.DistForGoalsWithFilename([]string{goal}, path, filename) -} - -func (c *makeVarsContext) DistForGoals(goals []string, paths ...Path) { - var copies distCopies - for _, path := range paths { - copies = append(copies, distCopy{ - from: path, - dest: path.Base(), - }) - } - c.addDist(goals, copies) -} - -func (c *makeVarsContext) DistForGoalsWithFilename(goals []string, path Path, filename string) { - c.addDist(goals, distCopies{{from: path, dest: filename}}) -} diff --git a/android/module.go b/android/module.go index 55dd119e0..c4a83777a 100644 --- a/android/module.go +++ b/android/module.go @@ -1908,10 +1908,17 @@ type CommonModuleInfo struct { // is used to avoid adding install or packaging dependencies into libraries provided // by apexes. UninstallableApexPlatformVariant bool - HideFromMake bool - SkipInstall bool - IsStubsModule bool - Host bool + MinSdkVersionSupported ApiLevel + ModuleWithMinSdkVersionCheck bool + // Tests if this module can be installed to APEX as a file. For example, this would return + // true for shared libs while return false for static libs because static libs are not + // installable module (but it can still be mutated for APEX) + IsInstallableToApex bool + HideFromMake bool + SkipInstall bool + IsStubsModule bool + Host bool + IsApexModule bool } type ApiLevelOrPlatform struct { @@ -2250,7 +2257,6 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) ReplacedByPrebuilt: m.commonProperties.ReplacedByPrebuilt, Target: m.commonProperties.CompileTarget, SkipAndroidMkProcessing: shouldSkipAndroidMkProcessing(ctx, m), - BaseModuleName: m.BaseModuleName(), UninstallableApexPlatformVariant: m.commonProperties.UninstallableApexPlatformVariant, HideFromMake: m.commonProperties.HideFromMake, SkipInstall: m.commonProperties.SkipInstall, @@ -2292,10 +2298,21 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) commonData.CanHaveApexVariants = am.CanHaveApexVariants() commonData.NotAvailableForPlatform = am.NotAvailableForPlatform() commonData.NotInPlatform = am.NotInPlatform() + commonData.MinSdkVersionSupported = am.MinSdkVersionSupported(ctx) + commonData.IsInstallableToApex = am.IsInstallableToApex() + commonData.IsApexModule = true } + + if _, ok := m.module.(ModuleWithMinSdkVersionCheck); ok { + commonData.ModuleWithMinSdkVersionCheck = true + } + if st, ok := m.module.(StubsAvailableModule); ok { commonData.IsStubsModule = st.IsStubsModule() } + if mm, ok := m.module.(interface{ BaseModuleName() string }); ok { + commonData.BaseModuleName = mm.BaseModuleName() + } SetProvider(ctx, CommonModuleInfoKey, commonData) if p, ok := m.module.(PrebuiltInterface); ok && p.Prebuilt() != nil { SetProvider(ctx, PrebuiltModuleInfoProvider, PrebuiltModuleInfo{ diff --git a/android/packaging.go b/android/packaging.go index 73cc7c783..6146f02c9 100644 --- a/android/packaging.go +++ b/android/packaging.go @@ -216,6 +216,11 @@ func (p *PackagingSpec) SrcPath() Path { return p.srcPath } +// The symlink target of the PackagingSpec. Do not use, for the soong-only migration. +func (p *PackagingSpec) SymlinkTarget() string { + return p.symlinkTarget +} + type PackageModule interface { Module packagingBase() *PackagingBase diff --git a/android/testing.go b/android/testing.go index 8e38b3b1c..fe9bcec26 100644 --- a/android/testing.go +++ b/android/testing.go @@ -1161,7 +1161,7 @@ func SetKatiEnabledForTests(config Config) { config.katiEnabled = true } -func AndroidMkEntriesForTest(t *testing.T, ctx *TestContext, mod blueprint.Module) []AndroidMkEntries { +func AndroidMkEntriesForTest(t *testing.T, ctx *TestContext, mod Module) []AndroidMkEntries { t.Helper() var p AndroidMkEntriesProvider var ok bool @@ -1170,15 +1170,15 @@ func AndroidMkEntriesForTest(t *testing.T, ctx *TestContext, mod blueprint.Modul } entriesList := p.AndroidMkEntries() - aconfigUpdateAndroidMkEntries(ctx, mod.(Module), &entriesList) + aconfigUpdateAndroidMkEntries(ctx, mod, &entriesList) for i := range entriesList { entriesList[i].fillInEntries(ctx, mod) } return entriesList } -func AndroidMkInfoForTest(t *testing.T, ctx *TestContext, mod blueprint.Module) *AndroidMkProviderInfo { - if runtime.GOOS == "darwin" && mod.(Module).base().Os() != Darwin { +func AndroidMkInfoForTest(t *testing.T, ctx *TestContext, mod Module) *AndroidMkProviderInfo { + if runtime.GOOS == "darwin" && mod.base().Os() != Darwin { // The AndroidMkInfo provider is not set in this case. t.Skip("AndroidMkInfo provider is not set on darwin") } @@ -1190,7 +1190,7 @@ func AndroidMkInfoForTest(t *testing.T, ctx *TestContext, mod blueprint.Module) } info := OtherModuleProviderOrDefault(ctx, mod, AndroidMkInfoProvider) - aconfigUpdateAndroidMkInfos(ctx, mod.(Module), info) + aconfigUpdateAndroidMkInfos(ctx, mod, info) info.PrimaryInfo.fillInEntries(ctx, mod) if len(info.ExtraInfo) > 0 { for _, ei := range info.ExtraInfo { @@ -1201,7 +1201,7 @@ func AndroidMkInfoForTest(t *testing.T, ctx *TestContext, mod blueprint.Module) return info } -func AndroidMkDataForTest(t *testing.T, ctx *TestContext, mod blueprint.Module) AndroidMkData { +func AndroidMkDataForTest(t *testing.T, ctx *TestContext, mod Module) AndroidMkData { t.Helper() var p AndroidMkDataProvider var ok bool @@ -1210,7 +1210,7 @@ func AndroidMkDataForTest(t *testing.T, ctx *TestContext, mod blueprint.Module) } data := p.AndroidMk() data.fillInData(ctx, mod) - aconfigUpdateAndroidMkData(ctx, mod.(Module), &data) + aconfigUpdateAndroidMkData(ctx, mod, &data) return data } diff --git a/android/vintf_fragment.go b/android/vintf_fragment.go index 85beb725c..4a29fee87 100644 --- a/android/vintf_fragment.go +++ b/android/vintf_fragment.go @@ -14,6 +14,8 @@ package android +import "github.com/google/blueprint" + type vintfFragmentProperties struct { // Vintf fragment XML file. Src string `android:"path"` @@ -37,6 +39,12 @@ func registerVintfFragmentComponents(ctx RegistrationContext) { ctx.RegisterModuleType("vintf_fragment", vintfLibraryFactory) } +type VintfFragmentInfo struct { + OutputFile Path +} + +var VintfFragmentInfoProvider = blueprint.NewProvider[VintfFragmentInfo]() + // vintf_fragment module processes vintf fragment file and installs under etc/vintf/manifest. // Vintf fragment files formerly listed in vintf_fragment property would be transformed into // this module type. @@ -68,6 +76,10 @@ func (m *VintfFragmentModule) GenerateAndroidBuildActions(ctx ModuleContext) { m.outputFilePath = processedVintfFragment ctx.InstallFile(m.installDirPath, processedVintfFragment.Base(), processedVintfFragment) + + SetProvider(ctx, VintfFragmentInfoProvider, VintfFragmentInfo{ + OutputFile: m.OutputFile(), + }) } func (m *VintfFragmentModule) OutputFile() Path { @@ -91,7 +103,6 @@ func (m *VintfFragmentModule) AndroidMkEntries() []AndroidMkEntries { var _ ApexModule = (*VintfFragmentModule)(nil) // Implements android.ApexModule -func (m *VintfFragmentModule) ShouldSupportSdkVersion(ctx BaseModuleContext, sdkVersion ApiLevel) error { - // VintfFragmetModule is independent from the SDK version. - return nil +func (m *VintfFragmentModule) MinSdkVersionSupported(ctx BaseModuleContext) ApiLevel { + return MinApiLevel } diff --git a/androidmk/androidmk/android.go b/androidmk/androidmk/android.go index 570f36c16..6485cc51d 100644 --- a/androidmk/androidmk/android.go +++ b/androidmk/androidmk/android.go @@ -103,25 +103,26 @@ func addStandardProperties(propertyType bpparser.Type, properties map[string]str func init() { addStandardProperties(bpparser.StringType, map[string]string{ - "LOCAL_MODULE": "name", - "LOCAL_CXX_STL": "stl", - "LOCAL_MULTILIB": "compile_multilib", - "LOCAL_ARM_MODE_HACK": "instruction_set", - "LOCAL_SDK_VERSION": "sdk_version", - "LOCAL_MIN_SDK_VERSION": "min_sdk_version", - "LOCAL_TARGET_SDK_VERSION": "target_sdk_version", - "LOCAL_NDK_STL_VARIANT": "stl", - "LOCAL_JAR_MANIFEST": "manifest", - "LOCAL_CERTIFICATE": "certificate", - "LOCAL_CERTIFICATE_LINEAGE": "lineage", - "LOCAL_PACKAGE_NAME": "name", - "LOCAL_MODULE_RELATIVE_PATH": "relative_install_path", - "LOCAL_PROTOC_OPTIMIZE_TYPE": "proto.type", - "LOCAL_MODULE_OWNER": "owner", - "LOCAL_RENDERSCRIPT_TARGET_API": "renderscript.target_api", - "LOCAL_JAVA_LANGUAGE_VERSION": "java_version", - "LOCAL_INSTRUMENTATION_FOR": "instrumentation_for", - "LOCAL_MANIFEST_FILE": "manifest", + "LOCAL_MODULE": "name", + "LOCAL_CXX_STL": "stl", + "LOCAL_MULTILIB": "compile_multilib", + "LOCAL_ARM_MODE_HACK": "instruction_set", + "LOCAL_SDK_VERSION": "sdk_version", + "LOCAL_MIN_SDK_VERSION": "min_sdk_version", + "LOCAL_ROTATION_MIN_SDK_VERSION": "rotationMinSdkVersion", + "LOCAL_TARGET_SDK_VERSION": "target_sdk_version", + "LOCAL_NDK_STL_VARIANT": "stl", + "LOCAL_JAR_MANIFEST": "manifest", + "LOCAL_CERTIFICATE": "certificate", + "LOCAL_CERTIFICATE_LINEAGE": "lineage", + "LOCAL_PACKAGE_NAME": "name", + "LOCAL_MODULE_RELATIVE_PATH": "relative_install_path", + "LOCAL_PROTOC_OPTIMIZE_TYPE": "proto.type", + "LOCAL_MODULE_OWNER": "owner", + "LOCAL_RENDERSCRIPT_TARGET_API": "renderscript.target_api", + "LOCAL_JAVA_LANGUAGE_VERSION": "java_version", + "LOCAL_INSTRUMENTATION_FOR": "instrumentation_for", + "LOCAL_MANIFEST_FILE": "manifest", "LOCAL_DEX_PREOPT_PROFILE_CLASS_LISTING": "dex_preopt.profile", "LOCAL_TEST_CONFIG": "test_config", diff --git a/apex/apex.go b/apex/apex.go index 4d0e3f183..4b510f8f1 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -624,7 +624,8 @@ type apexFile struct { } // TODO(jiyong): shorten the arglist using an option struct -func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidMkModuleName string, installDir string, class apexFileClass, module android.Module) apexFile { +func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidMkModuleName string, + installDir string, class apexFileClass, module android.Module) apexFile { ret := apexFile{ builtFile: builtFile, installDir: installDir, @@ -1375,24 +1376,29 @@ func (a *apexBundle) AddSanitizerDependencies(ctx android.BottomUpMutatorContext } } +func setDirInApexForNativeBridge(commonInfo *android.CommonModuleInfo, dir *string) { + if commonInfo.Target.NativeBridge == android.NativeBridgeEnabled { + *dir = filepath.Join(*dir, commonInfo.Target.NativeBridgeRelativePath) + } +} + // apexFileFor<Type> functions below create an apexFile struct for a given Soong module. The // returned apexFile saves information about the Soong module that will be used for creating the // build rules. -func apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod cc.VersionedLinkableInterface, handleSpecialLibs bool) apexFile { +func apexFileForNativeLibrary(ctx android.BaseModuleContext, module android.Module, + commonInfo *android.CommonModuleInfo, ccMod *cc.LinkableInfo, handleSpecialLibs bool) apexFile { // Decide the APEX-local directory by the multilib of the library In the future, we may // query this to the module. // TODO(jiyong): use the new PackagingSpec var dirInApex string - switch ccMod.Multilib() { + switch ccMod.Multilib { case "lib32": dirInApex = "lib" case "lib64": dirInApex = "lib64" } - if ccMod.Target().NativeBridge == android.NativeBridgeEnabled { - dirInApex = filepath.Join(dirInApex, ccMod.Target().NativeBridgeRelativePath) - } - if handleSpecialLibs && cc.InstallToBootstrap(ccMod.BaseModuleName(), ctx.Config()) { + setDirInApexForNativeBridge(commonInfo, &dirInApex) + if handleSpecialLibs && cc.InstallToBootstrap(commonInfo.BaseModuleName, ctx.Config()) { // Special case for Bionic libs and other libs installed with them. This is to // prevent those libs from being included in the search path // /apex/com.android.runtime/${LIB}. This exclusion is required because those libs @@ -1407,66 +1413,68 @@ func apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod cc.VersionedL // This needs to go after the runtime APEX handling because otherwise we would get // weird paths like lib64/rel_install_path/bionic rather than // lib64/bionic/rel_install_path. - dirInApex = filepath.Join(dirInApex, ccMod.RelativeInstallPath()) + dirInApex = filepath.Join(dirInApex, ccMod.RelativeInstallPath) - fileToCopy := android.OutputFileForModule(ctx, ccMod, "") - androidMkModuleName := ccMod.BaseModuleName() + ccMod.SubName() - return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, ccMod) + fileToCopy := android.OutputFileForModule(ctx, module, "") + androidMkModuleName := commonInfo.BaseModuleName + ccMod.SubName + return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, module) } -func apexFileForExecutable(ctx android.BaseModuleContext, cc *cc.Module) apexFile { +func apexFileForExecutable(ctx android.BaseModuleContext, module android.Module, + commonInfo *android.CommonModuleInfo, ccInfo *cc.CcInfo) apexFile { + linkableInfo := android.OtherModuleProviderOrDefault(ctx, module, cc.LinkableInfoProvider) dirInApex := "bin" - if cc.Target().NativeBridge == android.NativeBridgeEnabled { - dirInApex = filepath.Join(dirInApex, cc.Target().NativeBridgeRelativePath) - } - dirInApex = filepath.Join(dirInApex, cc.RelativeInstallPath()) - fileToCopy := android.OutputFileForModule(ctx, cc, "") - androidMkModuleName := cc.BaseModuleName() + cc.Properties.SubName - af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, cc) - af.symlinks = cc.Symlinks() - af.dataPaths = cc.DataPaths() + setDirInApexForNativeBridge(commonInfo, &dirInApex) + dirInApex = filepath.Join(dirInApex, linkableInfo.RelativeInstallPath) + fileToCopy := android.OutputFileForModule(ctx, module, "") + androidMkModuleName := commonInfo.BaseModuleName + linkableInfo.SubName + af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, module) + af.symlinks = linkableInfo.Symlinks + af.dataPaths = ccInfo.DataPaths return af } -func apexFileForRustExecutable(ctx android.BaseModuleContext, rustm *rust.Module) apexFile { +func apexFileForRustExecutable(ctx android.BaseModuleContext, module android.Module, + commonInfo *android.CommonModuleInfo) apexFile { + linkableInfo := android.OtherModuleProviderOrDefault(ctx, module, cc.LinkableInfoProvider) dirInApex := "bin" - if rustm.Target().NativeBridge == android.NativeBridgeEnabled { - dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath) - } - dirInApex = filepath.Join(dirInApex, rustm.RelativeInstallPath()) - fileToCopy := android.OutputFileForModule(ctx, rustm, "") - androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName - af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, rustm) + setDirInApexForNativeBridge(commonInfo, &dirInApex) + dirInApex = filepath.Join(dirInApex, linkableInfo.RelativeInstallPath) + fileToCopy := android.OutputFileForModule(ctx, module, "") + androidMkModuleName := commonInfo.BaseModuleName + linkableInfo.SubName + af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, module) return af } -func apexFileForShBinary(ctx android.BaseModuleContext, sh *sh.ShBinary) apexFile { - dirInApex := filepath.Join("bin", sh.SubDir()) - if sh.Target().NativeBridge == android.NativeBridgeEnabled { - dirInApex = filepath.Join(dirInApex, sh.Target().NativeBridgeRelativePath) - } - fileToCopy := sh.OutputFile() - af := newApexFile(ctx, fileToCopy, sh.BaseModuleName(), dirInApex, shBinary, sh) - af.symlinks = sh.Symlinks() +func apexFileForShBinary(ctx android.BaseModuleContext, module android.Module, + commonInfo *android.CommonModuleInfo, sh *sh.ShBinaryInfo) apexFile { + dirInApex := filepath.Join("bin", sh.SubDir) + setDirInApexForNativeBridge(commonInfo, &dirInApex) + fileToCopy := sh.OutputFile + af := newApexFile(ctx, fileToCopy, commonInfo.BaseModuleName, dirInApex, shBinary, module) + af.symlinks = sh.Symlinks return af } -func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt prebuilt_etc.PrebuiltEtcModule, outputFile android.Path) apexFile { - dirInApex := filepath.Join(prebuilt.BaseDir(), prebuilt.SubDir()) +func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, module android.Module, + prebuilt *prebuilt_etc.PrebuiltEtcInfo, outputFile android.Path) apexFile { + dirInApex := filepath.Join(prebuilt.BaseDir, prebuilt.SubDir) makeModuleName := strings.ReplaceAll(filepath.Join(dirInApex, outputFile.Base()), "/", "_") - return newApexFile(ctx, outputFile, makeModuleName, dirInApex, etc, prebuilt) + return newApexFile(ctx, outputFile, makeModuleName, dirInApex, etc, module) } -func apexFileForCompatConfig(ctx android.BaseModuleContext, config java.PlatformCompatConfigIntf, depName string) apexFile { - dirInApex := filepath.Join("etc", config.SubDir()) - fileToCopy := config.CompatConfig() - return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, config) +func apexFileForCompatConfig(ctx android.BaseModuleContext, module android.Module, + config *java.PlatformCompatConfigInfo, depName string) apexFile { + dirInApex := filepath.Join("etc", config.SubDir) + fileToCopy := config.CompatConfig + return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, module) } -func apexFileForVintfFragment(ctx android.BaseModuleContext, vintfFragment *android.VintfFragmentModule) apexFile { +func apexFileForVintfFragment(ctx android.BaseModuleContext, module android.Module, + commonInfo *android.CommonModuleInfo, vf *android.VintfFragmentInfo) apexFile { dirInApex := filepath.Join("etc", "vintf") - return newApexFile(ctx, vintfFragment.OutputFile(), vintfFragment.BaseModuleName(), dirInApex, etc, vintfFragment) + return newApexFile(ctx, vf.OutputFile, commonInfo.BaseModuleName, dirInApex, etc, module) } // javaModule is an interface to handle all Java modules (java_library, dex_import, etc) in the same @@ -1486,60 +1494,42 @@ var _ javaModule = (*java.DexImport)(nil) var _ javaModule = (*java.SdkLibraryImport)(nil) // apexFileForJavaModule creates an apexFile for a java module's dex implementation jar. -func apexFileForJavaModule(ctx android.ModuleContext, module javaModule) apexFile { - return apexFileForJavaModuleWithFile(ctx, module, module.DexJarBuildPath(ctx).PathOrNil()) +func apexFileForJavaModule(ctx android.ModuleContext, module android.Module, javaInfo *java.JavaInfo) apexFile { + return apexFileForJavaModuleWithFile(ctx, module, javaInfo, javaInfo.DexJarBuildPath.PathOrNil()) } // apexFileForJavaModuleWithFile creates an apexFile for a java module with the supplied file. -func apexFileForJavaModuleWithFile(ctx android.ModuleContext, module javaModule, dexImplementationJar android.Path) apexFile { +func apexFileForJavaModuleWithFile(ctx android.ModuleContext, module android.Module, + javaInfo *java.JavaInfo, dexImplementationJar android.Path) apexFile { dirInApex := "javalib" - af := newApexFile(ctx, dexImplementationJar, module.BaseModuleName(), dirInApex, javaSharedLib, module) - af.jacocoReportClassesFile = module.JacocoReportClassesFile() + commonInfo := android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey) + af := newApexFile(ctx, dexImplementationJar, commonInfo.BaseModuleName, dirInApex, javaSharedLib, module) + af.jacocoReportClassesFile = javaInfo.JacocoReportClassesFile if lintInfo, ok := android.OtherModuleProvider(ctx, module, java.LintProvider); ok { af.lintInfo = lintInfo } - af.customStem = module.Stem() + ".jar" + af.customStem = javaInfo.Stem + ".jar" // Collect any system server dex jars and dexpreopt artifacts for installation alongside the apex. // TODO: b/338641779 - Remove special casing of sdkLibrary once bcpf and sscpf depends // on the implementation library - if sdkLib, ok := module.(*java.SdkLibrary); ok { - af.systemServerDexpreoptInstalls = append(af.systemServerDexpreoptInstalls, sdkLib.ApexSystemServerDexpreoptInstalls()...) - af.systemServerDexJars = append(af.systemServerDexJars, sdkLib.ApexSystemServerDexJars()...) - } else if dexpreopter, ok := module.(java.DexpreopterInterface); ok { - af.systemServerDexpreoptInstalls = append(af.systemServerDexpreoptInstalls, dexpreopter.ApexSystemServerDexpreoptInstalls()...) - af.systemServerDexJars = append(af.systemServerDexJars, dexpreopter.ApexSystemServerDexJars()...) + if javaInfo.DexpreopterInfo != nil { + af.systemServerDexpreoptInstalls = append(af.systemServerDexpreoptInstalls, javaInfo.DexpreopterInfo.ApexSystemServerDexpreoptInstalls...) + af.systemServerDexJars = append(af.systemServerDexJars, javaInfo.DexpreopterInfo.ApexSystemServerDexJars...) } return af } -func apexFileForJavaModuleProfile(ctx android.BaseModuleContext, module javaModule) *apexFile { - if dexpreopter, ok := module.(java.DexpreopterInterface); ok { - if profilePathOnHost := dexpreopter.OutputProfilePathOnHost(); profilePathOnHost != nil { - dirInApex := "javalib" - af := newApexFile(ctx, profilePathOnHost, module.BaseModuleName()+"-profile", dirInApex, etc, nil) - af.customStem = module.Stem() + ".jar.prof" - return &af - } +func apexFileForJavaModuleProfile(ctx android.BaseModuleContext, commonInfo *android.CommonModuleInfo, + javaInfo *java.JavaInfo) *apexFile { + if profilePathOnHost := javaInfo.DexpreopterInfo.OutputProfilePathOnHost; profilePathOnHost != nil { + dirInApex := "javalib" + af := newApexFile(ctx, profilePathOnHost, commonInfo.BaseModuleName+"-profile", dirInApex, etc, nil) + af.customStem = javaInfo.Stem + ".jar.prof" + return &af } return nil } -// androidApp is an interface to handle all app modules (android_app, android_app_import, etc.) in -// the same way. -type androidApp interface { - android.Module - Privileged() bool - InstallApkName() string - OutputFile() android.Path - JacocoReportClassesFile() android.Path - Certificate() java.Certificate - BaseModuleName() string - PrivAppAllowlist() android.OptionalPath -} - -var _ androidApp = (*java.AndroidApp)(nil) -var _ androidApp = (*java.AndroidAppImport)(nil) - func sanitizedBuildIdForPath(ctx android.BaseModuleContext) string { buildId := ctx.Config().BuildId() @@ -1555,36 +1545,35 @@ func sanitizedBuildIdForPath(ctx android.BaseModuleContext) string { return buildId } -func apexFilesForAndroidApp(ctx android.BaseModuleContext, aapp androidApp) []apexFile { +func apexFilesForAndroidApp(ctx android.BaseModuleContext, module android.Module, + commonInfo *android.CommonModuleInfo, aapp *java.AppInfo) []apexFile { appDir := "app" - if aapp.Privileged() { + if aapp.Privileged { appDir = "priv-app" } // TODO(b/224589412, b/226559955): Ensure that the subdirname is suffixed // so that PackageManager correctly invalidates the existing installed apk // in favour of the new APK-in-APEX. See bugs for more information. - dirInApex := filepath.Join(appDir, aapp.InstallApkName()+"@"+sanitizedBuildIdForPath(ctx)) - fileToCopy := aapp.OutputFile() + dirInApex := filepath.Join(appDir, aapp.InstallApkName+"@"+sanitizedBuildIdForPath(ctx)) + fileToCopy := aapp.OutputFile - af := newApexFile(ctx, fileToCopy, aapp.BaseModuleName(), dirInApex, app, aapp) - af.jacocoReportClassesFile = aapp.JacocoReportClassesFile() - if lintInfo, ok := android.OtherModuleProvider(ctx, aapp, java.LintProvider); ok { + af := newApexFile(ctx, fileToCopy, commonInfo.BaseModuleName, dirInApex, app, module) + af.jacocoReportClassesFile = aapp.JacocoReportClassesFile + if lintInfo, ok := android.OtherModuleProvider(ctx, module, java.LintProvider); ok { af.lintInfo = lintInfo } - af.certificate = aapp.Certificate() + af.certificate = aapp.Certificate - if app, ok := aapp.(interface { - OverriddenManifestPackageName() string - }); ok { - af.overriddenPackageName = app.OverriddenManifestPackageName() + if aapp.OverriddenManifestPackageName != nil { + af.overriddenPackageName = *aapp.OverriddenManifestPackageName } apexFiles := []apexFile{} - if allowlist := aapp.PrivAppAllowlist(); allowlist.Valid() { + if allowlist := aapp.PrivAppAllowlist; allowlist.Valid() { dirInApex := filepath.Join("etc", "permissions") - privAppAllowlist := newApexFile(ctx, allowlist.Path(), aapp.BaseModuleName()+"_privapp", dirInApex, etc, aapp) + privAppAllowlist := newApexFile(ctx, allowlist.Path(), commonInfo.BaseModuleName+"_privapp", dirInApex, etc, module) apexFiles = append(apexFiles, privAppAllowlist) } @@ -1593,29 +1582,24 @@ func apexFilesForAndroidApp(ctx android.BaseModuleContext, aapp androidApp) []ap return apexFiles } -func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, rro java.RuntimeResourceOverlayModule) apexFile { +func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, module android.Module, rro java.RuntimeResourceOverlayInfo) apexFile { rroDir := "overlay" - dirInApex := filepath.Join(rroDir, rro.Theme()) - fileToCopy := rro.OutputFile() - af := newApexFile(ctx, fileToCopy, rro.Name(), dirInApex, app, rro) - af.certificate = rro.Certificate() + dirInApex := filepath.Join(rroDir, rro.Theme) + fileToCopy := rro.OutputFile + af := newApexFile(ctx, fileToCopy, module.Name(), dirInApex, app, module) + af.certificate = rro.Certificate - if a, ok := rro.(interface { - OverriddenManifestPackageName() string - }); ok { - af.overriddenPackageName = a.OverriddenManifestPackageName() - } return af } -func apexFileForBpfProgram(ctx android.BaseModuleContext, builtFile android.Path, apex_sub_dir string, bpfProgram bpf.BpfModule) apexFile { +func apexFileForBpfProgram(ctx android.BaseModuleContext, builtFile android.Path, apex_sub_dir string, bpfProgram android.Module) apexFile { dirInApex := filepath.Join("etc", "bpf", apex_sub_dir) return newApexFile(ctx, builtFile, builtFile.Base(), dirInApex, etc, bpfProgram) } -func apexFileForFilesystem(ctx android.BaseModuleContext, buildFile android.Path, fs filesystem.Filesystem) apexFile { +func apexFileForFilesystem(ctx android.BaseModuleContext, buildFile android.Path, module android.Module) apexFile { dirInApex := filepath.Join("etc", "fs") - return newApexFile(ctx, buildFile, buildFile.Base(), dirInApex, etc, fs) + return newApexFile(ctx, buildFile, buildFile.Base(), dirInApex, etc, module) } // WalkPayloadDeps visits dependencies that contributes to the payload of this APEX. For each of the @@ -1864,11 +1848,12 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok { return false } - if !child.Enabled(ctx) { + commonInfo := android.OtherModuleProviderOrDefault(ctx, child, android.CommonModuleInfoKey) + if !commonInfo.Enabled { return false } depName := ctx.OtherModuleName(child) - if _, isDirectDep := parent.(*apexBundle); isDirectDep { + if ctx.EqualModules(parent, ctx.Module()) { switch depTag { case sharedLibTag, jniLibTag: isJniLib := depTag == jniLibTag @@ -1877,17 +1862,17 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, propertyName = "jni_libs" } - if ch, ok := child.(cc.VersionedLinkableInterface); ok { - if ch.IsStubs() { + if ch, ok := android.OtherModuleProvider(ctx, child, cc.LinkableInfoProvider); ok { + if ch.IsStubs { ctx.PropertyErrorf(propertyName, "%q is a stub. Remove it from the list.", depName) } - fi := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs) + fi := apexFileForNativeLibrary(ctx, child, &commonInfo, ch, vctx.handleSpecialLibs) fi.isJniLib = isJniLib vctx.filesInfo = append(vctx.filesInfo, fi) // Collect the list of stub-providing libs except: // - VNDK libs are only for vendors // - bootstrap bionic libs are treated as provided by system - if ch.HasStubsVariants() && !a.vndkApex && !cc.InstallToBootstrap(ch.BaseModuleName(), ctx.Config()) { + if ch.HasStubsVariants && !a.vndkApex && !cc.InstallToBootstrap(commonInfo.BaseModuleName, ctx.Config()) { vctx.provideNativeLibs = append(vctx.provideNativeLibs, fi.stem()) } return true // track transitive dependencies @@ -1897,34 +1882,33 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, } case executableTag: - switch ch := child.(type) { - case *cc.Module: - vctx.filesInfo = append(vctx.filesInfo, apexFileForExecutable(ctx, ch)) + if ccInfo, ok := android.OtherModuleProvider(ctx, child, cc.CcInfoProvider); ok { + vctx.filesInfo = append(vctx.filesInfo, apexFileForExecutable(ctx, child, &commonInfo, ccInfo)) return true // track transitive dependencies - case *rust.Module: - vctx.filesInfo = append(vctx.filesInfo, apexFileForRustExecutable(ctx, ch)) + } + if _, ok := android.OtherModuleProvider(ctx, child, rust.RustInfoProvider); ok { + vctx.filesInfo = append(vctx.filesInfo, apexFileForRustExecutable(ctx, child, &commonInfo)) return true // track transitive dependencies - default: + } else { ctx.PropertyErrorf("binaries", "%q is neither cc_binary, rust_binary, (embedded) py_binary, (host) blueprint_go_binary, nor (host) bootstrap_go_binary", depName) } case shBinaryTag: - if csh, ok := child.(*sh.ShBinary); ok { - vctx.filesInfo = append(vctx.filesInfo, apexFileForShBinary(ctx, csh)) + if csh, ok := android.OtherModuleProvider(ctx, child, sh.ShBinaryInfoProvider); ok { + vctx.filesInfo = append(vctx.filesInfo, apexFileForShBinary(ctx, child, &commonInfo, &csh)) } else { ctx.PropertyErrorf("sh_binaries", "%q is not a sh_binary module", depName) } case bcpfTag: - _, ok := child.(*java.BootclasspathFragmentModule) + _, ok := android.OtherModuleProvider(ctx, child, java.BootclasspathFragmentInfoProvider) if !ok { ctx.PropertyErrorf("bootclasspath_fragments", "%q is not a bootclasspath_fragment module", depName) return false } - vctx.filesInfo = append(vctx.filesInfo, apexBootclasspathFragmentFiles(ctx, child)...) return true case sscpfTag: - if _, ok := child.(*java.SystemServerClasspathModule); !ok { + if _, ok := android.OtherModuleProvider(ctx, child, java.LibraryNameToPartitionInfoProvider); !ok { ctx.PropertyErrorf("systemserverclasspath_fragments", "%q is not a systemserverclasspath_fragment module", depName) return false @@ -1934,83 +1918,84 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, } return true case javaLibTag: - switch child.(type) { - case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport, *java.Import: - af := apexFileForJavaModule(ctx, child.(javaModule)) + if ctx.OtherModuleHasProvider(child, java.JavaLibraryInfoProvider) || + ctx.OtherModuleHasProvider(child, java.JavaDexImportInfoProvider) || + ctx.OtherModuleHasProvider(child, java.SdkLibraryInfoProvider) { + javaInfo := android.OtherModuleProviderOrDefault(ctx, child, java.JavaInfoProvider) + af := apexFileForJavaModule(ctx, child, javaInfo) if !af.ok() { ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName) return false } vctx.filesInfo = append(vctx.filesInfo, af) return true // track transitive dependencies - default: + } else { ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child)) } case androidAppTag: - switch ap := child.(type) { - case *java.AndroidApp: - vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...) - return true // track transitive dependencies - case *java.AndroidAppImport: - vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...) - case *java.AndroidTestHelperApp: - vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...) - case *java.AndroidAppSet: - appDir := "app" - if ap.Privileged() { - appDir = "priv-app" + if appInfo, ok := android.OtherModuleProvider(ctx, child, java.AppInfoProvider); ok { + if appInfo.AppSet { + appDir := "app" + if appInfo.Privileged { + appDir = "priv-app" + } + // TODO(b/224589412, b/226559955): Ensure that the dirname is + // suffixed so that PackageManager correctly invalidates the + // existing installed apk in favour of the new APK-in-APEX. + // See bugs for more information. + appDirName := filepath.Join(appDir, commonInfo.BaseModuleName+"@"+sanitizedBuildIdForPath(ctx)) + af := newApexFile(ctx, appInfo.OutputFile, commonInfo.BaseModuleName, appDirName, appSet, child) + af.certificate = java.PresignedCertificate + vctx.filesInfo = append(vctx.filesInfo, af) + } else { + vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, child, &commonInfo, appInfo)...) + if !appInfo.Prebuilt && !appInfo.TestHelperApp { + return true // track transitive dependencies + } } - // TODO(b/224589412, b/226559955): Ensure that the dirname is - // suffixed so that PackageManager correctly invalidates the - // existing installed apk in favour of the new APK-in-APEX. - // See bugs for more information. - appDirName := filepath.Join(appDir, ap.BaseModuleName()+"@"+sanitizedBuildIdForPath(ctx)) - af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(), appDirName, appSet, ap) - af.certificate = java.PresignedCertificate - vctx.filesInfo = append(vctx.filesInfo, af) - default: + } else { ctx.PropertyErrorf("apps", "%q is not an android_app module", depName) } case rroTag: - if rro, ok := child.(java.RuntimeResourceOverlayModule); ok { - vctx.filesInfo = append(vctx.filesInfo, apexFileForRuntimeResourceOverlay(ctx, rro)) + if rro, ok := android.OtherModuleProvider(ctx, child, java.RuntimeResourceOverlayInfoProvider); ok { + vctx.filesInfo = append(vctx.filesInfo, apexFileForRuntimeResourceOverlay(ctx, child, rro)) } else { ctx.PropertyErrorf("rros", "%q is not an runtime_resource_overlay module", depName) } case bpfTag: - if bpfProgram, ok := child.(bpf.BpfModule); ok { - filesToCopy := android.OutputFilesForModule(ctx, bpfProgram, "") - apex_sub_dir := bpfProgram.SubDir() + if bpfProgram, ok := android.OtherModuleProvider(ctx, child, bpf.BpfInfoProvider); ok { + filesToCopy := android.OutputFilesForModule(ctx, child, "") + apex_sub_dir := bpfProgram.SubDir for _, bpfFile := range filesToCopy { - vctx.filesInfo = append(vctx.filesInfo, apexFileForBpfProgram(ctx, bpfFile, apex_sub_dir, bpfProgram)) + vctx.filesInfo = append(vctx.filesInfo, apexFileForBpfProgram(ctx, bpfFile, apex_sub_dir, child)) } } else { ctx.PropertyErrorf("bpfs", "%q is not a bpf module", depName) } case fsTag: - if fs, ok := child.(filesystem.Filesystem); ok { - vctx.filesInfo = append(vctx.filesInfo, apexFileForFilesystem(ctx, fs.OutputPath(), fs)) + if fs, ok := android.OtherModuleProvider(ctx, child, filesystem.FilesystemProvider); ok { + vctx.filesInfo = append(vctx.filesInfo, apexFileForFilesystem(ctx, fs.Output, child)) } else { ctx.PropertyErrorf("filesystems", "%q is not a filesystem module", depName) } case prebuiltTag: - if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok { - filesToCopy := android.OutputFilesForModule(ctx, prebuilt, "") + if prebuilt, ok := android.OtherModuleProvider(ctx, child, prebuilt_etc.PrebuiltEtcInfoProvider); ok { + filesToCopy := android.OutputFilesForModule(ctx, child, "") for _, etcFile := range filesToCopy { - vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, etcFile)) + vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, child, &prebuilt, etcFile)) } } else { ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName) } case compatConfigTag: - if compatConfig, ok := child.(java.PlatformCompatConfigIntf); ok { - vctx.filesInfo = append(vctx.filesInfo, apexFileForCompatConfig(ctx, compatConfig, depName)) + if compatConfig, ok := android.OtherModuleProvider(ctx, child, java.PlatformCompatConfigInfoProvider); ok { + vctx.filesInfo = append(vctx.filesInfo, apexFileForCompatConfig(ctx, child, &compatConfig, depName)) } else { ctx.PropertyErrorf("compat_configs", "%q is not a platform_compat_config module", depName) } case testTag: - if ccTest, ok := child.(*cc.Module); ok { - af := apexFileForExecutable(ctx, ccTest) + if ccInfo, ok := android.OtherModuleProvider(ctx, child, cc.CcInfoProvider); ok { + af := apexFileForExecutable(ctx, child, &commonInfo, ccInfo) af.class = nativeTest vctx.filesInfo = append(vctx.filesInfo, af) return true // track transitive dependencies @@ -2018,14 +2003,14 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, ctx.PropertyErrorf("tests", "%q is not a cc module", depName) } case keyTag: - if key, ok := child.(*apexKey); ok { - a.privateKeyFile = key.privateKeyFile - a.publicKeyFile = key.publicKeyFile + if key, ok := android.OtherModuleProvider(ctx, child, ApexKeyInfoProvider); ok { + a.privateKeyFile = key.PrivateKeyFile + a.publicKeyFile = key.PublicKeyFile } else { ctx.PropertyErrorf("key", "%q is not an apex_key module", depName) } case certificateTag: - if dep, ok := child.(*java.AndroidAppCertificate); ok { + if dep, ok := android.OtherModuleProvider(ctx, child, java.AndroidAppCertificateInfoProvider); ok { a.containerCertificateFile = dep.Certificate.Pem a.containerPrivateKeyFile = dep.Certificate.Key } else { @@ -2040,18 +2025,17 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, } // indirect dependencies - am, ok := child.(android.ApexModule) - if !ok { + if !commonInfo.IsApexModule { return false } // We cannot use a switch statement on `depTag` here as the checked // tags used below are private (e.g. `cc.sharedDepTag`). if cc.IsSharedDepTag(depTag) || cc.IsRuntimeDepTag(depTag) { - if ch, ok := child.(cc.VersionedLinkableInterface); ok { - af := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs) + if ch, ok := android.OtherModuleProvider(ctx, child, cc.LinkableInfoProvider); ok { + af := apexFileForNativeLibrary(ctx, child, &commonInfo, ch, vctx.handleSpecialLibs) af.transitiveDep = true - if ch.IsStubs() || ch.HasStubsVariants() { + if ch.IsStubs || ch.HasStubsVariants { // If the dependency is a stubs lib, don't include it in this APEX, // but make sure that the lib is installed on the device. // In case no APEX is having the lib, the lib is installed to the system @@ -2062,10 +2046,10 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, // // Skip the dependency in unbundled builds where the device image is not // being built. - if ch.VersionedInterface().IsStubsImplementationRequired() && - !am.NotInPlatform() && !ctx.Config().UnbundledBuild() { + if ch.IsStubsImplementationRequired && + !commonInfo.NotInPlatform && !ctx.Config().UnbundledBuild() { // we need a module name for Make - name := ch.ImplementationModuleNameForMake(ctx) + ch.SubName() + name := ch.ImplementationModuleNameForMake + ch.SubName if !android.InList(name, a.makeModulesToInstall) { a.makeModulesToInstall = append(a.makeModulesToInstall, name) } @@ -2084,7 +2068,7 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, // like to record requiredNativeLibs even when // DepIsInSameAPex is false. We also shouldn't do // this for host. - if !android.IsDepInSameApex(ctx, parent, am) { + if !android.IsDepInSameApex(ctx, parent, child) { return false } @@ -2096,19 +2080,21 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, } else if java.IsJniDepTag(depTag) { // Because APK-in-APEX embeds jni_libs transitively, we don't need to track transitive deps } else if java.IsXmlPermissionsFileDepTag(depTag) { - if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok { - filesToCopy := android.OutputFilesForModule(ctx, prebuilt, "") + if prebuilt, ok := android.OtherModuleProvider(ctx, child, prebuilt_etc.PrebuiltEtcInfoProvider); ok { + filesToCopy := android.OutputFilesForModule(ctx, child, "") for _, etcFile := range filesToCopy { - vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, etcFile)) + vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, child, &prebuilt, etcFile)) } } } else if rust.IsDylibDepTag(depTag) { - if rustm, ok := child.(*rust.Module); ok && rustm.IsInstallableToApex() { - if !android.IsDepInSameApex(ctx, am, am) { + if _, ok := android.OtherModuleProvider(ctx, child, rust.RustInfoProvider); ok && + commonInfo.IsInstallableToApex { + if !android.IsDepInSameApex(ctx, parent, child) { return false } - af := apexFileForNativeLibrary(ctx, child.(cc.VersionedLinkableInterface), vctx.handleSpecialLibs) + linkableInfo := android.OtherModuleProviderOrDefault(ctx, child, cc.LinkableInfoProvider) + af := apexFileForNativeLibrary(ctx, child, &commonInfo, linkableInfo, vctx.handleSpecialLibs) af.transitiveDep = true vctx.filesInfo = append(vctx.filesInfo, af) return true // track transitive dependencies @@ -2119,10 +2105,9 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, return true } else if java.IsBootclasspathFragmentContentDepTag(depTag) { // Add the contents of the bootclasspath fragment to the apex. - switch child.(type) { - case *java.Library, *java.SdkLibrary: - javaModule := child.(javaModule) - af := apexFileForBootclasspathFragmentContentModule(ctx, parent, javaModule) + if ctx.OtherModuleHasProvider(child, java.JavaLibraryInfoProvider) || + ctx.OtherModuleHasProvider(child, java.SdkLibraryInfoProvider) { + af := apexFileForBootclasspathFragmentContentModule(ctx, parent, child) if !af.ok() { ctx.PropertyErrorf("bootclasspath_fragments", "bootclasspath_fragment content %q is not configured to be compiled into dex", depName) @@ -2130,21 +2115,22 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, } vctx.filesInfo = append(vctx.filesInfo, af) return true // track transitive dependencies - default: + } else { ctx.PropertyErrorf("bootclasspath_fragments", "bootclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child)) } } else if java.IsSystemServerClasspathFragmentContentDepTag(depTag) { // Add the contents of the systemserverclasspath fragment to the apex. - switch child.(type) { - case *java.Library, *java.SdkLibrary: - af := apexFileForJavaModule(ctx, child.(javaModule)) + if ctx.OtherModuleHasProvider(child, java.JavaLibraryInfoProvider) || + ctx.OtherModuleHasProvider(child, java.SdkLibraryInfoProvider) { + javaInfo := android.OtherModuleProviderOrDefault(ctx, child, java.JavaInfoProvider) + af := apexFileForJavaModule(ctx, child, javaInfo) vctx.filesInfo = append(vctx.filesInfo, af) - if profileAf := apexFileForJavaModuleProfile(ctx, child.(javaModule)); profileAf != nil { + if profileAf := apexFileForJavaModuleProfile(ctx, &commonInfo, javaInfo); profileAf != nil { vctx.filesInfo = append(vctx.filesInfo, *profileAf) } return true // track transitive dependencies - default: + } else { ctx.PropertyErrorf("systemserverclasspath_fragments", "systemserverclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child)) } @@ -2152,11 +2138,11 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, // nothing } else if depTag == android.RequiredDepTag { // nothing - } else if am.CanHaveApexVariants() && am.IsInstallableToApex() { + } else if commonInfo.IsInstallableToApex { ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName) } else if android.IsVintfDepTag(depTag) { - if vf, ok := child.(*android.VintfFragmentModule); ok { - apexFile := apexFileForVintfFragment(ctx, vf) + if vf, ok := android.OtherModuleProvider(ctx, child, android.VintfFragmentInfoProvider); ok { + apexFile := apexFileForVintfFragment(ctx, child, &commonInfo, &vf) vctx.filesInfo = append(vctx.filesInfo, apexFile) } } @@ -2325,8 +2311,8 @@ func (a *apexBundle) enforceAppUpdatability(mctx android.ModuleContext) { // checking direct deps is sufficient since apex->apk is a direct edge, even when inherited via apex_defaults mctx.VisitDirectDepsProxy(func(module android.ModuleProxy) { if appInfo, ok := android.OtherModuleProvider(mctx, module, java.AppInfoProvider); ok { - // ignore android_test_app - if !appInfo.TestHelperApp && !appInfo.Updatable { + // ignore android_test_app and android_app_import + if !appInfo.TestHelperApp && !appInfo.Prebuilt && !appInfo.Updatable { mctx.ModuleErrorf("app dependency %s must have updatable: true", mctx.OtherModuleName(module)) } } @@ -2336,7 +2322,7 @@ func (a *apexBundle) enforceAppUpdatability(mctx android.ModuleContext) { // apexBootclasspathFragmentFiles returns the list of apexFile structures defining the files that // the bootclasspath_fragment contributes to the apex. -func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module blueprint.Module) []apexFile { +func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module android.Module) []apexFile { bootclasspathFragmentInfo, _ := android.OtherModuleProvider(ctx, module, java.BootclasspathFragmentApexContentInfoProvider) var filesToAdd []apexFile @@ -2385,7 +2371,7 @@ func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module blueprint. // apexClasspathFragmentProtoFile returns *apexFile structure defining the classpath.proto config that // the module contributes to the apex; or nil if the proto config was not generated. -func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module blueprint.Module) *apexFile { +func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module android.Module) *apexFile { info, _ := android.OtherModuleProvider(ctx, module, java.ClasspathFragmentProtoContentInfoProvider) if !info.ClasspathFragmentProtoGenerated { return nil @@ -2397,7 +2383,7 @@ func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module blueprint. // apexFileForBootclasspathFragmentContentModule creates an apexFile for a bootclasspath_fragment // content module, i.e. a library that is part of the bootclasspath. -func apexFileForBootclasspathFragmentContentModule(ctx android.ModuleContext, fragmentModule blueprint.Module, javaModule javaModule) apexFile { +func apexFileForBootclasspathFragmentContentModule(ctx android.ModuleContext, fragmentModule, javaModule android.Module) apexFile { bootclasspathFragmentInfo, _ := android.OtherModuleProvider(ctx, fragmentModule, java.BootclasspathFragmentApexContentInfoProvider) // Get the dexBootJar from the bootclasspath_fragment as that is responsible for performing the @@ -2409,7 +2395,8 @@ func apexFileForBootclasspathFragmentContentModule(ctx android.ModuleContext, fr // Create an apexFile as for a normal java module but with the dex boot jar provided by the // bootclasspath_fragment. - af := apexFileForJavaModuleWithFile(ctx, javaModule, dexBootJar) + javaInfo := android.OtherModuleProviderOrDefault(ctx, javaModule, java.JavaInfoProvider) + af := apexFileForJavaModuleWithFile(ctx, javaModule, javaInfo, dexBootJar) return af } @@ -2896,14 +2883,14 @@ func (a *apexBundle) verifyNativeImplementationLibs(ctx android.ModuleContext) { if !inApex && !inApkInApex { ctx.ModuleErrorf("library in apex transitively linked against implementation library %q not in apex", lib) var depPath []android.Module - ctx.WalkDeps(func(child, parent android.Module) bool { + ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool { if depPath != nil { return false } tag := ctx.OtherModuleDependencyTag(child) - if parent == ctx.Module() { + if ctx.EqualModules(parent, ctx.Module()) { if !checkApexTag(tag) { return false } diff --git a/apex/key.go b/apex/key.go index 1622c65e6..cc66a131f 100644 --- a/apex/key.go +++ b/apex/key.go @@ -33,6 +33,13 @@ func registerApexKeyBuildComponents(ctx android.RegistrationContext) { ctx.RegisterParallelSingletonModuleType("all_apex_certs", allApexCertsFactory) } +type ApexKeyInfo struct { + PublicKeyFile android.Path + PrivateKeyFile android.Path +} + +var ApexKeyInfoProvider = blueprint.NewProvider[ApexKeyInfo]() + type apexKey struct { android.ModuleBase @@ -95,6 +102,11 @@ func (m *apexKey) GenerateAndroidBuildActions(ctx android.ModuleContext) { m.publicKeyFile.String(), pubKeyName, m.privateKeyFile, privKeyName) return } + + android.SetProvider(ctx, ApexKeyInfoProvider, ApexKeyInfo{ + PublicKeyFile: m.publicKeyFile, + PrivateKeyFile: m.privateKeyFile, + }) } type apexKeyEntry struct { diff --git a/bpf/bpf.go b/bpf/bpf.go index 3f3438247..deb465dd6 100644 --- a/bpf/bpf.go +++ b/bpf/bpf.go @@ -60,6 +60,12 @@ func registerBpfBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("bpf", BpfFactory) } +type BpfInfo struct { + SubDir string +} + +var BpfInfoProvider = blueprint.NewProvider[BpfInfo]() + var PrepareForTestWithBpf = android.FixtureRegisterWithContext(registerBpfBuildComponents) // BpfModule interface is used by the apex package to gather information from a bpf module. @@ -230,6 +236,10 @@ func (bpf *bpf) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.PackageFile(installDir, obj.Base(), obj) } + android.SetProvider(ctx, BpfInfoProvider, BpfInfo{ + SubDir: bpf.SubDir(), + }) + ctx.SetOutputFiles(bpf.objs, "") } @@ -117,6 +117,7 @@ type CcInfo struct { IsPrebuilt bool CmakeSnapshotSupported bool HasLlndkStubs bool + DataPaths []android.DataPath CompilerInfo *CompilerInfo LinkerInfo *LinkerInfo SnapshotInfo *SnapshotInfo @@ -148,10 +149,8 @@ type LinkableInfo struct { CrateName string // DepFlags returns a slice of Rustc string flags ExportedCrateLinkDirs []string - // This can be different from the one on CommonModuleInfo - BaseModuleName string - HasNonSystemVariants bool - IsLlndk bool + HasNonSystemVariants bool + IsLlndk bool // True if the library is in the configs known NDK list. IsNdk bool InVendorOrProduct bool @@ -169,7 +168,12 @@ type LinkableInfo struct { // TODO(b/362509506): remove this once all apex_exclude uses are switched to stubs. RustApexExclude bool // Bootstrap tests if this module is allowed to use non-APEX version of libraries. - Bootstrap bool + Bootstrap bool + Multilib string + ImplementationModuleNameForMake string + IsStubsImplementationRequired bool + // Symlinks returns a list of symlinks that should be created for this module. + Symlinks []string } var LinkableInfoProvider = blueprint.NewProvider[*LinkableInfo]() @@ -1576,7 +1580,7 @@ func (c *Module) ImplementationModuleName(ctx android.BaseModuleContext) string // where the Soong name is prebuilt_foo, this returns foo (which works in Make // under the premise that the prebuilt module overrides its source counterpart // if it is exposed to Make). -func (c *Module) ImplementationModuleNameForMake(ctx android.BaseModuleContext) string { +func (c *Module) ImplementationModuleNameForMake() string { name := c.BaseModuleName() if versioned, ok := c.linker.(VersionedInterface); ok { name = versioned.ImplementationModuleName(name) @@ -2293,6 +2297,7 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { IsPrebuilt: c.IsPrebuilt(), CmakeSnapshotSupported: proptools.Bool(c.Properties.Cmake_snapshot_supported), HasLlndkStubs: c.HasLlndkStubs(), + DataPaths: c.DataPaths(), } if c.compiler != nil { cflags := c.compiler.baseCompilerProps().Cflags @@ -2365,7 +2370,7 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { } func CreateCommonLinkableInfo(ctx android.ModuleContext, mod VersionedLinkableInterface) *LinkableInfo { - return &LinkableInfo{ + info := &LinkableInfo{ StaticExecutable: mod.StaticExecutable(), HasStubsVariants: mod.HasStubsVariants(), OutputFile: mod.OutputFile(), @@ -2376,7 +2381,6 @@ func CreateCommonLinkableInfo(ctx android.ModuleContext, mod VersionedLinkableIn CcLibrary: mod.CcLibrary(), CcLibraryInterface: mod.CcLibraryInterface(), RustLibraryInterface: mod.RustLibraryInterface(), - BaseModuleName: mod.BaseModuleName(), IsLlndk: mod.IsLlndk(), IsNdk: mod.IsNdk(ctx.Config()), HasNonSystemVariants: mod.HasNonSystemVariants(), @@ -2391,9 +2395,16 @@ func CreateCommonLinkableInfo(ctx android.ModuleContext, mod VersionedLinkableIn Installable: mod.Installable(), RelativeInstallPath: mod.RelativeInstallPath(), // TODO(b/362509506): remove this once all apex_exclude uses are switched to stubs. - RustApexExclude: mod.RustApexExclude(), - Bootstrap: mod.Bootstrap(), + RustApexExclude: mod.RustApexExclude(), + Bootstrap: mod.Bootstrap(), + Multilib: mod.Multilib(), + ImplementationModuleNameForMake: mod.ImplementationModuleNameForMake(), + Symlinks: mod.Symlinks(), } + if mod.VersionedInterface() != nil { + info.IsStubsImplementationRequired = mod.VersionedInterface().IsStubsImplementationRequired() + } + return info } func setOutputFilesIfNotEmpty(ctx ModuleContext, files android.Paths, tag string) { @@ -3582,7 +3593,7 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { c.sabi.Properties.ReexportedSystemIncludes, depExporterInfo.SystemIncludeDirs.Strings()...) } - makeLibName := MakeLibName(ccInfo, linkableInfo, &commonInfo, linkableInfo.BaseModuleName) + libDepTag.makeSuffix + makeLibName := MakeLibName(ccInfo, linkableInfo, &commonInfo, commonInfo.BaseModuleName) + libDepTag.makeSuffix switch { case libDepTag.header(): c.Properties.AndroidMkHeaderLibs = append( @@ -3609,7 +3620,8 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { switch depTag { case runtimeDepTag: c.Properties.AndroidMkRuntimeLibs = append( - c.Properties.AndroidMkRuntimeLibs, MakeLibName(ccInfo, linkableInfo, &commonInfo, linkableInfo.BaseModuleName)+libDepTag.makeSuffix) + c.Properties.AndroidMkRuntimeLibs, MakeLibName(ccInfo, linkableInfo, &commonInfo, + commonInfo.BaseModuleName)+libDepTag.makeSuffix) case objDepTag: depPaths.Objs.objFiles = append(depPaths.Objs.objFiles, linkFile.Path()) case CrtBeginDepTag: @@ -3771,7 +3783,7 @@ func MakeLibName(ccInfo *CcInfo, linkableInfo *LinkableInfo, commonInfo *android if ccInfo != nil { // Use base module name for snapshots when exporting to Makefile. if ccInfo.SnapshotInfo != nil { - return linkableInfo.BaseModuleName + ccInfo.SnapshotInfo.SnapshotAndroidMkSuffix + return commonInfo.BaseModuleName + ccInfo.SnapshotInfo.SnapshotAndroidMkSuffix } } @@ -4124,20 +4136,19 @@ func (c CcDepInSameApexChecker) IncomingDepIsInSameApex(depTag blueprint.Depende } // Implements android.ApexModule -func (c *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, - sdkVersion android.ApiLevel) error { +func (c *Module) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel { // We ignore libclang_rt.* prebuilt libs since they declare sdk_version: 14(b/121358700) if strings.HasPrefix(ctx.OtherModuleName(c), "libclang_rt") { - return nil + return android.MinApiLevel } // We don't check for prebuilt modules if _, ok := c.linker.(prebuiltLinkerInterface); ok { - return nil + return android.MinApiLevel } minSdkVersion := c.MinSdkVersion() if minSdkVersion == "apex_inherit" { - return nil + return android.MinApiLevel } if minSdkVersion == "" { // JNI libs within APK-in-APEX fall into here @@ -4146,14 +4157,16 @@ func (c *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, // non-SDK variant resets sdk_version, which works too. minSdkVersion = c.SdkVersion() } + if minSdkVersion == "" { - return fmt.Errorf("neither min_sdk_version nor sdk_version specificed") + return android.NoneApiLevel } + // Not using nativeApiLevelFromUser because the context here is not // necessarily a native context. - ver, err := android.ApiLevelFromUser(ctx, minSdkVersion) + ver, err := android.ApiLevelFromUserWithConfig(ctx.Config(), minSdkVersion) if err != nil { - return err + return android.NoneApiLevel } // A dependency only needs to support a min_sdk_version at least @@ -4161,15 +4174,14 @@ func (c *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, // This allows introducing new architectures in the platform that // need to be included in apexes that normally require an older // min_sdk_version. - minApiForArch := MinApiForArch(ctx, c.Target().Arch.ArchType) - if sdkVersion.LessThan(minApiForArch) { - sdkVersion = minApiForArch + if c.Enabled(ctx) { + minApiForArch := MinApiForArch(ctx, c.Target().Arch.ArchType) + if ver.LessThanOrEqualTo(minApiForArch) { + ver = android.MinApiLevel + } } - if ver.GreaterThan(sdkVersion) { - return fmt.Errorf("newer SDK(%v)", ver) - } - return nil + return ver } // Implements android.ApexModule diff --git a/cc/cc_test.go b/cc/cc_test.go index 2c06924ea..7240ea587 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -2689,7 +2689,7 @@ func TestIncludeDirectoryOrdering(t *testing.T) { cppOnly := []string{"-fPIC", "${config.CommonGlobalCppflags}", "${config.DeviceGlobalCppflags}", "${config.ArmCppflags}"} cflags := []string{"-Werror", "-std=candcpp"} - cstd := []string{"-std=gnu17", "-std=conly"} + cstd := []string{"-std=gnu23", "-std=conly"} cppstd := []string{"-std=gnu++20", "-std=cpp", "-fno-rtti"} lastNDKFlags := []string{ diff --git a/cc/config/global.go b/cc/config/global.go index 7bea124ea..5011acd50 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -375,7 +375,7 @@ var ( "-w", } - CStdVersion = "gnu17" + CStdVersion = "gnu23" CppStdVersion = "gnu++20" ExperimentalCStdVersion = "gnu2x" ExperimentalCppStdVersion = "gnu++2b" diff --git a/cc/linkable.go b/cc/linkable.go index 337b45943..f3aff1523 100644 --- a/cc/linkable.go +++ b/cc/linkable.go @@ -83,7 +83,7 @@ type VersionedLinkableInterface interface { SetSdkVersion(string) SetMinSdkVersion(version string) ApexSdkVersion() android.ApiLevel - ImplementationModuleNameForMake(ctx android.BaseModuleContext) string + ImplementationModuleNameForMake() 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. diff --git a/cc/llndk_library.go b/cc/llndk_library.go index 558657668..8ca3ca184 100644 --- a/cc/llndk_library.go +++ b/cc/llndk_library.go @@ -147,6 +147,8 @@ func (txt *llndkLibrariesTxtModule) GenerateAndroidBuildActions(ctx android.Modu ctx.InstallFile(installPath, filename, txt.outputFile) ctx.SetOutputFiles(android.Paths{txt.outputFile}, "") + + etc.SetCommonPrebuiltEtcInfo(ctx, txt) } func getVndkFileName(m *Module) (string, error) { diff --git a/cc/sanitize.go b/cc/sanitize.go index e7598e709..b704ef4bf 100644 --- a/cc/sanitize.go +++ b/cc/sanitize.go @@ -1901,6 +1901,8 @@ func (txt *sanitizerLibrariesTxtModule) GenerateAndroidBuildActions(ctx android. ctx.SetOutputFiles(android.Paths{outputFile}, "") txt.outputFile = outputFile + + etc.SetCommonPrebuiltEtcInfo(ctx, txt) } func (txt *sanitizerLibrariesTxtModule) PrepareAndroidMKProviderInfo(config android.Config) *android.AndroidMkProviderInfo { diff --git a/cc/test.go b/cc/test.go index b3b2ae8c4..2c5c36eac 100644 --- a/cc/test.go +++ b/cc/test.go @@ -418,6 +418,10 @@ func (test *testBinary) install(ctx ModuleContext, file android.Path) { if test.testConfig != nil { ctx.InstallFile(testCases, ctx.ModuleName()+".config", test.testConfig) } + dynamicConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml") + if dynamicConfig.Valid() { + ctx.InstallFile(testCases, ctx.ModuleName()+".dynamic", dynamicConfig.Path()) + } for _, extraTestConfig := range test.extraTestConfigs { ctx.InstallFile(testCases, extraTestConfig.Base(), extraTestConfig) } diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go index e882470ac..1452b412e 100644 --- a/dexpreopt/dexpreopt.go +++ b/dexpreopt/dexpreopt.go @@ -284,7 +284,8 @@ func dexpreoptCommand(ctx android.BuilderContext, globalSoong *GlobalSoongConfig clcTargetString := "PCL[" + strings.Join(clcTarget, ":") + "]" if systemServerClasspathJars.ContainsJar(module.Name) { - checkSystemServerOrder(ctx, jarIndex) + // TODO(b/397461231): renable this check + //checkSystemServerOrder(ctx, jarIndex) } else { // Standalone jars are loaded by separate class loaders with SYSTEMSERVERCLASSPATH as the // parent. diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go index bf54c0941..a440c9113 100644 --- a/etc/prebuilt_etc.go +++ b/etc/prebuilt_etc.go @@ -32,6 +32,7 @@ import ( "path/filepath" "strings" + "github.com/google/blueprint" "github.com/google/blueprint/proptools" "android/soong/android" @@ -90,6 +91,15 @@ func RegisterPrebuiltEtcBuildComponents(ctx android.RegistrationContext) { } +type PrebuiltEtcInfo struct { + // Returns the base install directory, such as "etc", "usr/share". + BaseDir string + // Returns the sub install directory relative to BaseDir(). + SubDir string +} + +var PrebuiltEtcInfoProvider = blueprint.NewProvider[PrebuiltEtcInfo]() + var PrepareForTestWithPrebuiltEtc = android.FixtureRegisterWithContext(RegisterPrebuiltEtcBuildComponents) type PrebuiltEtcProperties struct { @@ -502,6 +512,15 @@ func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx android.ModuleContext) { p.updateModuleInfoJSON(ctx) ctx.SetOutputFiles(p.outputFilePaths.Paths(), "") + + SetCommonPrebuiltEtcInfo(ctx, p) +} + +func SetCommonPrebuiltEtcInfo(ctx android.ModuleContext, p PrebuiltEtcModule) { + android.SetProvider(ctx, PrebuiltEtcInfoProvider, PrebuiltEtcInfo{ + BaseDir: p.BaseDir(), + SubDir: p.SubDir(), + }) } func (p *PrebuiltEtc) updateModuleInfoJSON(ctx android.ModuleContext) { diff --git a/filesystem/aconfig_files.go b/filesystem/aconfig_files.go index 6d034027d..b4173d784 100644 --- a/filesystem/aconfig_files.go +++ b/filesystem/aconfig_files.go @@ -22,6 +22,17 @@ import ( "github.com/google/blueprint/proptools" ) +func init() { + pctx.HostBinToolVariable("aconfig", "aconfig") +} + +var ( + aconfigCreateStorage = pctx.AndroidStaticRule("aconfig_create_storage", blueprint.RuleParams{ + Command: `$aconfig create-storage --container $container --file $fileType --out $out --cache $in --version $version`, + CommandDeps: []string{"$aconfig"}, + }, "container", "fileType", "version") +) + type installedAconfigFlagsInfo struct { aconfigFiles android.Paths } @@ -66,45 +77,57 @@ func (f *filesystem) buildAconfigFlagsFiles( container := f.PartitionType() - installAconfigFlagsPath := dir.Join(ctx, "etc", "aconfig_flags.pb") - cmd := builder.Command(). + aconfigFlagsPb := android.PathForModuleOut(ctx, "aconfig", "aconfig_flags.pb") + aconfigFlagsPbBuilder := android.NewRuleBuilder(pctx, ctx) + cmd := aconfigFlagsPbBuilder.Command(). BuiltTool("aconfig"). Text(" dump-cache --dedup --format protobuf --out"). - Output(installAconfigFlagsPath). + Output(aconfigFlagsPb). Textf("--filter container:%s+state:ENABLED", container). Textf("--filter container:%s+permission:READ_WRITE", container) for _, cache := range caches { cmd.FlagWithInput("--cache ", cache) } + aconfigFlagsPbBuilder.Build("aconfig_flags_pb", "build aconfig_flags.pb") + + installAconfigFlagsPath := dir.Join(ctx, "etc", "aconfig_flags.pb") + builder.Command().Text("mkdir -p ").Text(dir.Join(ctx, "etc").String()) + builder.Command().Text("cp").Input(aconfigFlagsPb).Text(installAconfigFlagsPath.String()) *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{ FullInstallPath: android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), "etc/aconfig_flags.pb"), - SourcePath: installAconfigFlagsPath, + SourcePath: aconfigFlagsPb, }) f.appendToEntry(ctx, installAconfigFlagsPath) - installAconfigStorageDir := dir.Join(ctx, "etc", "aconfig") - builder.Command().Text("mkdir -p").Text(installAconfigStorageDir.String()) - // To enable fingerprint, we need to have v2 storage files. The default version is 1. storageFilesVersion := 1 if ctx.Config().ReleaseFingerprintAconfigPackages() { storageFilesVersion = 2 } + installAconfigStorageDir := dir.Join(ctx, "etc", "aconfig") + builder.Command().Text("mkdir -p").Text(installAconfigStorageDir.String()) + generatePartitionAconfigStorageFile := func(fileType, fileName string) { - outputPath := installAconfigStorageDir.Join(ctx, fileName) + outPath := android.PathForModuleOut(ctx, "aconfig", fileName) + installPath := installAconfigStorageDir.Join(ctx, fileName) + ctx.Build(pctx, android.BuildParams{ + Rule: aconfigCreateStorage, + Input: aconfigFlagsPb, + Output: outPath, + Args: map[string]string{ + "container": container, + "fileType": fileType, + "version": strconv.Itoa(storageFilesVersion), + }, + }) builder.Command(). - BuiltTool("aconfig"). - FlagWithArg("create-storage --container ", container). - FlagWithArg("--file ", fileType). - FlagWithOutput("--out ", outputPath). - FlagWithArg("--cache ", installAconfigFlagsPath.String()). - FlagWithArg("--version ", strconv.Itoa(storageFilesVersion)) + Text("cp").Input(outPath).Text(installPath.String()) *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{ + SourcePath: outPath, FullInstallPath: android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), "etc/aconfig", fileName), - SourcePath: outputPath, }) - f.appendToEntry(ctx, outputPath) + f.appendToEntry(ctx, installPath) } if ctx.Config().ReleaseCreateAconfigStorageFile() { diff --git a/filesystem/android_device.go b/filesystem/android_device.go index 6d6521728..47c4e3d0c 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -336,11 +336,6 @@ func (a *androidDevice) buildTargetFilesZip(ctx android.ModuleContext) { targetFilesZipCopy{a.partitionProps.Init_boot_partition_name, "INIT_BOOT/RAMDISK"}, targetFilesZipCopy{a.partitionProps.Vendor_boot_partition_name, "VENDOR_BOOT/RAMDISK"}, } - // TODO: Handle cases where recovery files are copied to BOOT/ or RECOVERY/ - // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile;l=6211-6219?q=core%2FMakefile&ss=android%2Fplatform%2Fsuperproject%2Fmain - if ctx.DeviceConfig().BoardMoveRecoveryResourcesToVendorBoot() { - toCopy = append(toCopy, targetFilesZipCopy{a.partitionProps.Recovery_partition_name, "VENDOR_BOOT/RAMDISK"}) - } filesystemsToCopy := []targetFilesystemZipCopy{} for _, zipCopy := range toCopy { @@ -377,6 +372,12 @@ func (a *androidDevice) buildTargetFilesZip(ctx android.ModuleContext) { BuiltTool("acp"). Textf("-rd %s/. %s/%s", rootDirString, targetFilesDir, toCopy.destSubdir). Implicit(toCopy.fsInfo.Output) // so that the staging dir is built + for _, extraRootDir := range toCopy.fsInfo.ExtraRootDirs { + builder.Command(). + BuiltTool("acp"). + Textf("-rd %s/. %s/%s", extraRootDir, targetFilesDir, toCopy.destSubdir). + Implicit(toCopy.fsInfo.Output) // so that the staging dir is built + } if toCopy.destSubdir == "SYSTEM" { // Create the ROOT partition in target_files.zip diff --git a/filesystem/avb_add_hash_footer.go b/filesystem/avb_add_hash_footer.go index f32993c4b..c1e03cb62 100644 --- a/filesystem/avb_add_hash_footer.go +++ b/filesystem/avb_add_hash_footer.go @@ -149,6 +149,8 @@ func (a *avbAddHashFooter) GenerateAndroidBuildActions(ctx android.ModuleContext a.installDir = android.PathForModuleInstall(ctx, "etc") ctx.InstallFile(a.installDir, a.installFileName(), output) a.output = output + + setCommonFilesystemInfo(ctx, a) } func addAvbProp(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, prop avbProp) { diff --git a/filesystem/bootimg.go b/filesystem/bootimg.go index 6d6c15c05..effbd6542 100644 --- a/filesystem/bootimg.go +++ b/filesystem/bootimg.go @@ -230,6 +230,8 @@ func (b *bootimg) GenerateAndroidBuildActions(ctx android.ModuleContext) { ramdiskModule := ctx.GetDirectDepWithTag(ramdisk, bootimgRamdiskDep) fsInfo, _ := android.OtherModuleProvider(ctx, ramdiskModule, FilesystemProvider) android.SetProvider(ctx, FilesystemProvider, fsInfo) + } else { + setCommonFilesystemInfo(ctx, b) } // Set BootimgInfo for building target_files.zip diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index aadb76262..40a460b31 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -392,6 +392,9 @@ type InstalledModuleInfo struct { type FilesystemInfo struct { // The built filesystem image Output android.Path + // Returns the output file that is signed by avbtool. If this module is not signed, returns + // nil. + SignedOutputPath android.Path // An additional hermetic filesystem image. // e.g. this will contain inodes with pinned timestamps. // This will be copied to target_files.zip @@ -402,6 +405,9 @@ type FilesystemInfo struct { // to add a dependency on the Output file, as you cannot add dependencies on directories // in ninja. RootDir android.Path + // Extra root directories that are also built into the partition. Currently only used for + // including the recovery partition files into the vendor_boot image. + ExtraRootDirs android.Paths // The rebased staging directory used to build the output filesystem. If consuming this, make // sure to add a dependency on the Output file, as you cannot add dependencies on directories // in ninja. In many cases this is the same as RootDir, only in the system partition is it @@ -619,6 +625,7 @@ func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) { var outputHermetic android.WritablePath var buildImagePropFile android.Path var buildImagePropFileDeps android.Paths + var extraRootDirs android.Paths switch f.fsType(ctx) { case ext4Type, erofsType, f2fsType: buildImagePropFile, buildImagePropFileDeps = f.buildPropFile(ctx) @@ -632,9 +639,9 @@ func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) { f.buildImageUsingBuildImage(ctx, hermeticBuilder, buildImageParams{rootDir, propFileHermetic, buildImagePropFileDeps, outputHermetic}) mapFile = f.getMapFile(ctx) case compressedCpioType: - f.output = f.buildCpioImage(ctx, builder, rootDir, true) + f.output, extraRootDirs = f.buildCpioImage(ctx, builder, rootDir, true) case cpioType: - f.output = f.buildCpioImage(ctx, builder, rootDir, false) + f.output, extraRootDirs = f.buildCpioImage(ctx, builder, rootDir, false) default: return } @@ -662,10 +669,12 @@ func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) { } fsInfo := FilesystemInfo{ - Output: f.output, + Output: f.OutputPath(), + SignedOutputPath: f.SignedOutputPath(), OutputHermetic: outputHermetic, FileListFile: fileListFile, RootDir: rootDir, + ExtraRootDirs: extraRootDirs, RebasedDir: rebasedDir, MapFile: mapFile, ModuleName: ctx.ModuleName(), @@ -1165,7 +1174,7 @@ func (f *filesystem) buildCpioImage( builder *android.RuleBuilder, rootDir android.OutputPath, compressed bool, -) android.Path { +) (android.Path, android.Paths) { if proptools.Bool(f.properties.Use_avb) { ctx.PropertyErrorf("use_avb", "signing compresed cpio image using avbtool is not supported."+ "Consider adding this to bootimg module and signing the entire boot image.") @@ -1205,7 +1214,7 @@ func (f *filesystem) buildCpioImage( // rootDir is not deleted. Might be useful for quick inspection. builder.Build("build_cpio_image", fmt.Sprintf("Creating filesystem %s", f.BaseModuleName())) - return output + return output, rootDirs } var validPartitions = []string{ @@ -1519,3 +1528,10 @@ func (f *filesystem) MakeVars(ctx android.MakeVarsModuleContext) { ctx.StrictRaw("SOONG_DEFINED_SYSTEM_IMAGE_PATH", f.output.String()) } } + +func setCommonFilesystemInfo(ctx android.ModuleContext, m Filesystem) { + android.SetProvider(ctx, FilesystemProvider, FilesystemInfo{ + Output: m.OutputPath(), + SignedOutputPath: m.SignedOutputPath(), + }) +} diff --git a/filesystem/fsverity_metadata.go b/filesystem/fsverity_metadata.go index a3a2086ce..89da3182a 100644 --- a/filesystem/fsverity_metadata.go +++ b/filesystem/fsverity_metadata.go @@ -21,9 +21,27 @@ import ( "android/soong/android" + "github.com/google/blueprint" "github.com/google/blueprint/proptools" ) +func init() { + pctx.HostBinToolVariable("fsverity_metadata_generator", "fsverity_metadata_generator") + pctx.HostBinToolVariable("fsverity_manifest_generator", "fsverity_manifest_generator") + pctx.HostBinToolVariable("fsverity", "fsverity") +} + +var ( + buildFsverityMeta = pctx.AndroidStaticRule("build_fsverity_meta", blueprint.RuleParams{ + Command: `$fsverity_metadata_generator --fsverity-path $fsverity --signature none --hash-alg sha256 --output $out $in`, + CommandDeps: []string{"$fsverity_metadata_generator", "$fsverity"}, + }) + buildFsverityManifest = pctx.AndroidStaticRule("build_fsverity_manifest", blueprint.RuleParams{ + Command: `$fsverity_manifest_generator --fsverity-path $fsverity --output $out @$in`, + CommandDeps: []string{"$fsverity_manifest_generator", "$fsverity"}, + }) +) + type fsverityProperties struct { // Patterns of files for fsverity metadata generation. For each matched file, a .fsv_meta file // will be generated and included to the filesystem image. @@ -35,13 +53,57 @@ type fsverityProperties struct { Libs proptools.Configurable[[]string] `android:"path"` } -func (f *filesystem) writeManifestGeneratorListFile(ctx android.ModuleContext, outputPath android.WritablePath, matchedSpecs []android.PackagingSpec, rebasedDir android.OutputPath) { +// Mapping of a given fsverity file, which may be a real file or a symlink, and the on-device +// path it should have relative to the filesystem root. +type fsveritySrcDest struct { + src android.Path + dest string +} + +func (f *filesystem) writeManifestGeneratorListFile( + ctx android.ModuleContext, + outputPath android.WritablePath, + matchedFiles []fsveritySrcDest, + rootDir android.OutputPath, + rebasedDir android.OutputPath, +) []android.Path { + prefix, err := filepath.Rel(rootDir.String(), rebasedDir.String()) + if err != nil { + panic("rebasedDir should be relative to rootDir") + } + if prefix == "." { + prefix = "" + } + if f.PartitionType() == "system_ext" { + // Use the equivalent of $PRODUCT_OUT as the base dir. + // This ensures that the paths in build_manifest.pb contain on-device paths + // e.g. system_ext/framework/javalib.jar + // and not framework/javalib.jar. + // + // Although base-dir is outside the rootdir provided for packaging, this action + // is hermetic since it uses `manifestGeneratorListPath` to filter the files to be written to build_manifest.pb + prefix = "system_ext" + } + + var deps []android.Path var buf strings.Builder - for _, spec := range matchedSpecs { - buf.WriteString(rebasedDir.Join(ctx, spec.RelPathInPackage()).String()) - buf.WriteRune('\n') + for _, spec := range matchedFiles { + src := spec.src.String() + dst := filepath.Join(prefix, spec.dest) + if strings.Contains(src, ",") { + ctx.ModuleErrorf("Path cannot contain a comma: %s", src) + } + if strings.Contains(dst, ",") { + ctx.ModuleErrorf("Path cannot contain a comma: %s", dst) + } + buf.WriteString(src) + buf.WriteString(",") + buf.WriteString(dst) + buf.WriteString("\n") + deps = append(deps, spec.src) } android.WriteFileRuleVerbatim(ctx, outputPath, buf.String()) + return deps } func (f *filesystem) buildFsverityMetadataFiles( @@ -64,69 +126,98 @@ func (f *filesystem) buildFsverityMetadataFiles( return false } - var matchedSpecs []android.PackagingSpec + var matchedFiles []android.PackagingSpec + var matchedSymlinks []android.PackagingSpec for _, relPath := range android.SortedKeys(specs) { if match(relPath) { - matchedSpecs = append(matchedSpecs, specs[relPath]) + spec := specs[relPath] + if spec.SrcPath() != nil { + matchedFiles = append(matchedFiles, spec) + } else if spec.SymlinkTarget() != "" { + matchedSymlinks = append(matchedSymlinks, spec) + } else { + ctx.ModuleErrorf("Expected a file or symlink for fsverity packaging spec") + } } } - if len(matchedSpecs) == 0 { + if len(matchedFiles) == 0 && len(matchedSymlinks) == 0 { return } - fsverityPath := ctx.Config().HostToolPath(ctx, "fsverity") - // STEP 1: generate .fsv_meta - var sb strings.Builder - sb.WriteString("set -e\n") - for _, spec := range matchedSpecs { + var fsverityFileSpecs []fsveritySrcDest + for _, spec := range matchedFiles { + rel := spec.RelPathInPackage() + ".fsv_meta" + outPath := android.PathForModuleOut(ctx, "fsverity/meta_files", rel) + destPath := rebasedDir.Join(ctx, rel) // srcPath is copied by CopySpecsToDir() - srcPath := rebasedDir.Join(ctx, spec.RelPathInPackage()) - destPath := rebasedDir.Join(ctx, spec.RelPathInPackage()+".fsv_meta") - builder.Command(). - BuiltTool("fsverity_metadata_generator"). - FlagWithInput("--fsverity-path ", fsverityPath). - FlagWithArg("--signature ", "none"). - FlagWithArg("--hash-alg ", "sha256"). - FlagWithOutput("--output ", destPath). - Text(srcPath.String()) + ctx.Build(pctx, android.BuildParams{ + Rule: buildFsverityMeta, + Input: spec.SrcPath(), + Output: outPath, + }) + builder.Command().Textf("cp").Input(outPath).Output(destPath) f.appendToEntry(ctx, destPath) *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{ SourcePath: destPath, - FullInstallPath: android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), spec.RelPathInPackage()+".fsv_meta"), + FullInstallPath: android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), rel), + }) + fsverityFileSpecs = append(fsverityFileSpecs, fsveritySrcDest{ + src: spec.SrcPath(), + dest: spec.RelPathInPackage(), }) } - - fsVerityBaseDir := rootDir.String() - if f.PartitionType() == "system_ext" { - // Use the equivalent of $PRODUCT_OUT as the base dir. - // This ensures that the paths in build_manifest.pb contain on-device paths - // e.g. system_ext/framework/javalib.jar - // and not framework/javalib.jar. - // - // Although base-dir is outside the rootdir provided for packaging, this action - // is hermetic since it uses `manifestGeneratorListPath` to filter the files to be written to build_manifest.pb - fsVerityBaseDir = filepath.Dir(rootDir.String()) + for _, spec := range matchedSymlinks { + rel := spec.RelPathInPackage() + ".fsv_meta" + outPath := android.PathForModuleOut(ctx, "fsverity/meta_files", rel) + destPath := rebasedDir.Join(ctx, rel) + target := spec.SymlinkTarget() + ".fsv_meta" + ctx.Build(pctx, android.BuildParams{ + Rule: android.Symlink, + Output: outPath, + Args: map[string]string{ + "fromPath": target, + }, + }) + builder.Command(). + Textf("cp"). + Flag(ctx.Config().CpPreserveSymlinksFlags()). + Input(outPath). + Output(destPath) + f.appendToEntry(ctx, destPath) + *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{ + SymlinkTarget: target, + FullInstallPath: android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), rel), + }) + // The fsverity manifest tool needs to actually look at the symlink. But symlink + // packagingSpecs are not actually created on disk, at least until the staging dir is + // built for the partition. Create a fake one now so the tool can see it. + realizedSymlink := android.PathForModuleOut(ctx, "fsverity/realized_symlinks", spec.RelPathInPackage()) + ctx.Build(pctx, android.BuildParams{ + Rule: android.Symlink, + Output: realizedSymlink, + Args: map[string]string{ + "fromPath": spec.SymlinkTarget(), + }, + }) + fsverityFileSpecs = append(fsverityFileSpecs, fsveritySrcDest{ + src: realizedSymlink, + dest: spec.RelPathInPackage(), + }) } // STEP 2: generate signed BuildManifest.apk // STEP 2-1: generate build_manifest.pb - manifestGeneratorListPath := android.PathForModuleOut(ctx, "fsverity_manifest.list") - f.writeManifestGeneratorListFile(ctx, manifestGeneratorListPath, matchedSpecs, rebasedDir) - assetsPath := android.PathForModuleOut(ctx, "fsverity_manifest/assets") - manifestPbPath := assetsPath.Join(ctx, "build_manifest.pb") - builder.Command().Text("rm -rf " + assetsPath.String()) - builder.Command().Text("mkdir -p " + assetsPath.String()) - builder.Command(). - BuiltTool("fsverity_manifest_generator"). - FlagWithInput("--fsverity-path ", fsverityPath). - FlagWithArg("--base-dir ", fsVerityBaseDir). - FlagWithArg("--output ", manifestPbPath.String()). - FlagWithInput("@", manifestGeneratorListPath) - - f.appendToEntry(ctx, manifestPbPath) - f.appendToEntry(ctx, manifestGeneratorListPath) + manifestGeneratorListPath := android.PathForModuleOut(ctx, "fsverity/fsverity_manifest.list") + manifestDeps := f.writeManifestGeneratorListFile(ctx, manifestGeneratorListPath, fsverityFileSpecs, rootDir, rebasedDir) + manifestPbPath := android.PathForModuleOut(ctx, "fsverity/build_manifest.pb") + ctx.Build(pctx, android.BuildParams{ + Rule: buildFsverityManifest, + Input: manifestGeneratorListPath, + Implicits: manifestDeps, + Output: manifestPbPath, + }) // STEP 2-2: generate BuildManifest.apk (unsigned) apkNameSuffix := "" @@ -134,8 +225,8 @@ func (f *filesystem) buildFsverityMetadataFiles( //https://source.corp.google.com/h/googleplex-android/platform/build/+/e392d2b486c2d4187b20a72b1c67cc737ecbcca5:core/Makefile;l=3410;drc=ea8f34bc1d6e63656b4ec32f2391e9d54b3ebb6b;bpv=1;bpt=0 apkNameSuffix = "SystemExt" } - apkPath := rebasedDir.Join(ctx, "etc", "security", "fsverity", fmt.Sprintf("BuildManifest%s.apk", apkNameSuffix)) - idsigPath := rebasedDir.Join(ctx, "etc", "security", "fsverity", fmt.Sprintf("BuildManifest%s.apk.idsig", apkNameSuffix)) + apkPath := android.PathForModuleOut(ctx, "fsverity", fmt.Sprintf("BuildManifest%s.apk", apkNameSuffix)) + idsigPath := android.PathForModuleOut(ctx, "fsverity", fmt.Sprintf("BuildManifest%s.apk.idsig", apkNameSuffix)) manifestTemplatePath := android.PathForSource(ctx, "system/security/fsverity/AndroidManifest.xml") libs := android.PathsForModuleSrc(ctx, f.properties.Fsverity.Libs.GetOrDefault(ctx, nil)) @@ -144,12 +235,23 @@ func (f *filesystem) buildFsverityMetadataFiles( minSdkVersion = ctx.Config().PlatformSdkVersion().String() } - unsignedApkCommand := builder.Command(). - Textf("mkdir -p %s && ", filepath.Dir(apkPath.String())). + apkBuilder := android.NewRuleBuilder(pctx, ctx) + + // aapt2 doesn't support adding individual asset files. Create a temp directory to hold asset + // files and pass it to aapt2. + tmpAssetDir := android.PathForModuleOut(ctx, "fsverity/tmp_asset_dir") + stagedManifestPbPath := tmpAssetDir.Join(ctx, "build_manifest.pb") + apkBuilder.Command(). + Text("rm -rf").Text(tmpAssetDir.String()). + Text("&&"). + Text("mkdir -p").Text(tmpAssetDir.String()) + apkBuilder.Command().Text("cp").Input(manifestPbPath).Output(stagedManifestPbPath) + + unsignedApkCommand := apkBuilder.Command(). BuiltTool("aapt2"). Text("link"). FlagWithOutput("-o ", apkPath). - FlagWithArg("-A ", assetsPath.String()) + FlagWithArg("-A ", tmpAssetDir.String()).Implicit(stagedManifestPbPath) for _, lib := range libs { unsignedApkCommand.FlagWithInput("-I ", lib) } @@ -159,26 +261,36 @@ func (f *filesystem) buildFsverityMetadataFiles( FlagWithArg("--version-name ", ctx.Config().AppsDefaultVersionName()). FlagWithInput("--manifest ", manifestTemplatePath). Text(" --rename-manifest-package com.android.security.fsverity_metadata." + f.partitionName()) - *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{ - SourcePath: apkPath, - FullInstallPath: android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), fmt.Sprintf("etc/security/fsverity/BuildManifest%s.apk", apkNameSuffix)), - }) - - f.appendToEntry(ctx, apkPath) // STEP 2-3: sign BuildManifest.apk pemPath, keyPath := ctx.Config().DefaultAppCertificate(ctx) - builder.Command(). + apkBuilder.Command(). BuiltTool("apksigner"). Text("sign"). FlagWithArg("--in ", apkPath.String()). FlagWithInput("--cert ", pemPath). FlagWithInput("--key ", keyPath). ImplicitOutput(idsigPath) + apkBuilder.Build(fmt.Sprintf("%s_fsverity_apk", ctx.ModuleName()), "build fsverity apk") + + // STEP 2-4: Install the apk into the staging directory + installedApkPath := rebasedDir.Join(ctx, "etc", "security", "fsverity", fmt.Sprintf("BuildManifest%s.apk", apkNameSuffix)) + installedIdsigPath := rebasedDir.Join(ctx, "etc", "security", "fsverity", fmt.Sprintf("BuildManifest%s.apk.idsig", apkNameSuffix)) + builder.Command().Text("mkdir -p").Text(filepath.Dir(installedApkPath.String())) + builder.Command().Text("cp").Input(apkPath).Text(installedApkPath.String()) + builder.Command().Text("cp").Input(idsigPath).Text(installedIdsigPath.String()) + + *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{ + SourcePath: apkPath, + FullInstallPath: android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), fmt.Sprintf("etc/security/fsverity/BuildManifest%s.apk", apkNameSuffix)), + }) + + f.appendToEntry(ctx, installedApkPath) + *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{ SourcePath: idsigPath, FullInstallPath: android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), fmt.Sprintf("etc/security/fsverity/BuildManifest%s.apk.idsig", apkNameSuffix)), }) - f.appendToEntry(ctx, idsigPath) + f.appendToEntry(ctx, installedIdsigPath) } diff --git a/filesystem/logical_partition.go b/filesystem/logical_partition.go index d0888a9c8..1fd2e766b 100644 --- a/filesystem/logical_partition.go +++ b/filesystem/logical_partition.go @@ -198,6 +198,8 @@ func (l *logicalPartition) GenerateAndroidBuildActions(ctx android.ModuleContext ctx.SetOutputFiles([]android.Path{output}, "") l.output = output + + setCommonFilesystemInfo(ctx, l) } // Add a rule that converts the filesystem for the given partition to the given rule builder. The diff --git a/filesystem/raw_binary.go b/filesystem/raw_binary.go index 707fba06f..6ca155aaf 100644 --- a/filesystem/raw_binary.go +++ b/filesystem/raw_binary.go @@ -88,6 +88,8 @@ func (r *rawBinary) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.SetOutputFiles([]android.Path{outputFile}, "") r.output = outputFile + + setCommonFilesystemInfo(ctx, r) } var _ android.AndroidMkEntriesProvider = (*rawBinary)(nil) diff --git a/filesystem/vbmeta.go b/filesystem/vbmeta.go index e5809d31b..01b453e25 100644 --- a/filesystem/vbmeta.go +++ b/filesystem/vbmeta.go @@ -306,6 +306,8 @@ func (v *vbmeta) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.SetOutputFiles([]android.Path{output}, "") v.output = output + + setCommonFilesystemInfo(ctx, v) } // Returns the embedded shell command that prints the rollback index diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go index c2721d29f..e2485a1d3 100644 --- a/fsgen/filesystem_creator.go +++ b/fsgen/filesystem_creator.go @@ -377,7 +377,7 @@ func (f *filesystemCreator) createDeviceModule( if modName := partitions.nameForType("userdata"); modName != "" { partitionProps.Userdata_partition_name = proptools.StringPtr(modName) } - if modName := partitions.nameForType("recovery"); modName != "" { + if modName := partitions.nameForType("recovery"); modName != "" && !ctx.DeviceConfig().BoardMoveRecoveryResourcesToVendorBoot() { partitionProps.Recovery_partition_name = proptools.StringPtr(modName) } if modName := partitions.nameForType("system_dlkm"); modName != "" && !android.InList("system_dlkm", superImageSubPartitions) { diff --git a/genrule/genrule.go b/genrule/genrule.go index 92f038f6d..6bd1fcc8d 100644 --- a/genrule/genrule.go +++ b/genrule/genrule.go @@ -727,11 +727,8 @@ func (g *Module) AndroidMk() android.AndroidMkData { var _ android.ApexModule = (*Module)(nil) // Implements android.ApexModule -func (g *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, - sdkVersion android.ApiLevel) error { - // Because generated outputs are checked by client modules(e.g. cc_library, ...) - // we can safely ignore the check here. - return nil +func (m *Module) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel { + return android.MinApiLevel } func generatorFactory(taskGenerator taskFunc, props ...interface{}) *Module { diff --git a/java/aar.go b/java/aar.go index 95387a358..f7c5c13de 100644 --- a/java/aar.go +++ b/java/aar.go @@ -1638,9 +1638,8 @@ func (m AARImportDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.Dep } // Implements android.ApexModule -func (a *AARImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext, - sdkVersion android.ApiLevel) error { - return nil +func (a *AARImport) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel { + return android.MinApiLevel } var _ android.PrebuiltInterface = (*AARImport)(nil) diff --git a/java/app.go b/java/app.go index a634f9c32..9b10bf3cd 100644 --- a/java/app.go +++ b/java/app.go @@ -72,6 +72,16 @@ type AppInfo struct { EmbeddedJNILibs android.Paths MergedManifestFile android.Path + + Prebuilt bool + AppSet bool + Privileged bool + OutputFile android.Path + InstallApkName string + JacocoReportClassesFile android.Path + Certificate Certificate + PrivAppAllowlist android.OptionalPath + OverriddenManifestPackageName *string } var AppInfoProvider = blueprint.NewProvider[*AppInfo]() @@ -401,10 +411,12 @@ func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleCon android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{ TestOnly: true, }) - android.SetProvider(ctx, AppInfoProvider, &AppInfo{ + appInfo := &AppInfo{ Updatable: Bool(a.appProperties.Updatable), TestHelperApp: true, - }) + } + setCommonAppInfo(appInfo, a) + android.SetProvider(ctx, AppInfoProvider, appInfo) moduleInfoJSON := ctx.ModuleInfoJSON() moduleInfoJSON.Tags = append(moduleInfoJSON.Tags, "tests") @@ -428,12 +440,16 @@ func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) { embeddedJniLibs = append(embeddedJniLibs, jni.path) } } - android.SetProvider(ctx, AppInfoProvider, &AppInfo{ - Updatable: Bool(a.appProperties.Updatable), - TestHelperApp: false, - EmbeddedJNILibs: embeddedJniLibs, - MergedManifestFile: a.mergedManifest, - }) + overriddenName := a.OverriddenManifestPackageName() + appInfo := &AppInfo{ + Updatable: Bool(a.appProperties.Updatable), + TestHelperApp: false, + EmbeddedJNILibs: embeddedJniLibs, + MergedManifestFile: a.mergedManifest, + OverriddenManifestPackageName: &overriddenName, + } + setCommonAppInfo(appInfo, a) + android.SetProvider(ctx, AppInfoProvider, appInfo) a.requiredModuleNames = a.getRequiredModuleNames(ctx) } @@ -1281,7 +1297,7 @@ func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) { // Skip dependencies that are only available to APEXes; they are developed with updatability // in mind and don't need manual approval. - if to.(android.ApexModule).NotAvailableForPlatform() { + if android.OtherModuleProviderOrDefault(ctx, to, android.CommonModuleInfoKey).NotAvailableForPlatform { return true } @@ -1291,18 +1307,9 @@ func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) { depsInfo[depName] = info } else { toMinSdkVersion := "(no version)" - if m, ok := to.(interface { - MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel - }); ok { - if v := m.MinSdkVersion(ctx); !v.IsNone() { - toMinSdkVersion = v.String() - } - } else if m, ok := to.(interface{ MinSdkVersion() string }); ok { - // TODO(b/175678607) eliminate the use of MinSdkVersion returning - // string - if v := m.MinSdkVersion(); v != "" { - toMinSdkVersion = v - } + if info, ok := android.OtherModuleProvider(ctx, to, android.CommonModuleInfoKey); ok && + !info.MinSdkVersion.IsPlatform && info.MinSdkVersion.ApiLevel != nil { + toMinSdkVersion = info.MinSdkVersion.ApiLevel.String() } depsInfo[depName] = android.ApexModuleDepInfo{ To: depName, @@ -1636,6 +1643,10 @@ func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { if a.testConfig != nil { ctx.InstallFile(pathInTestCases, ctx.Module().Name()+".config", a.testConfig) } + dynamicConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml") + if dynamicConfig.Valid() { + ctx.InstallFile(pathInTestCases, ctx.Module().Name()+".dynamic", dynamicConfig.Path()) + } testDeps := append(a.data, a.extraTestConfigs...) for _, data := range android.SortedUniquePaths(testDeps) { dataPath := android.DataPath{SrcPath: data} @@ -2053,7 +2064,7 @@ func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext if _, ok := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); ok { // Skip java_sdk_library dependencies that provide stubs, but not an implementation. // This will be restricted to optional_uses_libs - if tag == usesLibOptTag && lib.DexJarBuildPath.PathOrNil() == nil { + if tag == usesLibOptTag && javaInfo.DexJarBuildPath.PathOrNil() == nil { u.shouldDisableDexpreopt = true return } @@ -2063,7 +2074,7 @@ func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext libName = *ulib.ProvidesUsesLib } clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional, - lib.DexJarBuildPath.PathOrNil(), lib.DexJarInstallPath, + javaInfo.DexJarBuildPath.PathOrNil(), lib.DexJarInstallPath, lib.ClassLoaderContexts) } else if ctx.Config().AllowMissingDependencies() { ctx.AddMissingDependencies([]string{dep}) @@ -2156,3 +2167,29 @@ func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk andr classLoaderContexts *dexpreopt.ClassLoaderContextMap) { u.verifyUsesLibraries(ctx, apk, nil, classLoaderContexts) // for APKs manifest_check does not write output file } + +// androidApp is an interface to handle all app modules (android_app, android_app_import, etc.) in +// the same way. +type androidApp interface { + android.Module + Privileged() bool + InstallApkName() string + OutputFile() android.Path + JacocoReportClassesFile() android.Path + Certificate() Certificate + BaseModuleName() string + PrivAppAllowlist() android.OptionalPath +} + +var _ androidApp = (*AndroidApp)(nil) +var _ androidApp = (*AndroidAppImport)(nil) +var _ androidApp = (*AndroidTestHelperApp)(nil) + +func setCommonAppInfo(appInfo *AppInfo, m androidApp) { + appInfo.Privileged = m.Privileged() + appInfo.OutputFile = m.OutputFile() + appInfo.InstallApkName = m.InstallApkName() + appInfo.JacocoReportClassesFile = m.JacocoReportClassesFile() + appInfo.Certificate = m.Certificate() + appInfo.PrivAppAllowlist = m.PrivAppAllowlist() +} diff --git a/java/app_import.go b/java/app_import.go index a122510de..37c673ca0 100644 --- a/java/app_import.go +++ b/java/app_import.go @@ -354,6 +354,12 @@ func (a *AndroidAppImport) stripEmbeddedJniLibsUnusedArch( func (a *AndroidAppImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.generateAndroidBuildActions(ctx) + + appInfo := &AppInfo{ + Prebuilt: true, + } + setCommonAppInfo(appInfo, a) + android.SetProvider(ctx, AppInfoProvider, appInfo) } func (a *AndroidAppImport) InstallApkName() string { @@ -654,10 +660,8 @@ func (a *AndroidAppImport) MinSdkVersion(ctx android.EarlyModuleContext) android var _ android.ApexModule = (*AndroidAppImport)(nil) // Implements android.ApexModule -func (j *AndroidAppImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext, - sdkVersion android.ApiLevel) error { - // Do not check for prebuilts against the min_sdk_version of enclosing APEX - return nil +func (m *AndroidAppImport) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel { + return android.MinApiLevel } func createVariantGroupType(variants []string, variantGroupName string) reflect.Type { diff --git a/java/app_set.go b/java/app_set.go index 7997570aa..2e9d31410 100644 --- a/java/app_set.go +++ b/java/app_set.go @@ -192,6 +192,11 @@ func (as *AndroidAppSet) GenerateAndroidBuildActions(ctx android.ModuleContext) }, ) + android.SetProvider(ctx, AppInfoProvider, &AppInfo{ + AppSet: true, + Privileged: as.Privileged(), + OutputFile: as.OutputFile(), + }) } func (as *AndroidAppSet) InstallBypassMake() bool { return true } diff --git a/java/base.go b/java/base.go index 730554896..fccc80691 100644 --- a/java/base.go +++ b/java/base.go @@ -658,11 +658,11 @@ func (j *Module) checkSdkVersions(ctx android.ModuleContext) { // See rank() for details. ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) { tag := ctx.OtherModuleDependencyTag(module) - _, isJavaLibrary := android.OtherModuleProvider(ctx, module, JavaLibraryInfoProvider) + libInfo, isJavaLibrary := android.OtherModuleProvider(ctx, module, JavaLibraryInfoProvider) _, isAndroidLibrary := android.OtherModuleProvider(ctx, module, AndroidLibraryInfoProvider) _, isJavaAconfigLibrary := android.OtherModuleProvider(ctx, module, android.CodegenInfoProvider) // Exclude java_aconfig_library modules to maintain consistency with existing behavior. - if (isJavaLibrary && !isJavaAconfigLibrary) || isAndroidLibrary { + if (isJavaLibrary && !libInfo.Prebuilt && !isJavaAconfigLibrary) || isAndroidLibrary { // TODO(satayev): cover other types as well, e.g. imports switch tag { case bootClasspathTag, sdkLibTag, libTag, staticLibTag, java9LibTag: @@ -2267,20 +2267,16 @@ func (m JavaDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.Dependen } // Implements android.ApexModule -func (j *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error { +func (j *Module) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel { sdkVersionSpec := j.SdkVersion(ctx) minSdkVersion := j.MinSdkVersion(ctx) - if !minSdkVersion.Specified() { - return fmt.Errorf("min_sdk_version is not specified") - } + // If the module is compiling against core (via sdk_version), skip comparison check. if sdkVersionSpec.Kind == android.SdkCore { - return nil + return android.MinApiLevel } - if minSdkVersion.GreaterThan(sdkVersion) { - return fmt.Errorf("newer SDK(%v)", minSdkVersion) - } - return nil + + return minSdkVersion } func (j *Module) Stem() string { diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go index 8383a5a1e..a09416dc4 100644 --- a/java/bootclasspath_fragment.go +++ b/java/bootclasspath_fragment.go @@ -41,6 +41,10 @@ func registerBootclasspathFragmentBuildComponents(ctx android.RegistrationContex ctx.RegisterModuleType("prebuilt_bootclasspath_fragment", prebuiltBootclasspathFragmentFactory) } +type BootclasspathFragmentInfo struct{} + +var BootclasspathFragmentInfoProvider = blueprint.NewProvider[BootclasspathFragmentInfo]() + // BootclasspathFragmentSdkMemberType is the member type used to add bootclasspath_fragments to // the SDK snapshot. It is exported for use by apex. var BootclasspathFragmentSdkMemberType = &bootclasspathFragmentMemberType{ @@ -252,6 +256,8 @@ type BootclasspathFragmentModule struct { profilePathErr error } +var _ android.ApexModule = (*BootclasspathFragmentModule)(nil) + // commonBootclasspathFragment defines the methods that are implemented by both source and prebuilt // bootclasspath fragment modules. type commonBootclasspathFragment interface { @@ -454,8 +460,8 @@ func (b BootclasspathFragmentDepInSameApexChecker) OutgoingDepIsInSameApex(tag b panic(fmt.Errorf("boot_image module should not have a dependency tag %s", android.PrettyPrintTag(tag))) } -func (b *BootclasspathFragmentModule) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error { - return nil +func (m *BootclasspathFragmentModule) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel { + return android.MinApiLevel } // ComponentDepsMutator adds dependencies onto modules before any prebuilt modules without a @@ -555,6 +561,8 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo if !ctx.IsFinalModule(ctx.Module()) { b.HideFromMake() } + + android.SetProvider(ctx, BootclasspathFragmentInfoProvider, BootclasspathFragmentInfo{}) } // getProfileProviderApex returns the name of the apex that provides a boot image profile, or an diff --git a/java/dex.go b/java/dex.go index 64465a2de..c9d3f376d 100644 --- a/java/dex.go +++ b/java/dex.go @@ -63,6 +63,14 @@ type DexProperties struct { // Defaults to false for apps and tests, true for libraries. Proguard_compatibility *bool + // If true, R8 will not add public or protected members (fields or methods) to + // the API surface of the compilation unit, i.e., classes that are kept or + // have kept subclasses will not expose any members added by R8 for internal + // use. That includes renamed members if obfuscation is enabled. + // This should only be used for building targets that go on the bootclasspath. + // Defaults to false. + Protect_api_surface *bool + // If true, optimize for size by removing unused code. Defaults to true for apps, // false for libraries and tests. Shrink *bool @@ -170,6 +178,71 @@ var d8, d8RE = pctx.MultiCommandRemoteStaticRules("d8", }, }, []string{"outDir", "d8Flags", "zipFlags", "mergeZipsFlags"}, nil) +// Include all of the args for d8r8, so that we can generate the partialcompileclean target's build using the same list. +var d8r8Clean = pctx.AndroidStaticRule("d8r8-partialcompileclean", + blueprint.RuleParams{ + Command: `rm -rf "${outDir}" "${outDict}" "${outConfig}" "${outUsage}" "${outUsageZip}" "${outUsageDir}" ` + + `"${resourcesOutput}" "${outR8ArtProfile}" ${builtOut}`, + }, "outDir", "outDict", "outConfig", "outUsage", "outUsageZip", "outUsageDir", "builtOut", + "d8Flags", "r8Flags", "zipFlags", "mergeZipsFlags", "resourcesOutput", "outR8ArtProfile", "implicits", +) + +var d8r8, d8r8RE = pctx.MultiCommandRemoteStaticRules("d8r8", + blueprint.RuleParams{ + Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` + + `rm -f "$outDict" && rm -f "$outConfig" && rm -rf "${outUsageDir}" && ` + + `mkdir -p $$(dirname ${outUsage}) && ` + + `if [ -n "$${SOONG_USE_PARTIAL_COMPILE}" ]; then ` + + ` for f in "${outConfig}" "${outDict}" "${outUsage}" "${resourcesOutput}"; do ` + + ` test -n "$${f}" && test ! -f "$${f}" && mkdir -p "$$(dirname "$${f}")" && touch "$${f}" || true; ` + + ` done && ` + + ` $d8Template${config.D8Cmd} ${config.D8Flags} $d8Flags --output $outDir --no-dex-input-jar $in; ` + + `else ` + + ` $r8Template${config.R8Cmd} ${config.R8Flags} $r8Flags -injars $in --output $outDir ` + + ` --no-data-resources ` + + ` -printmapping ${outDict} ` + + ` -printconfiguration ${outConfig} ` + + ` -printusage ${outUsage} ` + + ` --deps-file ${out}.d && ` + + ` touch "${outDict}" "${outConfig}" "${outUsage}"; ` + + `fi && ` + + `${config.SoongZipCmd} -o ${outUsageZip} -C ${outUsageDir} -f ${outUsage} && ` + + `rm -rf ${outUsageDir} && ` + + `$zipTemplate${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` + + `${config.MergeZipsCmd} -D -stripFile "**/*.class" $mergeZipsFlags $out $outDir/classes.dex.jar $in && ` + + `rm -f "$outDir"/classes*.dex "$outDir/classes.dex.jar" `, + CommandDeps: []string{ + "${config.D8Cmd}", + "${config.R8Cmd}", + "${config.SoongZipCmd}", + "${config.MergeZipsCmd}", + }, + }, map[string]*remoteexec.REParams{ + "$d8Template": &remoteexec.REParams{ + Labels: map[string]string{"type": "compile", "compiler": "d8"}, + Inputs: []string{"${config.D8Jar}"}, + ExecStrategy: "${config.RED8ExecStrategy}", + ToolchainInputs: []string{"${config.JavaCmd}"}, + Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"}, + }, + "$r8Template": &remoteexec.REParams{ + Labels: map[string]string{"type": "compile", "compiler": "r8"}, + Inputs: []string{"$implicits", "${config.R8Jar}"}, + OutputFiles: []string{"${outUsage}", "${outConfig}", "${outDict}", "${resourcesOutput}", "${outR8ArtProfile}"}, + ExecStrategy: "${config.RER8ExecStrategy}", + ToolchainInputs: []string{"${config.JavaCmd}"}, + Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"}, + }, + "$zipTemplate": &remoteexec.REParams{ + Labels: map[string]string{"type": "tool", "name": "soong_zip"}, + Inputs: []string{"${config.SoongZipCmd}", "$outDir"}, + OutputFiles: []string{"$outDir/classes.dex.jar"}, + ExecStrategy: "${config.RED8ExecStrategy}", + Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"}, + }, + }, []string{"outDir", "outDict", "outConfig", "outUsage", "outUsageZip", "outUsageDir", + "d8Flags", "r8Flags", "zipFlags", "mergeZipsFlags", "resourcesOutput", "outR8ArtProfile"}, []string{"implicits"}) + var r8, r8RE = pctx.MultiCommandRemoteStaticRules("r8", blueprint.RuleParams{ Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` + @@ -390,6 +463,10 @@ func (d *dexer) r8Flags(ctx android.ModuleContext, dexParams *compileDexParams, r8Flags = append(r8Flags, "--force-proguard-compatibility") } + if BoolDefault(opt.Protect_api_surface, false) { + r8Flags = append(r8Flags, "--protect-api-surface") + } + // Avoid unnecessary stack frame noise by only injecting source map ids for non-debug // optimized or obfuscated targets. if (Bool(opt.Optimize) || Bool(opt.Obfuscate)) && !debugMode { @@ -482,6 +559,7 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam // Compile classes.jar into classes.dex and then javalib.jar javalibJar := android.PathForModuleOut(ctx, "dex", dexParams.jarName).OutputPath + cleanPhonyPath := android.PathForModuleOut(ctx, "dex", dexParams.jarName+"-partialcompileclean").OutputPath outDir := android.PathForModuleOut(ctx, "dex") zipFlags := "--ignore_missing_files" @@ -498,7 +576,20 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam } useR8 := d.effectiveOptimizeEnabled() + useD8 := !useR8 || ctx.Config().PartialCompileFlags().Use_d8 + rbeR8 := ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_R8") + rbeD8 := ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_D8") + var rule blueprint.Rule + var description string var artProfileOutputPath *android.OutputPath + var implicitOutputs android.WritablePaths + var flags []string + var deps android.Paths + args := map[string]string{ + "zipFlags": zipFlags, + "outDir": outDir.String(), + "mergeZipsFlags": mergeZipsFlags, + } if useR8 { proguardDictionary := android.PathForModuleOut(ctx, "proguard_dictionary") d.proguardDictionary = android.OptionalPathForPath(proguardDictionary) @@ -511,25 +602,17 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam d.proguardUsageZip = android.OptionalPathForPath(proguardUsageZip) resourcesOutput := android.PathForModuleOut(ctx, "package-res-shrunken.apk") d.resourcesOutput = android.OptionalPathForPath(resourcesOutput) - implicitOutputs := android.WritablePaths{ + implicitOutputs = append(implicitOutputs, android.WritablePaths{ proguardDictionary, proguardUsageZip, proguardConfiguration, - } + }...) + description = "r8" debugMode := android.InList("--debug", commonFlags) r8Flags, r8Deps, r8ArtProfileOutputPath := d.r8Flags(ctx, dexParams, debugMode) - rule := r8 - args := map[string]string{ - "r8Flags": strings.Join(append(commonFlags, r8Flags...), " "), - "zipFlags": zipFlags, - "outDict": proguardDictionary.String(), - "outConfig": proguardConfiguration.String(), - "outUsageDir": proguardUsageDir.String(), - "outUsage": proguardUsage.String(), - "outUsageZip": proguardUsageZip.String(), - "outDir": outDir.String(), - "mergeZipsFlags": mergeZipsFlags, - } + flags = append(flags, r8Flags...) + deps = append(deps, r8Deps...) + args["r8Flags"] = strings.Join(append(commonFlags, r8Flags...), " ") if r8ArtProfileOutputPath != nil { artProfileOutputPath = r8ArtProfileOutputPath implicitOutputs = append( @@ -540,27 +623,29 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam // about this implicit output args["outR8ArtProfile"] = artProfileOutputPath.String() } - - if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_R8") { - rule = r8RE - args["implicits"] = strings.Join(r8Deps.Strings(), ",") - } + args["outDict"] = proguardDictionary.String() + args["outConfig"] = proguardConfiguration.String() + args["outUsageDir"] = proguardUsageDir.String() + args["outUsage"] = proguardUsage.String() + args["outUsageZip"] = proguardUsageZip.String() if d.resourcesInput.Valid() { implicitOutputs = append(implicitOutputs, resourcesOutput) args["resourcesOutput"] = resourcesOutput.String() } - ctx.Build(pctx, android.BuildParams{ - Rule: rule, - Description: "r8", - Output: javalibJar, - ImplicitOutputs: implicitOutputs, - Input: dexParams.classesJar, - Implicits: r8Deps, - Args: args, - }) - } else { - implicitOutputs := android.WritablePaths{} + + rule = r8 + if rbeR8 { + rule = r8RE + args["implicits"] = strings.Join(deps.Strings(), ",") + } + } + if useD8 { + description = "d8" d8Flags, d8Deps, d8ArtProfileOutputPath := d.d8Flags(ctx, dexParams) + flags = append(flags, d8Flags...) + deps = append(deps, d8Deps...) + deps = append(deps, commonDeps...) + args["d8Flags"] = strings.Join(append(commonFlags, d8Flags...), " ") if d8ArtProfileOutputPath != nil { artProfileOutputPath = d8ArtProfileOutputPath implicitOutputs = append( @@ -568,26 +653,42 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam artProfileOutputPath, ) } - d8Deps = append(d8Deps, commonDeps...) - rule := d8 - if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_D8") { + // If we are generating both d8 and r8, only use RBE when both are enabled. + switch { + case useR8 && rule == r8: + rule = d8r8 + description = "d8r8" + case useR8 && rule == r8RE && rbeD8: + rule = d8r8RE + description = "d8r8" + case rbeD8: rule = d8RE + default: + rule = d8 } + } + ctx.Build(pctx, android.BuildParams{ + Rule: rule, + Description: description, + Output: javalibJar, + ImplicitOutputs: implicitOutputs, + Input: dexParams.classesJar, + Implicits: deps, + Args: args, + }) + if useR8 && useD8 { + // Generate the rule for partial compile clean. + args["builtOut"] = javalibJar.String() ctx.Build(pctx, android.BuildParams{ - Rule: rule, - Description: "d8", - Output: javalibJar, - Input: dexParams.classesJar, - ImplicitOutputs: implicitOutputs, - Implicits: d8Deps, - Args: map[string]string{ - "d8Flags": strings.Join(append(commonFlags, d8Flags...), " "), - "zipFlags": zipFlags, - "outDir": outDir.String(), - "mergeZipsFlags": mergeZipsFlags, - }, + Rule: d8r8Clean, + Description: "d8r8Clean", + Output: cleanPhonyPath, + Args: args, + PhonyOutput: true, }) + ctx.Phony("partialcompileclean", cleanPhonyPath) } + if proptools.Bool(d.dexProperties.Uncompress_dex) { alignedJavalibJar := android.PathForModuleOut(ctx, "aligned", dexParams.jarName).OutputPath TransformZipAlign(ctx, alignedJavalibJar, javalibJar, nil) diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index 27027f07d..313d8c7a4 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -554,7 +554,10 @@ func addDependenciesOntoSelectedBootImageApexes(ctx android.BottomUpMutatorConte typ: dexpreoptBootJar, } - ctx.AddFarVariationDependencies(ctx.Target().Variations(), tag, android.RemoveOptionalPrebuiltPrefix(selected)) + dep := android.RemoveOptionalPrebuiltPrefix(selected) + if ctx.OtherModuleDependencyVariantExists(ctx.Target().Variations(), dep) { + ctx.AddFarVariationDependencies(ctx.Target().Variations(), tag, dep) + } } } } diff --git a/java/java.go b/java/java.go index 33941e9ea..45e55d53c 100644 --- a/java/java.go +++ b/java/java.go @@ -259,7 +259,6 @@ type AndroidLibraryDependencyInfo struct { } type UsesLibraryDependencyInfo struct { - DexJarBuildPath OptionalDexJarPath DexJarInstallPath android.Path ClassLoaderContexts dexpreopt.ClassLoaderContextMap } @@ -403,13 +402,6 @@ type JavaInfo struct { BuiltInstalled string - // ApexSystemServerDexpreoptInstalls stores the list of dexpreopt artifacts if this is a system server - // jar in an apex. - ApexSystemServerDexpreoptInstalls []DexpreopterInstall - - // ApexSystemServerDexJars stores the list of dex jars if this is a system server jar in an apex. - ApexSystemServerDexJars android.Paths - // The config is used for two purposes: // - Passing dexpreopt information about libraries from Soong to Make. This is needed when // a <uses-library> is defined in Android.bp, but used in Android.mk (see dex_preopt_config_merger.py). @@ -418,10 +410,6 @@ type JavaInfo struct { // dexpreopt another partition). ConfigPath android.WritablePath - // The path to the profile on host that dexpreopter generates. This is used as the input for - // dex2oat. - OutputProfilePathOnHost android.Path - LogtagsSrcs android.Paths ProguardDictionary android.OptionalPath @@ -438,14 +426,39 @@ type JavaInfo struct { // True if profile-guided optimization is actually enabled. ProfileGuided bool + + Stem string + + DexJarBuildPath OptionalDexJarPath + + DexpreopterInfo *DexpreopterInfo } var JavaInfoProvider = blueprint.NewProvider[*JavaInfo]() -type JavaLibraryInfo struct{} +type DexpreopterInfo struct { + // The path to the profile on host that dexpreopter generates. This is used as the input for + // dex2oat. + OutputProfilePathOnHost android.Path + // If the java module is to be installed into an APEX, this list contains information about the + // dexpreopt outputs to be installed on devices. Note that these dexpreopt outputs are installed + // outside of the APEX. + ApexSystemServerDexpreoptInstalls []DexpreopterInstall + + // ApexSystemServerDexJars returns the list of dex jars if this is an apex system server jar. + ApexSystemServerDexJars android.Paths +} + +type JavaLibraryInfo struct { + Prebuilt bool +} var JavaLibraryInfoProvider = blueprint.NewProvider[JavaLibraryInfo]() +type JavaDexImportInfo struct{} + +var JavaDexImportInfoProvider = blueprint.NewProvider[JavaDexImportInfo]() + // SyspropPublicStubInfo contains info about the sysprop public stub library that corresponds to // the sysprop implementation library. type SyspropPublicStubInfo struct { @@ -1127,7 +1140,9 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { TopLevelTarget: j.sourceProperties.Top_level_test_target, }) - android.SetProvider(ctx, JavaLibraryInfoProvider, JavaLibraryInfo{}) + android.SetProvider(ctx, JavaLibraryInfoProvider, JavaLibraryInfo{ + Prebuilt: false, + }) if javaInfo != nil { setExtraJavaInfo(ctx, j, javaInfo) @@ -1137,11 +1152,8 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { javaInfo.BootDexJarPath = j.bootDexJarPath javaInfo.UncompressDexState = j.uncompressDexState javaInfo.Active = j.active - javaInfo.ApexSystemServerDexpreoptInstalls = j.apexSystemServerDexpreoptInstalls - javaInfo.ApexSystemServerDexJars = j.apexSystemServerDexJars javaInfo.BuiltInstalled = j.builtInstalled javaInfo.ConfigPath = j.configPath - javaInfo.OutputProfilePathOnHost = j.outputProfilePathOnHost javaInfo.LogtagsSrcs = j.logtagsSrcs javaInfo.ProguardDictionary = j.proguardDictionary javaInfo.ProguardUsageZip = j.proguardUsageZip @@ -1910,6 +1922,10 @@ func (j *Test) generateAndroidBuildActionsWithConfig(ctx android.ModuleContext, if j.testConfig != nil { ctx.InstallFile(pathInTestCases, ctx.ModuleName()+".config", j.testConfig) } + dynamicConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml") + if dynamicConfig.Valid() { + ctx.InstallFile(pathInTestCases, ctx.ModuleName()+".dynamic", dynamicConfig.Path()) + } testDeps := append(j.data, j.extraTestConfigs...) for _, data := range android.SortedUniquePaths(testDeps) { dataPath := android.DataPath{SrcPath: data} @@ -3229,6 +3245,10 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { setExtraJavaInfo(ctx, j, javaInfo) android.SetProvider(ctx, JavaInfoProvider, javaInfo) + android.SetProvider(ctx, JavaLibraryInfoProvider, JavaLibraryInfo{ + Prebuilt: true, + }) + ctx.SetOutputFiles(android.Paths{j.combinedImplementationFile}, "") ctx.SetOutputFiles(android.Paths{j.combinedImplementationFile}, ".jar") @@ -3292,21 +3312,16 @@ func (m JavaImportDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.De } // Implements android.ApexModule -func (j *Import) ShouldSupportSdkVersion(ctx android.BaseModuleContext, - sdkVersion android.ApiLevel) error { +func (j *Import) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel { sdkVersionSpec := j.SdkVersion(ctx) minSdkVersion := j.MinSdkVersion(ctx) - if !minSdkVersion.Specified() { - return fmt.Errorf("min_sdk_version is not specified") - } + // If the module is compiling against core (via sdk_version), skip comparison check. if sdkVersionSpec.Kind == android.SdkCore { - return nil + return android.MinApiLevel } - if minSdkVersion.GreaterThan(sdkVersion) { - return fmt.Errorf("newer SDK(%v)", minSdkVersion) - } - return nil + + return minSdkVersion } // requiredFilesFromPrebuiltApexForImport returns information about the files that a java_import or @@ -3513,6 +3528,12 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), j.Stem()+".jar", dexOutputFile) } + + javaInfo := &JavaInfo{} + setExtraJavaInfo(ctx, j, javaInfo) + android.SetProvider(ctx, JavaInfoProvider, javaInfo) + + android.SetProvider(ctx, JavaDexImportInfoProvider, JavaDexImportInfo{}) } func (j *DexImport) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath { @@ -3522,10 +3543,8 @@ func (j *DexImport) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDex var _ android.ApexModule = (*DexImport)(nil) // Implements android.ApexModule -func (j *DexImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext, - sdkVersion android.ApiLevel) error { - // we don't check prebuilt modules for sdk_version - return nil +func (m *DexImport) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel { + return android.MinApiLevel } // dex_import imports a `.jar` file containing classes.dex files. @@ -3702,7 +3721,7 @@ func addCLCFromDep(ctx android.ModuleContext, depModule android.ModuleProxy, } } clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, optional, - dep.UsesLibraryDependencyInfo.DexJarBuildPath.PathOrNil(), + dep.DexJarBuildPath.PathOrNil(), dep.UsesLibraryDependencyInfo.DexJarInstallPath, dep.UsesLibraryDependencyInfo.ClassLoaderContexts) } else { clcMap.AddContextMap(dep.UsesLibraryDependencyInfo.ClassLoaderContexts, depName) @@ -3786,7 +3805,6 @@ func setExtraJavaInfo(ctx android.ModuleContext, module android.Module, javaInfo if ulDep, ok := module.(UsesLibraryDependency); ok { javaInfo.UsesLibraryDependencyInfo = &UsesLibraryDependencyInfo{ - DexJarBuildPath: ulDep.DexJarBuildPath(ctx), DexJarInstallPath: ulDep.DexJarInstallPath(), ClassLoaderContexts: ulDep.ClassLoaderContexts(), } @@ -3815,4 +3833,22 @@ func setExtraJavaInfo(ctx android.ModuleContext, module android.Module, javaInfo Stubs: stubs, } } + + if st, ok := module.(ModuleWithStem); ok { + javaInfo.Stem = st.Stem() + } + + if mm, ok := module.(interface { + DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath + }); ok { + javaInfo.DexJarBuildPath = mm.DexJarBuildPath(ctx) + } + + if di, ok := module.(DexpreopterInterface); ok { + javaInfo.DexpreopterInfo = &DexpreopterInfo{ + OutputProfilePathOnHost: di.OutputProfilePathOnHost(), + ApexSystemServerDexpreoptInstalls: di.ApexSystemServerDexpreoptInstalls(), + ApexSystemServerDexJars: di.ApexSystemServerDexJars(), + } + } } diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go index d4d2fb5bb..363521a7f 100644 --- a/java/platform_compat_config.go +++ b/java/platform_compat_config.go @@ -43,6 +43,13 @@ func registerPlatformCompatConfigBuildComponents(ctx android.RegistrationContext ctx.RegisterModuleType("global_compat_config", globalCompatConfigFactory) } +type PlatformCompatConfigInfo struct { + CompatConfig android.OutputPath + SubDir string +} + +var PlatformCompatConfigInfoProvider = blueprint.NewProvider[PlatformCompatConfigInfo]() + var PrepareForTestWithPlatformCompatConfig = android.FixtureRegisterWithContext(registerPlatformCompatConfigBuildComponents) func platformCompatConfigPath(ctx android.PathContext) android.OutputPath { @@ -124,6 +131,11 @@ func (p *platformCompatConfig) GenerateAndroidBuildActions(ctx android.ModuleCon rule.Build(configFileName, "Extract compat/compat_config.xml and install it") ctx.InstallFile(p.installDirPath, p.configFile.Base(), p.configFile) ctx.SetOutputFiles(android.Paths{p.configFile}, "") + + android.SetProvider(ctx, PlatformCompatConfigInfoProvider, PlatformCompatConfigInfo{ + CompatConfig: p.CompatConfig(), + SubDir: p.SubDir(), + }) } func (p *platformCompatConfig) AndroidMkEntries() []android.AndroidMkEntries { diff --git a/java/rro.go b/java/rro.go index d9f4ff7c8..f7f85f001 100644 --- a/java/rro.go +++ b/java/rro.go @@ -34,6 +34,15 @@ func RegisterRuntimeResourceOverlayBuildComponents(ctx android.RegistrationConte ctx.RegisterModuleType("override_runtime_resource_overlay", OverrideRuntimeResourceOverlayModuleFactory) } +type RuntimeResourceOverlayInfo struct { + OutputFile android.Path + Certificate Certificate + Theme string + OverriddenManifestPackageName string +} + +var RuntimeResourceOverlayInfoProvider = blueprint.NewProvider[RuntimeResourceOverlayInfo]() + type RuntimeResourceOverlay struct { android.ModuleBase android.DefaultableModuleBase @@ -207,6 +216,12 @@ func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleC AconfigTextFiles: aconfigTextFilePaths, }) + android.SetProvider(ctx, RuntimeResourceOverlayInfoProvider, RuntimeResourceOverlayInfo{ + OutputFile: r.OutputFile(), + Certificate: r.Certificate(), + Theme: r.Theme(), + }) + buildComplianceMetadata(ctx) } diff --git a/java/sdk.go b/java/sdk.go index 4960ab576..27b2434c5 100644 --- a/java/sdk.go +++ b/java/sdk.go @@ -381,6 +381,10 @@ func createAPIFingerprint(ctx android.SingletonContext) { } rule.Build("api_fingerprint", "generate api_fingerprint.txt") + + if ctx.Config().BuildOS == android.Linux { + ctx.DistForGoals([]string{"sdk", "droidcore"}, out) + } } func sdkMakeVars(ctx android.MakeVarsContext) { @@ -390,8 +394,4 @@ func sdkMakeVars(ctx android.MakeVarsContext) { ctx.Strict("FRAMEWORK_AIDL", sdkFrameworkAidlPath(ctx).String()) ctx.Strict("API_FINGERPRINT", android.ApiFingerprintPath(ctx).String()) - - if ctx.Config().BuildOS == android.Linux { - ctx.DistForGoals([]string{"sdk", "droidcore"}, android.ApiFingerprintPath(ctx)) - } } diff --git a/java/sdk_library.go b/java/sdk_library.go index fafb44801..7944bb2a8 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -702,7 +702,7 @@ func (paths *scopePaths) extractStubsLibraryInfoFromDependency(ctx android.Modul paths.stubsHeaderPath = lib.HeaderJars paths.stubsImplPath = lib.ImplementationJars - libDep := android.OtherModuleProviderOrDefault(ctx, dep, JavaInfoProvider).UsesLibraryDependencyInfo + libDep := android.OtherModuleProviderOrDefault(ctx, dep, JavaInfoProvider) paths.stubsDexJarPath = libDep.DexJarBuildPath paths.exportableStubsDexJarPath = libDep.DexJarBuildPath return nil @@ -718,7 +718,7 @@ func (paths *scopePaths) extractEverythingStubsLibraryInfoFromDependency(ctx and paths.stubsImplPath = lib.ImplementationJars } - libDep := android.OtherModuleProviderOrDefault(ctx, dep, JavaInfoProvider).UsesLibraryDependencyInfo + libDep := android.OtherModuleProviderOrDefault(ctx, dep, JavaInfoProvider) paths.stubsDexJarPath = libDep.DexJarBuildPath return nil } else { @@ -732,7 +732,7 @@ func (paths *scopePaths) extractExportableStubsLibraryInfoFromDependency(ctx and paths.stubsImplPath = lib.ImplementationJars } - libDep := android.OtherModuleProviderOrDefault(ctx, dep, JavaInfoProvider).UsesLibraryDependencyInfo + libDep := android.OtherModuleProviderOrDefault(ctx, dep, JavaInfoProvider) paths.exportableStubsDexJarPath = libDep.DexJarBuildPath return nil } else { @@ -931,6 +931,8 @@ type commonSdkLibraryAndImportModule interface { RootLibraryName() string } +var _ android.ApexModule = (*SdkLibrary)(nil) + func (m *SdkLibrary) RootLibraryName() string { return m.BaseModuleName() } @@ -1015,10 +1017,6 @@ func (c *commonToSdkLibraryAndImport) generateCommonBuildActions(ctx android.Mod removedApiFilePaths[kind] = removedApiFilePath } - javaInfo := &JavaInfo{} - setExtraJavaInfo(ctx, ctx.Module(), javaInfo) - android.SetProvider(ctx, JavaInfoProvider, javaInfo) - return SdkLibraryInfo{ EverythingStubDexJarPaths: everythingStubPaths, ExportableStubDexJarPaths: exportableStubPaths, @@ -1225,6 +1223,8 @@ type SdkLibraryInfo struct { // Whether if this can be used as a shared library. SharedLibrary bool + + Prebuilt bool } var SdkLibraryInfoProvider = blueprint.NewProvider[SdkLibraryInfo]() @@ -1511,10 +1511,10 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) module.dexJarFile = makeDexJarPathFromPath(module.implLibraryInfo.DexJarFile.Path()) module.headerJarFile = module.implLibraryInfo.HeaderJars[0] module.implementationAndResourcesJar = module.implLibraryInfo.ImplementationAndResourcesJars[0] - module.apexSystemServerDexpreoptInstalls = module.implLibraryInfo.ApexSystemServerDexpreoptInstalls - module.apexSystemServerDexJars = module.implLibraryInfo.ApexSystemServerDexJars + module.apexSystemServerDexpreoptInstalls = module.implLibraryInfo.DexpreopterInfo.ApexSystemServerDexpreoptInstalls + module.apexSystemServerDexJars = module.implLibraryInfo.DexpreopterInfo.ApexSystemServerDexJars module.dexpreopter.configPath = module.implLibraryInfo.ConfigPath - module.dexpreopter.outputProfilePathOnHost = module.implLibraryInfo.OutputProfilePathOnHost + module.dexpreopter.outputProfilePathOnHost = module.implLibraryInfo.DexpreopterInfo.OutputProfilePathOnHost // Properties required for Library.AndroidMkEntries module.logtagsSrcs = module.implLibraryInfo.LogtagsSrcs @@ -1580,7 +1580,12 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) setOutputFilesFromJavaInfo(ctx, module.implLibraryInfo) } + javaInfo := &JavaInfo{} + setExtraJavaInfo(ctx, ctx.Module(), javaInfo) + android.SetProvider(ctx, JavaInfoProvider, javaInfo) + sdkLibInfo.GeneratingLibs = generatingLibs + sdkLibInfo.Prebuilt = false android.SetProvider(ctx, SdkLibraryInfoProvider, sdkLibInfo) } @@ -2153,13 +2158,10 @@ func (m SdkLibraryImportDepIsInSameApexChecker) OutgoingDepIsInSameApex(tag blue } // Implements android.ApexModule -func (module *SdkLibraryImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext, - sdkVersion android.ApiLevel) error { - // we don't check prebuilt modules for sdk_version - return nil +func (m *SdkLibraryImport) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel { + return android.MinApiLevel } -// Implements android.ApexModule func (module *SdkLibraryImport) UniqueApexVariations() bool { return module.uniqueApexVariations() } @@ -2237,7 +2239,12 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo setOutputFilesFromJavaInfo(ctx, module.implLibraryInfo) } + javaInfo := &JavaInfo{} + setExtraJavaInfo(ctx, ctx.Module(), javaInfo) + android.SetProvider(ctx, JavaInfoProvider, javaInfo) + sdkLibInfo.GeneratingLibs = generatingLibs + sdkLibInfo.Prebuilt = true android.SetProvider(ctx, SdkLibraryInfoProvider, sdkLibInfo) } diff --git a/java/sdk_library_internal.go b/java/sdk_library_internal.go index db9cd24ce..f5feabeb4 100644 --- a/java/sdk_library_internal.go +++ b/java/sdk_library_internal.go @@ -807,10 +807,8 @@ func (module *sdkLibraryXml) DepsMutator(ctx android.BottomUpMutatorContext) { var _ android.ApexModule = (*sdkLibraryXml)(nil) // Implements android.ApexModule -func (module *sdkLibraryXml) ShouldSupportSdkVersion(ctx android.BaseModuleContext, - sdkVersion android.ApiLevel) error { - // sdkLibraryXml doesn't need to be checked separately because java_sdk_library is checked - return nil +func (m *sdkLibraryXml) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel { + return android.MinApiLevel } // File path to the runtime implementation library @@ -938,6 +936,8 @@ func (module *sdkLibraryXml) GenerateAndroidBuildActions(ctx android.ModuleConte ctx.PackageFile(module.installDirPath, libName+".xml", module.outputFilePath) ctx.SetOutputFiles(android.OutputPaths{module.outputFilePath}.Paths(), "") + + etc.SetCommonPrebuiltEtcInfo(ctx, module) } func (module *sdkLibraryXml) AndroidMkEntries() []android.AndroidMkEntries { diff --git a/java/systemserver_classpath_fragment.go b/java/systemserver_classpath_fragment.go index 6f746b45a..a60f6b82c 100644 --- a/java/systemserver_classpath_fragment.go +++ b/java/systemserver_classpath_fragment.go @@ -95,8 +95,10 @@ type SystemServerClasspathModule struct { properties systemServerClasspathFragmentProperties } -func (s *SystemServerClasspathModule) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error { - return nil +var _ android.ApexModule = (*SystemServerClasspathModule)(nil) + +func (m *SystemServerClasspathModule) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel { + return android.MinApiLevel } type systemServerClasspathFragmentProperties struct { diff --git a/linkerconfig/linkerconfig.go b/linkerconfig/linkerconfig.go index 4f1ef9d66..43fe8aa33 100644 --- a/linkerconfig/linkerconfig.go +++ b/linkerconfig/linkerconfig.go @@ -86,6 +86,8 @@ func (l *linkerConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.InstallFile(l.installDirPath, l.outputFilePath.Base(), l.outputFilePath) ctx.SetOutputFiles(android.Paths{l.outputFilePath}, "") + + etc.SetCommonPrebuiltEtcInfo(ctx, l) } func BuildLinkerConfig( diff --git a/python/binary.go b/python/binary.go index 4d6e11816..feac72a26 100644 --- a/python/binary.go +++ b/python/binary.go @@ -114,6 +114,12 @@ func (p *PythonBinaryModule) GenerateAndroidBuildActions(ctx android.ModuleConte android.SetProvider(ctx, PythonBinaryInfoProvider, PythonBinaryInfo{}) ctx.SetOutputFiles(android.Paths{p.installSource}, "") + + moduleInfoJSON := ctx.ModuleInfoJSON() + moduleInfoJSON.Class = []string{"EXECUTABLES"} + moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, p.androidMkSharedLibs...) + moduleInfoJSON.SharedLibs = append(moduleInfoJSON.SharedLibs, p.androidMkSharedLibs...) + moduleInfoJSON.SystemSharedLibs = []string{"none"} } func (p *PythonBinaryModule) buildBinary(ctx android.ModuleContext) { diff --git a/python/test.go b/python/test.go index 5e70fc185..df62ab794 100644 --- a/python/test.go +++ b/python/test.go @@ -224,6 +224,10 @@ func (p *PythonTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext if p.testConfig != nil { ctx.InstallFile(testCases, ctx.ModuleName()+".config", p.testConfig) } + dynamicConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml") + if dynamicConfig.Valid() { + ctx.InstallFile(testCases, ctx.ModuleName()+".dynamic", dynamicConfig.Path()) + } } // Install tests and data in arch specific subdir $PRODUCT_OUT/testcases/$module/$arch testCases = testCases.Join(ctx, ctx.Target().Arch.ArchType.String()) diff --git a/rust/rust.go b/rust/rust.go index 4fd800282..713cacc79 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -841,7 +841,7 @@ func (mod *Module) getSharedFlags() *cc.SharedFlags { return shared } -func (mod *Module) ImplementationModuleNameForMake(ctx android.BaseModuleContext) string { +func (mod *Module) ImplementationModuleNameForMake() string { name := mod.BaseModuleName() if versioned, ok := mod.compiler.(cc.VersionedInterface); ok { name = versioned.ImplementationModuleName(name) @@ -1411,7 +1411,7 @@ func rustMakeLibName(rustInfo *RustInfo, linkableInfo *cc.LinkableInfo, commonIn if rustInfo != nil { // Use base module name for snapshots when exporting to Makefile. if rustInfo.SnapshotInfo != nil { - baseName := linkableInfo.BaseModuleName + baseName := commonInfo.BaseModuleName return baseName + rustInfo.SnapshotInfo.SnapshotAndroidMkSuffix + rustInfo.AndroidMkSuffix } } @@ -2085,26 +2085,23 @@ func (mod *Module) MinSdkVersion() string { } // Implements android.ApexModule -func (mod *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error { +func (mod *Module) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel { minSdkVersion := mod.MinSdkVersion() if minSdkVersion == "apex_inherit" { - return nil + return android.MinApiLevel } + if minSdkVersion == "" { - return fmt.Errorf("min_sdk_version is not specificed") + return android.NoneApiLevel } - // Not using nativeApiLevelFromUser because the context here is not // necessarily a native context. - ver, err := android.ApiLevelFromUser(ctx, minSdkVersion) + ver, err := android.ApiLevelFromUserWithConfig(ctx.Config(), minSdkVersion) if err != nil { - return err + return android.NoneApiLevel } - if ver.GreaterThan(sdkVersion) { - return fmt.Errorf("newer SDK(%v)", ver) - } - return nil + return ver } // Implements android.ApexModule diff --git a/rust/test.go b/rust/test.go index b658ae252..5c183bc67 100644 --- a/rust/test.go +++ b/rust/test.go @@ -208,6 +208,10 @@ func (test *testDecorator) install(ctx ModuleContext) { if test.testConfig != nil { ctx.InstallFile(testCases, ctx.ModuleName()+".config", test.testConfig) } + dynamicConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml") + if dynamicConfig.Valid() { + ctx.InstallFile(testCases, ctx.ModuleName()+".dynamic", dynamicConfig.Path()) + } } // Install tests and data in arch specific subdir $PRODUCT_OUT/testcases/$module/$arch testCases = testCases.Join(ctx, ctx.Target().Arch.ArchType.String()) diff --git a/scripts/strip.sh b/scripts/strip.sh index 8d69f0d12..5320ef620 100755 --- a/scripts/strip.sh +++ b/scripts/strip.sh @@ -101,7 +101,12 @@ do_strip_keep_mini_debug_info_darwin() { do_strip_keep_mini_debug_info_linux() { rm -f "${outfile}.mini_debuginfo.xz" local fail= - "${CLANG_BIN}/llvm-strip" --strip-all --keep-section=.ARM.attributes --remove-section=.comment "${infile}" -o "${outfile}.tmp" || fail=true + if [ -z "${windows}" ]; then + "${CLANG_BIN}/llvm-strip" --strip-all --keep-section=.ARM.attributes --remove-section=.comment "${infile}" -o "${outfile}.tmp" || fail=true + else + # --keep-section not supported for Windows COFF. + fail=true + fi if [ -z $fail ]; then # create_minidebuginfo has issues with compressed debug sections. Just diff --git a/sh/sh_binary.go b/sh/sh_binary.go index d753d246a..c0c6ff2ae 100644 --- a/sh/sh_binary.go +++ b/sh/sh_binary.go @@ -41,6 +41,14 @@ func init() { registerShBuildComponents(android.InitRegistrationContext) } +type ShBinaryInfo struct { + SubDir string + OutputFile android.Path + Symlinks []string +} + +var ShBinaryInfoProvider = blueprint.NewProvider[ShBinaryInfo]() + func registerShBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("sh_binary", ShBinaryFactory) ctx.RegisterModuleType("sh_binary_host", ShBinaryHostFactory) @@ -314,6 +322,12 @@ func (s *ShBinary) generateAndroidBuildActions(ctx android.ModuleContext) { s.properties.SubName = s.GetSubname(ctx) + android.SetProvider(ctx, ShBinaryInfoProvider, ShBinaryInfo{ + SubDir: s.SubDir(), + OutputFile: s.OutputFile(), + Symlinks: s.Symlinks(), + }) + ctx.SetOutputFiles(android.Paths{s.outputFilePath}, "") } @@ -530,6 +544,28 @@ func (s *ShTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { MkAppClass: mkEntries.Class, InstallDir: s.installDir, }) + + moduleInfoJSON := ctx.ModuleInfoJSON() + moduleInfoJSON.Class = []string{"NATIVE_TESTS"} + if len(s.testProperties.Test_suites) > 0 { + moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, s.testProperties.Test_suites...) + } else { + moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") + } + if proptools.Bool(s.testProperties.Test_options.Unit_test) { + moduleInfoJSON.IsUnitTest = "true" + if ctx.Host() { + moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "host-unit-tests") + } + } + moduleInfoJSON.DataDependencies = append(moduleInfoJSON.DataDependencies, s.testProperties.Data_bins...) + if s.testConfig != nil { + if _, ok := s.testConfig.(android.WritablePath); ok { + moduleInfoJSON.AutoTestConfig = []string{"true"} + } + moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, s.testConfig.String()) + } + moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, s.extraTestConfigs.Strings()...) } func addArch(archType string, paths android.Paths) []string { diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go index 25fbc41d3..a398cbce2 100644 --- a/sysprop/sysprop_library.go +++ b/sysprop/sysprop_library.go @@ -226,6 +226,9 @@ type syspropLibraryProperties struct { // Make this module available when building for ramdisk Ramdisk_available *bool + // Make this module available when building for vendor ramdisk + Vendor_ramdisk_available *bool + // Make this module available when building for recovery Recovery_available *bool @@ -459,9 +462,8 @@ func (m *syspropLibrary) AndroidMk() android.AndroidMkData { var _ android.ApexModule = (*syspropLibrary)(nil) // Implements android.ApexModule -func (m *syspropLibrary) ShouldSupportSdkVersion(ctx android.BaseModuleContext, - sdkVersion android.ApiLevel) error { - return fmt.Errorf("sysprop_library is not supposed to be part of apex modules") +func (m *syspropLibrary) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel { + return android.MinApiLevel } // sysprop_library creates schematized APIs from sysprop description files (.sysprop). @@ -501,17 +503,18 @@ type ccLibraryProperties struct { Static_libs []string } } - Required []string - Recovery *bool - Recovery_available *bool - Vendor_available *bool - Product_available *bool - Ramdisk_available *bool - Host_supported *bool - Apex_available []string - Min_sdk_version *string - Cflags []string - Ldflags []string + Required []string + Recovery *bool + Recovery_available *bool + Vendor_available *bool + Product_available *bool + Ramdisk_available *bool + Vendor_ramdisk_available *bool + Host_supported *bool + Apex_available []string + Min_sdk_version *string + Cflags []string + Ldflags []string } type javaLibraryProperties struct { @@ -604,6 +607,7 @@ func syspropLibraryHook(ctx android.LoadHookContext, m *syspropLibrary) { ccProps.Vendor_available = m.properties.Vendor_available ccProps.Product_available = m.properties.Product_available ccProps.Ramdisk_available = m.properties.Ramdisk_available + ccProps.Vendor_ramdisk_available = m.properties.Vendor_ramdisk_available ccProps.Host_supported = m.properties.Host_supported ccProps.Apex_available = m.ApexProperties.Apex_available ccProps.Min_sdk_version = m.properties.Cpp.Min_sdk_version |