diff options
Diffstat (limited to 'android')
46 files changed, 820 insertions, 561 deletions
diff --git a/android/Android.bp b/android/Android.bp index 1cc7ffe1d..4b75148fc 100644 --- a/android/Android.bp +++ b/android/Android.bp @@ -97,6 +97,7 @@ bootstrap_go_package { "product_packages_file.go", "proto.go", "provider.go", + "provider_keys.go", "raw_files.go", "recovery_build_prop.go", "register.go", @@ -170,3 +171,7 @@ bootstrap_go_package { // Used by plugins visibility: ["//visibility:public"], } + +otatools_package_filegroup { + name: "otatools_package_filegroup", +} diff --git a/android/aconfig_providers.go b/android/aconfig_providers.go index 205b85590..bb73f0bdd 100644 --- a/android/aconfig_providers.go +++ b/android/aconfig_providers.go @@ -238,8 +238,7 @@ func getContainer(m Module) string { } else if base.ProductSpecific() { container = "product" } else if base.SystemExtSpecific() { - // system_ext and system partitions should be treated as one container - container = "system" + container = "system_ext" } return container @@ -249,14 +248,13 @@ func getContainer(m Module) string { // Please only access the module's internal data through providers. func getContainerUsingProviders(ctx OtherModuleProviderContext, m Module) string { container := "system" - commonInfo, _ := OtherModuleProvider(ctx, m, CommonModuleInfoKey) + commonInfo := OtherModulePointerProviderOrDefault(ctx, m, CommonModuleInfoProvider) if commonInfo.Vendor || commonInfo.Proprietary || commonInfo.SocSpecific { container = "vendor" } else if commonInfo.ProductSpecific { container = "product" } else if commonInfo.SystemExtSpecific { - // system_ext and system partitions should be treated as one container - container = "system" + container = "system_ext" } return container diff --git a/android/all_teams.go b/android/all_teams.go index 3b20107b9..18a050f5d 100644 --- a/android/all_teams.go +++ b/android/all_teams.go @@ -78,19 +78,19 @@ func (t *allTeamsSingleton) GenerateBuildActions(ctx SingletonContext) { t.teams = make(map[string]teamProperties) t.teams_for_mods = make(map[string]moduleTeamAndTestInfo) - ctx.VisitAllModules(func(module Module) { + ctx.VisitAllModuleProxies(func(module ModuleProxy) { bpFile := ctx.BlueprintFile(module) // Package Modules and Team Modules are stored in a map so we can look them up by name for // modules without a team. - if pack, ok := module.(*packageModule); ok { + if pack, ok := OtherModuleProvider(ctx, module, PackageInfoProvider); ok { // Packages don't have names, use the blueprint file as the key. we can't get qualifiedModuleId in t context. pkgKey := bpFile - t.packages[pkgKey] = pack.properties + t.packages[pkgKey] = pack.Properties return } - if team, ok := module.(*teamModule); ok { - t.teams[team.Name()] = team.properties + if team, ok := OtherModuleProvider(ctx, module, TeamInfoProvider); ok { + t.teams[module.Name()] = team.Properties return } @@ -116,7 +116,7 @@ func (t *allTeamsSingleton) GenerateBuildActions(ctx SingletonContext) { testOnly: testModInfo.TestOnly, topLevelTestTarget: testModInfo.TopLevelTarget, kind: ctx.ModuleType(module), - teamName: module.base().Team(), + teamName: OtherModulePointerProviderOrDefault(ctx, module, CommonModuleInfoProvider).Team, } t.teams_for_mods[module.Name()] = entry diff --git a/android/androidmk.go b/android/androidmk.go index 5cb5a66bc..784559312 100644 --- a/android/androidmk.go +++ b/android/androidmk.go @@ -78,6 +78,12 @@ type AndroidMkData struct { Entries AndroidMkEntries } +type AndroidMkDataInfo struct { + Class string +} + +var AndroidMkDataInfoProvider = blueprint.NewProvider[AndroidMkDataInfo]() + type AndroidMkExtraFunc func(w io.Writer, outputFile Path) // Interface for modules to declare their Android.mk outputs. Note that every module needs to @@ -349,30 +355,15 @@ func (d *distCopies) Strings() (ret []string) { return } -// Compute the contributions that the module makes to the dist. -func (a *AndroidMkEntries) getDistContributions(mod Module) *distContributions { +// This gets the dist contributuions from the given module that were specified in the Android.bp +// file using the dist: property. It does not include contribututions that the module's +// implementation may have defined with ctx.DistForGoals(), for that, see DistProvider. +func getDistContributions(ctx ConfigAndOtherModuleProviderContext, mod Module) *distContributions { amod := mod.base() name := amod.BaseModuleName() - // Collate the set of associated tag/paths available for copying to the dist. - // Start with an empty (nil) set. - var availableTaggedDists TaggedDistFiles - - // If no paths have been provided for the DefaultDistTag and the output file is - // valid then add that as the default dist path. - if a.OutputFile.Valid() { - availableTaggedDists = availableTaggedDists.addPathsForTag(DefaultDistTag, a.OutputFile.Path()) - } - - info := OtherModuleProviderOrDefault(a.entryContext, mod, InstallFilesProvider) - // If the distFiles created by GenerateTaggedDistFiles contains paths for the - // DefaultDistTag then that takes priority so delete any existing paths. - if _, ok := info.DistFiles[DefaultDistTag]; ok { - delete(availableTaggedDists, DefaultDistTag) - } - - // Finally, merge the distFiles created by GenerateTaggedDistFiles. - availableTaggedDists = availableTaggedDists.merge(info.DistFiles) + info := OtherModuleProviderOrDefault(ctx, mod, InstallFilesProvider) + availableTaggedDists := info.DistFiles if len(availableTaggedDists) == 0 { // Nothing dist-able for this module. @@ -446,7 +437,7 @@ func (a *AndroidMkEntries) getDistContributions(mod Module) *distContributions { productString := "" if dist.Append_artifact_with_product != nil && *dist.Append_artifact_with_product { - productString = fmt.Sprintf("_%s", a.entryContext.Config().DeviceProduct()) + productString = fmt.Sprintf("_%s", ctx.Config().DeviceProduct()) } if suffix != "" || productString != "" { @@ -494,7 +485,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 Module) []string { - distContributions := a.getDistContributions(mod) + distContributions := getDistContributions(a.entryContext, mod) if distContributions == nil { return nil } @@ -537,6 +528,14 @@ func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod Module) { fmt.Fprintf(&a.header, "\ninclude $(CLEAR_VARS) # type: %s, name: %s, variant: %s\n", ctx.ModuleType(mod), base.BaseModuleName(), ctx.ModuleSubDir(mod)) + // Add the TestSuites from the provider to LOCAL_SOONG_PROVIDER_TEST_SUITES. + // LOCAL_SOONG_PROVIDER_TEST_SUITES will be compared against LOCAL_COMPATIBILITY_SUITES + // in make and enforced they're the same, to ensure we've successfully translated all + // LOCAL_COMPATIBILITY_SUITES usages to the provider. + if testSuiteInfo, ok := OtherModuleProvider(ctx, mod, TestSuiteInfoProvider); ok { + a.AddStrings("LOCAL_SOONG_PROVIDER_TEST_SUITES", testSuiteInfo.TestSuites...) + } + // Collect make variable assignment entries. a.SetString("LOCAL_PATH", ctx.ModuleDir(mod)) a.SetString("LOCAL_MODULE", name+a.SubName) @@ -889,32 +888,23 @@ func getSoongOnlyDataFromMods(ctx fillInEntriesContext, mods []Module) ([]distCo } } - commonInfo, _ := OtherModuleProvider(ctx, mod, CommonModuleInfoKey) + commonInfo := OtherModulePointerProviderOrDefault(ctx, mod, CommonModuleInfoProvider) if commonInfo.SkipAndroidMkProcessing { continue } if info, ok := OtherModuleProvider(ctx, mod, AndroidMkInfoProvider); ok { // Deep copy the provider info since we need to modify the info later info := deepCopyAndroidMkProviderInfo(info) - info.PrimaryInfo.fillInEntries(ctx, mod, &commonInfo) + info.PrimaryInfo.fillInEntries(ctx, mod, commonInfo) if info.PrimaryInfo.disabled() { continue } if moduleInfoJSON, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok { moduleInfoJSONs = append(moduleInfoJSONs, moduleInfoJSON...) } - if contribution := info.PrimaryInfo.getDistContributions(ctx, mod, &commonInfo); contribution != nil { + if contribution := getDistContributions(ctx, mod); contribution != nil { allDistContributions = append(allDistContributions, *contribution) } - for _, ei := range info.ExtraInfo { - ei.fillInEntries(ctx, mod, &commonInfo) - if ei.disabled() { - continue - } - if contribution := ei.getDistContributions(ctx, mod, &commonInfo); contribution != nil { - allDistContributions = append(allDistContributions, *contribution) - } - } } else { if x, ok := mod.(AndroidMkDataProvider); ok { data := x.AndroidMk() @@ -930,7 +920,7 @@ func getSoongOnlyDataFromMods(ctx fillInEntriesContext, mods []Module) ([]distCo if moduleInfoJSON, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok { moduleInfoJSONs = append(moduleInfoJSONs, moduleInfoJSON...) } - if contribution := data.Entries.getDistContributions(mod); contribution != nil { + if contribution := getDistContributions(ctx, mod); contribution != nil { allDistContributions = append(allDistContributions, *contribution) } } @@ -944,7 +934,7 @@ func getSoongOnlyDataFromMods(ctx fillInEntriesContext, mods []Module) ([]distCo if moduleInfoJSON, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok { moduleInfoJSONs = append(moduleInfoJSONs, moduleInfoJSON...) } - if contribution := entries.getDistContributions(mod); contribution != nil { + if contribution := getDistContributions(ctx, mod); contribution != nil { allDistContributions = append(allDistContributions, *contribution) } } @@ -1330,7 +1320,7 @@ var AndroidMkInfoProvider = blueprint.NewProvider[*AndroidMkProviderInfo]() // Please only access the module's internal data through providers. func translateAndroidMkEntriesInfoModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON, mod Module, providerInfo *AndroidMkProviderInfo) error { - commonInfo, _ := OtherModuleProvider(ctx, mod, CommonModuleInfoKey) + commonInfo := OtherModulePointerProviderOrDefault(ctx, mod, CommonModuleInfoProvider) if commonInfo.SkipAndroidMkProcessing { return nil } @@ -1341,11 +1331,11 @@ func translateAndroidMkEntriesInfoModule(ctx SingletonContext, w io.Writer, modu aconfigUpdateAndroidMkInfos(ctx, mod, &info) // Any new or special cases here need review to verify correct propagation of license information. - info.PrimaryInfo.fillInEntries(ctx, mod, &commonInfo) + info.PrimaryInfo.fillInEntries(ctx, mod, commonInfo) info.PrimaryInfo.write(w) if len(info.ExtraInfo) > 0 { for _, ei := range info.ExtraInfo { - ei.fillInEntries(ctx, mod, &commonInfo) + ei.fillInEntries(ctx, mod, commonInfo) ei.write(w) } } @@ -1494,12 +1484,17 @@ func (a *AndroidMkInfo) fillInEntries(ctx fillInEntriesContext, mod Module, comm a.Host_required = append(a.Host_required, commonInfo.HostRequiredModuleNames...) a.Target_required = append(a.Target_required, commonInfo.TargetRequiredModuleNames...) - for _, distString := range a.GetDistForGoals(ctx, mod, commonInfo) { - a.HeaderStrings = append(a.HeaderStrings, distString) - } - + a.HeaderStrings = append(a.HeaderStrings, a.GetDistForGoals(ctx, mod, commonInfo)...) a.HeaderStrings = append(a.HeaderStrings, fmt.Sprintf("\ninclude $(CLEAR_VARS) # type: %s, name: %s, variant: %s", ctx.ModuleType(mod), commonInfo.BaseModuleName, ctx.ModuleSubDir(mod))) + // Add the TestSuites from the provider to LOCAL_SOONG_PROVIDER_TEST_SUITES. + // LOCAL_SOONG_PROVIDER_TEST_SUITES will be compared against LOCAL_COMPATIBILITY_SUITES + // in make and enforced they're the same, to ensure we've successfully translated all + // LOCAL_COMPATIBILITY_SUITES usages to the provider. + if testSuiteInfo, ok := OtherModuleProvider(ctx, mod, TestSuiteInfoProvider); ok { + helperInfo.AddStrings("LOCAL_SOONG_PROVIDER_TEST_SUITES", testSuiteInfo.TestSuites...) + } + // Collect make variable assignment entries. helperInfo.SetString("LOCAL_PATH", ctx.ModuleDir(mod)) helperInfo.SetString("LOCAL_MODULE", name+a.SubName) @@ -1653,7 +1648,7 @@ func (a *AndroidMkInfo) write(w io.Writer) { // TODO(b/397766191): Change the signature to take ModuleProxy // Please only access the module's internal data through providers. func (a *AndroidMkInfo) GetDistForGoals(ctx fillInEntriesContext, mod Module, commonInfo *CommonModuleInfo) []string { - distContributions := a.getDistContributions(ctx, mod, commonInfo) + distContributions := getDistContributions(ctx, mod) if distContributions == nil { return nil } @@ -1661,127 +1656,6 @@ func (a *AndroidMkInfo) GetDistForGoals(ctx fillInEntriesContext, mod Module, co return generateDistContributionsForMake(distContributions) } -// Compute the contributions that the module makes to the dist. -// TODO(b/397766191): Change the signature to take ModuleProxy -// Please only access the module's internal data through providers. -func (a *AndroidMkInfo) getDistContributions(ctx fillInEntriesContext, mod Module, - commonInfo *CommonModuleInfo) *distContributions { - name := commonInfo.BaseModuleName - - // Collate the set of associated tag/paths available for copying to the dist. - // Start with an empty (nil) set. - var availableTaggedDists TaggedDistFiles - - // If no paths have been provided for the DefaultDistTag and the output file is - // valid then add that as the default dist path. - if a.OutputFile.Valid() { - availableTaggedDists = availableTaggedDists.addPathsForTag(DefaultDistTag, a.OutputFile.Path()) - } - - info := OtherModuleProviderOrDefault(ctx, mod, InstallFilesProvider) - // If the distFiles created by GenerateTaggedDistFiles contains paths for the - // DefaultDistTag then that takes priority so delete any existing paths. - if _, ok := info.DistFiles[DefaultDistTag]; ok { - delete(availableTaggedDists, DefaultDistTag) - } - - // Finally, merge the distFiles created by GenerateTaggedDistFiles. - availableTaggedDists = availableTaggedDists.merge(info.DistFiles) - - if len(availableTaggedDists) == 0 { - // Nothing dist-able for this module. - return nil - } - - // Collate the contributions this module makes to the dist. - distContributions := &distContributions{} - - if !commonInfo.ExemptFromRequiredApplicableLicensesProperty { - distContributions.licenseMetadataFile = info.LicenseMetadataFile - } - - // Iterate over this module's dist structs, merged from the dist and dists properties. - for _, dist := range commonInfo.Dists { - // Get the list of goals this dist should be enabled for. e.g. sdk, droidcore - goals := strings.Join(dist.Targets, " ") - - // Get the tag representing the output files to be dist'd. e.g. ".jar", ".proguard_map" - var tag string - if dist.Tag == nil { - // If the dist struct does not specify a tag, use the default output files tag. - tag = DefaultDistTag - } else { - tag = *dist.Tag - } - - // Get the paths of the output files to be dist'd, represented by the tag. - // Can be an empty list. - tagPaths := availableTaggedDists[tag] - if len(tagPaths) == 0 { - // Nothing to dist for this tag, continue to the next dist. - continue - } - - if len(tagPaths) > 1 && (dist.Dest != nil || dist.Suffix != nil) { - errorMessage := "%s: Cannot apply dest/suffix for more than one dist " + - "file for %q goals tag %q in module %s. The list of dist files, " + - "which should have a single element, is:\n%s" - panic(fmt.Errorf(errorMessage, mod, goals, tag, name, tagPaths)) - } - - copiesForGoals := distContributions.getCopiesForGoals(goals) - - // Iterate over each path adding a copy instruction to copiesForGoals - for _, path := range tagPaths { - // It's possible that the Path is nil from errant modules. Be defensive here. - if path == nil { - tagName := "default" // for error message readability - if dist.Tag != nil { - tagName = *dist.Tag - } - panic(fmt.Errorf("Dist file should not be nil for the %s tag in %s", tagName, name)) - } - - dest := filepath.Base(path.String()) - - if dist.Dest != nil { - var err error - if dest, err = validateSafePath(*dist.Dest); err != nil { - // This was checked in ModuleBase.GenerateBuildActions - panic(err) - } - } - - ext := filepath.Ext(dest) - suffix := "" - if dist.Suffix != nil { - suffix = *dist.Suffix - } - - productString := "" - if dist.Append_artifact_with_product != nil && *dist.Append_artifact_with_product { - productString = fmt.Sprintf("_%s", ctx.Config().DeviceProduct()) - } - - if suffix != "" || productString != "" { - dest = strings.TrimSuffix(dest, ext) + suffix + productString + ext - } - - if dist.Dir != nil { - var err error - if dest, err = validateSafePath(*dist.Dir, dest); err != nil { - // This was checked in ModuleBase.GenerateBuildActions - panic(err) - } - } - - copiesForGoals.addCopyInstruction(path, dest) - } - } - - return distContributions -} - func deepCopyAndroidMkProviderInfo(providerInfo *AndroidMkProviderInfo) AndroidMkProviderInfo { info := AndroidMkProviderInfo{ PrimaryInfo: deepCopyAndroidMkInfo(&providerInfo.PrimaryInfo), diff --git a/android/androidmk_test.go b/android/androidmk_test.go index 4cdd6a37b..cd61133ef 100644 --- a/android/androidmk_test.go +++ b/android/androidmk_test.go @@ -346,7 +346,7 @@ func TestGetDistContributions(t *testing.T) { if len(entries) != 1 { t.Errorf("Expected a single AndroidMk entry, got %d", len(entries)) } - distContributions := entries[0].getDistContributions(module) + distContributions := getDistContributions(ctx, module) if err := compareContributions(expectedContributions, distContributions); err != nil { t.Errorf("%s\nExpected Contributions\n%sActualContributions\n%s", @@ -648,8 +648,8 @@ func TestGetDistContributions(t *testing.T) { default_dist_files: "none", dist_output_file: false, dists: [ - // The following is silently ignored because there is not default file - // in either the dist files or the output file. + // The following will dist one.out because there's no default dist file provided + // (default_dist_files: "none") and one.out is the outputfile for the "" tag. { targets: ["my_goal"], }, @@ -664,6 +664,12 @@ func TestGetDistContributions(t *testing.T) { { goals: "my_goal", copies: []distCopy{ + distCopyForTest("one.out", "one.out"), + }, + }, + { + goals: "my_goal", + copies: []distCopy{ distCopyForTest("two.out", "two.out"), distCopyForTest("three/four.out", "four.out"), }, diff --git a/android/apex.go b/android/apex.go index 91fa2c718..57baff5cf 100644 --- a/android/apex.go +++ b/android/apex.go @@ -196,7 +196,7 @@ func IsDepInSameApex(ctx BaseModuleContext, module, dep Module) bool { return false } - if !ctx.EqualModules(ctx.Module(), module) { + if !EqualModules(ctx.Module(), module) { if moduleInfo, ok := OtherModuleProvider(ctx, module, DepInSameApexInfoProvider); ok { if !moduleInfo.Checker.OutgoingDepIsInSameApex(depTag) { return false @@ -646,6 +646,13 @@ type ApexBundleDepsInfoIntf interface { FullListPath() Path } +type ApexBundleDepsData struct { + Updatable bool + FlatListPath Path +} + +var ApexBundleDepsDataProvider = blueprint.NewProvider[ApexBundleDepsData]() + func (d *ApexBundleDepsInfo) FlatListPath() Path { return d.flatListPath } @@ -688,7 +695,7 @@ func (d *ApexBundleDepsInfo) BuildDepsInfoLists(ctx ModuleContext, minSdkVersion // Function called while walking an APEX's payload dependencies. // // Return true if the `to` module should be visited, false otherwise. -type PayloadDepsCallback func(ctx BaseModuleContext, from Module, to ApexModule, externalDep bool) bool +type PayloadDepsCallback func(ctx BaseModuleContext, from, to ModuleProxy, externalDep bool) bool type WalkPayloadDepsFunc func(ctx BaseModuleContext, do PayloadDepsCallback) // ModuleWithMinSdkVersionCheck represents a module that implements min_sdk_version checks @@ -716,7 +723,7 @@ func CheckMinSdkVersion(ctx ModuleContext, minSdkVersion ApiLevel, walk WalkPayl return } - walk(ctx, func(ctx BaseModuleContext, from Module, to ApexModule, externalDep bool) bool { + walk(ctx, func(ctx BaseModuleContext, from, to ModuleProxy, externalDep bool) bool { if externalDep { // external deps are outside the payload boundary, which is "stable" // interface. We don't have to check min_sdk_version for external @@ -726,7 +733,7 @@ func CheckMinSdkVersion(ctx ModuleContext, minSdkVersion ApiLevel, walk WalkPayl if !IsDepInSameApex(ctx, from, to) { return false } - if info, ok := OtherModuleProvider(ctx, to, CommonModuleInfoKey); ok && info.ModuleWithMinSdkVersionCheck { + if info, ok := OtherModuleProvider(ctx, to, CommonModuleInfoProvider); 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. @@ -758,7 +765,7 @@ type MinSdkVersionFromValueContext interface { // 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) + info, ok := OtherModuleProvider(ctx, module, CommonModuleInfoProvider) if !ok || info.MinSdkVersionSupported.IsNone() { return fmt.Errorf("min_sdk_version is not specified") } diff --git a/android/api_levels.go b/android/api_levels.go index c042eebee..c83fae878 100644 --- a/android/api_levels.go +++ b/android/api_levels.go @@ -19,6 +19,8 @@ import ( "fmt" "strconv" "strings" + + "github.com/google/blueprint/gobtools" ) func init() { @@ -52,6 +54,34 @@ type ApiLevel struct { isPreview bool } +type apiLevelGob struct { + Value string + Number int + IsPreview bool +} + +func (a *ApiLevel) ToGob() *apiLevelGob { + return &apiLevelGob{ + Value: a.value, + Number: a.number, + IsPreview: a.isPreview, + } +} + +func (a *ApiLevel) FromGob(data *apiLevelGob) { + a.value = data.Value + a.number = data.Number + a.isPreview = data.IsPreview +} + +func (a ApiLevel) GobEncode() ([]byte, error) { + return gobtools.CustomGobEncode[apiLevelGob](&a) +} + +func (a *ApiLevel) GobDecode(data []byte) error { + return gobtools.CustomGobDecode[apiLevelGob](data, a) +} + func (this ApiLevel) FinalInt() int { if this.IsInvalid() { panic(fmt.Errorf("%v is not a recognized api_level\n", this)) diff --git a/android/arch.go b/android/arch.go index 3cd6e4b7a..d6b297119 100644 --- a/android/arch.go +++ b/android/arch.go @@ -1553,7 +1553,7 @@ func determineBuildOS(config *config) { config.BuildOS = func() OsType { switch runtime.GOOS { case "linux": - if Bool(config.productVariables.HostMusl) { + if Bool(config.productVariables.HostMusl) || runtime.GOARCH == "arm64" { return LinuxMusl } return Linux @@ -1565,11 +1565,25 @@ func determineBuildOS(config *config) { }() config.BuildArch = func() ArchType { - switch runtime.GOARCH { - case "amd64": - return X86_64 + switch runtime.GOOS { + case "linux": + switch runtime.GOARCH { + case "amd64": + return X86_64 + case "arm64": + return Arm64 + default: + panic(fmt.Sprintf("unsupported arch: %s", runtime.GOARCH)) + } + case "darwin": + switch runtime.GOARCH { + case "amd64": + return X86_64 + default: + panic(fmt.Sprintf("unsupported arch: %s", runtime.GOARCH)) + } default: - panic(fmt.Sprintf("unsupported Arch: %s", runtime.GOARCH)) + panic(fmt.Sprintf("unsupported OS: %s", runtime.GOOS)) } }() diff --git a/android/base_module_context.go b/android/base_module_context.go index 5e05f547a..5cb9e71cf 100644 --- a/android/base_module_context.go +++ b/android/base_module_context.go @@ -34,8 +34,6 @@ type BaseModuleContext interface { blueprintBaseModuleContext() blueprint.BaseModuleContext - EqualModules(m1, m2 Module) bool - // OtherModuleName returns the name of another Module. See BaseModuleContext.ModuleName for more information. // It is intended for use inside the visit functions of Visit* and WalkDeps. OtherModuleName(m blueprint.Module) string @@ -271,8 +269,8 @@ func getWrappedModule(module blueprint.Module) blueprint.Module { return module } -func (b *baseModuleContext) EqualModules(m1, m2 Module) bool { - return b.bp.EqualModules(getWrappedModule(m1), getWrappedModule(m2)) +func EqualModules(m1, m2 Module) bool { + return blueprint.EqualModules(getWrappedModule(m1), getWrappedModule(m2)) } func (b *baseModuleContext) OtherModuleName(m blueprint.Module) string { @@ -412,7 +410,7 @@ func (b *baseModuleContext) validateAndroidModuleProxy( return &aModule } - if !OtherModuleProviderOrDefault(b, module, CommonModuleInfoKey).Enabled { + if !OtherModulePointerProviderOrDefault(b, module, CommonModuleInfoProvider).Enabled { if t, ok := tag.(AllowDisabledModuleDependency); !ok || !t.AllowDisabledModuleDependencyProxy(b, aModule) { if b.Config().AllowMissingDependencies() { b.AddMissingDependencies([]string{b.OtherModuleName(aModule)}) @@ -442,7 +440,7 @@ func (b *baseModuleContext) getDirectDepsInternal(name string, tag blueprint.Dep func (b *baseModuleContext) getDirectDepsProxyInternal(name string, tag blueprint.DependencyTag) []ModuleProxy { var deps []ModuleProxy b.VisitDirectDepsProxy(func(module ModuleProxy) { - if OtherModuleProviderOrDefault(b, module, CommonModuleInfoKey).BaseModuleName == name { + if OtherModulePointerProviderOrDefault(b, module, CommonModuleInfoProvider).BaseModuleName == name { returnedTag := b.OtherModuleDependencyTag(module) if tag == nil || returnedTag == tag { deps = append(deps, module) diff --git a/android/compliance_metadata.go b/android/compliance_metadata.go index a6dbb8d17..16a385300 100644 --- a/android/compliance_metadata.go +++ b/android/compliance_metadata.go @@ -18,7 +18,9 @@ import ( "bytes" "encoding/csv" "fmt" + "path/filepath" "slices" + "sort" "strconv" "strings" @@ -127,27 +129,37 @@ var ( // dependencies, built/installed files, etc. It is a wrapper on a map[string]string with some utility // methods to get/set properties' values. type ComplianceMetadataInfo struct { - properties map[string]string + properties map[string]string + filesContained []string + prebuiltFilesCopied []string } type complianceMetadataInfoGob struct { - Properties map[string]string + Properties map[string]string + FilesContained []string + PrebuiltFilesCopied []string } func NewComplianceMetadataInfo() *ComplianceMetadataInfo { return &ComplianceMetadataInfo{ - properties: map[string]string{}, + properties: map[string]string{}, + filesContained: make([]string, 0), + prebuiltFilesCopied: make([]string, 0), } } func (m *ComplianceMetadataInfo) ToGob() *complianceMetadataInfoGob { return &complianceMetadataInfoGob{ - Properties: m.properties, + Properties: m.properties, + FilesContained: m.filesContained, + PrebuiltFilesCopied: m.prebuiltFilesCopied, } } func (m *ComplianceMetadataInfo) FromGob(data *complianceMetadataInfoGob) { m.properties = data.Properties + m.filesContained = data.FilesContained + m.prebuiltFilesCopied = data.PrebuiltFilesCopied } func (c *ComplianceMetadataInfo) GobEncode() ([]byte, error) { @@ -169,6 +181,22 @@ func (c *ComplianceMetadataInfo) SetListValue(propertyName string, value []strin c.SetStringValue(propertyName, strings.TrimSpace(strings.Join(value, " "))) } +func (c *ComplianceMetadataInfo) SetFilesContained(files []string) { + c.filesContained = files +} + +func (c *ComplianceMetadataInfo) GetFilesContained() []string { + return c.filesContained +} + +func (c *ComplianceMetadataInfo) SetPrebuiltFilesCopied(files []string) { + c.prebuiltFilesCopied = files +} + +func (c *ComplianceMetadataInfo) GetPrebuiltFilesCopied() []string { + return c.prebuiltFilesCopied +} + func (c *ComplianceMetadataInfo) getStringValue(propertyName string) string { if !slices.Contains(COMPLIANCE_METADATA_PROPS, propertyName) { panic(fmt.Errorf("Unknown metadata property: %s.", propertyName)) @@ -276,7 +304,7 @@ func (c *complianceMetadataSingleton) GenerateBuildActions(ctx SingletonContext) rowId := -1 ctx.VisitAllModuleProxies(func(module ModuleProxy) { - commonInfo, _ := OtherModuleProvider(ctx, module, CommonModuleInfoKey) + commonInfo := OtherModulePointerProviderOrDefault(ctx, module, CommonModuleInfoProvider) if !commonInfo.Enabled { return } @@ -316,9 +344,42 @@ func (c *complianceMetadataSingleton) GenerateBuildActions(ctx SingletonContext) makeMetadataCsv := PathForOutput(ctx, "compliance-metadata", deviceProduct, "make-metadata.csv") makeModulesCsv := PathForOutput(ctx, "compliance-metadata", deviceProduct, "make-modules.csv") + productOutPath := filepath.Join(ctx.Config().OutDir(), "target", "product", String(ctx.Config().productVariables.DeviceName)) if !ctx.Config().KatiEnabled() { - WriteFileRule(ctx, makeMetadataCsv, "installed_file,module_path,is_soong_module,is_prebuilt_make_module,product_copy_files,kernel_module_copy_files,is_platform_generated,static_libs,whole_static_libs,license_text") - WriteFileRule(ctx, makeModulesCsv, "name,module_path,module_class,module_type,static_libs,whole_static_libs,built_files,installed_files") + ctx.VisitAllModuleProxies(func(module ModuleProxy) { + // In soong-only build the installed file list is from android_device module + if androidDeviceInfo, ok := OtherModuleProvider(ctx, module, AndroidDeviceInfoProvider); ok && androidDeviceInfo.Main_device { + if metadataInfo, ok := OtherModuleProvider(ctx, module, ComplianceMetadataProvider); ok { + if len(metadataInfo.filesContained) > 0 || len(metadataInfo.prebuiltFilesCopied) > 0 { + allFiles := make([]string, 0, len(metadataInfo.filesContained)+len(metadataInfo.prebuiltFilesCopied)) + allFiles = append(allFiles, metadataInfo.filesContained...) + prebuiltFilesSrcDest := make(map[string]string) + for _, srcDestPair := range metadataInfo.prebuiltFilesCopied { + prebuiltFilePath := filepath.Join(productOutPath, strings.Split(srcDestPair, ":")[1]) + allFiles = append(allFiles, prebuiltFilePath) + prebuiltFilesSrcDest[prebuiltFilePath] = srcDestPair + } + sort.Strings(allFiles) + + csvHeaders := "installed_file,module_path,is_soong_module,is_prebuilt_make_module,product_copy_files,kernel_module_copy_files,is_platform_generated,static_libs,whole_static_libs,license_text" + csvContent := make([]string, 0, len(allFiles)+1) + csvContent = append(csvContent, csvHeaders) + for _, file := range allFiles { + if _, ok := prebuiltFilesSrcDest[file]; ok { + srcDestPair := prebuiltFilesSrcDest[file] + csvContent = append(csvContent, file+",,,,"+srcDestPair+",,,,,") + } else { + csvContent = append(csvContent, file+",,Y,,,,,,,") + } + } + + WriteFileRuleVerbatim(ctx, makeMetadataCsv, strings.Join(csvContent, "\n")) + WriteFileRuleVerbatim(ctx, makeModulesCsv, "name,module_path,module_class,module_type,static_libs,whole_static_libs,built_files,installed_files") + } + return + } + } + }) } // Import metadata from Make and Soong to sqlite3 database diff --git a/android/config.go b/android/config.go index a5edf0da8..d47f0d44a 100644 --- a/android/config.go +++ b/android/config.go @@ -200,6 +200,11 @@ func (c Config) ReleaseAconfigValueSets() []string { return c.config.productVariables.ReleaseAconfigValueSets } +// If native modules should have symbols stripped by default. Default false, enabled for build tools +func (c Config) StripByDefault() bool { + return proptools.Bool(c.config.productVariables.StripByDefault) +} + func (c Config) ReleaseAconfigExtraReleaseConfigs() []string { result := []string{} if val, ok := c.config.productVariables.BuildFlags["RELEASE_ACONFIG_EXTRA_RELEASE_CONFIGS"]; ok { @@ -233,11 +238,6 @@ func (c Config) ReleaseAconfigFlagDefaultPermission() string { return c.config.productVariables.ReleaseAconfigFlagDefaultPermission } -// Enable object size sanitizer -func (c Config) ReleaseBuildObjectSizeSanitizer() bool { - return c.config.productVariables.GetBuildFlagBool("RELEASE_BUILD_OBJECT_SIZE_SANITIZER") -} - // The flag indicating behavior for the tree wrt building modules or using prebuilts // derived from RELEASE_DEFAULT_MODULE_BUILD_FROM_SOURCE func (c Config) ReleaseDefaultModuleBuildFromSource() bool { @@ -385,24 +385,28 @@ type config struct { } type partialCompileFlags struct { - // Is partial compilation enabled at all? - Enabled bool - // Whether to use d8 instead of r8 Use_d8 bool + // Whether to disable stub validation. This is slightly more surgical + // than DISABLE_STUB_VALIDATION, in that it only applies to partial + // compile builds. + Disable_stub_validation bool + + // Whether to disable api lint. + Disable_api_lint bool + // Add others as needed. } // These are the flags when `SOONG_PARTIAL_COMPILE` is empty or not set. -var defaultPartialCompileFlags = partialCompileFlags{ - Enabled: false, -} +var defaultPartialCompileFlags = partialCompileFlags{} // These are the flags when `SOONG_PARTIAL_COMPILE=true`. var enabledPartialCompileFlags = partialCompileFlags{ - Enabled: true, - Use_d8: true, + Use_d8: true, + Disable_stub_validation: false, + Disable_api_lint: false, } type deviceConfig struct { @@ -477,13 +481,29 @@ func (c *config) parsePartialCompileFlags(isEngBuild bool) (partialCompileFlags, state = "+" } switch tok { + case "all": + // Turn on **all** of the flags. + ret = partialCompileFlags{ + Use_d8: true, + Disable_stub_validation: true, + Disable_api_lint: true, + } case "true": ret = enabledPartialCompileFlags case "false": // Set everything to false. ret = partialCompileFlags{} - case "enabled": - ret.Enabled = makeVal(state, defaultPartialCompileFlags.Enabled) + + case "api_lint", "enable_api_lint": + ret.Disable_api_lint = !makeVal(state, !defaultPartialCompileFlags.Disable_api_lint) + case "disable_api_lint": + ret.Disable_api_lint = makeVal(state, defaultPartialCompileFlags.Disable_api_lint) + + case "stub_validation", "enable_stub_validation": + ret.Disable_stub_validation = !makeVal(state, !defaultPartialCompileFlags.Disable_stub_validation) + case "disable_stub_validation": + ret.Disable_stub_validation = makeVal(state, defaultPartialCompileFlags.Disable_stub_validation) + case "use_d8": ret.Use_d8 = makeVal(state, defaultPartialCompileFlags.Use_d8) default: @@ -814,11 +834,18 @@ func (c *config) HostCcSharedLibPath(ctx PathContext, lib string) Path { func (c *config) PrebuiltOS() string { switch runtime.GOOS { case "linux": - return "linux-x86" + switch runtime.GOARCH { + case "amd64": + return "linux-x86" + case "arm64": + return "linux-arm64" + default: + panic(fmt.Errorf("Unknown GOARCH %s", runtime.GOARCH)) + } case "darwin": return "darwin-x86" default: - panic("Unknown GOOS") + panic(fmt.Errorf("Unknown GOOS %s", runtime.GOOS)) } } @@ -2222,7 +2249,6 @@ var ( "RELEASE_APEX_CONTRIBUTIONS_NFC": "com.android.nfcservices", "RELEASE_APEX_CONTRIBUTIONS_ONDEVICEPERSONALIZATION": "com.android.ondevicepersonalization", "RELEASE_APEX_CONTRIBUTIONS_PERMISSION": "com.android.permission", - "RELEASE_APEX_CONTRIBUTIONS_PRIMARY_LIBS": "", "RELEASE_APEX_CONTRIBUTIONS_PROFILING": "com.android.profiling", "RELEASE_APEX_CONTRIBUTIONS_REMOTEKEYPROVISIONING": "com.android.rkpd", "RELEASE_APEX_CONTRIBUTIONS_RESOLV": "com.android.resolv", diff --git a/android/config_test.go b/android/config_test.go index 3d8686041..d1b26c12a 100644 --- a/android/config_test.go +++ b/android/config_test.go @@ -213,13 +213,18 @@ func TestConfiguredJarList(t *testing.T) { }) } -func (p partialCompileFlags) updateEnabled(value bool) partialCompileFlags { - p.Enabled = value +func (p partialCompileFlags) updateUseD8(value bool) partialCompileFlags { + p.Use_d8 = value return p } -func (p partialCompileFlags) updateUseD8(value bool) partialCompileFlags { - p.Use_d8 = value +func (p partialCompileFlags) updateDisableApiLint(value bool) partialCompileFlags { + p.Disable_api_lint = value + return p +} + +func (p partialCompileFlags) updateDisableStubValidation(value bool) partialCompileFlags { + p.Disable_stub_validation = value return p } @@ -241,10 +246,29 @@ func TestPartialCompile(t *testing.T) { {"false", true, partialCompileFlags{}}, {"true", true, enabledPartialCompileFlags}, {"true", false, partialCompileFlags{}}, + {"all", true, partialCompileFlags{}.updateUseD8(true).updateDisableApiLint(true).updateDisableStubValidation(true)}, + + // This verifies both use_d8 and the processing order. {"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)}, + + // disable_api_lint can be specified with any of 3 options. + {"false,-api_lint", true, partialCompileFlags{}.updateDisableApiLint(true)}, + {"false,-enable_api_lint", true, partialCompileFlags{}.updateDisableApiLint(true)}, + {"false,+disable_api_lint", true, partialCompileFlags{}.updateDisableApiLint(true)}, + {"false,+api_lint", true, partialCompileFlags{}.updateDisableApiLint(false)}, + {"false,+enable_api_lint", true, partialCompileFlags{}.updateDisableApiLint(false)}, + {"false,-disable_api_lint", true, partialCompileFlags{}.updateDisableApiLint(false)}, + + // disable_stub_validation can be specified with any of 3 options. + {"false,-stub_validation", true, partialCompileFlags{}.updateDisableStubValidation(true)}, + {"false,-enable_stub_validation", true, partialCompileFlags{}.updateDisableStubValidation(true)}, + {"false,+disable_stub_validation", true, partialCompileFlags{}.updateDisableStubValidation(true)}, + {"false,+stub_validation", true, partialCompileFlags{}.updateDisableStubValidation(false)}, + {"false,+enable_stub_validation", true, partialCompileFlags{}.updateDisableStubValidation(false)}, + {"false,-disable_stub_validation", true, partialCompileFlags{}.updateDisableStubValidation(false)}, } for _, test := range tests { diff --git a/android/container.go b/android/container.go index 5dc97d38e..547fe816c 100644 --- a/android/container.go +++ b/android/container.go @@ -39,7 +39,7 @@ type StubsAvailableModule interface { // Returns true if the dependency module is a stubs module var depIsStubsModule exceptionHandleFunc = func(mctx ModuleContext, _ Module, dep ModuleProxy) bool { - return OtherModuleProviderOrDefault(mctx, dep, CommonModuleInfoKey).IsStubsModule + return OtherModulePointerProviderOrDefault(mctx, dep, CommonModuleInfoProvider).IsStubsModule } // Returns true if the dependency module belongs to any of the apexes. @@ -449,7 +449,7 @@ func generateContainerInfo(ctx ModuleContext) ContainersInfo { } func getContainerModuleInfo(ctx ModuleContext, module Module) (ContainersInfo, bool) { - if ctx.EqualModules(ctx.Module(), module) { + if EqualModules(ctx.Module(), module) { return ctx.getContainersInfo(), true } @@ -474,7 +474,7 @@ func checkContainerViolations(ctx ModuleContext) { if _, ok := ctx.Module().(InstallableModule); ok { containersInfo, _ := getContainerModuleInfo(ctx, ctx.Module()) ctx.VisitDirectDepsProxy(func(dep ModuleProxy) { - if !OtherModuleProviderOrDefault(ctx, dep, CommonModuleInfoKey).Enabled { + if !OtherModuleProviderOrDefault(ctx, dep, CommonModuleInfoProvider).Enabled { return } diff --git a/android/filegroup.go b/android/filegroup.go index 47102b915..9bcfd0a83 100644 --- a/android/filegroup.go +++ b/android/filegroup.go @@ -33,6 +33,7 @@ var PrepareForTestWithFilegroup = FixtureRegisterWithContext(func(ctx Registrati func RegisterFilegroupBuildComponents(ctx RegistrationContext) { ctx.RegisterModuleType("filegroup", FileGroupFactory) ctx.RegisterModuleType("filegroup_defaults", FileGroupDefaultsFactory) + ctx.RegisterModuleType("otatools_package_filegroup", OtatoolsFileGroupFactory) } type fileGroupProperties struct { @@ -131,10 +132,11 @@ func (fg *fileGroup) Srcs() Paths { return append(Paths{}, fg.srcs...) } -func (fg *fileGroup) MakeVars(ctx MakeVarsModuleContext) { +func (fg *fileGroup) MakeVars(_ MakeVarsModuleContext) []ModuleMakeVarsValue { if makeVar := String(fg.properties.Export_to_make_var); makeVar != "" { - ctx.StrictRaw(makeVar, strings.Join(fg.srcs.Strings(), " ")) + return []ModuleMakeVarsValue{{makeVar, strings.Join(fg.srcs.Strings(), " ")}} } + return nil } // Defaults @@ -162,3 +164,54 @@ func (fg *fileGroup) IDEInfo(ctx BaseModuleContext, dpInfo *IdeInfo) { } } } + +type OtatoolsFileGroup struct { + ModuleBase +} + +func OtatoolsFileGroupFactory() Module { + module := &OtatoolsFileGroup{} + InitAndroidModule(module) + AddLoadHook(module, func(ctx LoadHookContext) { + module.createOTAToolsPackagefilegroup(ctx) + }) + return module +} + +func (fg *OtatoolsFileGroup) GenerateAndroidBuildActions(ctx ModuleContext) { +} + +// Create the filegroup to collect cert files for otatools.zip. +func (fg *OtatoolsFileGroup) createOTAToolsPackagefilegroup(ctx LoadHookContext) { + ctx.CreateModuleInDirectory( + FileGroupFactory, + ".", + &struct { + Name *string + Srcs []string + Visibility []string + }{ + Name: proptools.StringPtr("soong_generated_otatools_package_filegroup"), + Srcs: []string{ + "build/make/target/product/security/**/*.x509.pem", + "build/make/target/product/security/**/*.pk8", + "device/**/*.pk8", + "device/**/verifiedboot*", + "device/**/*.pem", + "device/**/oem*.prop", + "device/**/*.avbpubkey", + "external/avb/test/data/**/testkey_*.pem", + "external/avb/test/data/**/atx_metadata.bin", + "packages/modules/**/*.x509.pem", + "packages/modules/**/*.pk8", + "packages/modules/**/*.key.pem", + "vendor/**/*.pk8", + "vendor/**/verifiedboot*", + "vendor/**/*.pem", + "vendor/**/oem*.prop", + "vendor/**/*.avbpubkey", + }, + Visibility: []string{"//build/make/tools/otatools_package"}, + }, + ) +} diff --git a/android/gen_notice.go b/android/gen_notice.go index 9adde9e9b..45f90f47c 100644 --- a/android/gen_notice.go +++ b/android/gen_notice.go @@ -19,6 +19,7 @@ import ( "path/filepath" "strings" + "github.com/google/blueprint" "github.com/google/blueprint/proptools" ) @@ -35,34 +36,31 @@ func RegisterGenNoticeBuildComponents(ctx RegistrationContext) { type genNoticeBuildRules struct{} func (s *genNoticeBuildRules) GenerateBuildActions(ctx SingletonContext) { - ctx.VisitAllModules(func(m Module) { - gm, ok := m.(*genNoticeModule) + ctx.VisitAllModuleProxies(func(m ModuleProxy) { + gm, ok := OtherModuleProvider(ctx, m, GenNoticeInfoProvider) if !ok { return } - if len(gm.missing) > 0 { - missingReferencesRule(ctx, gm) + if len(gm.Missing) > 0 { + missingReferencesRule(ctx, m, &gm) return } out := BuildNoticeTextOutputFromLicenseMetadata - if proptools.Bool(gm.properties.Xml) { + if gm.Xml { out = BuildNoticeXmlOutputFromLicenseMetadata - } else if proptools.Bool(gm.properties.Html) { + } else if gm.Html { out = BuildNoticeHtmlOutputFromLicenseMetadata } defaultName := "" - if len(gm.properties.For) > 0 { - defaultName = gm.properties.For[0] + if len(gm.For) > 0 { + defaultName = gm.For[0] } - modules := make([]Module, 0) - for _, name := range gm.properties.For { - mods := ctx.ModuleVariantsFromName(gm, name) + modules := make([]ModuleProxy, 0) + for _, name := range gm.For { + mods := ctx.ModuleVariantsFromName(m, name) for _, mod := range mods { - if mod == nil { - continue - } - if !mod.Enabled(ctx) { // don't depend on variants without build rules + if !OtherModulePointerProviderOrDefault(ctx, mod, CommonModuleInfoProvider).Enabled { // don't depend on variants without build rules continue } modules = append(modules, mod) @@ -71,8 +69,8 @@ func (s *genNoticeBuildRules) GenerateBuildActions(ctx SingletonContext) { if ctx.Failed() { return } - out(ctx, gm.output, ctx.ModuleName(gm), - proptools.StringDefault(gm.properties.ArtifactName, defaultName), + out(ctx, gm.Output, ctx.ModuleName(m), + proptools.StringDefault(gm.ArtifactName, defaultName), []string{ filepath.Join(ctx.Config().OutDir(), "target", "product", ctx.Config().DeviceName()) + "/", ctx.Config().OutDir() + "/", @@ -115,6 +113,22 @@ type genNoticeModule struct { missing []string } +type GenNoticeInfo struct { + // For specifies the modules for which to generate a notice file. + For []string + // ArtifactName specifies the internal name to use for the notice file. + // It appears in the "used by:" list for targets whose entire name is stripped by --strip_prefix. + ArtifactName *string + // Html indicates an html-format file is needed. The default is text. Can be Html or Xml but not both. + Html bool + // Xml indicates an xml-format file is needed. The default is text. Can be Html or Xml but not both. + Xml bool + Output OutputPath + Missing []string +} + +var GenNoticeInfoProvider = blueprint.NewProvider[GenNoticeInfo]() + func (m *genNoticeModule) DepsMutator(ctx BottomUpMutatorContext) { if ctx.ContainsProperty("licenses") { ctx.PropertyErrorf("licenses", "not supported on \"gen_notice\" modules") @@ -176,6 +190,15 @@ func (m *genNoticeModule) GenerateAndroidBuildActions(ctx ModuleContext) { } out := m.getStem() + m.getSuffix() m.output = PathForModuleOut(ctx, out).OutputPath + + SetProvider(ctx, GenNoticeInfoProvider, GenNoticeInfo{ + For: m.properties.For, + ArtifactName: m.properties.ArtifactName, + Xml: proptools.Bool(m.properties.Xml), + Html: proptools.Bool(m.properties.Html), + Output: m.output, + Missing: m.missing, + }) ctx.SetOutputFiles(Paths{m.output}, "") } @@ -205,17 +228,17 @@ func (m *genNoticeModule) AndroidMkEntries() []AndroidMkEntries { } // missingReferencesRule emits an ErrorRule for missing module references. -func missingReferencesRule(ctx BuilderContext, m *genNoticeModule) { - if len(m.missing) < 1 { +func missingReferencesRule(ctx BuilderContext, m ModuleProxy, genInfo *GenNoticeInfo) { + if len(genInfo.Missing) < 1 { panic(fmt.Errorf("missing references rule requested with no missing references")) } ctx.Build(pctx, BuildParams{ Rule: ErrorRule, - Output: m.output, - Description: "notice for " + proptools.StringDefault(m.properties.ArtifactName, "container"), + Output: genInfo.Output, + Description: "notice for " + proptools.StringDefault(genInfo.ArtifactName, "container"), Args: map[string]string{ - "error": m.Name() + " references missing module(s): " + strings.Join(m.missing, ", "), + "error": m.Name() + " references missing module(s): " + strings.Join(genInfo.Missing, ", "), }, }) } diff --git a/android/init.go b/android/init.go index d3a13d0ed..af50323d3 100644 --- a/android/init.go +++ b/android/init.go @@ -17,6 +17,7 @@ package android import "encoding/gob" func init() { + gob.Register(applicableLicensesPropertyImpl{}) gob.Register(extraFilesZip{}) gob.Register(InstallPath{}) gob.Register(ModuleGenPath{}) diff --git a/android/license_metadata.go b/android/license_metadata.go index d15dfa841..0b880dd8a 100644 --- a/android/license_metadata.go +++ b/android/license_metadata.go @@ -65,7 +65,7 @@ func buildLicenseMetadata(ctx *moduleContext, licenseMetadataFile WritablePath) var allDepMetadataDepSets []depset.DepSet[Path] ctx.VisitDirectDepsProxy(func(dep ModuleProxy) { - if !OtherModuleProviderOrDefault(ctx, dep, CommonModuleInfoKey).Enabled { + if !OtherModulePointerProviderOrDefault(ctx, dep, CommonModuleInfoProvider).Enabled { return } diff --git a/android/licenses.go b/android/licenses.go index 32d12c8a2..387792144 100644 --- a/android/licenses.go +++ b/android/licenses.go @@ -22,6 +22,7 @@ import ( "sync" "github.com/google/blueprint" + "github.com/google/blueprint/gobtools" ) // Adds cross-cutting licenses dependency to propagate license metadata through the build system. @@ -67,6 +68,31 @@ type applicableLicensesPropertyImpl struct { licensesProperty *[]string } +type applicableLicensesPropertyImplGob struct { + Name string + LicensesProperty []string +} + +func (a *applicableLicensesPropertyImpl) ToGob() *applicableLicensesPropertyImplGob { + return &applicableLicensesPropertyImplGob{ + Name: a.name, + LicensesProperty: *a.licensesProperty, + } +} + +func (a *applicableLicensesPropertyImpl) FromGob(data *applicableLicensesPropertyImplGob) { + a.name = data.Name + a.licensesProperty = &data.LicensesProperty +} + +func (a applicableLicensesPropertyImpl) GobEncode() ([]byte, error) { + return gobtools.CustomGobEncode[applicableLicensesPropertyImplGob](&a) +} + +func (a *applicableLicensesPropertyImpl) GobDecode(data []byte) error { + return gobtools.CustomGobDecode[applicableLicensesPropertyImplGob](data, a) +} + func newApplicableLicensesProperty(name string, licensesProperty *[]string) applicableLicensesProperty { return applicableLicensesPropertyImpl{ name: name, @@ -351,9 +377,7 @@ func licensesMakeVarsProvider(ctx MakeVarsContext) { ctx.Strict("HTMLNOTICE", ctx.Config().HostToolPath(ctx, "htmlnotice").String()) ctx.Strict("XMLNOTICE", ctx.Config().HostToolPath(ctx, "xmlnotice").String()) ctx.Strict("TEXTNOTICE", ctx.Config().HostToolPath(ctx, "textnotice").String()) - ctx.Strict("COMPLIANCENOTICE_BOM", ctx.Config().HostToolPath(ctx, "compliancenotice_bom").String()) ctx.Strict("COMPLIANCENOTICE_SHIPPEDLIBS", ctx.Config().HostToolPath(ctx, "compliancenotice_shippedlibs").String()) ctx.Strict("COMPLIANCE_LISTSHARE", ctx.Config().HostToolPath(ctx, "compliance_listshare").String()) ctx.Strict("COMPLIANCE_CHECKSHARE", ctx.Config().HostToolPath(ctx, "compliance_checkshare").String()) - ctx.Strict("COMPLIANCE_SBOM", ctx.Config().HostToolPath(ctx, "compliance_sbom").String()) } diff --git a/android/logtags.go b/android/logtags.go index abc37f997..074f402e7 100644 --- a/android/logtags.go +++ b/android/logtags.go @@ -42,8 +42,8 @@ func MergedLogtagsPath(ctx PathContext) OutputPath { func (l *logtagsSingleton) GenerateBuildActions(ctx SingletonContext) { var allLogtags Paths - ctx.VisitAllModules(func(module Module) { - if !module.ExportedToMake() { + ctx.VisitAllModuleProxies(func(module ModuleProxy) { + if !OtherModulePointerProviderOrDefault(ctx, module, CommonModuleInfoProvider).ExportedToMake { return } if logtagsInfo, ok := OtherModuleProvider(ctx, module, LogtagsProviderKey); ok { diff --git a/android/makevars.go b/android/makevars.go index 2931d0bed..7017e7db0 100644 --- a/android/makevars.go +++ b/android/makevars.go @@ -84,6 +84,7 @@ type MakeVarsContext interface { Errorf(format string, args ...interface{}) VisitAllModules(visit func(Module)) + VisitAllModuleProxies(visit func(proxy ModuleProxy)) VisitAllModulesIf(pred func(Module) bool, visit func(Module)) // Verify the make variable matches the Soong version, fail the build @@ -108,7 +109,7 @@ type MakeVarsContext interface { // MakeVarsModuleContext contains the set of functions available for modules // implementing the ModuleMakeVarsProvider interface. type MakeVarsModuleContext interface { - BaseMakeVarsContext + Config() Config } var _ PathContext = MakeVarsContext(nil) @@ -150,14 +151,21 @@ func singletonMakeVarsProviderAdapter(singleton SingletonMakeVarsProvider) MakeV return func(ctx MakeVarsContext) { singleton.MakeVars(ctx) } } +type ModuleMakeVarsValue struct { + // Make variable name. + Name string + // Make variable value. + Value string +} + // ModuleMakeVarsProvider is a Module with an extra method to provide extra values to be exported to Make. type ModuleMakeVarsProvider interface { - Module - // MakeVars uses a MakeVarsModuleContext to provide extra values to be exported to Make. - MakeVars(ctx MakeVarsModuleContext) + MakeVars(ctx MakeVarsModuleContext) []ModuleMakeVarsValue } +var ModuleMakeVarsInfoProvider = blueprint.NewProvider[[]ModuleMakeVarsValue]() + // ///////////////////////////////////////////////////////////////////////////// func makeVarsSingletonFunc() Singleton { @@ -250,19 +258,24 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) { dists = append(dists, singletonDists.dists...) singletonDists.lock.Unlock() - ctx.VisitAllModules(func(m Module) { - if provider, ok := m.(ModuleMakeVarsProvider); ok && m.Enabled(ctx) { + ctx.VisitAllModuleProxies(func(m ModuleProxy) { + commonInfo := OtherModulePointerProviderOrDefault(ctx, m, CommonModuleInfoProvider) + if provider, ok := OtherModuleProvider(ctx, m, ModuleMakeVarsInfoProvider); ok && + commonInfo.Enabled { mctx := &makeVarsContext{ SingletonContext: ctx, } - - provider.MakeVars(mctx) + for _, val := range provider { + if val.Name != "" { + mctx.StrictRaw(val.Name, val.Value) + } + } vars = append(vars, mctx.vars...) phonies = append(phonies, mctx.phonies...) } - if m.ExportedToMake() { + if commonInfo.ExportedToMake { info := OtherModuleProviderOrDefault(ctx, m, InstallFilesProvider) katiInstalls = append(katiInstalls, info.KatiInstalls...) katiInitRcInstalls = append(katiInitRcInstalls, info.KatiInitRcInstalls...) diff --git a/android/module.go b/android/module.go index d387c2cf3..a3fe837a5 100644 --- a/android/module.go +++ b/android/module.go @@ -15,6 +15,7 @@ package android import ( + "errors" "fmt" "net/url" "path/filepath" @@ -519,6 +520,11 @@ type baseProperties struct { // names of other modules to install on target if this module is installed Target_required []string `android:"arch_variant"` + + // If this is a soong config module, this property will be set to the name of the original + // module type. This is used by neverallow to ensure you can't bypass a ModuleType() matcher + // just by creating a soong config module type. + Soong_config_base_module_type *string `blueprint:"mutated"` } type distProperties struct { @@ -996,11 +1002,19 @@ func (m *ModuleBase) baseDepsMutator(ctx BottomUpMutatorContext) { pv := ctx.Config().productVariables fullManifest := pv.DeviceArch != nil && pv.DeviceName != nil if fullManifest { - addRequiredDeps(ctx) addVintfFragmentDeps(ctx) } } +// required property can be overridden too; handle it separately +func (m *ModuleBase) baseOverridablePropertiesDepsMutator(ctx BottomUpMutatorContext) { + pv := ctx.Config().productVariables + fullManifest := pv.DeviceArch != nil && pv.DeviceName != nil + if fullManifest { + addRequiredDeps(ctx) + } +} + // addRequiredDeps adds required, target_required, and host_required as dependencies. func addRequiredDeps(ctx BottomUpMutatorContext) { addDep := func(target Target, depName string) { @@ -1219,6 +1233,13 @@ func (m *ModuleBase) GenerateTaggedDistFiles(ctx BaseModuleContext) TaggedDistFi tag := proptools.StringDefault(dist.Tag, DefaultDistTag) distFileForTagFromProvider, err := outputFilesForModuleFromProvider(ctx, m.module, tag) + + // If the module doesn't define output files for the DefaultDistTag, try the files under + // the "" tag. + if tag == DefaultDistTag && errors.Is(err, ErrUnsupportedOutputTag) { + distFileForTagFromProvider, err = outputFilesForModuleFromProvider(ctx, m.module, "") + } + if err != OutputFilesProviderNotSet { if err != nil && tag != DefaultDistTag { ctx.PropertyErrorf("dist.tag", "%s", err.Error()) @@ -1475,7 +1496,7 @@ func (m *ModuleBase) computeInstallDeps(ctx ModuleContext) ([]depset.DepSet[Inst // Installation is still handled by Make, so anything hidden from Make is not // installable. info := OtherModuleProviderOrDefault(ctx, dep, InstallFilesProvider) - commonInfo := OtherModuleProviderOrDefault(ctx, dep, CommonModuleInfoKey) + commonInfo := OtherModulePointerProviderOrDefault(ctx, dep, CommonModuleInfoProvider) if !commonInfo.HideFromMake && !commonInfo.SkipInstall { installDeps = append(installDeps, info.TransitiveInstallFiles) } @@ -1492,7 +1513,7 @@ func (m *ModuleBase) computeInstallDeps(ctx ModuleContext) ([]depset.DepSet[Inst // should also install the output files of the given dependency and dependency tag. func isInstallDepNeeded(ctx ModuleContext, dep ModuleProxy) bool { // Don't add a dependency from the platform to a library provided by an apex. - if OtherModuleProviderOrDefault(ctx, dep, CommonModuleInfoKey).UninstallableApexPlatformVariant { + if OtherModulePointerProviderOrDefault(ctx, dep, CommonModuleInfoProvider).UninstallableApexPlatformVariant { return false } // Only install modules if the dependency tag is an InstallDepNeeded tag. @@ -1646,38 +1667,10 @@ func (m *ModuleBase) generateVariantTarget(ctx *moduleContext) { } +// generateModuleTarget generates phony targets so that you can do `m <module-name>`. +// It will be run on every variant of the module, so it relies on the fact that phony targets +// are deduped to merge all the deps from different variants together. func (m *ModuleBase) generateModuleTarget(ctx *moduleContext) { - var allInstalledFiles InstallPaths - var allCheckbuildTargets Paths - var alloutputFiles Paths - ctx.VisitAllModuleVariantProxies(func(module ModuleProxy) { - var checkbuildTarget Path - var uncheckedModule bool - var skipAndroidMkProcessing bool - if ctx.EqualModules(m.module, module) { - allInstalledFiles = append(allInstalledFiles, ctx.installFiles...) - checkbuildTarget = ctx.checkbuildTarget - uncheckedModule = ctx.uncheckedModule - skipAndroidMkProcessing = shouldSkipAndroidMkProcessing(ctx, m) - } else { - info := OtherModuleProviderOrDefault(ctx, module, InstallFilesProvider) - allInstalledFiles = append(allInstalledFiles, info.InstallFiles...) - checkbuildTarget = info.CheckbuildTarget - uncheckedModule = info.UncheckedModule - skipAndroidMkProcessing = OtherModuleProviderOrDefault(ctx, module, CommonModuleInfoKey).SkipAndroidMkProcessing - } - if outputFiles, err := outputFilesForModule(ctx, module, ""); err == nil { - alloutputFiles = append(alloutputFiles, outputFiles...) - } - // A module's -checkbuild phony targets should - // not be created if the module is not exported to make. - // Those could depend on the build target and fail to compile - // for the current build target. - if (!ctx.Config().KatiEnabled() || !skipAndroidMkProcessing) && !uncheckedModule && checkbuildTarget != nil { - allCheckbuildTargets = append(allCheckbuildTargets, checkbuildTarget) - } - }) - var namespacePrefix string nameSpace := ctx.Namespace().Path if nameSpace != "." { @@ -1685,25 +1678,30 @@ func (m *ModuleBase) generateModuleTarget(ctx *moduleContext) { } var deps Paths - var info FinalModuleBuildTargetsInfo + var info ModuleBuildTargetsInfo - if len(allInstalledFiles) > 0 { + if len(ctx.installFiles) > 0 { name := namespacePrefix + ctx.ModuleName() + "-install" - ctx.Phony(name, allInstalledFiles.Paths()...) + installFiles := ctx.installFiles.Paths() + ctx.Phony(name, installFiles...) info.InstallTarget = PathForPhony(ctx, name) - deps = append(deps, info.InstallTarget) + deps = append(deps, installFiles...) } - if len(allCheckbuildTargets) > 0 { + // A module's -checkbuild phony targets should + // not be created if the module is not exported to make. + // Those could depend on the build target and fail to compile + // for the current build target. + if (!ctx.Config().KatiEnabled() || !shouldSkipAndroidMkProcessing(ctx, m)) && !ctx.uncheckedModule && ctx.checkbuildTarget != nil { name := namespacePrefix + ctx.ModuleName() + "-checkbuild" - ctx.Phony(name, allCheckbuildTargets...) - deps = append(deps, PathForPhony(ctx, name)) + ctx.Phony(name, ctx.checkbuildTarget) + deps = append(deps, ctx.checkbuildTarget) } - if len(alloutputFiles) > 0 { + if outputFiles, err := outputFilesForModule(ctx, ctx.Module(), ""); err == nil && len(outputFiles) > 0 { name := namespacePrefix + ctx.ModuleName() + "-outputs" - ctx.Phony(name, alloutputFiles...) - deps = append(deps, PathForPhony(ctx, name)) + ctx.Phony(name, outputFiles...) + deps = append(deps, outputFiles...) } if len(deps) > 0 { @@ -1726,7 +1724,7 @@ func (m *ModuleBase) generateModuleTarget(ctx *moduleContext) { } info.BlueprintDir = ctx.ModuleDir() - SetProvider(ctx, FinalModuleBuildTargetsProvider, info) + SetProvider(ctx, ModuleBuildTargetsProvider, info) } } @@ -1868,15 +1866,15 @@ type SourceFilesInfo struct { var SourceFilesInfoProvider = blueprint.NewProvider[SourceFilesInfo]() -// FinalModuleBuildTargetsInfo is used by buildTargetSingleton to create checkbuild and -// per-directory build targets. Only set on the final variant of each module -type FinalModuleBuildTargetsInfo struct { +// ModuleBuildTargetsInfo is used by buildTargetSingleton to create checkbuild and +// per-directory build targets. +type ModuleBuildTargetsInfo struct { InstallTarget WritablePath CheckbuildTarget WritablePath BlueprintDir string } -var FinalModuleBuildTargetsProvider = blueprint.NewProvider[FinalModuleBuildTargetsInfo]() +var ModuleBuildTargetsProvider = blueprint.NewProvider[ModuleBuildTargetsInfo]() type CommonModuleInfo struct { Enabled bool @@ -1928,6 +1926,9 @@ type CommonModuleInfo struct { TargetRequiredModuleNames []string VintfFragmentModuleNames []string Dists []Dist + ExportedToMake bool + Team string + PartitionTag string } type ApiLevelOrPlatform struct { @@ -1935,7 +1936,7 @@ type ApiLevelOrPlatform struct { IsPlatform bool } -var CommonModuleInfoKey = blueprint.NewProvider[CommonModuleInfo]() +var CommonModuleInfoProvider = blueprint.NewProvider[*CommonModuleInfo]() type PrebuiltModuleInfo struct { SourceExists bool @@ -2141,14 +2142,19 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) } if sourceFileProducer, ok := m.module.(SourceFileProducer); ok { + srcs := sourceFileProducer.Srcs() + for _, src := range srcs { + if src == nil { + ctx.ModuleErrorf("SourceFileProducer cannot return nil srcs") + return + } + } SetProvider(ctx, SourceFilesInfoProvider, SourceFilesInfo{Srcs: sourceFileProducer.Srcs()}) } - if ctx.IsFinalModule(m.module) { - m.generateModuleTarget(ctx) - if ctx.Failed() { - return - } + m.generateModuleTarget(ctx) + if ctx.Failed() { + return } ctx.TransitiveInstallFiles = depset.New[InstallPath](depset.TOPOLOGICAL, ctx.installFiles, dependencyInstallFiles) @@ -2176,6 +2182,7 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) } else { hostRequired = m.baseProperties.Host_required } + hostRequired = append(hostRequired, moduleInfoJSON.ExtraHostRequired...) var data []string for _, d := range ctx.testData { @@ -2287,6 +2294,9 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) TargetRequiredModuleNames: m.module.TargetRequiredModuleNames(), VintfFragmentModuleNames: m.module.VintfFragmentModuleNames(ctx), Dists: m.Dists(), + ExportedToMake: m.ExportedToMake(), + Team: m.Team(), + PartitionTag: m.PartitionTag(ctx.DeviceConfig()), } if mm, ok := m.module.(interface { MinSdkVersion(ctx EarlyModuleContext) ApiLevel @@ -2334,7 +2344,7 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) if mm, ok := m.module.(interface{ BaseModuleName() string }); ok { commonData.BaseModuleName = mm.BaseModuleName() } - SetProvider(ctx, CommonModuleInfoKey, commonData) + SetProvider(ctx, CommonModuleInfoProvider, &commonData) if p, ok := m.module.(PrebuiltInterface); ok && p.Prebuilt() != nil { SetProvider(ctx, PrebuiltModuleInfoProvider, PrebuiltModuleInfo{ SourceExists: p.Prebuilt().SourceExists(), @@ -2357,6 +2367,18 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) GeneratedDeps: s.GeneratedDeps(), }) } + + if m.Enabled(ctx) { + if v, ok := m.module.(ModuleMakeVarsProvider); ok { + SetProvider(ctx, ModuleMakeVarsInfoProvider, v.MakeVars(ctx)) + } + + if am, ok := m.module.(AndroidMkDataProvider); ok { + SetProvider(ctx, AndroidMkDataInfoProvider, AndroidMkDataInfo{ + Class: am.AndroidMk().Class, + }) + } + } } func SetJarJarPrefixHandler(handler func(ModuleContext)) { @@ -2640,6 +2662,8 @@ func (e configurationEvalutor) EvaluateConfiguration(condition proptools.Configu return proptools.ConfigurableValueBool(ctx.Config().UseDebugArt()) case "selinux_ignore_neverallows": return proptools.ConfigurableValueBool(ctx.Config().SelinuxIgnoreNeverallows()) + case "always_use_prebuilt_sdks": + return proptools.ConfigurableValueBool(ctx.Config().AlwaysUsePrebuiltSdks()) default: // TODO(b/323382414): Might add these on a case-by-case basis ctx.OtherModulePropertyErrorf(m, property, fmt.Sprintf("TODO(b/323382414): Product variable %q is not yet supported in selects", variable)) @@ -2873,6 +2897,8 @@ func OutputFilesForModule(ctx PathContext, module Module, tag string) Paths { // OutputFileForModule returns the output file paths with the given tag. On error, including if the // module produced zero or multiple paths, it reports errors to the ctx and returns nil. +// TODO(b/397766191): Change the signature to take ModuleProxy +// Please only access the module's internal data through providers. func OutputFileForModule(ctx PathContext, module Module, tag string) Path { paths, err := outputFilesForModule(ctx, module, tag) if err != nil { @@ -2910,9 +2936,10 @@ type OutputFilesProviderModuleContext interface { OtherModuleProviderContext Module() Module GetOutputFiles() OutputFilesInfo - EqualModules(m1, m2 Module) bool } +// TODO(b/397766191): Change the signature to take ModuleProxy +// Please only access the module's internal data through providers. func outputFilesForModule(ctx PathContext, module Module, tag string) (Paths, error) { outputFilesFromProvider, err := outputFilesForModuleFromProvider(ctx, module, tag) if outputFilesFromProvider != nil || err != OutputFilesProviderNotSet { @@ -2920,7 +2947,7 @@ func outputFilesForModule(ctx PathContext, module Module, tag string) (Paths, er } if octx, ok := ctx.(OutputFilesProviderModuleContext); ok { - if octx.EqualModules(octx.Module(), module) { + if EqualModules(octx.Module(), module) { // It is the current module, we can access the srcs through interface if sourceFileProducer, ok := module.(SourceFileProducer); ok { return sourceFileProducer.Srcs(), nil @@ -2945,14 +2972,12 @@ func outputFilesForModule(ctx PathContext, module Module, tag string) (Paths, er // If a module doesn't have the OutputFilesProvider, nil is returned. func outputFilesForModuleFromProvider(ctx PathContext, module Module, tag string) (Paths, error) { var outputFiles OutputFilesInfo - fromProperty := false if mctx, isMctx := ctx.(OutputFilesProviderModuleContext); isMctx { - if !mctx.EqualModules(mctx.Module(), module) { + if !EqualModules(mctx.Module(), module) { outputFiles, _ = OtherModuleProvider(mctx, module, OutputFilesProvider) } else { outputFiles = mctx.GetOutputFiles() - fromProperty = true } } else if cta, isCta := ctx.(*singletonContextAdaptor); isCta { outputFiles, _ = OtherModuleProvider(cta, module, OutputFilesProvider) @@ -2969,10 +2994,8 @@ func outputFilesForModuleFromProvider(ctx PathContext, module Module, tag string } else if taggedOutputFiles, hasTag := outputFiles.TaggedOutputFiles[tag]; hasTag { return taggedOutputFiles, nil } else { - if fromProperty { - return nil, fmt.Errorf("unsupported tag %q for module getting its own output files", tag) - } else { - return nil, fmt.Errorf("unsupported module reference tag %q", tag) + return nil, UnsupportedOutputTagError{ + tag: tag, } } } @@ -2991,8 +3014,24 @@ type OutputFilesInfo struct { var OutputFilesProvider = blueprint.NewProvider[OutputFilesInfo]() +type UnsupportedOutputTagError struct { + tag string +} + +func (u UnsupportedOutputTagError) Error() string { + return fmt.Sprintf("unsupported output tag %q", u.tag) +} + +func (u UnsupportedOutputTagError) Is(e error) bool { + _, ok := e.(UnsupportedOutputTagError) + return ok +} + +var _ error = UnsupportedOutputTagError{} + // This is used to mark the case where OutputFilesProvider is not set on some modules. var OutputFilesProviderNotSet = fmt.Errorf("No output files from provider") +var ErrUnsupportedOutputTag = UnsupportedOutputTagError{} // Modules can implement HostToolProvider and return a valid OptionalPath from HostToolPath() to // specify that they can be used as a tool by a genrule module. @@ -3058,8 +3097,8 @@ func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) { modulesInDir := make(map[string]Paths) - ctx.VisitAllModules(func(module Module) { - info := OtherModuleProviderOrDefault(ctx, module, FinalModuleBuildTargetsProvider) + ctx.VisitAllModuleProxies(func(module ModuleProxy) { + info := OtherModuleProviderOrDefault(ctx, module, ModuleBuildTargetsProvider) if info.CheckbuildTarget != nil { checkbuildDeps = append(checkbuildDeps, info.CheckbuildTarget) @@ -3141,14 +3180,6 @@ type IDEInfo interface { BaseModuleName() string } -// Extract the base module name from the Import name. -// Often the Import name has a prefix "prebuilt_". -// Remove the prefix explicitly if needed -// until we find a better solution to get the Import name. -type IDECustomizedModuleName interface { - IDECustomizedModuleName() string -} - // Collect information for opening IDE project files in java/jdeps.go. type IdeInfo struct { BaseModuleName string `json:"-"` diff --git a/android/module_context.go b/android/module_context.go index fb62e6749..0a23a745f 100644 --- a/android/module_context.go +++ b/android/module_context.go @@ -456,6 +456,11 @@ func (m *moduleContext) Build(pctx PackageContext, params BuildParams) { } func (m *moduleContext) Phony(name string, deps ...Path) { + for _, dep := range deps { + if dep == nil { + panic("Phony dep cannot be nil") + } + } m.phonies[name] = append(m.phonies[name], deps...) } @@ -748,6 +753,9 @@ func (m *moduleContext) installFile(installPath InstallPath, name string, srcPat m.packageFile(fullInstallPath, srcPath, executable, m.requiresFullInstall()) if checkbuild { + if srcPath == nil { + panic("srcPath cannot be nil") + } m.checkbuildFiles = append(m.checkbuildFiles, srcPath) } @@ -879,6 +887,11 @@ func (m *moduleContext) InstallTestData(installPath InstallPath, data []DataPath // CheckbuildFile specifies the output files that should be built by checkbuild. func (m *moduleContext) CheckbuildFile(srcPaths ...Path) { + for _, srcPath := range srcPaths { + if srcPath == nil { + panic("CheckbuildFile() files cannot be nil") + } + } m.checkbuildFiles = append(m.checkbuildFiles, srcPaths...) } diff --git a/android/module_info_json.go b/android/module_info_json.go index bb309ffee..50c961abe 100644 --- a/android/module_info_json.go +++ b/android/module_info_json.go @@ -40,10 +40,12 @@ type ExtraModuleInfoJSON struct { StaticDependencies []string `json:"static_dependencies,omitempty"` // $(sort $(ALL_MODULES.$(m).LOCAL_STATIC_LIBRARIES)) DataDependencies []string `json:"data_dependencies,omitempty"` // $(sort $(ALL_MODULES.$(m).TEST_DATA_BINS)) - CompatibilitySuites []string `json:"compatibility_suites,omitempty"` // $(sort $(ALL_MODULES.$(m).COMPATIBILITY_SUITES)) - AutoTestConfig []string `json:"auto_test_config,omitempty"` // $(ALL_MODULES.$(m).auto_test_config) - TestConfig []string `json:"test_config,omitempty"` // $(strip $(ALL_MODULES.$(m).TEST_CONFIG) $(ALL_MODULES.$(m).EXTRA_TEST_CONFIGS) - ExtraRequired []string `json:"-"` + CompatibilitySuites []string `json:"compatibility_suites,omitempty"` // $(sort $(ALL_MODULES.$(m).COMPATIBILITY_SUITES)) + AutoTestConfig []string `json:"auto_test_config,omitempty"` // $(ALL_MODULES.$(m).auto_test_config) + TestConfig []string `json:"test_config,omitempty"` // $(strip $(ALL_MODULES.$(m).TEST_CONFIG) $(ALL_MODULES.$(m).EXTRA_TEST_CONFIGS) + TestModuleConfigBase string `json:"test_module_config_base,omitempty"` + ExtraRequired []string `json:"-"` + ExtraHostRequired []string `json:"-"` SupportedVariantsOverride []string `json:"-"` Disabled bool `json:"-"` diff --git a/android/neverallow.go b/android/neverallow.go index 70af2acc3..5c90501d7 100644 --- a/android/neverallow.go +++ b/android/neverallow.go @@ -60,7 +60,8 @@ func init() { AddNeverAllowRules(createCcStubsRule()) AddNeverAllowRules(createProhibitHeaderOnlyRule()) AddNeverAllowRules(createLimitNdkExportRule()...) - AddNeverAllowRules(createLimitDirgroupRule()...) + AddNeverAllowRules(createLimitDirgroupRules()...) + AddNeverAllowRules(createLimitGenruleRules()...) AddNeverAllowRules(createFilesystemIsAutoGeneratedRule()) AddNeverAllowRules(createKotlinPluginRule()...) AddNeverAllowRules(createPrebuiltEtcBpDefineRule()) @@ -251,6 +252,7 @@ func createInstallInRootAllowingRules() []Rule { NotModuleType("prebuilt_system"). NotModuleType("prebuilt_first_stage_ramdisk"). NotModuleType("prebuilt_res"). + NotModuleType("prebuilt_any"). Because("install_in_root is only for init_first_stage or librecovery_ui_ext."), } } @@ -287,45 +289,49 @@ func createLimitNdkExportRule() []Rule { } } -func createLimitDirgroupRule() []Rule { - reason := "dirgroup module and dir_srcs / keep_gendir property of genrule is allowed only to Trusty build rule." +func createLimitDirgroupRules() []Rule { + reason := "The dirgroup module can only be used with Trusty visibility" + scriptsDirsList := []string{"//trusty/vendor/google/aosp/scripts", "//trusty/vendor/google/proprietary/scripts"} return []Rule{ NeverAllow(). ModuleType("dirgroup"). - WithMatcher("visibility", NotInList([]string{"//trusty/vendor/google/aosp/scripts", "//trusty/vendor/google/proprietary/scripts"})).Because(reason), + WithMatcher("visibility", NotInList(scriptsDirsList)).Because(reason), NeverAllow(). ModuleType("dirgroup"). - WithoutMatcher("visibility", InAllowedList([]string{"//trusty/vendor/google/aosp/scripts", "//trusty/vendor/google/proprietary/scripts"})).Because(reason), + WithoutMatcher("visibility", InAllowedList(scriptsDirsList)).Because(reason), + } +} + +func createLimitGenruleRules() []Rule { + dirSrcsReason := "The `dir_srcs` property in a `genrule` module can only be used by Trusty" + keepGendirReason := "The `keep_gendir` property in a `genrule` module can only be used by Trusty" + allowedModuleNameList := []string{ + // Trusty TEE target names + "trusty_tee_package_goog", + "trusty_tee_package", + // Trusty vm target names + "trusty_desktop_vm_arm64.bin", + "trusty_desktop_vm_x86_64.elf", + "trusty_desktop_test_vm_arm64.bin", + "trusty_desktop_test_vm_x86_64.elf", + "trusty_test_vm_arm64.bin", + "trusty_test_vm_x86_64.elf", + "trusty_test_vm_os_arm64.bin", + "trusty_test_vm_os_x86_64.elf", + "trusty_security_vm_arm64.bin", + "trusty_security_vm_x86_64.elf", + "trusty_widevine_vm_arm64.bin", + "trusty_widevine_vm_x86_64.elf", + } + return []Rule{ NeverAllow(). ModuleType("genrule"). - // TODO: remove the 4 below targets once new targets are submitted - Without("name", "trusty-arm64.lk.elf.gen"). - Without("name", "trusty-arm64-virt-test-debug.lk.elf.gen"). - Without("name", "trusty-x86_64.lk.elf.gen"). - Without("name", "trusty-x86_64-test.lk.elf.gen"). - // trusty vm target names moving forward - Without("name", "trusty-test_vm-arm64.elf.gen"). - Without("name", "trusty-test_vm-x86.elf.gen"). - Without("name", "trusty-security_vm-arm64.elf.gen"). - Without("name", "trusty-security_vm-x86.elf.gen"). - Without("name", "trusty-widevine_vm-arm64.elf.gen"). - Without("name", "trusty-widevine_vm-x86.elf.gen"). - WithMatcher("dir_srcs", isSetMatcherInstance).Because(reason), + WithoutMatcher("name", InAllowedList(allowedModuleNameList)). + WithMatcher("dir_srcs", isSetMatcherInstance).Because(dirSrcsReason), NeverAllow(). ModuleType("genrule"). - // TODO: remove the 4 below targets once new targets are submitted - Without("name", "trusty-arm64.lk.elf.gen"). - Without("name", "trusty-arm64-virt-test-debug.lk.elf.gen"). - Without("name", "trusty-x86_64.lk.elf.gen"). - Without("name", "trusty-x86_64-test.lk.elf.gen"). - // trusty vm target names moving forward - Without("name", "trusty-test_vm-arm64.elf.gen"). - Without("name", "trusty-test_vm-x86.elf.gen"). - Without("name", "trusty-security_vm-arm64.elf.gen"). - Without("name", "trusty-security_vm-x86.elf.gen"). - Without("name", "trusty-widevine_vm-arm64.elf.gen"). - Without("name", "trusty-widevine_vm-x86.elf.gen"). - With("keep_gendir", "true").Because(reason), + WithoutMatcher("name", InAllowedList(allowedModuleNameList)). + With("keep_gendir", "true").Because(keepGendirReason), } } @@ -363,6 +369,7 @@ func createKotlinPluginRule() []Rule { func createPrebuiltEtcBpDefineRule() Rule { return NeverAllow(). ModuleType( + "prebuilt_any", "prebuilt_usr_srec", "prebuilt_priv_app", "prebuilt_rfs", @@ -378,6 +385,9 @@ func createPrebuiltEtcBpDefineRule() Rule { "prebuilt_sbin", "prebuilt_system", "prebuilt_first_stage_ramdisk", + "prebuilt_radio", + "prebuilt_gpu", + "prebuilt_vendor_overlay", ). DefinedInBpFile(). Because("module type not allowed to be defined in bp file") @@ -409,7 +419,8 @@ func neverallowMutator(ctx BottomUpMutatorContext) { continue } - if !n.appliesToModuleType(ctx.ModuleType()) { + modType := proptools.StringDefault(m.base().baseProperties.Soong_config_base_module_type, ctx.ModuleType()) + if !n.appliesToModuleType(modType) { continue } diff --git a/android/neverallow_test.go b/android/neverallow_test.go index c74d5ff58..3ccc883af 100644 --- a/android/neverallow_test.go +++ b/android/neverallow_test.go @@ -388,6 +388,30 @@ var neverallowTests = []struct { `module type not allowed to be defined in bp file`, }, }, + // Test the a neverallowed module type can't be smuggled through a soong config module type + { + name: `smuggling module types through soong config modules`, + fs: map[string][]byte{ + "a/b/Android.bp": []byte(` + soong_config_bool_variable { + name: "my_var", + } + soong_config_module_type { + name: "smuggled_prebuilt_usr_srec", + module_type: "prebuilt_usr_srec", + config_namespace: "ANDROID", + variables: ["my_var"], + properties: ["enabled"], + } + smuggled_prebuilt_usr_srec { + name: "foo", + } + `), + }, + expectedErrors: []string{ + `module type not allowed to be defined in bp file`, + }, + }, } var prepareForNeverAllowTest = GroupFixturePreparers( @@ -399,6 +423,7 @@ var prepareForNeverAllowTest = GroupFixturePreparers( ctx.RegisterModuleType("filesystem", newMockFilesystemModule) ctx.RegisterModuleType("prebuilt_usr_srec", newMockPrebuiltUsrSrecModule) }), + PrepareForTestWithSoongConfigModuleBuildComponents, ) func TestNeverallow(t *testing.T) { diff --git a/android/notices.go b/android/notices.go index 3c41d924e..dc2290cce 100644 --- a/android/notices.go +++ b/android/notices.go @@ -18,9 +18,11 @@ import ( "fmt" "path/filepath" "strings" + + "github.com/google/blueprint" ) -func modulesOutputDirs(ctx BuilderContext, modules ...Module) []string { +func modulesOutputDirs(ctx BuilderContext, modules ...ModuleProxy) []string { dirs := make([]string, 0, len(modules)) for _, module := range modules { paths, err := outputFilesForModule(ctx, module, "") @@ -41,12 +43,12 @@ type BuilderAndOtherModuleProviderContext interface { OtherModuleProviderContext } -func modulesLicenseMetadata(ctx OtherModuleProviderContext, modules ...Module) Paths { +func modulesLicenseMetadata(ctx OtherModuleProviderContext, modules ...ModuleProxy) Paths { result := make(Paths, 0, len(modules)) mctx, isMctx := ctx.(ModuleContext) for _, module := range modules { var mf Path - if isMctx && mctx.Module() == module { + if isMctx && EqualModules(mctx.Module(), module) { mf = mctx.LicenseMetadataFile() } else { mf = OtherModuleProviderOrDefault(ctx, module, InstallFilesProvider).LicenseMetadataFile @@ -61,12 +63,12 @@ func modulesLicenseMetadata(ctx OtherModuleProviderContext, modules ...Module) P // buildNoticeOutputFromLicenseMetadata writes out a notice file. func buildNoticeOutputFromLicenseMetadata( ctx BuilderAndOtherModuleProviderContext, tool, ruleName string, outputFile WritablePath, - libraryName string, stripPrefix []string, modules ...Module) { + libraryName string, stripPrefix []string, modules ...ModuleProxy) { depsFile := outputFile.ReplaceExtension(ctx, strings.TrimPrefix(outputFile.Ext()+".d", ".")) rule := NewRuleBuilder(pctx, ctx) if len(modules) == 0 { if mctx, ok := ctx.(ModuleContext); ok { - modules = []Module{mctx.Module()} + modules = []ModuleProxy{{blueprint.CreateModuleProxy(mctx.Module())}} } else { panic(fmt.Errorf("%s %q needs a module to generate the notice for", ruleName, libraryName)) } @@ -97,7 +99,7 @@ func buildNoticeOutputFromLicenseMetadata( // current context module if none given. func BuildNoticeTextOutputFromLicenseMetadata( ctx BuilderAndOtherModuleProviderContext, outputFile WritablePath, ruleName, libraryName string, - stripPrefix []string, modules ...Module) { + stripPrefix []string, modules ...ModuleProxy) { buildNoticeOutputFromLicenseMetadata(ctx, "textnotice", "text_notice_"+ruleName, outputFile, libraryName, stripPrefix, modules...) } @@ -107,7 +109,7 @@ func BuildNoticeTextOutputFromLicenseMetadata( // current context module if none given. func BuildNoticeHtmlOutputFromLicenseMetadata( ctx BuilderAndOtherModuleProviderContext, outputFile WritablePath, ruleName, libraryName string, - stripPrefix []string, modules ...Module) { + stripPrefix []string, modules ...ModuleProxy) { buildNoticeOutputFromLicenseMetadata(ctx, "htmlnotice", "html_notice_"+ruleName, outputFile, libraryName, stripPrefix, modules...) } @@ -117,7 +119,7 @@ func BuildNoticeHtmlOutputFromLicenseMetadata( // current context module if none given. func BuildNoticeXmlOutputFromLicenseMetadata( ctx BuilderAndOtherModuleProviderContext, outputFile WritablePath, ruleName, libraryName string, - stripPrefix []string, modules ...Module) { + stripPrefix []string, modules ...ModuleProxy) { buildNoticeOutputFromLicenseMetadata(ctx, "xmlnotice", "xml_notice_"+ruleName, outputFile, libraryName, stripPrefix, modules...) } diff --git a/android/override_module.go b/android/override_module.go index 50ddc9b35..96620ef7a 100644 --- a/android/override_module.go +++ b/android/override_module.go @@ -367,6 +367,7 @@ func checkPrebuiltReplacesOverride(ctx BottomUpMutatorContext, b OverridableModu } func overridableModuleDepsMutator(ctx BottomUpMutatorContext) { + ctx.Module().base().baseOverridablePropertiesDepsMutator(ctx) if b, ok := ctx.Module().(OverridableModule); ok && b.Enabled(ctx) { b.OverridablePropertiesDepsMutator(ctx) } diff --git a/android/package.go b/android/package.go index 385326e53..52bddf9d9 100644 --- a/android/package.go +++ b/android/package.go @@ -38,6 +38,12 @@ type packageProperties struct { Default_team *string `android:"path"` } +type PackageInfo struct { + Properties packageProperties +} + +var PackageInfoProvider = blueprint.NewProvider[PackageInfo]() + type packageModule struct { ModuleBase @@ -56,10 +62,14 @@ func (p *packageModule) DepsMutator(ctx BottomUpMutatorContext) { } func (p *packageModule) GenerateBuildActions(ctx blueprint.ModuleContext) { - ctx.SetProvider(CommonModuleInfoKey, CommonModuleInfo{ + ctx.SetProvider(CommonModuleInfoProvider, &CommonModuleInfo{ Enabled: true, PrimaryLicensesProperty: p.primaryLicensesProperty, }) + + ctx.SetProvider(PackageInfoProvider, PackageInfo{ + Properties: p.properties, + }) } func (p *packageModule) qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName { diff --git a/android/packaging.go b/android/packaging.go index 6146f02c9..bb1fe4e45 100644 --- a/android/packaging.go +++ b/android/packaging.go @@ -89,6 +89,8 @@ type packagingSpecGob struct { ArchType ArchType Overrides []string Owner string + RequiresFullInstall bool + FullInstallPath InstallPath Variation string } @@ -113,6 +115,8 @@ func (p *PackagingSpec) ToGob() *packagingSpecGob { ArchType: p.archType, Overrides: p.overrides.ToSlice(), Owner: p.owner, + RequiresFullInstall: p.requiresFullInstall, + FullInstallPath: p.fullInstallPath, Variation: p.variation, } } @@ -129,6 +133,8 @@ func (p *PackagingSpec) FromGob(data *packagingSpecGob) { p.archType = data.ArchType p.overrides = uniquelist.Make(data.Overrides) p.owner = data.Owner + p.requiresFullInstall = data.RequiresFullInstall + p.fullInstallPath = data.FullInstallPath p.variation = data.Variation } diff --git a/android/paths.go b/android/paths.go index 1c0321c02..977473fbd 100644 --- a/android/paths.go +++ b/android/paths.go @@ -209,6 +209,10 @@ type ModuleErrorfContext interface { var _ ModuleErrorfContext = blueprint.ModuleContext(nil) +type AddMissingDependenciesContext interface { + AddMissingDependencies([]string) +} + // reportPathError will register an error with the attached context. It // attempts ctx.ModuleErrorf for a better error message first, then falls // back to ctx.Errorf. @@ -220,7 +224,9 @@ func reportPathError(ctx PathContext, err error) { // attempts ctx.ModuleErrorf for a better error message first, then falls // back to ctx.Errorf. func ReportPathErrorf(ctx PathContext, format string, args ...interface{}) { - if mctx, ok := ctx.(ModuleErrorfContext); ok { + if mctx, ok := ctx.(AddMissingDependenciesContext); ok && ctx.Config().AllowMissingDependencies() { + mctx.AddMissingDependencies([]string{fmt.Sprintf(format, args...)}) + } else if mctx, ok := ctx.(ModuleErrorfContext); ok { mctx.ModuleErrorf(format, args...) } else if ectx, ok := ctx.(errorfContext); ok { ectx.Errorf(format, args...) @@ -229,6 +235,8 @@ func ReportPathErrorf(ctx PathContext, format string, args ...interface{}) { } } +// TODO(b/397766191): Change the signature to take ModuleProxy +// Please only access the module's internal data through providers. func pathContextName(ctx PathContext, module blueprint.Module) string { if x, ok := ctx.(interface{ ModuleName(blueprint.Module) string }); ok { return x.ModuleName(module) @@ -675,7 +683,7 @@ func getPathsFromModuleDep(ctx ModuleWithDepsPathContext, path, moduleName, tag if module == nil { return nil, missingDependencyError{[]string{moduleName}} } - if !OtherModuleProviderOrDefault(ctx, *module, CommonModuleInfoKey).Enabled { + if !OtherModulePointerProviderOrDefault(ctx, *module, CommonModuleInfoProvider).Enabled { return nil, missingDependencyError{[]string{moduleName}} } diff --git a/android/phony.go b/android/phony.go index 7bdd9d31d..99ff0aaa4 100644 --- a/android/phony.go +++ b/android/phony.go @@ -55,7 +55,7 @@ var _ SingletonMakeVarsProvider = (*phonySingleton)(nil) func (p *phonySingleton) GenerateBuildActions(ctx SingletonContext) { p.phonyMap = getSingletonPhonyMap(ctx.Config()) - ctx.VisitAllModules(func(m Module) { + ctx.VisitAllModuleProxies(func(m ModuleProxy) { if info, ok := OtherModuleProvider(ctx, m, ModulePhonyProvider); ok { for k, v := range info.Phonies { p.phonyMap[k] = append(p.phonyMap[k], v...) diff --git a/android/prebuilt.go b/android/prebuilt.go index 72735991d..1ff009bf5 100644 --- a/android/prebuilt.go +++ b/android/prebuilt.go @@ -358,7 +358,7 @@ func IsModulePreferred(module Module) bool { } func IsModulePreferredProxy(ctx OtherModuleProviderContext, module ModuleProxy) bool { - if OtherModuleProviderOrDefault(ctx, module, CommonModuleInfoKey).ReplacedByPrebuilt { + if OtherModulePointerProviderOrDefault(ctx, module, CommonModuleInfoProvider).ReplacedByPrebuilt { // A source module that has been replaced by a prebuilt counterpart. return false } @@ -397,7 +397,7 @@ func GetEmbeddedPrebuilt(module Module) *Prebuilt { // the right module. This function is only safe to call after all TransitionMutators // have run, e.g. in GenerateAndroidBuildActions. func PrebuiltGetPreferred(ctx BaseModuleContext, module Module) Module { - if !OtherModuleProviderOrDefault(ctx, module, CommonModuleInfoKey).ReplacedByPrebuilt { + if !OtherModulePointerProviderOrDefault(ctx, module, CommonModuleInfoProvider).ReplacedByPrebuilt { return module } if _, ok := OtherModuleProvider(ctx, module, PrebuiltModuleInfoProvider); ok { @@ -412,7 +412,7 @@ func PrebuiltGetPreferred(ctx BaseModuleContext, module Module) Module { if prebuiltMod != nil { return false } - if ctx.EqualModules(parent, ctx.Module()) { + if EqualModules(parent, ctx.Module()) { // First level: Only recurse if the module is found as a direct dependency. sourceModDepFound = child == module return sourceModDepFound @@ -607,11 +607,6 @@ func hideUnflaggedModules(ctx BottomUpMutatorContext, psi PrebuiltSelectionInfoM if !moduleInFamily.ExportedToMake() { continue } - // Skip for the top-level java_sdk_library_(_import). This has some special cases that need to be addressed first. - // This does not run into non-determinism because PrebuiltPostDepsMutator also has the special case - if sdkLibrary, ok := moduleInFamily.(interface{ SdkLibraryName() *string }); ok && sdkLibrary.SdkLibraryName() != nil { - continue - } if p := GetEmbeddedPrebuilt(moduleInFamily); p != nil && p.properties.UsePrebuilt { if selectedPrebuilt == nil { selectedPrebuilt = moduleInFamily @@ -638,26 +633,10 @@ func PrebuiltPostDepsMutator(ctx BottomUpMutatorContext) { if p := GetEmbeddedPrebuilt(m); p != nil { bmn, _ := m.(baseModuleName) name := bmn.BaseModuleName() - psi := PrebuiltSelectionInfoMap{} - ctx.VisitDirectDepsWithTag(AcDepTag, func(am Module) { - psi, _ = OtherModuleProvider(ctx, am, PrebuiltSelectionInfoProvider) - }) if p.properties.UsePrebuilt { if p.properties.SourceExists { ctx.ReplaceDependenciesIf(name, func(from blueprint.Module, tag blueprint.DependencyTag, to blueprint.Module) bool { - if sdkLibrary, ok := m.(interface{ SdkLibraryName() *string }); ok && sdkLibrary.SdkLibraryName() != nil { - // Do not replace deps to the top-level prebuilt java_sdk_library hook. - // This hook has been special-cased in #isSelected to be _always_ active, even in next builds - // for dexpreopt and hiddenapi processing. - // If we do not special-case this here, rdeps referring to a java_sdk_library in next builds via libs - // will get prebuilt stubs - // TODO (b/308187268): Remove this after the apexes have been added to apex_contributions - if psi.IsSelected(name) { - return false - } - } - if t, ok := tag.(ReplaceSourceWithPrebuilt); ok { return t.ReplaceSourceWithPrebuilt() } @@ -679,23 +658,13 @@ func PrebuiltPostDepsMutator(ctx BottomUpMutatorContext) { // java_sdk_library_import is a macro that creates // 1. top-level "impl" library // 2. stub libraries (suffixed with .stubs...) -// -// the impl of java_sdk_library_import is a "hook" for hiddenapi and dexpreopt processing. It does not have an impl jar, but acts as a shim -// to provide the jar deapxed from the prebuilt apex -// -// isSelected uses `all_apex_contributions` to supersede source vs prebuilts selection of the stub libraries. It does not supersede the -// selection of the top-level "impl" library so that this hook can work -// -// TODO (b/308174306) - Fix this when we need to support multiple prebuilts in main func isSelected(psi PrebuiltSelectionInfoMap, m Module) bool { if sdkLibrary, ok := m.(interface{ SdkLibraryName() *string }); ok && sdkLibrary.SdkLibraryName() != nil { sln := proptools.String(sdkLibrary.SdkLibraryName()) // This is the top-level library - // Do not supersede the existing prebuilts vs source selection mechanisms - // TODO (b/308187268): Remove this after the apexes have been added to apex_contributions if bmn, ok := m.(baseModuleName); ok && sln == bmn.BaseModuleName() { - return false + return psi.IsSelected(m.Name()) } // Stub library created by java_sdk_library_import diff --git a/android/prebuilt_build_tool.go b/android/prebuilt_build_tool.go index 17b323067..7773bf8af 100644 --- a/android/prebuilt_build_tool.go +++ b/android/prebuilt_build_tool.go @@ -84,13 +84,12 @@ func (t *prebuiltBuildTool) GenerateAndroidBuildActions(ctx ModuleContext) { t.toolPath = OptionalPathForPath(installedPath) } -func (t *prebuiltBuildTool) MakeVars(ctx MakeVarsModuleContext) { - if makeVar := String(t.properties.Export_to_make_var); makeVar != "" { - if t.Target().Os != ctx.Config().BuildOS { - return - } - ctx.StrictRaw(makeVar, t.toolPath.String()) +func (t *prebuiltBuildTool) MakeVars(ctx MakeVarsModuleContext) []ModuleMakeVarsValue { + if makeVar := String(t.properties.Export_to_make_var); makeVar != "" && + t.Target().Os == ctx.Config().BuildOS { + return []ModuleMakeVarsValue{{makeVar, t.toolPath.String()}} } + return nil } func (t *prebuiltBuildTool) HostToolPath() OptionalPath { diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go index 27a68fbe5..d31fc4fcd 100644 --- a/android/prebuilt_test.go +++ b/android/prebuilt_test.go @@ -551,6 +551,9 @@ func (s *sourceModule) GenerateAndroidBuildActions(ctx ModuleContext) { } func (s *sourceModule) Srcs() Paths { + if s.src == nil { + return nil + } return Paths{s.src} } diff --git a/android/provider.go b/android/provider.go index b48fd9148..aae93ef88 100644 --- a/android/provider.go +++ b/android/provider.go @@ -16,6 +16,12 @@ var _ OtherModuleProviderContext = BottomUpMutatorContext(nil) var _ OtherModuleProviderContext = SingletonContext(nil) var _ OtherModuleProviderContext = (*TestContext)(nil) +// ConfigAndOtherModuleProviderContext is OtherModuleProviderContext + ConfigContext +type ConfigAndOtherModuleProviderContext interface { + OtherModuleProviderContext + ConfigContext +} + // OtherModuleProvider reads the provider for the given module. If the provider has been set the value is // returned and the boolean is true. If it has not been set the zero value of the provider's type is returned // and the boolean is false. The value returned may be a deep copy of the value originally passed to SetProvider. @@ -35,6 +41,14 @@ func OtherModuleProviderOrDefault[K any](ctx OtherModuleProviderContext, module return value } +func OtherModulePointerProviderOrDefault[K *T, T any](ctx OtherModuleProviderContext, module blueprint.Module, provider blueprint.ProviderKey[K]) K { + if value, ok := OtherModuleProvider(ctx, module, provider); ok { + return value + } + var val T + return &val +} + // ModuleProviderContext is a helper interface that is a subset of ModuleContext or BottomUpMutatorContext // for use in ModuleProvider. type ModuleProviderContext interface { diff --git a/android/provider_keys.go b/android/provider_keys.go new file mode 100644 index 000000000..60b383f53 --- /dev/null +++ b/android/provider_keys.go @@ -0,0 +1,24 @@ +// Copyright 2025 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package android + +import "github.com/google/blueprint" + +// Providers of package filesystem +type AndroidDeviceInfo struct { + Main_device bool +} + +var AndroidDeviceInfoProvider = blueprint.NewProvider[AndroidDeviceInfo]() diff --git a/android/rule_builder.go b/android/rule_builder.go index db56c3f29..01fe6d8ea 100644 --- a/android/rule_builder.go +++ b/android/rule_builder.go @@ -660,12 +660,17 @@ func (r *RuleBuilder) build(name string, desc string) { } for _, c := range r.commands { for _, tool := range c.packagedTools { - command.CopyBefore = append(command.CopyBefore, &sbox_proto.Copy{ - From: proto.String(tool.srcPath.String()), - To: proto.String(sboxPathForPackagedToolRel(tool)), - Executable: proto.Bool(tool.executable), - }) - tools = append(tools, tool.srcPath) + if tool.srcPath != nil { + command.CopyBefore = append(command.CopyBefore, &sbox_proto.Copy{ + From: proto.String(tool.srcPath.String()), + To: proto.String(sboxPathForPackagedToolRel(tool)), + Executable: proto.Bool(tool.executable), + }) + tools = append(tools, tool.srcPath) + } else if tool.SymlinkTarget() == "" { + // We ignore symlinks for now, could be added later if needed + panic("Expected tool packagingSpec to either be a file or symlink") + } } } } @@ -1187,7 +1192,11 @@ func (c *RuleBuilderCommand) Text(text string) *RuleBuilderCommand { // Textf adds the specified formatted text to the command line. The text should not contain input or output paths or // the rule will not have them listed in its dependencies or outputs. func (c *RuleBuilderCommand) Textf(format string, a ...interface{}) *RuleBuilderCommand { - return c.Text(fmt.Sprintf(format, a...)) + if c.buf.Len() > 0 { + c.buf.WriteByte(' ') + } + fmt.Fprintf(&c.buf, format, a...) + return c } // Flag adds the specified raw text to the command line. The text should not contain input or output paths or the diff --git a/android/singleton.go b/android/singleton.go index a03ea74aa..e5f26842a 100644 --- a/android/singleton.go +++ b/android/singleton.go @@ -36,7 +36,7 @@ type SingletonContext interface { // ModuleVariantsFromName returns the list of module variants named `name` in the same namespace as `referer` enforcing visibility rules. // Allows generating build actions for `referer` based on the metadata for `name` deferred until the singleton context. - ModuleVariantsFromName(referer Module, name string) []Module + ModuleVariantsFromName(referer ModuleProxy, name string) []ModuleProxy otherModuleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) @@ -290,6 +290,10 @@ func (s *singletonContextAdaptor) ModuleType(module blueprint.Module) string { return s.SingletonContext.ModuleType(getWrappedModule(module)) } +func (s *singletonContextAdaptor) BlueprintFile(module blueprint.Module) string { + return s.SingletonContext.BlueprintFile(getWrappedModule(module)) +} + func (s *singletonContextAdaptor) VisitAllModulesBlueprint(visit func(blueprint.Module)) { s.SingletonContext.VisitAllModules(visit) } @@ -327,7 +331,7 @@ func (s *singletonContextAdaptor) VisitAllModuleVariants(module Module, visit fu } func (s *singletonContextAdaptor) VisitAllModuleVariantProxies(module Module, visit func(proxy ModuleProxy)) { - s.SingletonContext.VisitAllModuleVariantProxies(module, visitProxyAdaptor(visit)) + s.SingletonContext.VisitAllModuleVariantProxies(getWrappedModule(module), visitProxyAdaptor(visit)) } func (s *singletonContextAdaptor) PrimaryModule(module Module) Module { @@ -339,32 +343,30 @@ func (s *singletonContextAdaptor) PrimaryModuleProxy(module ModuleProxy) ModuleP } func (s *singletonContextAdaptor) IsFinalModule(module Module) bool { - return s.SingletonContext.IsFinalModule(module) + return s.SingletonContext.IsFinalModule(getWrappedModule(module)) } -func (s *singletonContextAdaptor) ModuleVariantsFromName(referer Module, name string) []Module { +func (s *singletonContextAdaptor) ModuleVariantsFromName(referer ModuleProxy, name string) []ModuleProxy { // get module reference for visibility enforcement - qualified := createVisibilityModuleReference(s.ModuleName(referer), s.ModuleDir(referer), referer) - - modules := s.SingletonContext.ModuleVariantsFromName(referer, name) - result := make([]Module, 0, len(modules)) - for _, m := range modules { - if module, ok := m.(Module); ok { - // enforce visibility - depName := s.ModuleName(module) - depDir := s.ModuleDir(module) - depQualified := qualifiedModuleName{depDir, depName} - // Targets are always visible to other targets in their own package. - if depQualified.pkg != qualified.name.pkg { - rule := effectiveVisibilityRules(s.Config(), depQualified) - if !rule.matches(qualified) { - s.ModuleErrorf(referer, "module %q references %q which is not visible to this module\nYou may need to add %q to its visibility", - referer.Name(), depQualified, "//"+s.ModuleDir(referer)) - continue - } + qualified := createVisibilityModuleProxyReference(s, s.ModuleName(referer), s.ModuleDir(referer), referer) + + modules := s.SingletonContext.ModuleVariantsFromName(referer.module, name) + result := make([]ModuleProxy, 0, len(modules)) + for _, module := range modules { + // enforce visibility + depName := s.ModuleName(module) + depDir := s.ModuleDir(module) + depQualified := qualifiedModuleName{depDir, depName} + // Targets are always visible to other targets in their own package. + if depQualified.pkg != qualified.name.pkg { + rule := effectiveVisibilityRules(s.Config(), depQualified) + if !rule.matches(qualified) { + s.ModuleErrorf(referer, "module %q references %q which is not visible to this module\nYou may need to add %q to its visibility", + referer.Name(), depQualified, "//"+s.ModuleDir(referer)) + continue } - result = append(result, module) } + result = append(result, ModuleProxy{module}) } return result } diff --git a/android/soong_config_modules.go b/android/soong_config_modules.go index e0b1d7cbe..a61c9d33d 100644 --- a/android/soong_config_modules.go +++ b/android/soong_config_modules.go @@ -506,6 +506,10 @@ func configModuleFactory(factory blueprint.ModuleFactory, moduleType *soongconfi conditionalProps := proptools.CloneEmptyProperties(conditionalFactoryProps) props = append(props, conditionalProps.Interface()) + if m, ok := module.(Module); ok { + m.base().baseProperties.Soong_config_base_module_type = &moduleType.BaseModuleType + } + // Regular Soong operation wraps the existing module factory with a // conditional on Soong config variables by reading the product // config variables from Make. diff --git a/android/team.go b/android/team.go index c273dc647..ad37f28c9 100644 --- a/android/team.go +++ b/android/team.go @@ -32,6 +32,12 @@ type teamProperties struct { Trendy_team_id *string `json:"trendy_team_id"` } +type TeamInfo struct { + Properties teamProperties +} + +var TeamInfoProvider = blueprint.NewProvider[TeamInfo]() + type teamModule struct { ModuleBase DefaultableModuleBase @@ -48,7 +54,11 @@ var TestOnlyProviderKey = blueprint.NewProvider[TestModuleInformation]() // Real work is done for the module that depends on us. // If needed, the team can serialize the config to json/proto file as well. -func (t *teamModule) GenerateAndroidBuildActions(ctx ModuleContext) {} +func (t *teamModule) GenerateAndroidBuildActions(ctx ModuleContext) { + SetProvider(ctx, TeamInfoProvider, TeamInfo{ + Properties: t.properties, + }) +} func (t *teamModule) TrendyTeamId(ctx ModuleContext) string { return *t.properties.Trendy_team_id diff --git a/android/test_suites.go b/android/test_suites.go index 39317ec62..9eaf78549 100644 --- a/android/test_suites.go +++ b/android/test_suites.go @@ -29,10 +29,7 @@ func testSuiteFilesFactory() Singleton { return &testSuiteFiles{} } -type testSuiteFiles struct { - robolectric []Path - ravenwood []Path -} +type testSuiteFiles struct{} type TestSuiteModule interface { Module @@ -61,51 +58,22 @@ func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) { } }) - t.robolectric = robolectricTestSuite(ctx, files["robolectric-tests"]) - ctx.Phony("robolectric-tests", t.robolectric...) - - t.ravenwood = ravenwoodTestSuite(ctx, files["ravenwood-tests"]) - ctx.Phony("ravenwood-tests", t.ravenwood...) - ctx.DistForGoal("robolectric-tests", t.robolectric...) - ctx.DistForGoal("ravenwood-tests", t.ravenwood...) -} - -func robolectricTestSuite(ctx SingletonContext, files map[string]InstallPaths) []Path { - var installedPaths InstallPaths - for _, module := range SortedKeys(files) { - installedPaths = append(installedPaths, files[module]...) - } - - outputFile := pathForPackaging(ctx, "robolectric-tests.zip") - rule := NewRuleBuilder(pctx, ctx) - rule.Command().BuiltTool("soong_zip"). - FlagWithOutput("-o ", outputFile). - FlagWithArg("-P ", "host/testcases"). - FlagWithArg("-C ", pathForTestCases(ctx).String()). - FlagWithRspFileInputList("-r ", outputFile.ReplaceExtension(ctx, "rsp"), installedPaths.Paths()). - Flag("-sha256") // necessary to save cas_uploader's time - - testList := buildTestList(ctx, "robolectric-tests_list", installedPaths) - testListZipOutputFile := pathForPackaging(ctx, "robolectric-tests_list.zip") - - rule.Command().BuiltTool("soong_zip"). - FlagWithOutput("-o ", testListZipOutputFile). - FlagWithArg("-C ", pathForPackaging(ctx).String()). - FlagWithInput("-f ", testList). - Flag("-sha256") - - rule.Build("robolectric_tests_zip", "robolectric-tests.zip") + robolectricZip, robolectrictListZip := buildTestSuite(ctx, "robolectric-tests", files["robolectric-tests"]) + ctx.Phony("robolectric-tests", robolectricZip, robolectrictListZip) + ctx.DistForGoal("robolectric-tests", robolectricZip, robolectrictListZip) - return []Path{outputFile, testListZipOutputFile} + ravenwoodZip, ravenwoodListZip := buildTestSuite(ctx, "ravenwood-tests", files["ravenwood-tests"]) + ctx.Phony("ravenwood-tests", ravenwoodZip, ravenwoodListZip) + ctx.DistForGoal("ravenwood-tests", ravenwoodZip, ravenwoodListZip) } -func ravenwoodTestSuite(ctx SingletonContext, files map[string]InstallPaths) []Path { +func buildTestSuite(ctx SingletonContext, suiteName string, files map[string]InstallPaths) (Path, Path) { var installedPaths InstallPaths for _, module := range SortedKeys(files) { installedPaths = append(installedPaths, files[module]...) } - outputFile := pathForPackaging(ctx, "ravenwood-tests.zip") + outputFile := pathForPackaging(ctx, suiteName+".zip") rule := NewRuleBuilder(pctx, ctx) rule.Command().BuiltTool("soong_zip"). FlagWithOutput("-o ", outputFile). @@ -114,8 +82,8 @@ func ravenwoodTestSuite(ctx SingletonContext, files map[string]InstallPaths) []P FlagWithRspFileInputList("-r ", outputFile.ReplaceExtension(ctx, "rsp"), installedPaths.Paths()). Flag("-sha256") // necessary to save cas_uploader's time - testList := buildTestList(ctx, "ravenwood-tests_list", installedPaths) - testListZipOutputFile := pathForPackaging(ctx, "ravenwood-tests_list.zip") + testList := buildTestList(ctx, suiteName+"_list", installedPaths) + testListZipOutputFile := pathForPackaging(ctx, suiteName+"_list.zip") rule.Command().BuiltTool("soong_zip"). FlagWithOutput("-o ", testListZipOutputFile). @@ -123,9 +91,9 @@ func ravenwoodTestSuite(ctx SingletonContext, files map[string]InstallPaths) []P FlagWithInput("-f ", testList). Flag("-sha256") - rule.Build("ravenwood_tests_zip", "ravenwood-tests.zip") + rule.Build(strings.ReplaceAll(suiteName, "-", "_")+"_zip", suiteName+".zip") - return []Path{outputFile, testListZipOutputFile} + return outputFile, testListZipOutputFile } func buildTestList(ctx SingletonContext, listFile string, installedPaths InstallPaths) Path { diff --git a/android/test_suites_test.go b/android/test_suites_test.go index dda93297a..03aa42413 100644 --- a/android/test_suites_test.go +++ b/android/test_suites_test.go @@ -108,7 +108,8 @@ var prepareForFakeTestSuite = GroupFixturePreparers( func (f *fake_module) GenerateAndroidBuildActions(ctx ModuleContext) { for _, output := range f.props.Outputs { - ctx.InstallFile(pathForTestCases(ctx), output, nil) + f := PathForModuleOut(ctx, output) + ctx.InstallFile(pathForTestCases(ctx), output, f) } SetProvider(ctx, TestSuiteInfoProvider, TestSuiteInfo{ diff --git a/android/testing.go b/android/testing.go index 1962fdea5..d2949ec8e 100644 --- a/android/testing.go +++ b/android/testing.go @@ -1197,11 +1197,11 @@ func AndroidMkInfoForTest(t *testing.T, ctx *TestContext, mod Module) *AndroidMk info := OtherModuleProviderOrDefault(ctx, mod, AndroidMkInfoProvider) aconfigUpdateAndroidMkInfos(ctx, mod, info) - commonInfo, _ := OtherModuleProvider(ctx, mod, CommonModuleInfoKey) - info.PrimaryInfo.fillInEntries(ctx, mod, &commonInfo) + commonInfo := OtherModulePointerProviderOrDefault(ctx, mod, CommonModuleInfoProvider) + info.PrimaryInfo.fillInEntries(ctx, mod, commonInfo) if len(info.ExtraInfo) > 0 { for _, ei := range info.ExtraInfo { - ei.fillInEntries(ctx, mod, &commonInfo) + ei.fillInEntries(ctx, mod, commonInfo) } } diff --git a/android/variable.go b/android/variable.go index 81999f340..3d5a6ae12 100644 --- a/android/variable.go +++ b/android/variable.go @@ -65,12 +65,6 @@ type variableProperties struct { Enabled proptools.Configurable[bool] `android:"arch_variant,replace_instead_of_append"` } `android:"arch_variant"` - // similar to `Unbundled_build`, but `Always_use_prebuilt_sdks` means that it uses prebuilt - // sdk specifically. - Always_use_prebuilt_sdks struct { - Enabled proptools.Configurable[bool] `android:"arch_variant,replace_instead_of_append"` - } `android:"arch_variant"` - Malloc_low_memory struct { Cflags []string `android:"arch_variant"` Shared_libs []string `android:"arch_variant"` @@ -216,6 +210,7 @@ type ProductVariables struct { Platform_display_version_name *string `json:",omitempty"` Platform_version_name *string `json:",omitempty"` Platform_sdk_version *int `json:",omitempty"` + Platform_sdk_minor_version *int `json:",omitempty"` Platform_sdk_codename *string `json:",omitempty"` Platform_sdk_version_or_codename *string `json:",omitempty"` Platform_sdk_final *bool `json:",omitempty"` @@ -553,6 +548,8 @@ type ProductVariables struct { OdmManifestFiles []string `json:",omitempty"` UseSoongNoticeXML *bool `json:",omitempty"` + + StripByDefault *bool `json:",omitempty"` } type PartitionQualifiedVariablesType struct { @@ -653,6 +650,7 @@ type PartitionVariables struct { ProductUseDynamicPartitions bool `json:",omitempty"` ProductRetrofitDynamicPartitions bool `json:",omitempty"` ProductBuildSuperPartition bool `json:",omitempty"` + BuildingSuperEmptyImage bool `json:",omitempty"` BoardSuperPartitionSize string `json:",omitempty"` BoardSuperPartitionMetadataDevice string `json:",omitempty"` BoardSuperPartitionBlockDevices []string `json:",omitempty"` @@ -667,6 +665,7 @@ type PartitionVariables struct { AbOtaPartitions []string `json:",omitempty"` AbOtaKeys []string `json:",omitempty"` AbOtaPostInstallConfig []string `json:",omitempty"` + BoardSuperImageInUpdatePackage bool `json:",omitempty"` // Avb (android verified boot) stuff BoardAvbEnable bool `json:",omitempty"` @@ -715,6 +714,8 @@ type PartitionVariables struct { ProductFsCompression string `json:",omitempty"` ReleaseToolsExtensionDir string `json:",omitempty"` + + BoardFastbootInfoFile string `json:",omitempty"` } func boolPtr(v bool) *bool { diff --git a/android/visibility.go b/android/visibility.go index 4837c7d4b..915368710 100644 --- a/android/visibility.go +++ b/android/visibility.go @@ -58,15 +58,29 @@ const ( var visibilityRuleRegexp = regexp.MustCompile(visibilityRulePattern) type visibilityModuleReference struct { - name qualifiedModuleName - module Module + name qualifiedModuleName + partitionType *string } func createVisibilityModuleReference(name, dir string, module Module) visibilityModuleReference { - return visibilityModuleReference{ - name: createQualifiedModuleName(name, dir), - module: module, + vis := visibilityModuleReference{ + name: createQualifiedModuleName(name, dir), } + if m, ok := module.(PartitionTypeInterface); ok { + pt := m.PartitionType() + vis.partitionType = &pt + } + return vis +} + +func createVisibilityModuleProxyReference(ctx OtherModuleProviderContext, name, dir string, module ModuleProxy) visibilityModuleReference { + vis := visibilityModuleReference{ + name: createQualifiedModuleName(name, dir), + } + if m, ok := OtherModuleProvider(ctx, module, PartitionTypeInfoProvider); ok { + vis.partitionType = &m.PartitionType + } + return vis } // A visibility rule is associated with a module and determines which other modules it is visible @@ -222,9 +236,17 @@ type PartitionTypeInterface interface { PartitionType() string } +type PartitionTypeInfo struct { + // Identifies which partition this is for //visibility:any_system_image (and others) visibility + // checks, and will be used in the future for API surface checks. + PartitionType string +} + +var PartitionTypeInfoProvider = blueprint.NewProvider[PartitionTypeInfo]() + func (r anyPartitionRule) matches(m visibilityModuleReference) bool { - if m2, ok := m.module.(PartitionTypeInterface); ok { - return m2.PartitionType() == r.partitionType + if m.partitionType != nil { + return *m.partitionType == r.partitionType } return false } @@ -529,7 +551,7 @@ func visibilityRuleEnforcer(ctx BottomUpMutatorContext) { rule := effectiveVisibilityRules(ctx.Config(), depQualified) if !rule.matches(qualified) { - ctx.ModuleErrorf("depends on %s which is not visible to this module\nYou may need to add %q to its visibility, %#v", depQualified, "//"+ctx.ModuleDir(), ctx.OtherModuleDependencyTag(dep)) + ctx.ModuleErrorf("depends on %s which is not visible to this module\nYou may need to add %q to its visibility", depQualified, "//"+ctx.ModuleDir()) } }) } @@ -647,42 +669,6 @@ func (v *visibilityRuleSet) Strings() []string { return v.rules } -// Get the effective visibility rules, i.e. the actual rules that affect the visibility of the -// property irrespective of where they are defined. -// -// Includes visibility rules specified by package default_visibility and/or on defaults. -// Short hand forms, e.g. //:__subpackages__ are replaced with their full form, e.g. -// //package/containing/rule:__subpackages__. -func EffectiveVisibilityRules(ctx BaseModuleContext, module Module) VisibilityRuleSet { - moduleName := ctx.OtherModuleName(module) - dir := ctx.OtherModuleDir(module) - qualified := qualifiedModuleName{dir, moduleName} - - rule := effectiveVisibilityRules(ctx.Config(), qualified) - - currentModule := createVisibilityModuleReference(moduleName, dir, module) - - // Modules are implicitly visible to other modules in the same package, - // without checking the visibility rules. Here we need to add that visibility - // explicitly. - if !rule.matches(currentModule) { - if len(rule) == 1 { - if _, ok := rule[0].(privateRule); ok { - // If the rule is //visibility:private we can't append another - // visibility to it. Semantically we need to convert it to a package - // visibility rule for the location where the result is used, but since - // modules are implicitly visible within the package we get the same - // result without any rule at all, so just make it an empty list to be - // appended below. - rule = nil - } - } - rule = append(rule, packageRule{dir}) - } - - return &visibilityRuleSet{rule.Strings()} -} - // Clear the default visibility properties so they can be replaced. func clearVisibilityProperties(module Module) { module.base().visibilityPropertyInfo = nil diff --git a/android/visibility_test.go b/android/visibility_test.go index 277be0f65..4acaa02e5 100644 --- a/android/visibility_test.go +++ b/android/visibility_test.go @@ -2112,7 +2112,10 @@ func (j *mockFilesystemModule) DepsMutator(ctx BottomUpMutatorContext) { ctx.AddVariationDependencies(nil, dependencyTag{name: "mockdeps"}, j.properties.Deps...) } -func (p *mockFilesystemModule) GenerateAndroidBuildActions(ModuleContext) { +func (p *mockFilesystemModule) GenerateAndroidBuildActions(ctx ModuleContext) { + SetProvider(ctx, PartitionTypeInfoProvider, PartitionTypeInfo{ + PartitionType: p.PartitionType(), + }) } func (p *mockFilesystemModule) PartitionType() string { |