diff options
86 files changed, 1960 insertions, 1028 deletions
diff --git a/Android.bp b/Android.bp index 523f55c4b..337545bce 100644 --- a/Android.bp +++ b/Android.bp @@ -150,10 +150,11 @@ cc_defaults { arch: { arm64: { cflags: [ - // Prevent the compiler from optimizing code using SVE, as the - // baremetal environment might not have configured the hardware. - "-Xclang -target-feature", - "-Xclang -sve", + // Override the global -march= flag (as set by TARGET_ARCH_VARIANT) + // and explicitly use the baseline architecture (ARMv8-A is the first + // version with 64-bit support) to avoid emitting potentially + // unsupported instructions. + "-march=armv8-a", ], }, }, diff --git a/android/Android.bp b/android/Android.bp index aef18fec0..1cc7ffe1d 100644 --- a/android/Android.bp +++ b/android/Android.bp @@ -112,6 +112,7 @@ bootstrap_go_package { "soong_config_modules.go", "team.go", "test_asserts.go", + "test_mapping_zip.go", "test_suites.go", "testing.go", "transition.go", diff --git a/android/aconfig_providers.go b/android/aconfig_providers.go index b698d24a5..205b85590 100644 --- a/android/aconfig_providers.go +++ b/android/aconfig_providers.go @@ -136,7 +136,7 @@ func aconfigUpdateAndroidBuildActions(ctx ModuleContext) { AconfigFiles: mergedAconfigFiles, ModeInfos: mergedModeInfos, }) - ctx.setAconfigPaths(getAconfigFilePaths(ctx.Module().base(), mergedAconfigFiles)) + ctx.setAconfigPaths(getAconfigFilePaths(getContainer(ctx.Module()), mergedAconfigFiles)) } } @@ -147,7 +147,8 @@ func aconfigUpdateAndroidMkData(ctx fillInEntriesContext, mod Module, data *Andr return } data.Extra = append(data.Extra, func(w io.Writer, outputFile Path) { - AndroidMkEmitAssignList(w, "LOCAL_ACONFIG_FILES", getAconfigFilePaths(mod.base(), info.AconfigFiles).Strings()) + AndroidMkEmitAssignList(w, "LOCAL_ACONFIG_FILES", getAconfigFilePaths( + getContainerUsingProviders(ctx, mod), info.AconfigFiles).Strings()) }) // If there is a Custom writer, it needs to support this provider. if data.Custom != nil { @@ -179,24 +180,29 @@ func aconfigUpdateAndroidMkEntries(ctx fillInEntriesContext, mod Module, entries // All of the files in the module potentially depend on the aconfig flag values. for idx, _ := range *entries { (*entries)[idx].ExtraEntries = append((*entries)[idx].ExtraEntries, - func(ctx AndroidMkExtraEntriesContext, entries *AndroidMkEntries) { - entries.AddPaths("LOCAL_ACONFIG_FILES", getAconfigFilePaths(mod.base(), info.AconfigFiles)) + func(_ AndroidMkExtraEntriesContext, entries *AndroidMkEntries) { + entries.AddPaths("LOCAL_ACONFIG_FILES", getAconfigFilePaths( + getContainerUsingProviders(ctx, mod), info.AconfigFiles)) }, ) } } +// TODO(b/397766191): Change the signature to take ModuleProxy +// Please only access the module's internal data through providers. func aconfigUpdateAndroidMkInfos(ctx fillInEntriesContext, mod Module, infos *AndroidMkProviderInfo) { info, ok := OtherModuleProvider(ctx, mod, AconfigPropagatingProviderKey) if !ok || len(info.AconfigFiles) == 0 { return } // All of the files in the module potentially depend on the aconfig flag values. - infos.PrimaryInfo.AddPaths("LOCAL_ACONFIG_FILES", getAconfigFilePaths(mod.base(), info.AconfigFiles)) + infos.PrimaryInfo.AddPaths("LOCAL_ACONFIG_FILES", getAconfigFilePaths( + getContainerUsingProviders(ctx, mod), info.AconfigFiles)) if len(infos.ExtraInfo) > 0 { for _, ei := range (*infos).ExtraInfo { - ei.AddPaths("LOCAL_ACONFIG_FILES", getAconfigFilePaths(mod.base(), info.AconfigFiles)) + ei.AddPaths("LOCAL_ACONFIG_FILES", getAconfigFilePaths( + getContainerUsingProviders(ctx, mod), info.AconfigFiles)) } } } @@ -224,19 +230,39 @@ func mergeAconfigFiles(ctx ModuleContext, container string, inputs Paths, genera return Paths{output} } -func getAconfigFilePaths(m *ModuleBase, aconfigFiles map[string]Paths) (paths Paths) { - // TODO(b/311155208): The default container here should be system. +func getContainer(m Module) string { container := "system" + base := m.base() + if base.SocSpecific() { + container = "vendor" + } else if base.ProductSpecific() { + container = "product" + } else if base.SystemExtSpecific() { + // system_ext and system partitions should be treated as one container + container = "system" + } - if m.SocSpecific() { + return container +} + +// TODO(b/397766191): Change the signature to take ModuleProxy +// Please only access the module's internal data through providers. +func getContainerUsingProviders(ctx OtherModuleProviderContext, m Module) string { + container := "system" + commonInfo, _ := OtherModuleProvider(ctx, m, CommonModuleInfoKey) + if commonInfo.Vendor || commonInfo.Proprietary || commonInfo.SocSpecific { container = "vendor" - } else if m.ProductSpecific() { + } else if commonInfo.ProductSpecific { container = "product" - } else if m.SystemExtSpecific() { + } else if commonInfo.SystemExtSpecific { // system_ext and system partitions should be treated as one container container = "system" } + return container +} + +func getAconfigFilePaths(container string, aconfigFiles map[string]Paths) (paths Paths) { paths = append(paths, aconfigFiles[container]...) if container == "system" { // TODO(b/311155208): Once the default container is system, we can drop this. diff --git a/android/androidmk.go b/android/androidmk.go index 7d6b05673..d9d78f349 100644 --- a/android/androidmk.go +++ b/android/androidmk.go @@ -165,7 +165,7 @@ type AndroidMkExtraEntriesContext interface { type androidMkExtraEntriesContext struct { ctx fillInEntriesContext - mod blueprint.Module + mod Module } func (a *androidMkExtraEntriesContext) Provider(provider blueprint.AnyProviderKey) (any, bool) { @@ -352,8 +352,8 @@ func (d *distCopies) Strings() (ret []string) { } // Compute the contributions that the module makes to the dist. -func (a *AndroidMkEntries) getDistContributions(mod blueprint.Module) *distContributions { - amod := mod.(Module).base() +func (a *AndroidMkEntries) getDistContributions(mod Module) *distContributions { + amod := mod.base() name := amod.BaseModuleName() // Collate the set of associated tag/paths available for copying to the dist. @@ -390,7 +390,7 @@ func (a *AndroidMkEntries) getDistContributions(mod blueprint.Module) *distContr // Collate the contributions this module makes to the dist. distContributions := &distContributions{} - if !exemptFromRequiredApplicableLicensesProperty(mod.(Module)) { + if !exemptFromRequiredApplicableLicensesProperty(mod) { distContributions.licenseMetadataFile = info.LicenseMetadataFile } @@ -501,7 +501,7 @@ func generateDistContributionsForMake(distContributions *distContributions) []st // Compute the list of Make strings to declare phony goals and dist-for-goals // calls from the module's dist and dists properties. -func (a *AndroidMkEntries) GetDistForGoals(mod blueprint.Module) []string { +func (a *AndroidMkEntries) GetDistForGoals(mod Module) []string { distContributions := a.getDistContributions(mod) if distContributions == nil { return nil @@ -522,11 +522,10 @@ type fillInEntriesContext interface { HasMutatorFinished(mutatorName string) bool } -func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint.Module) { +func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod Module) { a.entryContext = ctx a.EntryMap = make(map[string][]string) - amod := mod.(Module) - base := amod.base() + base := mod.base() name := base.BaseModuleName() if a.OverrideName != "" { name = a.OverrideName @@ -535,10 +534,10 @@ func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint if a.Include == "" { a.Include = "$(BUILD_PREBUILT)" } - a.Required = append(a.Required, amod.RequiredModuleNames(ctx)...) - a.Required = append(a.Required, amod.VintfFragmentModuleNames(ctx)...) - a.Host_required = append(a.Host_required, amod.HostRequiredModuleNames()...) - a.Target_required = append(a.Target_required, amod.TargetRequiredModuleNames()...) + a.Required = append(a.Required, mod.RequiredModuleNames(ctx)...) + a.Required = append(a.Required, mod.VintfFragmentModuleNames(ctx)...) + a.Host_required = append(a.Host_required, mod.HostRequiredModuleNames()...) + a.Target_required = append(a.Target_required, mod.TargetRequiredModuleNames()...) for _, distString := range a.GetDistForGoals(mod) { fmt.Fprintln(&a.header, distString) @@ -554,7 +553,7 @@ func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint a.AddStrings("LOCAL_REQUIRED_MODULES", a.Required...) a.AddStrings("LOCAL_HOST_REQUIRED_MODULES", a.Host_required...) a.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", a.Target_required...) - a.AddStrings("LOCAL_SOONG_MODULE_TYPE", ctx.ModuleType(amod)) + a.AddStrings("LOCAL_SOONG_MODULE_TYPE", ctx.ModuleType(mod)) // If the install rule was generated by Soong tell Make about it. info := OtherModuleProviderOrDefault(ctx, mod, InstallFilesProvider) @@ -718,10 +717,10 @@ func AndroidMkSingleton() Singleton { type androidMkSingleton struct{} -func allModulesSorted(ctx SingletonContext) []blueprint.Module { - var allModules []blueprint.Module +func allModulesSorted(ctx SingletonContext) []Module { + var allModules []Module - ctx.VisitAllModulesBlueprint(func(module blueprint.Module) { + ctx.VisitAllModules(func(module Module) { allModules = append(allModules, module) }) @@ -776,20 +775,11 @@ func (so *soongOnlyAndroidMkSingleton) GenerateBuildActions(ctx SingletonContext // In soong-only mode, we don't do most of the androidmk stuff. But disted files are still largely // defined through the androidmk mechanisms, so this function is an alternate implementation of // the androidmk singleton that just focuses on getting the dist contributions -func (so *soongOnlyAndroidMkSingleton) soongOnlyBuildActions(ctx SingletonContext, mods []blueprint.Module) { +// TODO(b/397766191): Change the signature to take ModuleProxy +// Please only access the module's internal data through providers. +func (so *soongOnlyAndroidMkSingleton) soongOnlyBuildActions(ctx SingletonContext, mods []Module) { allDistContributions, moduleInfoJSONs := getSoongOnlyDataFromMods(ctx, mods) - for _, provider := range append(makeVarsInitProviders, *getSingletonMakevarsProviders(ctx.Config())...) { - mctx := &makeVarsContext{ - SingletonContext: ctx, - pctx: provider.pctx, - } - provider.call(mctx) - if contribution := distsToDistContributions(mctx.dists); contribution != nil { - allDistContributions = append(allDistContributions, *contribution) - } - } - singletonDists := getSingletonDists(ctx.Config()) singletonDists.lock.Lock() if contribution := distsToDistContributions(singletonDists.dists); contribution != nil { @@ -897,7 +887,7 @@ func distsToDistContributions(dists []dist) *distContributions { // getSoongOnlyDataFromMods gathers data from the given modules needed in soong-only builds. // Currently, this is the dist contributions, and the module-info.json contents. -func getSoongOnlyDataFromMods(ctx fillInEntriesContext, mods []blueprint.Module) ([]distContributions, []*ModuleInfoJSON) { +func getSoongOnlyDataFromMods(ctx fillInEntriesContext, mods []Module) ([]distContributions, []*ModuleInfoJSON) { var allDistContributions []distContributions var moduleInfoJSONs []*ModuleInfoJSON for _, mod := range mods { @@ -907,28 +897,29 @@ func getSoongOnlyDataFromMods(ctx fillInEntriesContext, mods []blueprint.Module) } } - if amod, ok := mod.(Module); ok && shouldSkipAndroidMkProcessing(ctx, amod.base()) { + commonInfo, _ := OtherModuleProvider(ctx, mod, CommonModuleInfoKey) + 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) + 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); contribution != nil { + if contribution := info.PrimaryInfo.getDistContributions(ctx, mod, &commonInfo); contribution != nil { allDistContributions = append(allDistContributions, *contribution) } for _, ei := range info.ExtraInfo { - ei.fillInEntries(ctx, mod) + ei.fillInEntries(ctx, mod, &commonInfo) if ei.disabled() { continue } - if contribution := ei.getDistContributions(ctx, mod); contribution != nil { + if contribution := ei.getDistContributions(ctx, mod, &commonInfo); contribution != nil { allDistContributions = append(allDistContributions, *contribution) } } @@ -966,37 +957,12 @@ func getSoongOnlyDataFromMods(ctx fillInEntriesContext, mods []blueprint.Module) } } } - if x, ok := mod.(ModuleMakeVarsProvider); ok { - mctx := &makeVarsContext{ - SingletonContext: ctx.(SingletonContext), - config: ctx.Config(), - pctx: pctx, - } - if !x.Enabled(ctx) { - continue - } - x.MakeVars(mctx) - if contribution := distsToDistContributions(mctx.dists); contribution != nil { - allDistContributions = append(allDistContributions, *contribution) - } - } - if x, ok := mod.(SingletonMakeVarsProvider); ok { - mctx := &makeVarsContext{ - SingletonContext: ctx.(SingletonContext), - config: ctx.Config(), - pctx: pctx, - } - x.MakeVars(mctx) - if contribution := distsToDistContributions(mctx.dists); contribution != nil { - allDistContributions = append(allDistContributions, *contribution) - } - } } } return allDistContributions, moduleInfoJSONs } -func translateAndroidMk(ctx SingletonContext, absMkFile string, moduleInfoJSONPath WritablePath, mods []blueprint.Module) error { +func translateAndroidMk(ctx SingletonContext, absMkFile string, moduleInfoJSONPath WritablePath, mods []Module) error { buf := &bytes.Buffer{} var moduleInfoJSONs []*ModuleInfoJSON @@ -1011,8 +977,8 @@ func translateAndroidMk(ctx SingletonContext, absMkFile string, moduleInfoJSONPa return err } - if amod, ok := mod.(Module); ok && ctx.PrimaryModule(amod) == amod { - typeStats[ctx.ModuleType(amod)] += 1 + if ctx.PrimaryModule(mod) == mod { + typeStats[ctx.ModuleType(mod)] += 1 } } @@ -1056,7 +1022,7 @@ func writeModuleInfoJSON(ctx SingletonContext, moduleInfoJSONs []*ModuleInfoJSON return nil } -func translateAndroidMkModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON, mod blueprint.Module) error { +func translateAndroidMkModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON, mod Module) error { defer func() { if r := recover(); r != nil { panic(fmt.Errorf("%s in translateAndroidMkModule for module %s variant %s", @@ -1087,7 +1053,7 @@ func translateAndroidMkModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs return err } -func (data *AndroidMkData) fillInData(ctx fillInEntriesContext, mod blueprint.Module) { +func (data *AndroidMkData) fillInData(ctx fillInEntriesContext, mod Module) { // Get the preamble content through AndroidMkEntries logic. data.Entries = AndroidMkEntries{ Class: data.Class, @@ -1110,9 +1076,9 @@ func (data *AndroidMkData) fillInData(ctx fillInEntriesContext, mod blueprint.Mo // A support func for the deprecated AndroidMkDataProvider interface. Use AndroidMkEntryProvider // instead. func translateAndroidModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON, - mod blueprint.Module, provider AndroidMkDataProvider) error { + mod Module, provider AndroidMkDataProvider) error { - amod := mod.(Module).base() + amod := mod.base() if shouldSkipAndroidMkProcessing(ctx, amod) { return nil } @@ -1124,7 +1090,7 @@ func translateAndroidModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs * } data.fillInData(ctx, mod) - aconfigUpdateAndroidMkData(ctx, mod.(Module), &data) + aconfigUpdateAndroidMkData(ctx, mod, &data) prefix := "" if amod.ArchSpecific() { @@ -1205,13 +1171,13 @@ func WriteAndroidMkData(w io.Writer, data AndroidMkData) { } func translateAndroidMkEntriesModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON, - mod blueprint.Module, provider AndroidMkEntriesProvider) error { - if shouldSkipAndroidMkProcessing(ctx, mod.(Module).base()) { + mod Module, provider AndroidMkEntriesProvider) error { + if shouldSkipAndroidMkProcessing(ctx, mod.base()) { return nil } entriesList := provider.AndroidMkEntries() - aconfigUpdateAndroidMkEntries(ctx, mod.(Module), &entriesList) + aconfigUpdateAndroidMkEntries(ctx, mod, &entriesList) moduleInfoJSON, providesModuleInfoJSON := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider) @@ -1370,23 +1336,26 @@ type AndroidMkProviderInfoProducer interface { // TODO: rename it to AndroidMkEntriesProvider after AndroidMkEntriesProvider interface is gone. var AndroidMkInfoProvider = blueprint.NewProvider[*AndroidMkProviderInfo]() +// TODO(b/397766191): Change the signature to take ModuleProxy +// Please only access the module's internal data through providers. func translateAndroidMkEntriesInfoModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON, - mod blueprint.Module, providerInfo *AndroidMkProviderInfo) error { - if shouldSkipAndroidMkProcessing(ctx, mod.(Module).base()) { + mod Module, providerInfo *AndroidMkProviderInfo) error { + commonInfo, _ := OtherModuleProvider(ctx, mod, CommonModuleInfoKey) + if commonInfo.SkipAndroidMkProcessing { return nil } // Deep copy the provider info since we need to modify the info later info := deepCopyAndroidMkProviderInfo(providerInfo) - aconfigUpdateAndroidMkInfos(ctx, mod.(Module), &info) + aconfigUpdateAndroidMkInfos(ctx, mod, &info) // Any new or special cases here need review to verify correct propagation of license information. - info.PrimaryInfo.fillInEntries(ctx, mod) + info.PrimaryInfo.fillInEntries(ctx, mod, &commonInfo) info.PrimaryInfo.write(w) if len(info.ExtraInfo) > 0 { for _, ei := range info.ExtraInfo { - ei.fillInEntries(ctx, mod) + ei.fillInEntries(ctx, mod, &commonInfo) ei.write(w) } } @@ -1515,14 +1484,14 @@ func (a *AndroidMkInfo) AddCompatibilityTestSuites(suites ...string) { a.AddStrings("LOCAL_COMPATIBILITY_SUITE", suites...) } -func (a *AndroidMkInfo) fillInEntries(ctx fillInEntriesContext, mod blueprint.Module) { +// TODO(b/397766191): Change the signature to take ModuleProxy +// Please only access the module's internal data through providers. +func (a *AndroidMkInfo) fillInEntries(ctx fillInEntriesContext, mod Module, commonInfo *CommonModuleInfo) { helperInfo := AndroidMkInfo{ EntryMap: make(map[string][]string), } - amod := mod.(Module) - base := amod.base() - name := base.BaseModuleName() + name := commonInfo.BaseModuleName if a.OverrideName != "" { name = a.OverrideName } @@ -1530,16 +1499,16 @@ func (a *AndroidMkInfo) fillInEntries(ctx fillInEntriesContext, mod blueprint.Mo if a.Include == "" { a.Include = "$(BUILD_PREBUILT)" } - a.Required = append(a.Required, amod.RequiredModuleNames(ctx)...) - a.Required = append(a.Required, amod.VintfFragmentModuleNames(ctx)...) - a.Host_required = append(a.Host_required, amod.HostRequiredModuleNames()...) - a.Target_required = append(a.Target_required, amod.TargetRequiredModuleNames()...) + a.Required = append(a.Required, commonInfo.RequiredModuleNames...) + a.Required = append(a.Required, commonInfo.VintfFragmentModuleNames...) + 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) { + for _, distString := range a.GetDistForGoals(ctx, mod, commonInfo) { a.HeaderStrings = append(a.HeaderStrings, distString) } - a.HeaderStrings = append(a.HeaderStrings, fmt.Sprintf("\ninclude $(CLEAR_VARS) # type: %s, name: %s, variant: %s", ctx.ModuleType(mod), base.BaseModuleName(), ctx.ModuleSubDir(mod))) + a.HeaderStrings = append(a.HeaderStrings, fmt.Sprintf("\ninclude $(CLEAR_VARS) # type: %s, name: %s, variant: %s", ctx.ModuleType(mod), commonInfo.BaseModuleName, ctx.ModuleSubDir(mod))) // Collect make variable assignment entries. helperInfo.SetString("LOCAL_PATH", ctx.ModuleDir(mod)) @@ -1549,7 +1518,7 @@ func (a *AndroidMkInfo) fillInEntries(ctx fillInEntriesContext, mod blueprint.Mo helperInfo.AddStrings("LOCAL_REQUIRED_MODULES", a.Required...) helperInfo.AddStrings("LOCAL_HOST_REQUIRED_MODULES", a.Host_required...) helperInfo.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", a.Target_required...) - helperInfo.AddStrings("LOCAL_SOONG_MODULE_TYPE", ctx.ModuleType(amod)) + helperInfo.AddStrings("LOCAL_SOONG_MODULE_TYPE", ctx.ModuleType(mod)) // If the install rule was generated by Soong tell Make about it. info := OtherModuleProviderOrDefault(ctx, mod, InstallFilesProvider) @@ -1564,7 +1533,7 @@ func (a *AndroidMkInfo) fillInEntries(ctx fillInEntriesContext, mod blueprint.Mo // Soong may not have generated the install rule also when `no_full_install: true`. // Mark this module as uninstallable in order to prevent Make from creating an // install rule there. - helperInfo.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", proptools.Bool(base.commonProperties.No_full_install)) + helperInfo.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", commonInfo.NoFullInstall) } if info.UncheckedModule { @@ -1579,31 +1548,31 @@ func (a *AndroidMkInfo) fillInEntries(ctx fillInEntriesContext, mod blueprint.Mo helperInfo.AddStrings("LOCAL_TEST_DATA", androidMkDataPaths(info.TestData)...) } - if am, ok := mod.(ApexModule); ok { - helperInfo.SetBoolIfTrue("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", am.NotAvailableForPlatform()) + if commonInfo.IsApexModule { + helperInfo.SetBoolIfTrue("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", commonInfo.NotAvailableForPlatform) } - archStr := base.Arch().ArchType.String() + archStr := commonInfo.Target.Arch.ArchType.String() host := false - switch base.Os().Class { + switch commonInfo.Target.Os.Class { case Host: - if base.Target().HostCross { + if commonInfo.Target.HostCross { // Make cannot identify LOCAL_MODULE_HOST_CROSS_ARCH:= common. - if base.Arch().ArchType != Common { + if commonInfo.Target.Arch.ArchType != Common { helperInfo.SetString("LOCAL_MODULE_HOST_CROSS_ARCH", archStr) } } else { // Make cannot identify LOCAL_MODULE_HOST_ARCH:= common. - if base.Arch().ArchType != Common { + if commonInfo.Target.Arch.ArchType != Common { helperInfo.SetString("LOCAL_MODULE_HOST_ARCH", archStr) } } host = true case Device: // Make cannot identify LOCAL_MODULE_TARGET_ARCH:= common. - if base.Arch().ArchType != Common { - if base.Target().NativeBridge { - hostArchStr := base.Target().NativeBridgeHostArchName + if commonInfo.Target.Arch.ArchType != Common { + if commonInfo.Target.NativeBridge { + hostArchStr := commonInfo.Target.NativeBridgeHostArchName if hostArchStr != "" { helperInfo.SetString("LOCAL_MODULE_TARGET_ARCH", hostArchStr) } @@ -1612,27 +1581,28 @@ func (a *AndroidMkInfo) fillInEntries(ctx fillInEntriesContext, mod blueprint.Mo } } - if !base.InVendorRamdisk() { + if !commonInfo.InVendorRamdisk { helperInfo.AddPaths("LOCAL_FULL_INIT_RC", info.InitRcPaths) } if len(info.VintfFragmentsPaths) > 0 { helperInfo.AddPaths("LOCAL_FULL_VINTF_FRAGMENTS", info.VintfFragmentsPaths) } - helperInfo.SetBoolIfTrue("LOCAL_PROPRIETARY_MODULE", Bool(base.commonProperties.Proprietary)) - if Bool(base.commonProperties.Vendor) || Bool(base.commonProperties.Soc_specific) { + helperInfo.SetBoolIfTrue("LOCAL_PROPRIETARY_MODULE", commonInfo.Proprietary) + if commonInfo.Vendor || commonInfo.SocSpecific { helperInfo.SetString("LOCAL_VENDOR_MODULE", "true") } - helperInfo.SetBoolIfTrue("LOCAL_ODM_MODULE", Bool(base.commonProperties.Device_specific)) - helperInfo.SetBoolIfTrue("LOCAL_PRODUCT_MODULE", Bool(base.commonProperties.Product_specific)) - helperInfo.SetBoolIfTrue("LOCAL_SYSTEM_EXT_MODULE", Bool(base.commonProperties.System_ext_specific)) - if base.commonProperties.Owner != nil { - helperInfo.SetString("LOCAL_MODULE_OWNER", *base.commonProperties.Owner) + helperInfo.SetBoolIfTrue("LOCAL_ODM_MODULE", commonInfo.DeviceSpecific) + helperInfo.SetBoolIfTrue("LOCAL_PRODUCT_MODULE", commonInfo.ProductSpecific) + helperInfo.SetBoolIfTrue("LOCAL_SYSTEM_EXT_MODULE", commonInfo.SystemExtSpecific) + if commonInfo.Owner != "" { + helperInfo.SetString("LOCAL_MODULE_OWNER", commonInfo.Owner) } } if host { - makeOs := base.Os().String() - if base.Os() == Linux || base.Os() == LinuxBionic || base.Os() == LinuxMusl { + os := commonInfo.Target.Os + makeOs := os.String() + if os == Linux || os == LinuxBionic || os == LinuxMusl { makeOs = "linux" } helperInfo.SetString("LOCAL_MODULE_HOST_OS", makeOs) @@ -1690,8 +1660,10 @@ func (a *AndroidMkInfo) write(w io.Writer) { // Compute the list of Make strings to declare phony goals and dist-for-goals // calls from the module's dist and dists properties. -func (a *AndroidMkInfo) GetDistForGoals(ctx fillInEntriesContext, mod blueprint.Module) []string { - distContributions := a.getDistContributions(ctx, mod) +// 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) if distContributions == nil { return nil } @@ -1700,9 +1672,11 @@ func (a *AndroidMkInfo) GetDistForGoals(ctx fillInEntriesContext, mod blueprint. } // Compute the contributions that the module makes to the dist. -func (a *AndroidMkInfo) getDistContributions(ctx fillInEntriesContext, mod blueprint.Module) *distContributions { - amod := mod.(Module).base() - name := amod.BaseModuleName() +// 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. @@ -1738,12 +1712,12 @@ func (a *AndroidMkInfo) getDistContributions(ctx fillInEntriesContext, mod bluep // Collate the contributions this module makes to the dist. distContributions := &distContributions{} - if !exemptFromRequiredApplicableLicensesProperty(mod.(Module)) { + if !commonInfo.ExemptFromRequiredApplicableLicensesProperty { distContributions.licenseMetadataFile = info.LicenseMetadataFile } // Iterate over this module's dist structs, merged from the dist and dists properties. - for _, dist := range amod.Dists() { + 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, " ") diff --git a/android/base_module_context.go b/android/base_module_context.go index 4b90083be..5e05f547a 100644 --- a/android/base_module_context.go +++ b/android/base_module_context.go @@ -53,6 +53,9 @@ type BaseModuleContext interface { // dependencies on the module being visited, it returns the dependency tag used for the current dependency. OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag + // OtherModuleSubDir returns the string representing the variations of a module. + OtherModuleSubDir(m blueprint.Module) string + // OtherModuleExists returns true if a module with the specified name exists, as determined by the NameInterface // passed to Context.SetNameInterface, or SimpleNameInterface if it was not called. OtherModuleExists(name string) bool @@ -88,6 +91,11 @@ type BaseModuleContext interface { // This method shouldn't be used directly, prefer the type-safe android.OtherModuleProvider instead. otherModuleProvider(m blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) + // OtherModuleHasProvider returns true if the module has the given provider set. This + // can avoid copying the provider if the caller only cares about the existence of + // the provider. + OtherModuleHasProvider(m blueprint.Module, provider blueprint.AnyProviderKey) bool + // OtherModuleIsAutoGenerated returns true if the module is auto generated by another module // instead of being defined in Android.bp file. OtherModuleIsAutoGenerated(m blueprint.Module) bool @@ -279,6 +287,9 @@ func (b *baseModuleContext) OtherModuleErrorf(m blueprint.Module, fmt string, ar func (b *baseModuleContext) OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag { return b.bp.OtherModuleDependencyTag(getWrappedModule(m)) } +func (b *baseModuleContext) OtherModuleSubDir(m blueprint.Module) string { + return b.bp.OtherModuleSubDir(getWrappedModule(m)) +} func (b *baseModuleContext) OtherModuleExists(name string) bool { return b.bp.OtherModuleExists(name) } func (b *baseModuleContext) OtherModuleDependencyVariantExists(variations []blueprint.Variation, name string) bool { return b.bp.OtherModuleDependencyVariantExists(variations, name) @@ -297,6 +308,10 @@ func (b *baseModuleContext) otherModuleProvider(m blueprint.Module, provider blu return b.bp.OtherModuleProvider(getWrappedModule(m), provider) } +func (b *baseModuleContext) OtherModuleHasProvider(m blueprint.Module, provider blueprint.AnyProviderKey) bool { + return b.bp.OtherModuleHasProvider(getWrappedModule(m), provider) +} + func (b *baseModuleContext) OtherModuleIsAutoGenerated(m blueprint.Module) bool { return b.bp.OtherModuleIsAutoGenerated(m) } diff --git a/android/compliance_metadata.go b/android/compliance_metadata.go index 35805a2a8..a6dbb8d17 100644 --- a/android/compliance_metadata.go +++ b/android/compliance_metadata.go @@ -275,16 +275,18 @@ func (c *complianceMetadataSingleton) GenerateBuildActions(ctx SingletonContext) writerToCsv(csvWriter, columnNames) rowId := -1 - ctx.VisitAllModules(func(module Module) { - if !module.Enabled(ctx) { + ctx.VisitAllModuleProxies(func(module ModuleProxy) { + commonInfo, _ := OtherModuleProvider(ctx, module, CommonModuleInfoKey) + if !commonInfo.Enabled { return } + moduleType := ctx.ModuleType(module) if moduleType == "package" { metadataMap := map[string]string{ ComplianceMetadataProp.NAME: ctx.ModuleName(module), ComplianceMetadataProp.MODULE_TYPE: ctx.ModuleType(module), - ComplianceMetadataProp.PKG_DEFAULT_APPLICABLE_LICENSES: strings.Join(module.base().primaryLicensesProperty.getStrings(), " "), + ComplianceMetadataProp.PKG_DEFAULT_APPLICABLE_LICENSES: strings.Join(commonInfo.PrimaryLicensesProperty.getStrings(), " "), } rowId = rowId + 1 metadata := []string{strconv.Itoa(rowId)} @@ -294,8 +296,7 @@ func (c *complianceMetadataSingleton) GenerateBuildActions(ctx SingletonContext) writerToCsv(csvWriter, metadata) return } - if provider, ok := ctx.otherModuleProvider(module, ComplianceMetadataProvider); ok { - metadataInfo := provider.(*ComplianceMetadataInfo) + if metadataInfo, ok := OtherModuleProvider(ctx, module, ComplianceMetadataProvider); ok { rowId = rowId + 1 metadata := []string{strconv.Itoa(rowId)} for _, propertyName := range COMPLIANCE_METADATA_PROPS { diff --git a/android/config.go b/android/config.go index acaad60ad..f6d08b841 100644 --- a/android/config.go +++ b/android/config.go @@ -394,6 +394,17 @@ type partialCompileFlags struct { // Add others as needed. } +// These are the flags when `SOONG_PARTIAL_COMPILE` is empty or not set. +var defaultPartialCompileFlags = partialCompileFlags{ + Enabled: false, +} + +// These are the flags when `SOONG_PARTIAL_COMPILE=true`. +var enabledPartialCompileFlags = partialCompileFlags{ + Enabled: true, + Use_d8: true, +} + type deviceConfig struct { config *config OncePer @@ -427,11 +438,6 @@ type jsonConfigurable interface { // To add a new feature to the list, add the field in the struct // `partialCompileFlags` above, and then add the name of the field in the // switch statement below. -var defaultPartialCompileFlags = partialCompileFlags{ - // Set any opt-out flags here. Opt-in flags are off by default. - Enabled: false, -} - func (c *config) parsePartialCompileFlags(isEngBuild bool) (partialCompileFlags, error) { if !isEngBuild { return partialCompileFlags{}, nil @@ -472,8 +478,7 @@ func (c *config) parsePartialCompileFlags(isEngBuild bool) (partialCompileFlags, } switch tok { case "true": - ret = defaultPartialCompileFlags - ret.Enabled = true + ret = enabledPartialCompileFlags case "false": // Set everything to false. ret = partialCompileFlags{} @@ -2171,14 +2176,6 @@ func (c *config) UseOptimizedResourceShrinkingByDefault() bool { return c.productVariables.GetBuildFlagBool("RELEASE_USE_OPTIMIZED_RESOURCE_SHRINKING_BY_DEFAULT") } -func (c *config) UseResourceProcessorByDefault() bool { - return c.productVariables.GetBuildFlagBool("RELEASE_USE_RESOURCE_PROCESSOR_BY_DEFAULT") -} - -func (c *config) UseTransitiveJarsInClasspath() bool { - return c.productVariables.GetBuildFlagBool("RELEASE_USE_TRANSITIVE_JARS_IN_CLASSPATH") -} - func (c *config) UseR8FullModeByDefault() bool { return c.productVariables.GetBuildFlagBool("RELEASE_R8_FULL_MODE_BY_DEFAULT") } @@ -2191,6 +2188,10 @@ func (c *config) UseR8StoreStoreFenceConstructorInlining() bool { return c.productVariables.GetBuildFlagBool("RELEASE_R8_STORE_STORE_FENCE_CONSTRUCTOR_INLINING") } +func (c *config) UseR8GlobalCheckNotNullFlags() bool { + return c.productVariables.GetBuildFlagBool("RELEASE_R8_GLOBAL_CHECK_NOT_NULL_FLAGS") +} + func (c *config) UseDexV41() bool { return c.productVariables.GetBuildFlagBool("RELEASE_USE_DEX_V41") } diff --git a/android/config_test.go b/android/config_test.go index 4bdf05f0e..3d8686041 100644 --- a/android/config_test.go +++ b/android/config_test.go @@ -239,10 +239,10 @@ func TestPartialCompile(t *testing.T) { }{ {"", true, defaultPartialCompileFlags}, {"false", true, partialCompileFlags{}}, - {"true", true, defaultPartialCompileFlags.updateEnabled(true)}, + {"true", true, enabledPartialCompileFlags}, {"true", false, partialCompileFlags{}}, - {"true,use_d8", true, defaultPartialCompileFlags.updateEnabled(true).updateUseD8(true)}, - {"true,-use_d8", true, defaultPartialCompileFlags.updateEnabled(true).updateUseD8(false)}, + {"true,use_d8", true, enabledPartialCompileFlags.updateUseD8(true)}, + {"true,-use_d8", true, enabledPartialCompileFlags.updateUseD8(false)}, {"use_d8,false", true, partialCompileFlags{}}, {"false,+use_d8", true, partialCompileFlags{}.updateUseD8(true)}, } diff --git a/android/makevars.go b/android/makevars.go index baa1d4453..2931d0bed 100644 --- a/android/makevars.go +++ b/android/makevars.go @@ -65,24 +65,6 @@ type BaseMakeVarsContext interface { // dependencies to be added to it. Phony can be called on the same name multiple // times to add additional dependencies. Phony(names string, deps ...Path) - - // DistForGoal creates a rule to copy one or more Paths to the artifacts - // directory on the build server when the specified goal is built. - DistForGoal(goal string, paths ...Path) - - // DistForGoalWithFilename creates a rule to copy a Path to the artifacts - // directory on the build server with the given filename when the specified - // goal is built. - DistForGoalWithFilename(goal string, path Path, filename string) - - // DistForGoals creates a rule to copy one or more Paths to the artifacts - // directory on the build server when any of the specified goals are built. - DistForGoals(goals []string, paths ...Path) - - // DistForGoalsWithFilename creates a rule to copy a Path to the artifacts - // directory on the build server with the given filename when any of the - // specified goals are built. - DistForGoalsWithFilename(goals []string, path Path, filename string) } // MakeVarsContext contains the set of functions available for MakeVarsProvider @@ -198,11 +180,9 @@ var makeVarsInitProviders []makeVarsProvider type makeVarsContext struct { SingletonContext - config Config pctx PackageContext vars []makeVarsVariable phonies []phony - dists []dist } var _ MakeVarsContext = &makeVarsContext{} @@ -263,7 +243,6 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) { vars = append(vars, mctx.vars...) phonies = append(phonies, mctx.phonies...) - dists = append(dists, mctx.dists...) } singletonDists := getSingletonDists(ctx.Config()) @@ -281,7 +260,6 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) { vars = append(vars, mctx.vars...) phonies = append(phonies, mctx.phonies...) - dists = append(dists, mctx.dists...) } if m.ExportedToMake() { @@ -611,13 +589,6 @@ func (c *makeVarsContext) addPhony(name string, deps []string) { c.phonies = append(c.phonies, phony{name, deps}) } -func (c *makeVarsContext) addDist(goals []string, paths []distCopy) { - c.dists = append(c.dists, dist{ - goals: goals, - paths: paths, - }) -} - func (c *makeVarsContext) Strict(name, ninjaStr string) { c.addVariable(name, ninjaStr, true, false) } @@ -641,26 +612,3 @@ func (c *makeVarsContext) CheckRaw(name, value string) { func (c *makeVarsContext) Phony(name string, deps ...Path) { c.addPhony(name, Paths(deps).Strings()) } - -func (c *makeVarsContext) DistForGoal(goal string, paths ...Path) { - c.DistForGoals([]string{goal}, paths...) -} - -func (c *makeVarsContext) DistForGoalWithFilename(goal string, path Path, filename string) { - c.DistForGoalsWithFilename([]string{goal}, path, filename) -} - -func (c *makeVarsContext) DistForGoals(goals []string, paths ...Path) { - var copies distCopies - for _, path := range paths { - copies = append(copies, distCopy{ - from: path, - dest: path.Base(), - }) - } - c.addDist(goals, copies) -} - -func (c *makeVarsContext) DistForGoalsWithFilename(goals []string, path Path, filename string) { - c.addDist(goals, distCopies{{from: path, dest: filename}}) -} diff --git a/android/metrics.go b/android/metrics.go index 6834b1bde..dc5170319 100644 --- a/android/metrics.go +++ b/android/metrics.go @@ -57,8 +57,8 @@ type soongMetricsSingleton struct{} func (soongMetricsSingleton) GenerateBuildActions(ctx SingletonContext) { metrics := getSoongMetrics(ctx.Config()) - ctx.VisitAllModules(func(m Module) { - if ctx.PrimaryModule(m) == m { + ctx.VisitAllModuleProxies(func(m ModuleProxy) { + if ctx.PrimaryModuleProxy(m) == m { metrics.modules++ } metrics.variants++ diff --git a/android/module.go b/android/module.go index 0ffb6cb53..996c64e52 100644 --- a/android/module.go +++ b/android/module.go @@ -1908,12 +1908,37 @@ type CommonModuleInfo struct { // is used to avoid adding install or packaging dependencies into libraries provided // by apexes. UninstallableApexPlatformVariant bool - HideFromMake bool - SkipInstall bool - IsStubsModule bool - Host bool MinSdkVersionSupported ApiLevel ModuleWithMinSdkVersionCheck bool + // Tests if this module can be installed to APEX as a file. For example, this would return + // true for shared libs while return false for static libs because static libs are not + // installable module (but it can still be mutated for APEX) + IsInstallableToApex bool + HideFromMake bool + SkipInstall bool + IsStubsModule bool + Host bool + IsApexModule bool + // The primary licenses property, may be nil, records license metadata for the module. + PrimaryLicensesProperty applicableLicensesProperty + Owner string + Vendor bool + Proprietary bool + SocSpecific bool + ProductSpecific bool + SystemExtSpecific bool + DeviceSpecific bool + // When set to true, this module is not installed to the full install path (ex: under + // out/target/product/<name>/<partition>). It can be installed only to the packaging + // modules like android_filesystem. + NoFullInstall bool + InVendorRamdisk bool + ExemptFromRequiredApplicableLicensesProperty bool + RequiredModuleNames []string + HostRequiredModuleNames []string + TargetRequiredModuleNames []string + VintfFragmentModuleNames []string + Dists []Dist } type ApiLevelOrPlatform struct { @@ -2249,14 +2274,30 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) buildComplianceMetadataProvider(ctx, m) commonData := CommonModuleInfo{ + Enabled: m.Enabled(ctx), ReplacedByPrebuilt: m.commonProperties.ReplacedByPrebuilt, Target: m.commonProperties.CompileTarget, SkipAndroidMkProcessing: shouldSkipAndroidMkProcessing(ctx, m), - BaseModuleName: m.BaseModuleName(), UninstallableApexPlatformVariant: m.commonProperties.UninstallableApexPlatformVariant, HideFromMake: m.commonProperties.HideFromMake, SkipInstall: m.commonProperties.SkipInstall, Host: m.Host(), + PrimaryLicensesProperty: m.primaryLicensesProperty, + Owner: m.module.Owner(), + SocSpecific: Bool(m.commonProperties.Soc_specific), + Vendor: Bool(m.commonProperties.Vendor), + Proprietary: Bool(m.commonProperties.Proprietary), + ProductSpecific: Bool(m.commonProperties.Product_specific), + SystemExtSpecific: Bool(m.commonProperties.System_ext_specific), + DeviceSpecific: Bool(m.commonProperties.Device_specific), + NoFullInstall: proptools.Bool(m.commonProperties.No_full_install), + InVendorRamdisk: m.InVendorRamdisk(), + ExemptFromRequiredApplicableLicensesProperty: exemptFromRequiredApplicableLicensesProperty(m.module), + RequiredModuleNames: m.module.RequiredModuleNames(ctx), + HostRequiredModuleNames: m.module.HostRequiredModuleNames(), + TargetRequiredModuleNames: m.module.TargetRequiredModuleNames(), + VintfFragmentModuleNames: m.module.VintfFragmentModuleNames(ctx), + Dists: m.Dists(), } if mm, ok := m.module.(interface { MinSdkVersion(ctx EarlyModuleContext) ApiLevel @@ -2285,16 +2326,13 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) commonData.SdkVersion = mm.SdkVersion() } - if m.commonProperties.ForcedDisabled { - commonData.Enabled = false - } else { - commonData.Enabled = m.commonProperties.Enabled.GetOrDefault(m.ConfigurableEvaluator(ctx), !m.Os().DefaultDisabled) - } if am, ok := m.module.(ApexModule); ok { commonData.CanHaveApexVariants = am.CanHaveApexVariants() commonData.NotAvailableForPlatform = am.NotAvailableForPlatform() commonData.NotInPlatform = am.NotInPlatform() commonData.MinSdkVersionSupported = am.MinSdkVersionSupported(ctx) + commonData.IsInstallableToApex = am.IsInstallableToApex() + commonData.IsApexModule = true } if _, ok := m.module.(ModuleWithMinSdkVersionCheck); ok { @@ -2304,6 +2342,9 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) if st, ok := m.module.(StubsAvailableModule); ok { commonData.IsStubsModule = st.IsStubsModule() } + if mm, ok := m.module.(interface{ BaseModuleName() string }); ok { + commonData.BaseModuleName = mm.BaseModuleName() + } SetProvider(ctx, CommonModuleInfoKey, commonData) if p, ok := m.module.(PrebuiltInterface); ok && p.Prebuilt() != nil { SetProvider(ctx, PrebuiltModuleInfoProvider, PrebuiltModuleInfo{ diff --git a/android/module_context.go b/android/module_context.go index f279fd9e5..fb62e6749 100644 --- a/android/module_context.go +++ b/android/module_context.go @@ -655,6 +655,7 @@ func (m *moduleContext) packageFile(fullInstallPath InstallPath, srcPath Path, e owner: owner, requiresFullInstall: requiresFullInstall, fullInstallPath: fullInstallPath, + variation: m.ModuleSubDir(), } m.packagingSpecs = append(m.packagingSpecs, spec) return spec @@ -806,6 +807,7 @@ func (m *moduleContext) InstallSymlink(installPath InstallPath, name string, src owner: owner, requiresFullInstall: m.requiresFullInstall(), fullInstallPath: fullInstallPath, + variation: m.ModuleSubDir(), }) return fullInstallPath @@ -856,6 +858,7 @@ func (m *moduleContext) InstallAbsoluteSymlink(installPath InstallPath, name str owner: owner, requiresFullInstall: m.requiresFullInstall(), fullInstallPath: fullInstallPath, + variation: m.ModuleSubDir(), }) return fullInstallPath diff --git a/android/package.go b/android/package.go index eb76751f5..385326e53 100644 --- a/android/package.go +++ b/android/package.go @@ -56,7 +56,10 @@ func (p *packageModule) DepsMutator(ctx BottomUpMutatorContext) { } func (p *packageModule) GenerateBuildActions(ctx blueprint.ModuleContext) { - // Nothing to do. + ctx.SetProvider(CommonModuleInfoKey, CommonModuleInfo{ + Enabled: true, + PrimaryLicensesProperty: p.primaryLicensesProperty, + }) } func (p *packageModule) qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName { diff --git a/android/packaging.go b/android/packaging.go index 4e0c74a12..6146f02c9 100644 --- a/android/packaging.go +++ b/android/packaging.go @@ -72,6 +72,9 @@ type PackagingSpec struct { // tools that want to interact with these files outside of the build. You should not use it // inside of the build. Will be nil if this module doesn't require a "full install". fullInstallPath InstallPath + + // String representation of the variation of the module where this packaging spec is output of + variation string } type packagingSpecGob struct { @@ -86,6 +89,15 @@ type packagingSpecGob struct { ArchType ArchType Overrides []string Owner string + Variation string +} + +func (p *PackagingSpec) Owner() string { + return p.owner +} + +func (p *PackagingSpec) Variation() string { + return p.variation } func (p *PackagingSpec) ToGob() *packagingSpecGob { @@ -101,6 +113,7 @@ func (p *PackagingSpec) ToGob() *packagingSpecGob { ArchType: p.archType, Overrides: p.overrides.ToSlice(), Owner: p.owner, + Variation: p.variation, } } @@ -116,6 +129,7 @@ func (p *PackagingSpec) FromGob(data *packagingSpecGob) { p.archType = data.ArchType p.overrides = uniquelist.Make(data.Overrides) p.owner = data.Owner + p.variation = data.Variation } func (p *PackagingSpec) GobEncode() ([]byte, error) { diff --git a/android/plugin.go b/android/plugin.go index d62fc9453..4348f1475 100644 --- a/android/plugin.go +++ b/android/plugin.go @@ -135,6 +135,6 @@ func (p *pluginSingleton) GenerateBuildActions(ctx SingletonContext) { disallowedPlugins[name] = true }) if len(disallowedPlugins) > 0 { - ctx.Errorf("New plugins are not supported; however %q were found. Please reach out to the build team or use BUILD_BROKEN_PLUGIN_VALIDATION (see Changes.md for more info).", SortedStringKeys(disallowedPlugins)) + ctx.Errorf("New plugins are not supported; however %q were found. Please reach out to the build team or use BUILD_BROKEN_PLUGIN_VALIDATION (see Changes.md for more info).", SortedKeys(disallowedPlugins)) } } diff --git a/android/prebuilt.go b/android/prebuilt.go index 6b076b7b4..72735991d 100644 --- a/android/prebuilt.go +++ b/android/prebuilt.go @@ -357,6 +357,17 @@ func IsModulePreferred(module Module) bool { return true } +func IsModulePreferredProxy(ctx OtherModuleProviderContext, module ModuleProxy) bool { + if OtherModuleProviderOrDefault(ctx, module, CommonModuleInfoKey).ReplacedByPrebuilt { + // A source module that has been replaced by a prebuilt counterpart. + return false + } + if p, ok := OtherModuleProvider(ctx, module, PrebuiltModuleInfoProvider); ok { + return p.UsePrebuilt + } + return true +} + // IsModulePrebuilt returns true if the module implements PrebuiltInterface and // has been initialized as a prebuilt and so returns a non-nil value from the // PrebuiltInterface.Prebuilt() method. diff --git a/android/singleton.go b/android/singleton.go index df2204591..a03ea74aa 100644 --- a/android/singleton.go +++ b/android/singleton.go @@ -84,6 +84,9 @@ type SingletonContext interface { VisitAllModuleVariantProxies(module Module, visit func(proxy ModuleProxy)) PrimaryModule(module Module) Module + + PrimaryModuleProxy(module ModuleProxy) ModuleProxy + IsFinalModule(module Module) bool AddNinjaFileDeps(deps ...string) @@ -271,6 +274,22 @@ func predAdaptor(pred func(Module) bool) func(blueprint.Module) bool { } } +func (s *singletonContextAdaptor) ModuleName(module blueprint.Module) string { + return s.SingletonContext.ModuleName(getWrappedModule(module)) +} + +func (s *singletonContextAdaptor) ModuleDir(module blueprint.Module) string { + return s.SingletonContext.ModuleDir(getWrappedModule(module)) +} + +func (s *singletonContextAdaptor) ModuleSubDir(module blueprint.Module) string { + return s.SingletonContext.ModuleSubDir(getWrappedModule(module)) +} + +func (s *singletonContextAdaptor) ModuleType(module blueprint.Module) string { + return s.SingletonContext.ModuleType(getWrappedModule(module)) +} + func (s *singletonContextAdaptor) VisitAllModulesBlueprint(visit func(blueprint.Module)) { s.SingletonContext.VisitAllModules(visit) } @@ -315,6 +334,10 @@ func (s *singletonContextAdaptor) PrimaryModule(module Module) Module { return s.SingletonContext.PrimaryModule(module).(Module) } +func (s *singletonContextAdaptor) PrimaryModuleProxy(module ModuleProxy) ModuleProxy { + return ModuleProxy{s.SingletonContext.PrimaryModuleProxy(module.module)} +} + func (s *singletonContextAdaptor) IsFinalModule(module Module) bool { return s.SingletonContext.IsFinalModule(module) } diff --git a/android/test_mapping_zip.go b/android/test_mapping_zip.go new file mode 100644 index 000000000..8dc70d7fe --- /dev/null +++ b/android/test_mapping_zip.go @@ -0,0 +1,49 @@ +// 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 + +func init() { + InitRegistrationContext.RegisterSingletonType("test_mapping_zip_singleton", testMappingZipSingletonFactory) +} + +func testMappingZipSingletonFactory() Singleton { + return &testMappingZipSingleton{} +} + +type testMappingZipSingleton struct{} + +func (s *testMappingZipSingleton) GenerateBuildActions(ctx SingletonContext) { + fileListFile := PathForArbitraryOutput(ctx, ".module_paths", "TEST_MAPPING.list") + out := PathForOutput(ctx, "test_mappings.zip") + dep := PathForOutput(ctx, "test_mappings.zip.d") + + // disabled-presubmit-tests used to be filled out based on modules that set + // LOCAL_PRESUBMIT_DISABLED. But that's no longer used and there was never a soong equivalent + // anyways, so just always create an empty file. + disabledPresubmitTestsFile := PathForOutput(ctx, "disabled-presubmit-tests") + WriteFileRule(ctx, disabledPresubmitTestsFile, "") + + builder := NewRuleBuilder(pctx, ctx) + builder.Command().BuiltTool("soong_zip"). + FlagWithOutput("-o ", out). + FlagWithInput("-l ", fileListFile). + FlagWithArg("-e ", "disabled-presubmit-tests"). + FlagWithInput("-f ", disabledPresubmitTestsFile) + builder.Command().Textf("echo '%s : ' $(cat %s) > ", out, fileListFile).DepFile(dep) + builder.Build("test_mappings_zip", "build TEST_MAPPING zip") + + ctx.Phony("test_mapping", out) + ctx.DistForGoals([]string{"dist_files", "test_mapping"}, out) +} diff --git a/android/test_suites.go b/android/test_suites.go index 18744f1da..39317ec62 100644 --- a/android/test_suites.go +++ b/android/test_suites.go @@ -17,6 +17,8 @@ package android import ( "path/filepath" "strings" + + "github.com/google/blueprint" ) func init() { @@ -37,18 +39,24 @@ type TestSuiteModule interface { TestSuites() []string } +type TestSuiteInfo struct { + TestSuites []string +} + +var TestSuiteInfoProvider = blueprint.NewProvider[TestSuiteInfo]() + func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) { files := make(map[string]map[string]InstallPaths) - ctx.VisitAllModules(func(m Module) { - if tsm, ok := m.(TestSuiteModule); ok { - for _, testSuite := range tsm.TestSuites() { + ctx.VisitAllModuleProxies(func(m ModuleProxy) { + if tsm, ok := OtherModuleProvider(ctx, m, TestSuiteInfoProvider); ok { + for _, testSuite := range tsm.TestSuites { if files[testSuite] == nil { files[testSuite] = make(map[string]InstallPaths) } name := ctx.ModuleName(m) files[testSuite][name] = append(files[testSuite][name], - OtherModuleProviderOrDefault(ctx, tsm, InstallFilesProvider).InstallFiles...) + OtherModuleProviderOrDefault(ctx, m, InstallFilesProvider).InstallFiles...) } } }) diff --git a/android/test_suites_test.go b/android/test_suites_test.go index bf4de197e..dda93297a 100644 --- a/android/test_suites_test.go +++ b/android/test_suites_test.go @@ -110,6 +110,10 @@ func (f *fake_module) GenerateAndroidBuildActions(ctx ModuleContext) { for _, output := range f.props.Outputs { ctx.InstallFile(pathForTestCases(ctx), output, nil) } + + SetProvider(ctx, TestSuiteInfoProvider, TestSuiteInfo{ + TestSuites: f.TestSuites(), + }) } func (f *fake_module) TestSuites() []string { diff --git a/android/testing.go b/android/testing.go index 8e38b3b1c..1962fdea5 100644 --- a/android/testing.go +++ b/android/testing.go @@ -931,6 +931,7 @@ func (b baseTestingComponent) maybeBuildParamsFromRule(rule string) (TestingBuil } func (b baseTestingComponent) buildParamsFromRule(rule string) TestingBuildParams { + b.t.Helper() p, searchRules := b.maybeBuildParamsFromRule(rule) if p.Rule == nil { b.t.Fatalf("couldn't find rule %q.\nall rules:\n%s", rule, strings.Join(searchRules, "\n")) @@ -950,6 +951,7 @@ func (b baseTestingComponent) maybeBuildParamsFromDescription(desc string) (Test } func (b baseTestingComponent) buildParamsFromDescription(desc string) TestingBuildParams { + b.t.Helper() p, searchedDescriptions := b.maybeBuildParamsFromDescription(desc) if p.Rule == nil { b.t.Fatalf("couldn't find description %q\nall descriptions:\n%s", desc, strings.Join(searchedDescriptions, "\n")) @@ -983,6 +985,7 @@ func (b baseTestingComponent) maybeBuildParamsFromOutput(file string) (TestingBu } func (b baseTestingComponent) buildParamsFromOutput(file string) TestingBuildParams { + b.t.Helper() p, searchedOutputs := b.maybeBuildParamsFromOutput(file) if p.Rule == nil { b.t.Fatalf("couldn't find output %q.\nall outputs:\n %s\n", @@ -1008,6 +1011,7 @@ func (b baseTestingComponent) MaybeRule(rule string) TestingBuildParams { // Rule finds a call to ctx.Build with BuildParams.Rule set to a rule with the given name. Panics if no rule is found. func (b baseTestingComponent) Rule(rule string) TestingBuildParams { + b.t.Helper() return b.buildParamsFromRule(rule) } @@ -1021,6 +1025,7 @@ func (b baseTestingComponent) MaybeDescription(desc string) TestingBuildParams { // Description finds a call to ctx.Build with BuildParams.Description set to a the given string. Panics if no rule is // found. func (b baseTestingComponent) Description(desc string) TestingBuildParams { + b.t.Helper() return b.buildParamsFromDescription(desc) } @@ -1034,6 +1039,7 @@ func (b baseTestingComponent) MaybeOutput(file string) TestingBuildParams { // Output finds a call to ctx.Build with a BuildParams.Output or BuildParams.Outputs whose String() or Rel() // value matches the provided string. Panics if no rule is found. func (b baseTestingComponent) Output(file string) TestingBuildParams { + b.t.Helper() return b.buildParamsFromOutput(file) } @@ -1161,7 +1167,7 @@ func SetKatiEnabledForTests(config Config) { config.katiEnabled = true } -func AndroidMkEntriesForTest(t *testing.T, ctx *TestContext, mod blueprint.Module) []AndroidMkEntries { +func AndroidMkEntriesForTest(t *testing.T, ctx *TestContext, mod Module) []AndroidMkEntries { t.Helper() var p AndroidMkEntriesProvider var ok bool @@ -1170,15 +1176,15 @@ func AndroidMkEntriesForTest(t *testing.T, ctx *TestContext, mod blueprint.Modul } entriesList := p.AndroidMkEntries() - aconfigUpdateAndroidMkEntries(ctx, mod.(Module), &entriesList) + aconfigUpdateAndroidMkEntries(ctx, mod, &entriesList) for i := range entriesList { entriesList[i].fillInEntries(ctx, mod) } return entriesList } -func AndroidMkInfoForTest(t *testing.T, ctx *TestContext, mod blueprint.Module) *AndroidMkProviderInfo { - if runtime.GOOS == "darwin" && mod.(Module).base().Os() != Darwin { +func AndroidMkInfoForTest(t *testing.T, ctx *TestContext, mod Module) *AndroidMkProviderInfo { + if runtime.GOOS == "darwin" && mod.base().Os() != Darwin { // The AndroidMkInfo provider is not set in this case. t.Skip("AndroidMkInfo provider is not set on darwin") } @@ -1190,18 +1196,19 @@ func AndroidMkInfoForTest(t *testing.T, ctx *TestContext, mod blueprint.Module) } info := OtherModuleProviderOrDefault(ctx, mod, AndroidMkInfoProvider) - aconfigUpdateAndroidMkInfos(ctx, mod.(Module), info) - info.PrimaryInfo.fillInEntries(ctx, mod) + aconfigUpdateAndroidMkInfos(ctx, mod, info) + commonInfo, _ := OtherModuleProvider(ctx, mod, CommonModuleInfoKey) + info.PrimaryInfo.fillInEntries(ctx, mod, &commonInfo) if len(info.ExtraInfo) > 0 { for _, ei := range info.ExtraInfo { - ei.fillInEntries(ctx, mod) + ei.fillInEntries(ctx, mod, &commonInfo) } } return info } -func AndroidMkDataForTest(t *testing.T, ctx *TestContext, mod blueprint.Module) AndroidMkData { +func AndroidMkDataForTest(t *testing.T, ctx *TestContext, mod Module) AndroidMkData { t.Helper() var p AndroidMkDataProvider var ok bool @@ -1210,7 +1217,7 @@ func AndroidMkDataForTest(t *testing.T, ctx *TestContext, mod blueprint.Module) } data := p.AndroidMk() data.fillInData(ctx, mod) - aconfigUpdateAndroidMkData(ctx, mod.(Module), &data) + aconfigUpdateAndroidMkData(ctx, mod, &data) return data } diff --git a/android/util.go b/android/util.go index 8591cc63e..7b305b575 100644 --- a/android/util.go +++ b/android/util.go @@ -102,13 +102,6 @@ func JoinWithPrefixSuffixAndSeparator(strs []string, prefix, suffix, sep string) return buf.String() } -// SortedStringKeys returns the keys of the given map in the ascending order. -// -// Deprecated: Use SortedKeys instead. -func SortedStringKeys[V any](m map[string]V) []string { - return SortedKeys(m) -} - // SortedKeys returns the keys of the given map in the ascending order. func SortedKeys[T cmp.Ordered, V any](m map[T]V) []T { if len(m) == 0 { diff --git a/android/vintf_fragment.go b/android/vintf_fragment.go index 49cf99972..4a29fee87 100644 --- a/android/vintf_fragment.go +++ b/android/vintf_fragment.go @@ -14,6 +14,8 @@ package android +import "github.com/google/blueprint" + type vintfFragmentProperties struct { // Vintf fragment XML file. Src string `android:"path"` @@ -37,6 +39,12 @@ func registerVintfFragmentComponents(ctx RegistrationContext) { ctx.RegisterModuleType("vintf_fragment", vintfLibraryFactory) } +type VintfFragmentInfo struct { + OutputFile Path +} + +var VintfFragmentInfoProvider = blueprint.NewProvider[VintfFragmentInfo]() + // vintf_fragment module processes vintf fragment file and installs under etc/vintf/manifest. // Vintf fragment files formerly listed in vintf_fragment property would be transformed into // this module type. @@ -68,6 +76,10 @@ func (m *VintfFragmentModule) GenerateAndroidBuildActions(ctx ModuleContext) { m.outputFilePath = processedVintfFragment ctx.InstallFile(m.installDirPath, processedVintfFragment.Base(), processedVintfFragment) + + SetProvider(ctx, VintfFragmentInfoProvider, VintfFragmentInfo{ + OutputFile: m.OutputFile(), + }) } func (m *VintfFragmentModule) OutputFile() Path { diff --git a/androidmk/androidmk/android.go b/androidmk/androidmk/android.go index 570f36c16..6485cc51d 100644 --- a/androidmk/androidmk/android.go +++ b/androidmk/androidmk/android.go @@ -103,25 +103,26 @@ func addStandardProperties(propertyType bpparser.Type, properties map[string]str func init() { addStandardProperties(bpparser.StringType, map[string]string{ - "LOCAL_MODULE": "name", - "LOCAL_CXX_STL": "stl", - "LOCAL_MULTILIB": "compile_multilib", - "LOCAL_ARM_MODE_HACK": "instruction_set", - "LOCAL_SDK_VERSION": "sdk_version", - "LOCAL_MIN_SDK_VERSION": "min_sdk_version", - "LOCAL_TARGET_SDK_VERSION": "target_sdk_version", - "LOCAL_NDK_STL_VARIANT": "stl", - "LOCAL_JAR_MANIFEST": "manifest", - "LOCAL_CERTIFICATE": "certificate", - "LOCAL_CERTIFICATE_LINEAGE": "lineage", - "LOCAL_PACKAGE_NAME": "name", - "LOCAL_MODULE_RELATIVE_PATH": "relative_install_path", - "LOCAL_PROTOC_OPTIMIZE_TYPE": "proto.type", - "LOCAL_MODULE_OWNER": "owner", - "LOCAL_RENDERSCRIPT_TARGET_API": "renderscript.target_api", - "LOCAL_JAVA_LANGUAGE_VERSION": "java_version", - "LOCAL_INSTRUMENTATION_FOR": "instrumentation_for", - "LOCAL_MANIFEST_FILE": "manifest", + "LOCAL_MODULE": "name", + "LOCAL_CXX_STL": "stl", + "LOCAL_MULTILIB": "compile_multilib", + "LOCAL_ARM_MODE_HACK": "instruction_set", + "LOCAL_SDK_VERSION": "sdk_version", + "LOCAL_MIN_SDK_VERSION": "min_sdk_version", + "LOCAL_ROTATION_MIN_SDK_VERSION": "rotationMinSdkVersion", + "LOCAL_TARGET_SDK_VERSION": "target_sdk_version", + "LOCAL_NDK_STL_VARIANT": "stl", + "LOCAL_JAR_MANIFEST": "manifest", + "LOCAL_CERTIFICATE": "certificate", + "LOCAL_CERTIFICATE_LINEAGE": "lineage", + "LOCAL_PACKAGE_NAME": "name", + "LOCAL_MODULE_RELATIVE_PATH": "relative_install_path", + "LOCAL_PROTOC_OPTIMIZE_TYPE": "proto.type", + "LOCAL_MODULE_OWNER": "owner", + "LOCAL_RENDERSCRIPT_TARGET_API": "renderscript.target_api", + "LOCAL_JAVA_LANGUAGE_VERSION": "java_version", + "LOCAL_INSTRUMENTATION_FOR": "instrumentation_for", + "LOCAL_MANIFEST_FILE": "manifest", "LOCAL_DEX_PREOPT_PROFILE_CLASS_LISTING": "dex_preopt.profile", "LOCAL_TEST_CONFIG": "test_config", diff --git a/apex/apex.go b/apex/apex.go index 4d0e3f183..4b510f8f1 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -624,7 +624,8 @@ type apexFile struct { } // TODO(jiyong): shorten the arglist using an option struct -func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidMkModuleName string, installDir string, class apexFileClass, module android.Module) apexFile { +func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidMkModuleName string, + installDir string, class apexFileClass, module android.Module) apexFile { ret := apexFile{ builtFile: builtFile, installDir: installDir, @@ -1375,24 +1376,29 @@ func (a *apexBundle) AddSanitizerDependencies(ctx android.BottomUpMutatorContext } } +func setDirInApexForNativeBridge(commonInfo *android.CommonModuleInfo, dir *string) { + if commonInfo.Target.NativeBridge == android.NativeBridgeEnabled { + *dir = filepath.Join(*dir, commonInfo.Target.NativeBridgeRelativePath) + } +} + // apexFileFor<Type> functions below create an apexFile struct for a given Soong module. The // returned apexFile saves information about the Soong module that will be used for creating the // build rules. -func apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod cc.VersionedLinkableInterface, handleSpecialLibs bool) apexFile { +func apexFileForNativeLibrary(ctx android.BaseModuleContext, module android.Module, + commonInfo *android.CommonModuleInfo, ccMod *cc.LinkableInfo, handleSpecialLibs bool) apexFile { // Decide the APEX-local directory by the multilib of the library In the future, we may // query this to the module. // TODO(jiyong): use the new PackagingSpec var dirInApex string - switch ccMod.Multilib() { + switch ccMod.Multilib { case "lib32": dirInApex = "lib" case "lib64": dirInApex = "lib64" } - if ccMod.Target().NativeBridge == android.NativeBridgeEnabled { - dirInApex = filepath.Join(dirInApex, ccMod.Target().NativeBridgeRelativePath) - } - if handleSpecialLibs && cc.InstallToBootstrap(ccMod.BaseModuleName(), ctx.Config()) { + setDirInApexForNativeBridge(commonInfo, &dirInApex) + if handleSpecialLibs && cc.InstallToBootstrap(commonInfo.BaseModuleName, ctx.Config()) { // Special case for Bionic libs and other libs installed with them. This is to // prevent those libs from being included in the search path // /apex/com.android.runtime/${LIB}. This exclusion is required because those libs @@ -1407,66 +1413,68 @@ func apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod cc.VersionedL // This needs to go after the runtime APEX handling because otherwise we would get // weird paths like lib64/rel_install_path/bionic rather than // lib64/bionic/rel_install_path. - dirInApex = filepath.Join(dirInApex, ccMod.RelativeInstallPath()) + dirInApex = filepath.Join(dirInApex, ccMod.RelativeInstallPath) - fileToCopy := android.OutputFileForModule(ctx, ccMod, "") - androidMkModuleName := ccMod.BaseModuleName() + ccMod.SubName() - return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, ccMod) + fileToCopy := android.OutputFileForModule(ctx, module, "") + androidMkModuleName := commonInfo.BaseModuleName + ccMod.SubName + return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, module) } -func apexFileForExecutable(ctx android.BaseModuleContext, cc *cc.Module) apexFile { +func apexFileForExecutable(ctx android.BaseModuleContext, module android.Module, + commonInfo *android.CommonModuleInfo, ccInfo *cc.CcInfo) apexFile { + linkableInfo := android.OtherModuleProviderOrDefault(ctx, module, cc.LinkableInfoProvider) dirInApex := "bin" - if cc.Target().NativeBridge == android.NativeBridgeEnabled { - dirInApex = filepath.Join(dirInApex, cc.Target().NativeBridgeRelativePath) - } - dirInApex = filepath.Join(dirInApex, cc.RelativeInstallPath()) - fileToCopy := android.OutputFileForModule(ctx, cc, "") - androidMkModuleName := cc.BaseModuleName() + cc.Properties.SubName - af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, cc) - af.symlinks = cc.Symlinks() - af.dataPaths = cc.DataPaths() + setDirInApexForNativeBridge(commonInfo, &dirInApex) + dirInApex = filepath.Join(dirInApex, linkableInfo.RelativeInstallPath) + fileToCopy := android.OutputFileForModule(ctx, module, "") + androidMkModuleName := commonInfo.BaseModuleName + linkableInfo.SubName + af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, module) + af.symlinks = linkableInfo.Symlinks + af.dataPaths = ccInfo.DataPaths return af } -func apexFileForRustExecutable(ctx android.BaseModuleContext, rustm *rust.Module) apexFile { +func apexFileForRustExecutable(ctx android.BaseModuleContext, module android.Module, + commonInfo *android.CommonModuleInfo) apexFile { + linkableInfo := android.OtherModuleProviderOrDefault(ctx, module, cc.LinkableInfoProvider) dirInApex := "bin" - if rustm.Target().NativeBridge == android.NativeBridgeEnabled { - dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath) - } - dirInApex = filepath.Join(dirInApex, rustm.RelativeInstallPath()) - fileToCopy := android.OutputFileForModule(ctx, rustm, "") - androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName - af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, rustm) + setDirInApexForNativeBridge(commonInfo, &dirInApex) + dirInApex = filepath.Join(dirInApex, linkableInfo.RelativeInstallPath) + fileToCopy := android.OutputFileForModule(ctx, module, "") + androidMkModuleName := commonInfo.BaseModuleName + linkableInfo.SubName + af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, module) return af } -func apexFileForShBinary(ctx android.BaseModuleContext, sh *sh.ShBinary) apexFile { - dirInApex := filepath.Join("bin", sh.SubDir()) - if sh.Target().NativeBridge == android.NativeBridgeEnabled { - dirInApex = filepath.Join(dirInApex, sh.Target().NativeBridgeRelativePath) - } - fileToCopy := sh.OutputFile() - af := newApexFile(ctx, fileToCopy, sh.BaseModuleName(), dirInApex, shBinary, sh) - af.symlinks = sh.Symlinks() +func apexFileForShBinary(ctx android.BaseModuleContext, module android.Module, + commonInfo *android.CommonModuleInfo, sh *sh.ShBinaryInfo) apexFile { + dirInApex := filepath.Join("bin", sh.SubDir) + setDirInApexForNativeBridge(commonInfo, &dirInApex) + fileToCopy := sh.OutputFile + af := newApexFile(ctx, fileToCopy, commonInfo.BaseModuleName, dirInApex, shBinary, module) + af.symlinks = sh.Symlinks return af } -func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt prebuilt_etc.PrebuiltEtcModule, outputFile android.Path) apexFile { - dirInApex := filepath.Join(prebuilt.BaseDir(), prebuilt.SubDir()) +func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, module android.Module, + prebuilt *prebuilt_etc.PrebuiltEtcInfo, outputFile android.Path) apexFile { + dirInApex := filepath.Join(prebuilt.BaseDir, prebuilt.SubDir) makeModuleName := strings.ReplaceAll(filepath.Join(dirInApex, outputFile.Base()), "/", "_") - return newApexFile(ctx, outputFile, makeModuleName, dirInApex, etc, prebuilt) + return newApexFile(ctx, outputFile, makeModuleName, dirInApex, etc, module) } -func apexFileForCompatConfig(ctx android.BaseModuleContext, config java.PlatformCompatConfigIntf, depName string) apexFile { - dirInApex := filepath.Join("etc", config.SubDir()) - fileToCopy := config.CompatConfig() - return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, config) +func apexFileForCompatConfig(ctx android.BaseModuleContext, module android.Module, + config *java.PlatformCompatConfigInfo, depName string) apexFile { + dirInApex := filepath.Join("etc", config.SubDir) + fileToCopy := config.CompatConfig + return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, module) } -func apexFileForVintfFragment(ctx android.BaseModuleContext, vintfFragment *android.VintfFragmentModule) apexFile { +func apexFileForVintfFragment(ctx android.BaseModuleContext, module android.Module, + commonInfo *android.CommonModuleInfo, vf *android.VintfFragmentInfo) apexFile { dirInApex := filepath.Join("etc", "vintf") - return newApexFile(ctx, vintfFragment.OutputFile(), vintfFragment.BaseModuleName(), dirInApex, etc, vintfFragment) + return newApexFile(ctx, vf.OutputFile, commonInfo.BaseModuleName, dirInApex, etc, module) } // javaModule is an interface to handle all Java modules (java_library, dex_import, etc) in the same @@ -1486,60 +1494,42 @@ var _ javaModule = (*java.DexImport)(nil) var _ javaModule = (*java.SdkLibraryImport)(nil) // apexFileForJavaModule creates an apexFile for a java module's dex implementation jar. -func apexFileForJavaModule(ctx android.ModuleContext, module javaModule) apexFile { - return apexFileForJavaModuleWithFile(ctx, module, module.DexJarBuildPath(ctx).PathOrNil()) +func apexFileForJavaModule(ctx android.ModuleContext, module android.Module, javaInfo *java.JavaInfo) apexFile { + return apexFileForJavaModuleWithFile(ctx, module, javaInfo, javaInfo.DexJarBuildPath.PathOrNil()) } // apexFileForJavaModuleWithFile creates an apexFile for a java module with the supplied file. -func apexFileForJavaModuleWithFile(ctx android.ModuleContext, module javaModule, dexImplementationJar android.Path) apexFile { +func apexFileForJavaModuleWithFile(ctx android.ModuleContext, module android.Module, + javaInfo *java.JavaInfo, dexImplementationJar android.Path) apexFile { dirInApex := "javalib" - af := newApexFile(ctx, dexImplementationJar, module.BaseModuleName(), dirInApex, javaSharedLib, module) - af.jacocoReportClassesFile = module.JacocoReportClassesFile() + commonInfo := android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey) + af := newApexFile(ctx, dexImplementationJar, commonInfo.BaseModuleName, dirInApex, javaSharedLib, module) + af.jacocoReportClassesFile = javaInfo.JacocoReportClassesFile if lintInfo, ok := android.OtherModuleProvider(ctx, module, java.LintProvider); ok { af.lintInfo = lintInfo } - af.customStem = module.Stem() + ".jar" + af.customStem = javaInfo.Stem + ".jar" // Collect any system server dex jars and dexpreopt artifacts for installation alongside the apex. // TODO: b/338641779 - Remove special casing of sdkLibrary once bcpf and sscpf depends // on the implementation library - if sdkLib, ok := module.(*java.SdkLibrary); ok { - af.systemServerDexpreoptInstalls = append(af.systemServerDexpreoptInstalls, sdkLib.ApexSystemServerDexpreoptInstalls()...) - af.systemServerDexJars = append(af.systemServerDexJars, sdkLib.ApexSystemServerDexJars()...) - } else if dexpreopter, ok := module.(java.DexpreopterInterface); ok { - af.systemServerDexpreoptInstalls = append(af.systemServerDexpreoptInstalls, dexpreopter.ApexSystemServerDexpreoptInstalls()...) - af.systemServerDexJars = append(af.systemServerDexJars, dexpreopter.ApexSystemServerDexJars()...) + if javaInfo.DexpreopterInfo != nil { + af.systemServerDexpreoptInstalls = append(af.systemServerDexpreoptInstalls, javaInfo.DexpreopterInfo.ApexSystemServerDexpreoptInstalls...) + af.systemServerDexJars = append(af.systemServerDexJars, javaInfo.DexpreopterInfo.ApexSystemServerDexJars...) } return af } -func apexFileForJavaModuleProfile(ctx android.BaseModuleContext, module javaModule) *apexFile { - if dexpreopter, ok := module.(java.DexpreopterInterface); ok { - if profilePathOnHost := dexpreopter.OutputProfilePathOnHost(); profilePathOnHost != nil { - dirInApex := "javalib" - af := newApexFile(ctx, profilePathOnHost, module.BaseModuleName()+"-profile", dirInApex, etc, nil) - af.customStem = module.Stem() + ".jar.prof" - return &af - } +func apexFileForJavaModuleProfile(ctx android.BaseModuleContext, commonInfo *android.CommonModuleInfo, + javaInfo *java.JavaInfo) *apexFile { + if profilePathOnHost := javaInfo.DexpreopterInfo.OutputProfilePathOnHost; profilePathOnHost != nil { + dirInApex := "javalib" + af := newApexFile(ctx, profilePathOnHost, commonInfo.BaseModuleName+"-profile", dirInApex, etc, nil) + af.customStem = javaInfo.Stem + ".jar.prof" + return &af } return nil } -// androidApp is an interface to handle all app modules (android_app, android_app_import, etc.) in -// the same way. -type androidApp interface { - android.Module - Privileged() bool - InstallApkName() string - OutputFile() android.Path - JacocoReportClassesFile() android.Path - Certificate() java.Certificate - BaseModuleName() string - PrivAppAllowlist() android.OptionalPath -} - -var _ androidApp = (*java.AndroidApp)(nil) -var _ androidApp = (*java.AndroidAppImport)(nil) - func sanitizedBuildIdForPath(ctx android.BaseModuleContext) string { buildId := ctx.Config().BuildId() @@ -1555,36 +1545,35 @@ func sanitizedBuildIdForPath(ctx android.BaseModuleContext) string { return buildId } -func apexFilesForAndroidApp(ctx android.BaseModuleContext, aapp androidApp) []apexFile { +func apexFilesForAndroidApp(ctx android.BaseModuleContext, module android.Module, + commonInfo *android.CommonModuleInfo, aapp *java.AppInfo) []apexFile { appDir := "app" - if aapp.Privileged() { + if aapp.Privileged { appDir = "priv-app" } // TODO(b/224589412, b/226559955): Ensure that the subdirname is suffixed // so that PackageManager correctly invalidates the existing installed apk // in favour of the new APK-in-APEX. See bugs for more information. - dirInApex := filepath.Join(appDir, aapp.InstallApkName()+"@"+sanitizedBuildIdForPath(ctx)) - fileToCopy := aapp.OutputFile() + dirInApex := filepath.Join(appDir, aapp.InstallApkName+"@"+sanitizedBuildIdForPath(ctx)) + fileToCopy := aapp.OutputFile - af := newApexFile(ctx, fileToCopy, aapp.BaseModuleName(), dirInApex, app, aapp) - af.jacocoReportClassesFile = aapp.JacocoReportClassesFile() - if lintInfo, ok := android.OtherModuleProvider(ctx, aapp, java.LintProvider); ok { + af := newApexFile(ctx, fileToCopy, commonInfo.BaseModuleName, dirInApex, app, module) + af.jacocoReportClassesFile = aapp.JacocoReportClassesFile + if lintInfo, ok := android.OtherModuleProvider(ctx, module, java.LintProvider); ok { af.lintInfo = lintInfo } - af.certificate = aapp.Certificate() + af.certificate = aapp.Certificate - if app, ok := aapp.(interface { - OverriddenManifestPackageName() string - }); ok { - af.overriddenPackageName = app.OverriddenManifestPackageName() + if aapp.OverriddenManifestPackageName != nil { + af.overriddenPackageName = *aapp.OverriddenManifestPackageName } apexFiles := []apexFile{} - if allowlist := aapp.PrivAppAllowlist(); allowlist.Valid() { + if allowlist := aapp.PrivAppAllowlist; allowlist.Valid() { dirInApex := filepath.Join("etc", "permissions") - privAppAllowlist := newApexFile(ctx, allowlist.Path(), aapp.BaseModuleName()+"_privapp", dirInApex, etc, aapp) + privAppAllowlist := newApexFile(ctx, allowlist.Path(), commonInfo.BaseModuleName+"_privapp", dirInApex, etc, module) apexFiles = append(apexFiles, privAppAllowlist) } @@ -1593,29 +1582,24 @@ func apexFilesForAndroidApp(ctx android.BaseModuleContext, aapp androidApp) []ap return apexFiles } -func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, rro java.RuntimeResourceOverlayModule) apexFile { +func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, module android.Module, rro java.RuntimeResourceOverlayInfo) apexFile { rroDir := "overlay" - dirInApex := filepath.Join(rroDir, rro.Theme()) - fileToCopy := rro.OutputFile() - af := newApexFile(ctx, fileToCopy, rro.Name(), dirInApex, app, rro) - af.certificate = rro.Certificate() + dirInApex := filepath.Join(rroDir, rro.Theme) + fileToCopy := rro.OutputFile + af := newApexFile(ctx, fileToCopy, module.Name(), dirInApex, app, module) + af.certificate = rro.Certificate - if a, ok := rro.(interface { - OverriddenManifestPackageName() string - }); ok { - af.overriddenPackageName = a.OverriddenManifestPackageName() - } return af } -func apexFileForBpfProgram(ctx android.BaseModuleContext, builtFile android.Path, apex_sub_dir string, bpfProgram bpf.BpfModule) apexFile { +func apexFileForBpfProgram(ctx android.BaseModuleContext, builtFile android.Path, apex_sub_dir string, bpfProgram android.Module) apexFile { dirInApex := filepath.Join("etc", "bpf", apex_sub_dir) return newApexFile(ctx, builtFile, builtFile.Base(), dirInApex, etc, bpfProgram) } -func apexFileForFilesystem(ctx android.BaseModuleContext, buildFile android.Path, fs filesystem.Filesystem) apexFile { +func apexFileForFilesystem(ctx android.BaseModuleContext, buildFile android.Path, module android.Module) apexFile { dirInApex := filepath.Join("etc", "fs") - return newApexFile(ctx, buildFile, buildFile.Base(), dirInApex, etc, fs) + return newApexFile(ctx, buildFile, buildFile.Base(), dirInApex, etc, module) } // WalkPayloadDeps visits dependencies that contributes to the payload of this APEX. For each of the @@ -1864,11 +1848,12 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok { return false } - if !child.Enabled(ctx) { + commonInfo := android.OtherModuleProviderOrDefault(ctx, child, android.CommonModuleInfoKey) + if !commonInfo.Enabled { return false } depName := ctx.OtherModuleName(child) - if _, isDirectDep := parent.(*apexBundle); isDirectDep { + if ctx.EqualModules(parent, ctx.Module()) { switch depTag { case sharedLibTag, jniLibTag: isJniLib := depTag == jniLibTag @@ -1877,17 +1862,17 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, propertyName = "jni_libs" } - if ch, ok := child.(cc.VersionedLinkableInterface); ok { - if ch.IsStubs() { + if ch, ok := android.OtherModuleProvider(ctx, child, cc.LinkableInfoProvider); ok { + if ch.IsStubs { ctx.PropertyErrorf(propertyName, "%q is a stub. Remove it from the list.", depName) } - fi := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs) + fi := apexFileForNativeLibrary(ctx, child, &commonInfo, ch, vctx.handleSpecialLibs) fi.isJniLib = isJniLib vctx.filesInfo = append(vctx.filesInfo, fi) // Collect the list of stub-providing libs except: // - VNDK libs are only for vendors // - bootstrap bionic libs are treated as provided by system - if ch.HasStubsVariants() && !a.vndkApex && !cc.InstallToBootstrap(ch.BaseModuleName(), ctx.Config()) { + if ch.HasStubsVariants && !a.vndkApex && !cc.InstallToBootstrap(commonInfo.BaseModuleName, ctx.Config()) { vctx.provideNativeLibs = append(vctx.provideNativeLibs, fi.stem()) } return true // track transitive dependencies @@ -1897,34 +1882,33 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, } case executableTag: - switch ch := child.(type) { - case *cc.Module: - vctx.filesInfo = append(vctx.filesInfo, apexFileForExecutable(ctx, ch)) + if ccInfo, ok := android.OtherModuleProvider(ctx, child, cc.CcInfoProvider); ok { + vctx.filesInfo = append(vctx.filesInfo, apexFileForExecutable(ctx, child, &commonInfo, ccInfo)) return true // track transitive dependencies - case *rust.Module: - vctx.filesInfo = append(vctx.filesInfo, apexFileForRustExecutable(ctx, ch)) + } + if _, ok := android.OtherModuleProvider(ctx, child, rust.RustInfoProvider); ok { + vctx.filesInfo = append(vctx.filesInfo, apexFileForRustExecutable(ctx, child, &commonInfo)) return true // track transitive dependencies - default: + } else { ctx.PropertyErrorf("binaries", "%q is neither cc_binary, rust_binary, (embedded) py_binary, (host) blueprint_go_binary, nor (host) bootstrap_go_binary", depName) } case shBinaryTag: - if csh, ok := child.(*sh.ShBinary); ok { - vctx.filesInfo = append(vctx.filesInfo, apexFileForShBinary(ctx, csh)) + if csh, ok := android.OtherModuleProvider(ctx, child, sh.ShBinaryInfoProvider); ok { + vctx.filesInfo = append(vctx.filesInfo, apexFileForShBinary(ctx, child, &commonInfo, &csh)) } else { ctx.PropertyErrorf("sh_binaries", "%q is not a sh_binary module", depName) } case bcpfTag: - _, ok := child.(*java.BootclasspathFragmentModule) + _, ok := android.OtherModuleProvider(ctx, child, java.BootclasspathFragmentInfoProvider) if !ok { ctx.PropertyErrorf("bootclasspath_fragments", "%q is not a bootclasspath_fragment module", depName) return false } - vctx.filesInfo = append(vctx.filesInfo, apexBootclasspathFragmentFiles(ctx, child)...) return true case sscpfTag: - if _, ok := child.(*java.SystemServerClasspathModule); !ok { + if _, ok := android.OtherModuleProvider(ctx, child, java.LibraryNameToPartitionInfoProvider); !ok { ctx.PropertyErrorf("systemserverclasspath_fragments", "%q is not a systemserverclasspath_fragment module", depName) return false @@ -1934,83 +1918,84 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, } return true case javaLibTag: - switch child.(type) { - case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport, *java.Import: - af := apexFileForJavaModule(ctx, child.(javaModule)) + if ctx.OtherModuleHasProvider(child, java.JavaLibraryInfoProvider) || + ctx.OtherModuleHasProvider(child, java.JavaDexImportInfoProvider) || + ctx.OtherModuleHasProvider(child, java.SdkLibraryInfoProvider) { + javaInfo := android.OtherModuleProviderOrDefault(ctx, child, java.JavaInfoProvider) + af := apexFileForJavaModule(ctx, child, javaInfo) if !af.ok() { ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName) return false } vctx.filesInfo = append(vctx.filesInfo, af) return true // track transitive dependencies - default: + } else { ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child)) } case androidAppTag: - switch ap := child.(type) { - case *java.AndroidApp: - vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...) - return true // track transitive dependencies - case *java.AndroidAppImport: - vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...) - case *java.AndroidTestHelperApp: - vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...) - case *java.AndroidAppSet: - appDir := "app" - if ap.Privileged() { - appDir = "priv-app" + if appInfo, ok := android.OtherModuleProvider(ctx, child, java.AppInfoProvider); ok { + if appInfo.AppSet { + appDir := "app" + if appInfo.Privileged { + appDir = "priv-app" + } + // TODO(b/224589412, b/226559955): Ensure that the dirname is + // suffixed so that PackageManager correctly invalidates the + // existing installed apk in favour of the new APK-in-APEX. + // See bugs for more information. + appDirName := filepath.Join(appDir, commonInfo.BaseModuleName+"@"+sanitizedBuildIdForPath(ctx)) + af := newApexFile(ctx, appInfo.OutputFile, commonInfo.BaseModuleName, appDirName, appSet, child) + af.certificate = java.PresignedCertificate + vctx.filesInfo = append(vctx.filesInfo, af) + } else { + vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, child, &commonInfo, appInfo)...) + if !appInfo.Prebuilt && !appInfo.TestHelperApp { + return true // track transitive dependencies + } } - // TODO(b/224589412, b/226559955): Ensure that the dirname is - // suffixed so that PackageManager correctly invalidates the - // existing installed apk in favour of the new APK-in-APEX. - // See bugs for more information. - appDirName := filepath.Join(appDir, ap.BaseModuleName()+"@"+sanitizedBuildIdForPath(ctx)) - af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(), appDirName, appSet, ap) - af.certificate = java.PresignedCertificate - vctx.filesInfo = append(vctx.filesInfo, af) - default: + } else { ctx.PropertyErrorf("apps", "%q is not an android_app module", depName) } case rroTag: - if rro, ok := child.(java.RuntimeResourceOverlayModule); ok { - vctx.filesInfo = append(vctx.filesInfo, apexFileForRuntimeResourceOverlay(ctx, rro)) + if rro, ok := android.OtherModuleProvider(ctx, child, java.RuntimeResourceOverlayInfoProvider); ok { + vctx.filesInfo = append(vctx.filesInfo, apexFileForRuntimeResourceOverlay(ctx, child, rro)) } else { ctx.PropertyErrorf("rros", "%q is not an runtime_resource_overlay module", depName) } case bpfTag: - if bpfProgram, ok := child.(bpf.BpfModule); ok { - filesToCopy := android.OutputFilesForModule(ctx, bpfProgram, "") - apex_sub_dir := bpfProgram.SubDir() + if bpfProgram, ok := android.OtherModuleProvider(ctx, child, bpf.BpfInfoProvider); ok { + filesToCopy := android.OutputFilesForModule(ctx, child, "") + apex_sub_dir := bpfProgram.SubDir for _, bpfFile := range filesToCopy { - vctx.filesInfo = append(vctx.filesInfo, apexFileForBpfProgram(ctx, bpfFile, apex_sub_dir, bpfProgram)) + vctx.filesInfo = append(vctx.filesInfo, apexFileForBpfProgram(ctx, bpfFile, apex_sub_dir, child)) } } else { ctx.PropertyErrorf("bpfs", "%q is not a bpf module", depName) } case fsTag: - if fs, ok := child.(filesystem.Filesystem); ok { - vctx.filesInfo = append(vctx.filesInfo, apexFileForFilesystem(ctx, fs.OutputPath(), fs)) + if fs, ok := android.OtherModuleProvider(ctx, child, filesystem.FilesystemProvider); ok { + vctx.filesInfo = append(vctx.filesInfo, apexFileForFilesystem(ctx, fs.Output, child)) } else { ctx.PropertyErrorf("filesystems", "%q is not a filesystem module", depName) } case prebuiltTag: - if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok { - filesToCopy := android.OutputFilesForModule(ctx, prebuilt, "") + if prebuilt, ok := android.OtherModuleProvider(ctx, child, prebuilt_etc.PrebuiltEtcInfoProvider); ok { + filesToCopy := android.OutputFilesForModule(ctx, child, "") for _, etcFile := range filesToCopy { - vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, etcFile)) + vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, child, &prebuilt, etcFile)) } } else { ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName) } case compatConfigTag: - if compatConfig, ok := child.(java.PlatformCompatConfigIntf); ok { - vctx.filesInfo = append(vctx.filesInfo, apexFileForCompatConfig(ctx, compatConfig, depName)) + if compatConfig, ok := android.OtherModuleProvider(ctx, child, java.PlatformCompatConfigInfoProvider); ok { + vctx.filesInfo = append(vctx.filesInfo, apexFileForCompatConfig(ctx, child, &compatConfig, depName)) } else { ctx.PropertyErrorf("compat_configs", "%q is not a platform_compat_config module", depName) } case testTag: - if ccTest, ok := child.(*cc.Module); ok { - af := apexFileForExecutable(ctx, ccTest) + if ccInfo, ok := android.OtherModuleProvider(ctx, child, cc.CcInfoProvider); ok { + af := apexFileForExecutable(ctx, child, &commonInfo, ccInfo) af.class = nativeTest vctx.filesInfo = append(vctx.filesInfo, af) return true // track transitive dependencies @@ -2018,14 +2003,14 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, ctx.PropertyErrorf("tests", "%q is not a cc module", depName) } case keyTag: - if key, ok := child.(*apexKey); ok { - a.privateKeyFile = key.privateKeyFile - a.publicKeyFile = key.publicKeyFile + if key, ok := android.OtherModuleProvider(ctx, child, ApexKeyInfoProvider); ok { + a.privateKeyFile = key.PrivateKeyFile + a.publicKeyFile = key.PublicKeyFile } else { ctx.PropertyErrorf("key", "%q is not an apex_key module", depName) } case certificateTag: - if dep, ok := child.(*java.AndroidAppCertificate); ok { + if dep, ok := android.OtherModuleProvider(ctx, child, java.AndroidAppCertificateInfoProvider); ok { a.containerCertificateFile = dep.Certificate.Pem a.containerPrivateKeyFile = dep.Certificate.Key } else { @@ -2040,18 +2025,17 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, } // indirect dependencies - am, ok := child.(android.ApexModule) - if !ok { + if !commonInfo.IsApexModule { return false } // We cannot use a switch statement on `depTag` here as the checked // tags used below are private (e.g. `cc.sharedDepTag`). if cc.IsSharedDepTag(depTag) || cc.IsRuntimeDepTag(depTag) { - if ch, ok := child.(cc.VersionedLinkableInterface); ok { - af := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs) + if ch, ok := android.OtherModuleProvider(ctx, child, cc.LinkableInfoProvider); ok { + af := apexFileForNativeLibrary(ctx, child, &commonInfo, ch, vctx.handleSpecialLibs) af.transitiveDep = true - if ch.IsStubs() || ch.HasStubsVariants() { + if ch.IsStubs || ch.HasStubsVariants { // If the dependency is a stubs lib, don't include it in this APEX, // but make sure that the lib is installed on the device. // In case no APEX is having the lib, the lib is installed to the system @@ -2062,10 +2046,10 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, // // Skip the dependency in unbundled builds where the device image is not // being built. - if ch.VersionedInterface().IsStubsImplementationRequired() && - !am.NotInPlatform() && !ctx.Config().UnbundledBuild() { + if ch.IsStubsImplementationRequired && + !commonInfo.NotInPlatform && !ctx.Config().UnbundledBuild() { // we need a module name for Make - name := ch.ImplementationModuleNameForMake(ctx) + ch.SubName() + name := ch.ImplementationModuleNameForMake + ch.SubName if !android.InList(name, a.makeModulesToInstall) { a.makeModulesToInstall = append(a.makeModulesToInstall, name) } @@ -2084,7 +2068,7 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, // like to record requiredNativeLibs even when // DepIsInSameAPex is false. We also shouldn't do // this for host. - if !android.IsDepInSameApex(ctx, parent, am) { + if !android.IsDepInSameApex(ctx, parent, child) { return false } @@ -2096,19 +2080,21 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, } else if java.IsJniDepTag(depTag) { // Because APK-in-APEX embeds jni_libs transitively, we don't need to track transitive deps } else if java.IsXmlPermissionsFileDepTag(depTag) { - if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok { - filesToCopy := android.OutputFilesForModule(ctx, prebuilt, "") + if prebuilt, ok := android.OtherModuleProvider(ctx, child, prebuilt_etc.PrebuiltEtcInfoProvider); ok { + filesToCopy := android.OutputFilesForModule(ctx, child, "") for _, etcFile := range filesToCopy { - vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, etcFile)) + vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, child, &prebuilt, etcFile)) } } } else if rust.IsDylibDepTag(depTag) { - if rustm, ok := child.(*rust.Module); ok && rustm.IsInstallableToApex() { - if !android.IsDepInSameApex(ctx, am, am) { + if _, ok := android.OtherModuleProvider(ctx, child, rust.RustInfoProvider); ok && + commonInfo.IsInstallableToApex { + if !android.IsDepInSameApex(ctx, parent, child) { return false } - af := apexFileForNativeLibrary(ctx, child.(cc.VersionedLinkableInterface), vctx.handleSpecialLibs) + linkableInfo := android.OtherModuleProviderOrDefault(ctx, child, cc.LinkableInfoProvider) + af := apexFileForNativeLibrary(ctx, child, &commonInfo, linkableInfo, vctx.handleSpecialLibs) af.transitiveDep = true vctx.filesInfo = append(vctx.filesInfo, af) return true // track transitive dependencies @@ -2119,10 +2105,9 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, return true } else if java.IsBootclasspathFragmentContentDepTag(depTag) { // Add the contents of the bootclasspath fragment to the apex. - switch child.(type) { - case *java.Library, *java.SdkLibrary: - javaModule := child.(javaModule) - af := apexFileForBootclasspathFragmentContentModule(ctx, parent, javaModule) + if ctx.OtherModuleHasProvider(child, java.JavaLibraryInfoProvider) || + ctx.OtherModuleHasProvider(child, java.SdkLibraryInfoProvider) { + af := apexFileForBootclasspathFragmentContentModule(ctx, parent, child) if !af.ok() { ctx.PropertyErrorf("bootclasspath_fragments", "bootclasspath_fragment content %q is not configured to be compiled into dex", depName) @@ -2130,21 +2115,22 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, } vctx.filesInfo = append(vctx.filesInfo, af) return true // track transitive dependencies - default: + } else { ctx.PropertyErrorf("bootclasspath_fragments", "bootclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child)) } } else if java.IsSystemServerClasspathFragmentContentDepTag(depTag) { // Add the contents of the systemserverclasspath fragment to the apex. - switch child.(type) { - case *java.Library, *java.SdkLibrary: - af := apexFileForJavaModule(ctx, child.(javaModule)) + if ctx.OtherModuleHasProvider(child, java.JavaLibraryInfoProvider) || + ctx.OtherModuleHasProvider(child, java.SdkLibraryInfoProvider) { + javaInfo := android.OtherModuleProviderOrDefault(ctx, child, java.JavaInfoProvider) + af := apexFileForJavaModule(ctx, child, javaInfo) vctx.filesInfo = append(vctx.filesInfo, af) - if profileAf := apexFileForJavaModuleProfile(ctx, child.(javaModule)); profileAf != nil { + if profileAf := apexFileForJavaModuleProfile(ctx, &commonInfo, javaInfo); profileAf != nil { vctx.filesInfo = append(vctx.filesInfo, *profileAf) } return true // track transitive dependencies - default: + } else { ctx.PropertyErrorf("systemserverclasspath_fragments", "systemserverclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child)) } @@ -2152,11 +2138,11 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, // nothing } else if depTag == android.RequiredDepTag { // nothing - } else if am.CanHaveApexVariants() && am.IsInstallableToApex() { + } else if commonInfo.IsInstallableToApex { ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName) } else if android.IsVintfDepTag(depTag) { - if vf, ok := child.(*android.VintfFragmentModule); ok { - apexFile := apexFileForVintfFragment(ctx, vf) + if vf, ok := android.OtherModuleProvider(ctx, child, android.VintfFragmentInfoProvider); ok { + apexFile := apexFileForVintfFragment(ctx, child, &commonInfo, &vf) vctx.filesInfo = append(vctx.filesInfo, apexFile) } } @@ -2325,8 +2311,8 @@ func (a *apexBundle) enforceAppUpdatability(mctx android.ModuleContext) { // checking direct deps is sufficient since apex->apk is a direct edge, even when inherited via apex_defaults mctx.VisitDirectDepsProxy(func(module android.ModuleProxy) { if appInfo, ok := android.OtherModuleProvider(mctx, module, java.AppInfoProvider); ok { - // ignore android_test_app - if !appInfo.TestHelperApp && !appInfo.Updatable { + // ignore android_test_app and android_app_import + if !appInfo.TestHelperApp && !appInfo.Prebuilt && !appInfo.Updatable { mctx.ModuleErrorf("app dependency %s must have updatable: true", mctx.OtherModuleName(module)) } } @@ -2336,7 +2322,7 @@ func (a *apexBundle) enforceAppUpdatability(mctx android.ModuleContext) { // apexBootclasspathFragmentFiles returns the list of apexFile structures defining the files that // the bootclasspath_fragment contributes to the apex. -func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module blueprint.Module) []apexFile { +func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module android.Module) []apexFile { bootclasspathFragmentInfo, _ := android.OtherModuleProvider(ctx, module, java.BootclasspathFragmentApexContentInfoProvider) var filesToAdd []apexFile @@ -2385,7 +2371,7 @@ func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module blueprint. // apexClasspathFragmentProtoFile returns *apexFile structure defining the classpath.proto config that // the module contributes to the apex; or nil if the proto config was not generated. -func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module blueprint.Module) *apexFile { +func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module android.Module) *apexFile { info, _ := android.OtherModuleProvider(ctx, module, java.ClasspathFragmentProtoContentInfoProvider) if !info.ClasspathFragmentProtoGenerated { return nil @@ -2397,7 +2383,7 @@ func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module blueprint. // apexFileForBootclasspathFragmentContentModule creates an apexFile for a bootclasspath_fragment // content module, i.e. a library that is part of the bootclasspath. -func apexFileForBootclasspathFragmentContentModule(ctx android.ModuleContext, fragmentModule blueprint.Module, javaModule javaModule) apexFile { +func apexFileForBootclasspathFragmentContentModule(ctx android.ModuleContext, fragmentModule, javaModule android.Module) apexFile { bootclasspathFragmentInfo, _ := android.OtherModuleProvider(ctx, fragmentModule, java.BootclasspathFragmentApexContentInfoProvider) // Get the dexBootJar from the bootclasspath_fragment as that is responsible for performing the @@ -2409,7 +2395,8 @@ func apexFileForBootclasspathFragmentContentModule(ctx android.ModuleContext, fr // Create an apexFile as for a normal java module but with the dex boot jar provided by the // bootclasspath_fragment. - af := apexFileForJavaModuleWithFile(ctx, javaModule, dexBootJar) + javaInfo := android.OtherModuleProviderOrDefault(ctx, javaModule, java.JavaInfoProvider) + af := apexFileForJavaModuleWithFile(ctx, javaModule, javaInfo, dexBootJar) return af } @@ -2896,14 +2883,14 @@ func (a *apexBundle) verifyNativeImplementationLibs(ctx android.ModuleContext) { if !inApex && !inApkInApex { ctx.ModuleErrorf("library in apex transitively linked against implementation library %q not in apex", lib) var depPath []android.Module - ctx.WalkDeps(func(child, parent android.Module) bool { + ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool { if depPath != nil { return false } tag := ctx.OtherModuleDependencyTag(child) - if parent == ctx.Module() { + if ctx.EqualModules(parent, ctx.Module()) { if !checkApexTag(tag) { return false } diff --git a/apex/apex_test.go b/apex/apex_test.go index 5519bd2fd..9eaf814d0 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -7874,7 +7874,7 @@ func TestJavaSDKLibrary_WithinApex(t *testing.T) { // The bar library should depend on the implementation jar. barLibrary := ctx.ModuleForTests(t, "bar", "android_common_apex10000").Rule("javac") - if expected, actual := `^-classpath [^:]*/turbine-combined/foo\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) { + if expected, actual := `^-classpath [^:]*/turbine/foo\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) { t.Errorf("expected %q, found %#q", expected, actual) } } @@ -7926,7 +7926,7 @@ func TestJavaSDKLibrary_CrossBoundary(t *testing.T) { // The bar library should depend on the stubs jar. barLibrary := ctx.ModuleForTests(t, "bar", "android_common").Rule("javac") - if expected, actual := `^-classpath [^:]*/turbine-combined/foo\.stubs\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) { + if expected, actual := `^-classpath [^:]*/foo\.stubs\.from-text/foo\.stubs\.from-text\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) { t.Errorf("expected %q, found %#q", expected, actual) } } @@ -8020,7 +8020,7 @@ func TestJavaSDKLibrary_ImportPreferred(t *testing.T) { // The bar library should depend on the implementation jar. barLibrary := ctx.ModuleForTests(t, "bar", "android_common_apex10000").Rule("javac") - if expected, actual := `^-classpath [^:]*/turbine-combined/foo\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) { + if expected, actual := `^-classpath [^:]*/turbine/foo\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) { t.Errorf("expected %q, found %#q", expected, actual) } } diff --git a/apex/key.go b/apex/key.go index 1622c65e6..cc66a131f 100644 --- a/apex/key.go +++ b/apex/key.go @@ -33,6 +33,13 @@ func registerApexKeyBuildComponents(ctx android.RegistrationContext) { ctx.RegisterParallelSingletonModuleType("all_apex_certs", allApexCertsFactory) } +type ApexKeyInfo struct { + PublicKeyFile android.Path + PrivateKeyFile android.Path +} + +var ApexKeyInfoProvider = blueprint.NewProvider[ApexKeyInfo]() + type apexKey struct { android.ModuleBase @@ -95,6 +102,11 @@ func (m *apexKey) GenerateAndroidBuildActions(ctx android.ModuleContext) { m.publicKeyFile.String(), pubKeyName, m.privateKeyFile, privKeyName) return } + + android.SetProvider(ctx, ApexKeyInfoProvider, ApexKeyInfo{ + PublicKeyFile: m.publicKeyFile, + PrivateKeyFile: m.privateKeyFile, + }) } type apexKeyEntry struct { diff --git a/bpf/bpf.go b/bpf/bpf.go index 3f3438247..deb465dd6 100644 --- a/bpf/bpf.go +++ b/bpf/bpf.go @@ -60,6 +60,12 @@ func registerBpfBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("bpf", BpfFactory) } +type BpfInfo struct { + SubDir string +} + +var BpfInfoProvider = blueprint.NewProvider[BpfInfo]() + var PrepareForTestWithBpf = android.FixtureRegisterWithContext(registerBpfBuildComponents) // BpfModule interface is used by the apex package to gather information from a bpf module. @@ -230,6 +236,10 @@ func (bpf *bpf) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.PackageFile(installDir, obj.Base(), obj) } + android.SetProvider(ctx, BpfInfoProvider, BpfInfo{ + SubDir: bpf.SubDir(), + }) + ctx.SetOutputFiles(bpf.objs, "") } diff --git a/cc/afdo.go b/cc/afdo.go index 828e494e1..8d8341eb4 100644 --- a/cc/afdo.go +++ b/cc/afdo.go @@ -96,8 +96,10 @@ func (afdo *afdo) flags(ctx ModuleContext, flags Flags) Flags { flags.Local.CFlags = append([]string{"-funique-internal-linkage-names"}, flags.Local.CFlags...) // Flags for Flow Sensitive AutoFDO flags.Local.CFlags = append([]string{"-mllvm", "-enable-fs-discriminator=true"}, flags.Local.CFlags...) + flags.Local.LdFlags = append([]string{"-Wl,-mllvm,-enable-fs-discriminator=true"}, flags.Local.LdFlags...) // TODO(b/266595187): Remove the following feature once it is enabled in LLVM by default. flags.Local.CFlags = append([]string{"-mllvm", "-improved-fs-discriminator=true"}, flags.Local.CFlags...) + flags.Local.LdFlags = append([]string{"-Wl,-mllvm,-improved-fs-discriminator=true"}, flags.Local.LdFlags...) } if fdoProfilePath := getFdoProfilePathFromDep(ctx); fdoProfilePath != "" { // The flags are prepended to allow overriding. @@ -117,6 +117,7 @@ type CcInfo struct { IsPrebuilt bool CmakeSnapshotSupported bool HasLlndkStubs bool + DataPaths []android.DataPath CompilerInfo *CompilerInfo LinkerInfo *LinkerInfo SnapshotInfo *SnapshotInfo @@ -148,10 +149,8 @@ type LinkableInfo struct { CrateName string // DepFlags returns a slice of Rustc string flags ExportedCrateLinkDirs []string - // This can be different from the one on CommonModuleInfo - BaseModuleName string - HasNonSystemVariants bool - IsLlndk bool + HasNonSystemVariants bool + IsLlndk bool // True if the library is in the configs known NDK list. IsNdk bool InVendorOrProduct bool @@ -163,13 +162,20 @@ type LinkableInfo struct { OnlyInVendorRamdisk bool InRecovery bool OnlyInRecovery bool + InVendor bool Installable *bool // RelativeInstallPath returns the relative install path for this module. RelativeInstallPath string // TODO(b/362509506): remove this once all apex_exclude uses are switched to stubs. RustApexExclude bool // Bootstrap tests if this module is allowed to use non-APEX version of libraries. - Bootstrap bool + Bootstrap bool + Multilib string + ImplementationModuleNameForMake string + IsStubsImplementationRequired bool + // Symlinks returns a list of symlinks that should be created for this module. + Symlinks []string + APIListCoverageXMLPath android.ModuleOutPath } var LinkableInfoProvider = blueprint.NewProvider[*LinkableInfo]() @@ -1576,7 +1582,7 @@ func (c *Module) ImplementationModuleName(ctx android.BaseModuleContext) string // where the Soong name is prebuilt_foo, this returns foo (which works in Make // under the premise that the prebuilt module overrides its source counterpart // if it is exposed to Make). -func (c *Module) ImplementationModuleNameForMake(ctx android.BaseModuleContext) string { +func (c *Module) ImplementationModuleNameForMake() string { name := c.BaseModuleName() if versioned, ok := c.linker.(VersionedInterface); ok { name = versioned.ImplementationModuleName(name) @@ -2293,6 +2299,7 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { IsPrebuilt: c.IsPrebuilt(), CmakeSnapshotSupported: proptools.Bool(c.Properties.Cmake_snapshot_supported), HasLlndkStubs: c.HasLlndkStubs(), + DataPaths: c.DataPaths(), } if c.compiler != nil { cflags := c.compiler.baseCompilerProps().Cflags @@ -2365,7 +2372,7 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { } func CreateCommonLinkableInfo(ctx android.ModuleContext, mod VersionedLinkableInterface) *LinkableInfo { - return &LinkableInfo{ + info := &LinkableInfo{ StaticExecutable: mod.StaticExecutable(), HasStubsVariants: mod.HasStubsVariants(), OutputFile: mod.OutputFile(), @@ -2376,7 +2383,6 @@ func CreateCommonLinkableInfo(ctx android.ModuleContext, mod VersionedLinkableIn CcLibrary: mod.CcLibrary(), CcLibraryInterface: mod.CcLibraryInterface(), RustLibraryInterface: mod.RustLibraryInterface(), - BaseModuleName: mod.BaseModuleName(), IsLlndk: mod.IsLlndk(), IsNdk: mod.IsNdk(ctx.Config()), HasNonSystemVariants: mod.HasNonSystemVariants(), @@ -2388,18 +2394,24 @@ func CreateCommonLinkableInfo(ctx android.ModuleContext, mod VersionedLinkableIn OnlyInVendorRamdisk: mod.OnlyInVendorRamdisk(), InRecovery: mod.InRecovery(), OnlyInRecovery: mod.OnlyInRecovery(), + InVendor: mod.InVendor(), Installable: mod.Installable(), RelativeInstallPath: mod.RelativeInstallPath(), // TODO(b/362509506): remove this once all apex_exclude uses are switched to stubs. - RustApexExclude: mod.RustApexExclude(), - Bootstrap: mod.Bootstrap(), + RustApexExclude: mod.RustApexExclude(), + Bootstrap: mod.Bootstrap(), + Multilib: mod.Multilib(), + ImplementationModuleNameForMake: mod.ImplementationModuleNameForMake(), + Symlinks: mod.Symlinks(), } -} -func setOutputFilesIfNotEmpty(ctx ModuleContext, files android.Paths, tag string) { - if len(files) > 0 { - ctx.SetOutputFiles(files, tag) + vi := mod.VersionedInterface() + if vi != nil { + info.IsStubsImplementationRequired = vi.IsStubsImplementationRequired() + info.APIListCoverageXMLPath = vi.GetAPIListCoverageXMLPath() } + + return info } func (c *Module) setOutputFiles(ctx ModuleContext) { @@ -3582,7 +3594,7 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { c.sabi.Properties.ReexportedSystemIncludes, depExporterInfo.SystemIncludeDirs.Strings()...) } - makeLibName := MakeLibName(ccInfo, linkableInfo, &commonInfo, linkableInfo.BaseModuleName) + libDepTag.makeSuffix + makeLibName := MakeLibName(ccInfo, linkableInfo, &commonInfo, commonInfo.BaseModuleName) + libDepTag.makeSuffix switch { case libDepTag.header(): c.Properties.AndroidMkHeaderLibs = append( @@ -3609,7 +3621,8 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { switch depTag { case runtimeDepTag: c.Properties.AndroidMkRuntimeLibs = append( - c.Properties.AndroidMkRuntimeLibs, MakeLibName(ccInfo, linkableInfo, &commonInfo, linkableInfo.BaseModuleName)+libDepTag.makeSuffix) + c.Properties.AndroidMkRuntimeLibs, MakeLibName(ccInfo, linkableInfo, &commonInfo, + commonInfo.BaseModuleName)+libDepTag.makeSuffix) case objDepTag: depPaths.Objs.objFiles = append(depPaths.Objs.objFiles, linkFile.Path()) case CrtBeginDepTag: @@ -3771,7 +3784,7 @@ func MakeLibName(ccInfo *CcInfo, linkableInfo *LinkableInfo, commonInfo *android if ccInfo != nil { // Use base module name for snapshots when exporting to Makefile. if ccInfo.SnapshotInfo != nil { - return linkableInfo.BaseModuleName + ccInfo.SnapshotInfo.SnapshotAndroidMkSuffix + return commonInfo.BaseModuleName + ccInfo.SnapshotInfo.SnapshotAndroidMkSuffix } } @@ -4033,15 +4046,6 @@ func installable(c LinkableInterface, apexInfo android.ApexInfo) bool { return ret } - // Special case for modules that are configured to be installed to /data, which includes - // test modules. For these modules, both APEX and non-APEX variants are considered as - // installable. This is because even the APEX variants won't be included in the APEX, but - // will anyway be installed to /data/*. - // See b/146995717 - if c.InstallInData() { - return ret - } - return false } diff --git a/cc/linkable.go b/cc/linkable.go index 337b45943..f3aff1523 100644 --- a/cc/linkable.go +++ b/cc/linkable.go @@ -83,7 +83,7 @@ type VersionedLinkableInterface interface { SetSdkVersion(string) SetMinSdkVersion(version string) ApexSdkVersion() android.ApiLevel - ImplementationModuleNameForMake(ctx android.BaseModuleContext) string + ImplementationModuleNameForMake() string // RustApexExclude returns ApexExclude() for Rust modules; always returns false for all non-Rust modules. // TODO(b/362509506): remove this once all apex_exclude uses are switched to stubs. diff --git a/cc/llndk_library.go b/cc/llndk_library.go index 558657668..8ca3ca184 100644 --- a/cc/llndk_library.go +++ b/cc/llndk_library.go @@ -147,6 +147,8 @@ func (txt *llndkLibrariesTxtModule) GenerateAndroidBuildActions(ctx android.Modu ctx.InstallFile(installPath, filename, txt.outputFile) ctx.SetOutputFiles(android.Paths{txt.outputFile}, "") + + etc.SetCommonPrebuiltEtcInfo(ctx, txt) } func getVndkFileName(m *Module) (string, error) { diff --git a/cc/sanitize.go b/cc/sanitize.go index e7598e709..b704ef4bf 100644 --- a/cc/sanitize.go +++ b/cc/sanitize.go @@ -1901,6 +1901,8 @@ func (txt *sanitizerLibrariesTxtModule) GenerateAndroidBuildActions(ctx android. ctx.SetOutputFiles(android.Paths{outputFile}, "") txt.outputFile = outputFile + + etc.SetCommonPrebuiltEtcInfo(ctx, txt) } func (txt *sanitizerLibrariesTxtModule) PrepareAndroidMKProviderInfo(config android.Config) *android.AndroidMkProviderInfo { diff --git a/cc/stub_library.go b/cc/stub_library.go index 9d7b5bc1a..21ef13915 100644 --- a/cc/stub_library.go +++ b/cc/stub_library.go @@ -43,9 +43,9 @@ func IsStubTarget(info *LinkableInfo) bool { } // Get target file name to be installed from this module -func getInstalledFileName(ctx android.SingletonContext, m LinkableInterface) string { +func getInstalledFileName(ctx android.SingletonContext, m android.ModuleProxy) string { for _, ps := range android.OtherModuleProviderOrDefault( - ctx, m.Module(), android.InstallFilesProvider).PackagingSpecs { + ctx, m, android.InstallFilesProvider).PackagingSpecs { if name := ps.FileName(); name != "" { return name } @@ -57,18 +57,18 @@ func (s *stubLibraries) GenerateBuildActions(ctx android.SingletonContext) { // Visit all generated soong modules and store stub library file names. stubLibraryMap := make(map[string]bool) vendorStubLibraryMap := make(map[string]bool) - ctx.VisitAllModules(func(module android.Module) { - if m, ok := module.(VersionedLinkableInterface); ok { - if IsStubTarget(android.OtherModuleProviderOrDefault(ctx, m, LinkableInfoProvider)) { - if name := getInstalledFileName(ctx, m); name != "" { + ctx.VisitAllModuleProxies(func(module android.ModuleProxy) { + if linkableInfo, ok := android.OtherModuleProvider(ctx, module, LinkableInfoProvider); ok { + if IsStubTarget(linkableInfo) { + if name := getInstalledFileName(ctx, module); name != "" { stubLibraryMap[name] = true - if m.InVendor() { + if linkableInfo.InVendor { vendorStubLibraryMap[name] = true } } } - if m.CcLibraryInterface() && android.IsModulePreferred(m) { - if p := m.VersionedInterface().GetAPIListCoverageXMLPath().String(); p != "" { + if linkableInfo.CcLibraryInterface && android.IsModulePreferredProxy(ctx, module) { + if p := linkableInfo.APIListCoverageXMLPath.String(); p != "" { s.apiListCoverageXmlPaths = append(s.apiListCoverageXmlPaths, p) } } diff --git a/cc/test.go b/cc/test.go index ccd83fec3..d2c4b28e8 100644 --- a/cc/test.go +++ b/cc/test.go @@ -424,6 +424,10 @@ func (test *testBinary) install(ctx ModuleContext, file android.Path) { if test.testConfig != nil { ctx.InstallFile(testCases, ctx.ModuleName()+".config", test.testConfig) } + dynamicConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml") + if dynamicConfig.Valid() { + ctx.InstallFile(testCases, ctx.ModuleName()+".dynamic", dynamicConfig.Path()) + } for _, extraTestConfig := range test.extraTestConfigs { ctx.InstallFile(testCases, extraTestConfig.Base(), extraTestConfig) } diff --git a/ci_tests/Android.bp b/ci_tests/Android.bp new file mode 100644 index 000000000..181ded46d --- /dev/null +++ b/ci_tests/Android.bp @@ -0,0 +1,21 @@ +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +bootstrap_go_package { + name: "soong-ci-tests", + pkgPath: "android/soong/ci_tests", + deps: [ + "blueprint", + "blueprint-proptools", + "soong", + "soong-android", + ], + srcs: [ + "ci_test_package_zip.go", + ], + testSrcs: [ + ], + pluginFor: ["soong_build"], + visibility: ["//visibility:public"], +} diff --git a/ci_tests/ci_test_package_zip.go b/ci_tests/ci_test_package_zip.go new file mode 100644 index 000000000..acfa8e073 --- /dev/null +++ b/ci_tests/ci_test_package_zip.go @@ -0,0 +1,241 @@ +// Copyright (C) 2025 The Android Open Source Project +// +// 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 ci_tests + +import ( + "fmt" + "path/filepath" + "strings" + + "android/soong/android" + "github.com/google/blueprint" + "github.com/google/blueprint/proptools" +) + +func init() { + pctx.Import("android/soong/android") + registerTestPackageZipBuildComponents(android.InitRegistrationContext) +} + +func registerTestPackageZipBuildComponents(ctx android.RegistrationContext) { + ctx.RegisterModuleType("test_package", TestPackageZipFactory) +} + +type testPackageZip struct { + android.ModuleBase + android.DefaultableModuleBase + + properties CITestPackageProperties + + output android.Path +} + +type CITestPackageProperties struct { + // test modules will be added as dependencies using the device os and the common architecture's variant. + Tests proptools.Configurable[[]string] `android:"arch_variant"` + // test modules that will be added as dependencies based on the first supported arch variant and the device os variant + Device_first_tests proptools.Configurable[[]string] `android:"arch_variant"` + // test modules that will be added as dependencies based on both 32bit and 64bit arch variant and the device os variant + Device_both_tests proptools.Configurable[[]string] `android:"arch_variant"` + // test modules that will be added as dependencies based on host + Host_tests proptools.Configurable[[]string] `android:"arch_variant"` + // git-main only test modules. Will only be added as dependencies using the device os and the common architecture's variant if exists. + Tests_if_exist_common proptools.Configurable[[]string] `android:"arch_variant"` + // git-main only test modules. Will only be added as dependencies based on both 32bit and 64bit arch variant and the device os variant if exists. + Tests_if_exist_device_both proptools.Configurable[[]string] `android:"arch_variant"` +} + +type testPackageZipDepTagType struct { + blueprint.BaseDependencyTag +} + +var testPackageZipDepTag testPackageZipDepTagType + +var ( + pctx = android.NewPackageContext("android/soong/ci_tests") + // test_package module type should only be used for the following modules. + // TODO: remove "_soong" from the module names inside when eliminating the corresponding make modules + moduleNamesAllowed = []string{"continuous_native_tests_soong", "continuous_instrumentation_tests_soong", "platform_tests"} +) + +func (p *testPackageZip) DepsMutator(ctx android.BottomUpMutatorContext) { + // adding tests property deps + for _, t := range p.properties.Tests.GetOrDefault(ctx, nil) { + ctx.AddVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), testPackageZipDepTag, t) + } + + // adding device_first_tests property deps + for _, t := range p.properties.Device_first_tests.GetOrDefault(ctx, nil) { + ctx.AddVariationDependencies(ctx.Config().AndroidFirstDeviceTarget.Variations(), testPackageZipDepTag, t) + } + + // adding device_both_tests property deps + p.addDeviceBothDeps(ctx, false) + + // adding host_tests property deps + for _, t := range p.properties.Host_tests.GetOrDefault(ctx, nil) { + ctx.AddVariationDependencies(ctx.Config().BuildOSTarget.Variations(), testPackageZipDepTag, t) + } + + // adding Tests_if_exist_* property deps + for _, t := range p.properties.Tests_if_exist_common.GetOrDefault(ctx, nil) { + if ctx.OtherModuleExists(t) { + ctx.AddVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), testPackageZipDepTag, t) + } + } + p.addDeviceBothDeps(ctx, true) +} + +func (p *testPackageZip) addDeviceBothDeps(ctx android.BottomUpMutatorContext, checkIfExist bool) { + android32TargetList := android.FirstTarget(ctx.Config().Targets[android.Android], "lib32") + android64TargetList := android.FirstTarget(ctx.Config().Targets[android.Android], "lib64") + if len(android32TargetList) > 0 { + maybeAndroid32Target := &android32TargetList[0] + if checkIfExist { + for _, t := range p.properties.Tests_if_exist_device_both.GetOrDefault(ctx, nil) { + if ctx.OtherModuleExists(t) { + ctx.AddFarVariationDependencies(maybeAndroid32Target.Variations(), testPackageZipDepTag, t) + } + } + } else { + ctx.AddFarVariationDependencies(maybeAndroid32Target.Variations(), testPackageZipDepTag, p.properties.Device_both_tests.GetOrDefault(ctx, nil)...) + } + } + if len(android64TargetList) > 0 { + maybeAndroid64Target := &android64TargetList[0] + if checkIfExist { + for _, t := range p.properties.Tests_if_exist_device_both.GetOrDefault(ctx, nil) { + if ctx.OtherModuleExists(t) { + ctx.AddFarVariationDependencies(maybeAndroid64Target.Variations(), testPackageZipDepTag, t) + } + } + } else { + ctx.AddFarVariationDependencies(maybeAndroid64Target.Variations(), testPackageZipDepTag, p.properties.Device_both_tests.GetOrDefault(ctx, nil)...) + } + } +} + +func TestPackageZipFactory() android.Module { + module := &testPackageZip{} + + module.AddProperties(&module.properties) + + android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon) + android.InitDefaultableModule(module) + + return module +} + +func (p *testPackageZip) GenerateAndroidBuildActions(ctx android.ModuleContext) { + if !android.InList(ctx.ModuleName(), moduleNamesAllowed) { + ctx.ModuleErrorf("%s is not allowed to use module type test_package") + } + + p.output = createOutput(ctx, pctx) + + ctx.SetOutputFiles(android.Paths{p.output}, "") + + // dist the test output + if ctx.ModuleName() == "platform_tests_soong" { + distedName := ctx.Config().Getenv("TARGET_PRODUCT") + "-tests-" + ctx.Config().BuildId() + ".zip" + ctx.DistForGoalsWithFilename([]string{"droid", "platform_tests"}, p.output, distedName) + } +} + +func createOutput(ctx android.ModuleContext, pctx android.PackageContext) android.ModuleOutPath { + productOut := filepath.Join(ctx.Config().OutDir(), "target", "product", ctx.Config().DeviceName()) + stagingDir := android.PathForModuleOut(ctx, "STAGING") + productVariables := ctx.Config().ProductVariables() + arch := proptools.String(productVariables.DeviceArch) + secondArch := proptools.String(productVariables.DeviceSecondaryArch) + + builder := android.NewRuleBuilder(pctx, ctx) + builder.Command().Text("rm").Flag("-rf").Text(stagingDir.String()) + builder.Command().Text("mkdir").Flag("-p").Output(stagingDir) + builder.Temporary(stagingDir) + ctx.VisitDirectDepsWithTag(testPackageZipDepTag, func(m android.Module) { + info, ok := android.OtherModuleProvider(ctx, m, android.ModuleInfoJSONProvider) + if !ok { + ctx.OtherModuleErrorf(m, "doesn't set ModuleInfoJSON provider") + } else if len(info) != 1 { + ctx.OtherModuleErrorf(m, "doesn't provide exactly one ModuleInfoJSON") + } + + classes := info[0].GetClass() + if len(info[0].Class) != 1 { + ctx.OtherModuleErrorf(m, "doesn't have exactly one class in its ModuleInfoJSON") + } + class := strings.ToLower(classes[0]) + if class == "apps" { + class = "app" + } else if class == "java_libraries" { + class = "framework" + } + + installedFilesInfo, ok := android.OtherModuleProvider(ctx, m, android.InstallFilesProvider) + if !ok { + ctx.ModuleErrorf("Module %s doesn't set InstallFilesProvider", m.Name()) + } + + for _, installedFile := range installedFilesInfo.InstallFiles { + // there are additional installed files for some app-class modules, we only need the .apk files in the test package + if class == "app" && installedFile.Ext() != ".apk" { + continue + } + name := removeFileExtension(installedFile.Base()) + f := strings.TrimPrefix(installedFile.String(), productOut+"/") + if strings.HasPrefix(f, "out") { + continue + } + f = strings.ReplaceAll(f, "system/", "DATA/") + f = strings.ReplaceAll(f, filepath.Join("testcases", name, arch), filepath.Join("DATA", class, name)) + f = strings.ReplaceAll(f, filepath.Join("testcases", name, secondArch), filepath.Join("DATA", class, name)) + f = strings.ReplaceAll(f, "testcases", filepath.Join("DATA", class)) + f = strings.ReplaceAll(f, "data/", "DATA/") + f = strings.ReplaceAll(f, "DATA_other", "system_other") + f = strings.ReplaceAll(f, "system_other/DATA", "system_other/system") + dir := filepath.Dir(f) + tempOut := android.PathForModuleOut(ctx, "STAGING", f) + builder.Command().Text("mkdir").Flag("-p").Text(filepath.Join(stagingDir.String(), dir)) + builder.Command().Text("cp").Flag("-Rf").Input(installedFile).Output(tempOut) + builder.Temporary(tempOut) + } + }) + + output := android.PathForModuleOut(ctx, ctx.ModuleName()+".zip") + builder.Command(). + BuiltTool("soong_zip"). + Flag("-o").Output(output). + Flag("-C").Text(stagingDir.String()). + Flag("-D").Text(stagingDir.String()) + builder.Command().Text("rm").Flag("-rf").Text(stagingDir.String()) + builder.Build("test_package", fmt.Sprintf("build test_package for %s", ctx.ModuleName())) + return output +} + +func removeFileExtension(filename string) string { + return strings.TrimSuffix(filename, filepath.Ext(filename)) +} + +// The only purpose of this method is to make sure we can build the module directly +// without adding suffix "-soong" +func (p *testPackageZip) AndroidMkEntries() []android.AndroidMkEntries { + return []android.AndroidMkEntries{ + android.AndroidMkEntries{ + Class: "ETC", + OutputFile: android.OptionalPathForPath(p.output), + }, + } +} diff --git a/cmd/symbols_map/symbols_map.go b/cmd/symbols_map/symbols_map.go index c56cf93e8..3955c8ad1 100644 --- a/cmd/symbols_map/symbols_map.go +++ b/cmd/symbols_map/symbols_map.go @@ -72,6 +72,7 @@ func main() { elfFile := flags.String("elf", "", "extract identifier from an elf file") r8File := flags.String("r8", "", "extract identifier from an r8 dictionary") + locationFlag := flags.String("location", "", "an override for the value of the location field in the proto. If not specified, the filename will be used") merge := flags.String("merge", "", "merge multiple identifier protos") writeIfChanged := flags.Bool("write_if_changed", false, "only write output file if it is modified") @@ -134,6 +135,10 @@ func main() { panic("shouldn't get here") } + if *locationFlag != "" { + location = *locationFlag + } + mapping := symbols_map_proto.Mapping{ Identifier: proto.String(identifier), Location: proto.String(location), diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go index bf54c0941..a440c9113 100644 --- a/etc/prebuilt_etc.go +++ b/etc/prebuilt_etc.go @@ -32,6 +32,7 @@ import ( "path/filepath" "strings" + "github.com/google/blueprint" "github.com/google/blueprint/proptools" "android/soong/android" @@ -90,6 +91,15 @@ func RegisterPrebuiltEtcBuildComponents(ctx android.RegistrationContext) { } +type PrebuiltEtcInfo struct { + // Returns the base install directory, such as "etc", "usr/share". + BaseDir string + // Returns the sub install directory relative to BaseDir(). + SubDir string +} + +var PrebuiltEtcInfoProvider = blueprint.NewProvider[PrebuiltEtcInfo]() + var PrepareForTestWithPrebuiltEtc = android.FixtureRegisterWithContext(RegisterPrebuiltEtcBuildComponents) type PrebuiltEtcProperties struct { @@ -502,6 +512,15 @@ func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx android.ModuleContext) { p.updateModuleInfoJSON(ctx) ctx.SetOutputFiles(p.outputFilePaths.Paths(), "") + + SetCommonPrebuiltEtcInfo(ctx, p) +} + +func SetCommonPrebuiltEtcInfo(ctx android.ModuleContext, p PrebuiltEtcModule) { + android.SetProvider(ctx, PrebuiltEtcInfoProvider, PrebuiltEtcInfo{ + BaseDir: p.BaseDir(), + SubDir: p.SubDir(), + }) } func (p *PrebuiltEtc) updateModuleInfoJSON(ctx android.ModuleContext) { diff --git a/filesystem/android_device.go b/filesystem/android_device.go index 8d7f92f7d..3b8bf9381 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -15,16 +15,26 @@ package filesystem import ( + "cmp" "fmt" + "path/filepath" + "slices" "strings" "sync/atomic" "android/soong/android" + "android/soong/java" "github.com/google/blueprint" "github.com/google/blueprint/proptools" ) +var proguardDictToProto = pctx.AndroidStaticRule("proguard_dict_to_proto", blueprint.RuleParams{ + Command: `${symbols_map} -r8 $in -location $location -write_if_changed $out`, + Restat: true, + CommandDeps: []string{"${symbols_map}"}, +}, "location") + type PartitionNameProperties struct { // Name of the super partition filesystem module Super_partition_name *string @@ -159,7 +169,11 @@ func (a *androidDevice) GenerateAndroidBuildActions(ctx android.ModuleContext) { } } + allInstalledModules := a.allInstalledModules(ctx) + a.buildTargetFilesZip(ctx) + a.buildProguardZips(ctx, allInstalledModules) + var deps []android.Path if proptools.String(a.partitionProps.Super_partition_name) != "" { superImage := ctx.GetDirectDepProxyWithTag(*a.partitionProps.Super_partition_name, superPartitionDepTag) @@ -212,7 +226,7 @@ func (a *androidDevice) GenerateAndroidBuildActions(ctx android.ModuleContext) { allImagesZip := android.PathForModuleOut(ctx, "all_images.zip") allImagesZipBuilder := android.NewRuleBuilder(pctx, ctx) - cmd := allImagesZipBuilder.Command().BuiltTool("soong_zip").Flag("--sort_entries") + cmd := allImagesZipBuilder.Command().BuiltTool("soong_zip") for _, dep := range deps { cmd.FlagWithArg("-e ", dep.Base()) cmd.FlagWithInput("-f ", dep) @@ -247,6 +261,38 @@ func (a *androidDevice) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.distFiles(ctx) } +// Returns a list of modules that are installed, which are collected from the dependency +// filesystem and super_image modules. +func (a *androidDevice) allInstalledModules(ctx android.ModuleContext) []android.Module { + fsInfoMap := a.getFsInfos(ctx) + allOwners := make(map[string][]string) + for _, partition := range android.SortedKeys(fsInfoMap) { + fsInfo := fsInfoMap[partition] + for _, owner := range fsInfo.Owners { + allOwners[owner.Name] = append(allOwners[owner.Name], owner.Variation) + } + } + + ret := []android.Module{} + ctx.WalkDepsProxy(func(mod, _ android.ModuleProxy) bool { + if variations, ok := allOwners[mod.Name()]; ok && android.InList(ctx.OtherModuleSubDir(mod), variations) { + ret = append(ret, mod) + } + return true + }) + + // Remove duplicates + ret = android.FirstUniqueFunc(ret, func(a, b android.Module) bool { + return a.String() == b.String() + }) + + // Sort the modules by their names and variants + slices.SortFunc(ret, func(a, b android.Module) int { + return cmp.Compare(a.String(), b.String()) + }) + return ret +} + func (a *androidDevice) distFiles(ctx android.ModuleContext) { if !ctx.Config().KatiEnabled() { if proptools.Bool(a.deviceProps.Main_device) { @@ -271,6 +317,52 @@ func (a *androidDevice) MakeVars(ctx android.MakeVarsModuleContext) { } } +func (a *androidDevice) buildProguardZips(ctx android.ModuleContext, allInstalledModules []android.Module) { + dictZip := android.PathForModuleOut(ctx, "proguard-dict.zip") + dictZipBuilder := android.NewRuleBuilder(pctx, ctx) + dictZipCmd := dictZipBuilder.Command().BuiltTool("soong_zip").Flag("-d").FlagWithOutput("-o ", dictZip) + + dictMapping := android.PathForModuleOut(ctx, "proguard-dict-mapping.textproto") + dictMappingBuilder := android.NewRuleBuilder(pctx, ctx) + dictMappingCmd := dictMappingBuilder.Command().BuiltTool("symbols_map").Flag("-merge").Output(dictMapping) + + protosDir := android.PathForModuleOut(ctx, "proguard_mapping_protos") + + usageZip := android.PathForModuleOut(ctx, "proguard-usage.zip") + usageZipBuilder := android.NewRuleBuilder(pctx, ctx) + usageZipCmd := usageZipBuilder.Command().BuiltTool("merge_zips").Output(usageZip) + + for _, mod := range allInstalledModules { + if proguardInfo, ok := android.OtherModuleProvider(ctx, mod, java.ProguardProvider); ok { + // Maintain these out/target/common paths for backwards compatibility. They may be able + // to be changed if tools look up file locations from the protobuf, but I'm not + // exactly sure how that works. + dictionaryFakePath := fmt.Sprintf("out/target/common/obj/%s/%s_intermediates/proguard_dictionary", proguardInfo.Class, proguardInfo.ModuleName) + dictZipCmd.FlagWithArg("-e ", dictionaryFakePath) + dictZipCmd.FlagWithInput("-f ", proguardInfo.ProguardDictionary) + dictZipCmd.Textf("-e out/target/common/obj/%s/%s_intermediates/classes.jar", proguardInfo.Class, proguardInfo.ModuleName) + dictZipCmd.FlagWithInput("-f ", proguardInfo.ClassesJar) + + protoFile := protosDir.Join(ctx, filepath.Dir(dictionaryFakePath), "proguard_dictionary.textproto") + ctx.Build(pctx, android.BuildParams{ + Rule: proguardDictToProto, + Input: proguardInfo.ProguardDictionary, + Output: protoFile, + Args: map[string]string{ + "location": dictionaryFakePath, + }, + }) + dictMappingCmd.Input(protoFile) + + usageZipCmd.Input(proguardInfo.ProguardUsageZip) + } + } + + dictZipBuilder.Build("proguard_dict_zip", "Building proguard dictionary zip") + dictMappingBuilder.Build("proguard_dict_mapping_proto", "Building proguard mapping proto") + usageZipBuilder.Build("proguard_usage_zip", "Building proguard usage zip") +} + // Helper structs for target_files.zip creation type targetFilesZipCopy struct { srcModule *string @@ -302,11 +394,6 @@ func (a *androidDevice) buildTargetFilesZip(ctx android.ModuleContext) { targetFilesZipCopy{a.partitionProps.Init_boot_partition_name, "INIT_BOOT/RAMDISK"}, targetFilesZipCopy{a.partitionProps.Vendor_boot_partition_name, "VENDOR_BOOT/RAMDISK"}, } - // TODO: Handle cases where recovery files are copied to BOOT/ or RECOVERY/ - // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile;l=6211-6219?q=core%2FMakefile&ss=android%2Fplatform%2Fsuperproject%2Fmain - if ctx.DeviceConfig().BoardMoveRecoveryResourcesToVendorBoot() { - toCopy = append(toCopy, targetFilesZipCopy{a.partitionProps.Recovery_partition_name, "VENDOR_BOOT/RAMDISK"}) - } filesystemsToCopy := []targetFilesystemZipCopy{} for _, zipCopy := range toCopy { @@ -322,7 +409,7 @@ func (a *androidDevice) buildTargetFilesZip(ctx android.ModuleContext) { if a.partitionProps.Super_partition_name != nil { superPartition := ctx.GetDirectDepProxyWithTag(*a.partitionProps.Super_partition_name, superPartitionDepTag) if info, ok := android.OtherModuleProvider(ctx, superPartition, SuperImageProvider); ok { - for _, partition := range android.SortedStringKeys(info.SubImageInfo) { + for _, partition := range android.SortedKeys(info.SubImageInfo) { filesystemsToCopy = append( filesystemsToCopy, targetFilesystemZipCopy{info.SubImageInfo[partition], strings.ToUpper(partition)}, @@ -343,6 +430,12 @@ func (a *androidDevice) buildTargetFilesZip(ctx android.ModuleContext) { BuiltTool("acp"). Textf("-rd %s/. %s/%s", rootDirString, targetFilesDir, toCopy.destSubdir). Implicit(toCopy.fsInfo.Output) // so that the staging dir is built + for _, extraRootDir := range toCopy.fsInfo.ExtraRootDirs { + builder.Command(). + BuiltTool("acp"). + Textf("-rd %s/. %s/%s", extraRootDir, targetFilesDir, toCopy.destSubdir). + Implicit(toCopy.fsInfo.Output) // so that the staging dir is built + } if toCopy.destSubdir == "SYSTEM" { // Create the ROOT partition in target_files.zip diff --git a/filesystem/avb_add_hash_footer.go b/filesystem/avb_add_hash_footer.go index f32993c4b..c1e03cb62 100644 --- a/filesystem/avb_add_hash_footer.go +++ b/filesystem/avb_add_hash_footer.go @@ -149,6 +149,8 @@ func (a *avbAddHashFooter) GenerateAndroidBuildActions(ctx android.ModuleContext a.installDir = android.PathForModuleInstall(ctx, "etc") ctx.InstallFile(a.installDir, a.installFileName(), output) a.output = output + + setCommonFilesystemInfo(ctx, a) } func addAvbProp(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, prop avbProp) { diff --git a/filesystem/bootimg.go b/filesystem/bootimg.go index 6d6c15c05..effbd6542 100644 --- a/filesystem/bootimg.go +++ b/filesystem/bootimg.go @@ -230,6 +230,8 @@ func (b *bootimg) GenerateAndroidBuildActions(ctx android.ModuleContext) { ramdiskModule := ctx.GetDirectDepWithTag(ramdisk, bootimgRamdiskDep) fsInfo, _ := android.OtherModuleProvider(ctx, ramdiskModule, FilesystemProvider) android.SetProvider(ctx, FilesystemProvider, fsInfo) + } else { + setCommonFilesystemInfo(ctx, b) } // Set BootimgInfo for building target_files.zip diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index f84993de7..28eb36d1e 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -33,11 +33,14 @@ import ( "github.com/google/blueprint/proptools" ) +var pctx = android.NewPackageContext("android/soong/filesystem") + func init() { registerBuildComponents(android.InitRegistrationContext) registerMutators(android.InitRegistrationContext) pctx.HostBinToolVariable("fileslist", "fileslist") pctx.HostBinToolVariable("fs_config", "fs_config") + pctx.HostBinToolVariable("symbols_map", "symbols_map") } func registerBuildComponents(ctx android.RegistrationContext) { @@ -384,9 +387,17 @@ type InstalledFilesStruct struct { Json android.Path } +type InstalledModuleInfo struct { + Name string + Variation string +} + type FilesystemInfo struct { // The built filesystem image Output android.Path + // Returns the output file that is signed by avbtool. If this module is not signed, returns + // nil. + SignedOutputPath android.Path // An additional hermetic filesystem image. // e.g. this will contain inodes with pinned timestamps. // This will be copied to target_files.zip @@ -397,6 +408,9 @@ type FilesystemInfo struct { // to add a dependency on the Output file, as you cannot add dependencies on directories // in ninja. RootDir android.Path + // Extra root directories that are also built into the partition. Currently only used for + // including the recovery partition files into the vendor_boot image. + ExtraRootDirs android.Paths // The rebased staging directory used to build the output filesystem. If consuming this, make // sure to add a dependency on the Output file, as you cannot add dependencies on directories // in ninja. In many cases this is the same as RootDir, only in the system partition is it @@ -428,6 +442,8 @@ type FilesystemInfo struct { SelinuxFc android.Path FilesystemConfig android.Path + + Owners []InstalledModuleInfo } // FullInstallPathInfo contains information about the "full install" paths of all the files @@ -563,8 +579,6 @@ func buildInstalledFiles(ctx android.ModuleContext, partition string, rootDir an return txt, json } -var pctx = android.NewPackageContext("android/soong/filesystem") - func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) { validatePartitionType(ctx, f) if f.filesystemBuilder.ShouldUseVintfFragmentModuleOnly() { @@ -587,7 +601,8 @@ func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) { specs := f.gatherFilteredPackagingSpecs(ctx) var fullInstallPaths []FullInstallPathInfo - for _, spec := range specs { + for _, specRel := range android.SortedKeys(specs) { + spec := specs[specRel] fullInstallPaths = append(fullInstallPaths, FullInstallPathInfo{ FullInstallPath: spec.FullInstallPath(), RequiresFullInstall: spec.RequiresFullInstall(), @@ -612,6 +627,7 @@ func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) { var outputHermetic android.WritablePath var buildImagePropFile android.Path var buildImagePropFileDeps android.Paths + var extraRootDirs android.Paths switch f.fsType(ctx) { case ext4Type, erofsType, f2fsType: buildImagePropFile, buildImagePropFileDeps = f.buildPropFile(ctx) @@ -625,9 +641,9 @@ func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) { f.buildImageUsingBuildImage(ctx, hermeticBuilder, buildImageParams{rootDir, propFileHermetic, buildImagePropFileDeps, outputHermetic}) mapFile = f.getMapFile(ctx) case compressedCpioType: - f.output = f.buildCpioImage(ctx, builder, rootDir, true) + f.output, extraRootDirs = f.buildCpioImage(ctx, builder, rootDir, true) case cpioType: - f.output = f.buildCpioImage(ctx, builder, rootDir, false) + f.output, extraRootDirs = f.buildCpioImage(ctx, builder, rootDir, false) default: return } @@ -655,10 +671,12 @@ func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) { } fsInfo := FilesystemInfo{ - Output: f.output, + Output: f.OutputPath(), + SignedOutputPath: f.SignedOutputPath(), OutputHermetic: outputHermetic, FileListFile: fileListFile, RootDir: rootDir, + ExtraRootDirs: extraRootDirs, RebasedDir: rebasedDir, MapFile: mapFile, ModuleName: ctx.ModuleName(), @@ -673,6 +691,7 @@ func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) { ErofsCompressHints: erofsCompressHints, SelinuxFc: f.selinuxFc, FilesystemConfig: f.generateFilesystemConfig(ctx, rootDir, rebasedDir), + Owners: f.gatherOwners(specs), } android.SetProvider(ctx, FilesystemProvider, fsInfo) @@ -1157,7 +1176,7 @@ func (f *filesystem) buildCpioImage( builder *android.RuleBuilder, rootDir android.OutputPath, compressed bool, -) android.Path { +) (android.Path, android.Paths) { if proptools.Bool(f.properties.Use_avb) { ctx.PropertyErrorf("use_avb", "signing compresed cpio image using avbtool is not supported."+ "Consider adding this to bootimg module and signing the entire boot image.") @@ -1197,7 +1216,7 @@ func (f *filesystem) buildCpioImage( // rootDir is not deleted. Might be useful for quick inspection. builder.Build("build_cpio_image", fmt.Sprintf("Creating filesystem %s", f.BaseModuleName())) - return output + return output, rootDirs } var validPartitions = []string{ @@ -1326,6 +1345,18 @@ func (f *filesystem) gatherFilteredPackagingSpecs(ctx android.ModuleContext) map return f.PackagingBase.GatherPackagingSpecsWithFilterAndModifier(ctx, f.filesystemBuilder.FilterPackagingSpec, f.filesystemBuilder.ModifyPackagingSpec) } +func (f *filesystem) gatherOwners(specs map[string]android.PackagingSpec) []InstalledModuleInfo { + var owners []InstalledModuleInfo + for _, p := range android.SortedKeys(specs) { + spec := specs[p] + owners = append(owners, InstalledModuleInfo{ + Name: spec.Owner(), + Variation: spec.Variation(), + }) + } + return owners +} + // Dexpreopt files are installed to system_other. Collect the packaingSpecs for the dexpreopt files // from this partition to export to the system_other partition later. func (f *filesystem) systemOtherFiles(ctx android.ModuleContext) map[string]android.PackagingSpec { @@ -1499,3 +1530,10 @@ func (f *filesystem) MakeVars(ctx android.MakeVarsModuleContext) { ctx.StrictRaw("SOONG_DEFINED_SYSTEM_IMAGE_PATH", f.output.String()) } } + +func setCommonFilesystemInfo(ctx android.ModuleContext, m Filesystem) { + android.SetProvider(ctx, FilesystemProvider, FilesystemInfo{ + Output: m.OutputPath(), + SignedOutputPath: m.SignedOutputPath(), + }) +} diff --git a/filesystem/logical_partition.go b/filesystem/logical_partition.go index d0888a9c8..1fd2e766b 100644 --- a/filesystem/logical_partition.go +++ b/filesystem/logical_partition.go @@ -198,6 +198,8 @@ func (l *logicalPartition) GenerateAndroidBuildActions(ctx android.ModuleContext ctx.SetOutputFiles([]android.Path{output}, "") l.output = output + + setCommonFilesystemInfo(ctx, l) } // Add a rule that converts the filesystem for the given partition to the given rule builder. The diff --git a/filesystem/raw_binary.go b/filesystem/raw_binary.go index 707fba06f..6ca155aaf 100644 --- a/filesystem/raw_binary.go +++ b/filesystem/raw_binary.go @@ -88,6 +88,8 @@ func (r *rawBinary) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.SetOutputFiles([]android.Path{outputFile}, "") r.output = outputFile + + setCommonFilesystemInfo(ctx, r) } var _ android.AndroidMkEntriesProvider = (*rawBinary)(nil) diff --git a/filesystem/system_other.go b/filesystem/system_other.go index 1c00dd35e..5309e9012 100644 --- a/filesystem/system_other.go +++ b/filesystem/system_other.go @@ -23,6 +23,12 @@ import ( "github.com/google/blueprint/proptools" ) +var ( + systemOtherPropFileTweaks = pctx.AndroidStaticRule("system_other_prop_file_tweaks", blueprint.RuleParams{ + Command: `rm -rf $out && sed -e 's@^mount_point=/$$@mount_point=system_other@g' -e 's@^partition_name=system$$@partition_name=system_other@g' $in > $out`, + }) +) + type SystemOtherImageProperties struct { // The system_other image always requires a reference to the system image. The system_other // partition gets built into the system partition's "b" slot in a/b partition builds. Thus, it @@ -123,12 +129,23 @@ func (m *systemOtherImage) GenerateAndroidBuildActions(ctx android.ModuleContext fec := ctx.Config().HostToolPath(ctx, "fec") pathToolDirs := []string{filepath.Dir(fec.String())} + // In make, the exact same prop file is used for both system and system_other. However, I + // believe make goes through a different build_image code path that is based on the name of + // the output file. So it sees the output file is named system_other.img and makes some changes. + // We don't use that codepath, so make the changes manually to the prop file. + propFile := android.PathForModuleOut(ctx, "prop") + ctx.Build(pctx, android.BuildParams{ + Rule: systemOtherPropFileTweaks, + Input: systemInfo.BuildImagePropFile, + Output: propFile, + }) + builder = android.NewRuleBuilder(pctx, ctx) builder.Command(). Textf("PATH=%s:$PATH", strings.Join(pathToolDirs, ":")). BuiltTool("build_image"). Text(stagingDir.String()). // input directory - Input(systemInfo.BuildImagePropFile). + Input(propFile). Implicits(systemInfo.BuildImagePropFileDeps). Implicit(fec). Implicit(stagingDirTimestamp). @@ -140,7 +157,7 @@ func (m *systemOtherImage) GenerateAndroidBuildActions(ctx android.ModuleContext // Create a hermetic system_other.img with pinned timestamps builder = android.NewRuleBuilder(pctx, ctx) outputHermetic := android.PathForModuleOut(ctx, "for_target_files", "system_other.img") - outputHermeticPropFile := m.propFileForHermeticImg(ctx, builder, systemInfo.BuildImagePropFile) + outputHermeticPropFile := m.propFileForHermeticImg(ctx, builder, propFile) builder.Command(). Textf("PATH=%s:$PATH", strings.Join(pathToolDirs, ":")). BuiltTool("build_image"). diff --git a/filesystem/vbmeta.go b/filesystem/vbmeta.go index e5809d31b..01b453e25 100644 --- a/filesystem/vbmeta.go +++ b/filesystem/vbmeta.go @@ -306,6 +306,8 @@ func (v *vbmeta) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.SetOutputFiles([]android.Path{output}, "") v.output = output + + setCommonFilesystemInfo(ctx, v) } // Returns the embedded shell command that prints the rollback index diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go index c2721d29f..e2485a1d3 100644 --- a/fsgen/filesystem_creator.go +++ b/fsgen/filesystem_creator.go @@ -377,7 +377,7 @@ func (f *filesystemCreator) createDeviceModule( if modName := partitions.nameForType("userdata"); modName != "" { partitionProps.Userdata_partition_name = proptools.StringPtr(modName) } - if modName := partitions.nameForType("recovery"); modName != "" { + if modName := partitions.nameForType("recovery"); modName != "" && !ctx.DeviceConfig().BoardMoveRecoveryResourcesToVendorBoot() { partitionProps.Recovery_partition_name = proptools.StringPtr(modName) } if modName := partitions.nameForType("system_dlkm"); modName != "" && !android.InList("system_dlkm", superImageSubPartitions) { diff --git a/java/aar.go b/java/aar.go index f7c5c13de..976e4fcb1 100644 --- a/java/aar.go +++ b/java/aar.go @@ -217,7 +217,7 @@ func (p propagateRROEnforcementTransitionMutator) Mutate(ctx android.BottomUpMut } func (a *aapt) useResourceProcessorBusyBox(ctx android.BaseModuleContext) bool { - return BoolDefault(a.aaptProperties.Use_resource_processor, ctx.Config().UseResourceProcessorByDefault()) && + return BoolDefault(a.aaptProperties.Use_resource_processor, true) && // TODO(b/331641946): remove this when ResourceProcessorBusyBox supports generating shared libraries. !slices.Contains(a.aaptProperties.Aaptflags, "--shared-lib") && // Use the legacy resource processor in kythe builds. @@ -1479,12 +1479,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { completeStaticLibsResourceJars := depset.New(depset.PREORDER, nil, transitiveStaticLibsResourceJars) var implementationJarFile android.Path - var combineJars android.Paths - if ctx.Config().UseTransitiveJarsInClasspath() { - combineJars = completeStaticLibsImplementationJars.ToList() - } else { - combineJars = append(android.Paths{classpathFile}, staticJars...) - } + combineJars := completeStaticLibsImplementationJars.ToList() if len(combineJars) > 1 { implementationJarOutputPath := android.PathForModuleOut(ctx, "combined", jarName) @@ -1495,12 +1490,8 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { } var resourceJarFile android.Path - var resourceJars android.Paths - if ctx.Config().UseTransitiveJarsInClasspath() { - resourceJars = completeStaticLibsResourceJars.ToList() - } else { - resourceJars = staticResourceJars - } + resourceJars := completeStaticLibsResourceJars.ToList() + if len(resourceJars) > 1 { combinedJar := android.PathForModuleOut(ctx, "res-combined", jarName) TransformJarsToJar(ctx, combinedJar, "for resources", resourceJars, android.OptionalPath{}, @@ -1511,12 +1502,8 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { } // merge implementation jar with resources if necessary - var implementationAndResourcesJars android.Paths - if ctx.Config().UseTransitiveJarsInClasspath() { - implementationAndResourcesJars = append(slices.Clone(resourceJars), combineJars...) - } else { - implementationAndResourcesJars = android.PathsIfNonNil(resourceJarFile, implementationJarFile) - } + implementationAndResourcesJars := append(slices.Clone(resourceJars), combineJars...) + var implementationAndResourcesJar android.Path if len(implementationAndResourcesJars) > 1 { combinedJar := android.PathForModuleOut(ctx, "withres", jarName) @@ -1531,12 +1518,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource a.implementationAndResourcesJarFile = implementationAndResourcesJar.WithoutRel() - var headerJars android.Paths - if ctx.Config().UseTransitiveJarsInClasspath() { - headerJars = completeStaticLibsHeaderJars.ToList() - } else { - headerJars = append(android.Paths{classpathFile}, staticHeaderJars...) - } + headerJars := completeStaticLibsHeaderJars.ToList() if len(headerJars) > 1 { headerJarFile := android.PathForModuleOut(ctx, "turbine-combined", jarName) TransformJarsToJar(ctx, headerJarFile, "combine header jars", headerJars, android.OptionalPath{}, false, nil, nil) @@ -1545,12 +1527,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.headerJarFile = headerJars[0] } - if ctx.Config().UseTransitiveJarsInClasspath() { - ctx.CheckbuildFile(classpathFile) - } else { - ctx.CheckbuildFile(a.headerJarFile) - ctx.CheckbuildFile(a.implementationJarFile) - } + ctx.CheckbuildFile(classpathFile) javaInfo := &JavaInfo{ HeaderJars: android.PathsIfNonNil(a.headerJarFile), diff --git a/java/app.go b/java/app.go index f0e0c9a6c..17548e74a 100644 --- a/java/app.go +++ b/java/app.go @@ -72,6 +72,16 @@ type AppInfo struct { EmbeddedJNILibs android.Paths MergedManifestFile android.Path + + Prebuilt bool + AppSet bool + Privileged bool + OutputFile android.Path + InstallApkName string + JacocoReportClassesFile android.Path + Certificate Certificate + PrivAppAllowlist android.OptionalPath + OverriddenManifestPackageName *string } var AppInfoProvider = blueprint.NewProvider[*AppInfo]() @@ -401,10 +411,12 @@ func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleCon android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{ TestOnly: true, }) - android.SetProvider(ctx, AppInfoProvider, &AppInfo{ + appInfo := &AppInfo{ Updatable: Bool(a.appProperties.Updatable), TestHelperApp: true, - }) + } + setCommonAppInfo(appInfo, a) + android.SetProvider(ctx, AppInfoProvider, appInfo) moduleInfoJSON := ctx.ModuleInfoJSON() moduleInfoJSON.Tags = append(moduleInfoJSON.Tags, "tests") @@ -428,14 +440,28 @@ func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) { embeddedJniLibs = append(embeddedJniLibs, jni.path) } } - android.SetProvider(ctx, AppInfoProvider, &AppInfo{ - Updatable: Bool(a.appProperties.Updatable), - TestHelperApp: false, - EmbeddedJNILibs: embeddedJniLibs, - MergedManifestFile: a.mergedManifest, - }) + overriddenName := a.OverriddenManifestPackageName() + appInfo := &AppInfo{ + Updatable: Bool(a.appProperties.Updatable), + TestHelperApp: false, + EmbeddedJNILibs: embeddedJniLibs, + MergedManifestFile: a.mergedManifest, + OverriddenManifestPackageName: &overriddenName, + } + setCommonAppInfo(appInfo, a) + android.SetProvider(ctx, AppInfoProvider, appInfo) a.requiredModuleNames = a.getRequiredModuleNames(ctx) + + if a.dexer.proguardDictionary.Valid() { + android.SetProvider(ctx, ProguardProvider, ProguardInfo{ + ModuleName: ctx.ModuleName(), + Class: "APPS", + ProguardDictionary: a.dexer.proguardDictionary.Path(), + ProguardUsageZip: a.dexer.proguardUsageZip.Path(), + ClassesJar: a.implementationAndResourcesJar, + }) + } } func (a *AndroidApp) getRequiredModuleNames(ctx android.ModuleContext) []string { @@ -1628,6 +1654,10 @@ func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { if a.testConfig != nil { ctx.InstallFile(pathInTestCases, ctx.Module().Name()+".config", a.testConfig) } + dynamicConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml") + if dynamicConfig.Valid() { + ctx.InstallFile(pathInTestCases, ctx.Module().Name()+".dynamic", dynamicConfig.Path()) + } testDeps := append(a.data, a.extraTestConfigs...) for _, data := range android.SortedUniquePaths(testDeps) { dataPath := android.DataPath{SrcPath: data} @@ -2045,7 +2075,7 @@ func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext if _, ok := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); ok { // Skip java_sdk_library dependencies that provide stubs, but not an implementation. // This will be restricted to optional_uses_libs - if tag == usesLibOptTag && lib.DexJarBuildPath.PathOrNil() == nil { + if tag == usesLibOptTag && javaInfo.DexJarBuildPath.PathOrNil() == nil { u.shouldDisableDexpreopt = true return } @@ -2055,7 +2085,7 @@ func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext libName = *ulib.ProvidesUsesLib } clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional, - lib.DexJarBuildPath.PathOrNil(), lib.DexJarInstallPath, + javaInfo.DexJarBuildPath.PathOrNil(), lib.DexJarInstallPath, lib.ClassLoaderContexts) } else if ctx.Config().AllowMissingDependencies() { ctx.AddMissingDependencies([]string{dep}) @@ -2148,3 +2178,29 @@ func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk andr classLoaderContexts *dexpreopt.ClassLoaderContextMap) { u.verifyUsesLibraries(ctx, apk, nil, classLoaderContexts) // for APKs manifest_check does not write output file } + +// androidApp is an interface to handle all app modules (android_app, android_app_import, etc.) in +// the same way. +type androidApp interface { + android.Module + Privileged() bool + InstallApkName() string + OutputFile() android.Path + JacocoReportClassesFile() android.Path + Certificate() Certificate + BaseModuleName() string + PrivAppAllowlist() android.OptionalPath +} + +var _ androidApp = (*AndroidApp)(nil) +var _ androidApp = (*AndroidAppImport)(nil) +var _ androidApp = (*AndroidTestHelperApp)(nil) + +func setCommonAppInfo(appInfo *AppInfo, m androidApp) { + appInfo.Privileged = m.Privileged() + appInfo.OutputFile = m.OutputFile() + appInfo.InstallApkName = m.InstallApkName() + appInfo.JacocoReportClassesFile = m.JacocoReportClassesFile() + appInfo.Certificate = m.Certificate() + appInfo.PrivAppAllowlist = m.PrivAppAllowlist() +} diff --git a/java/app_import.go b/java/app_import.go index 919266f28..37c673ca0 100644 --- a/java/app_import.go +++ b/java/app_import.go @@ -354,6 +354,12 @@ func (a *AndroidAppImport) stripEmbeddedJniLibsUnusedArch( func (a *AndroidAppImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.generateAndroidBuildActions(ctx) + + appInfo := &AppInfo{ + Prebuilt: true, + } + setCommonAppInfo(appInfo, a) + android.SetProvider(ctx, AppInfoProvider, appInfo) } func (a *AndroidAppImport) InstallApkName() string { diff --git a/java/app_set.go b/java/app_set.go index 7997570aa..2e9d31410 100644 --- a/java/app_set.go +++ b/java/app_set.go @@ -192,6 +192,11 @@ func (as *AndroidAppSet) GenerateAndroidBuildActions(ctx android.ModuleContext) }, ) + android.SetProvider(ctx, AppInfoProvider, &AppInfo{ + AppSet: true, + Privileged: as.Privileged(), + OutputFile: as.OutputFile(), + }) } func (as *AndroidAppSet) InstallBypassMake() bool { return true } diff --git a/java/app_test.go b/java/app_test.go index 4f23f61a4..5f5f04d78 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -887,15 +887,24 @@ func TestAndroidResourceProcessor(t *testing.T) { }, appSrcJars: []string{"out/soong/.intermediates/app/android_common/gen/android/R.srcjar"}, appClasspath: []string{ - "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", - "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar", - "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar", - "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar", + "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar", + "out/soong/.intermediates/shared/android_common/turbine/shared.jar", + "out/soong/.intermediates/shared_transitive_static/android_common/turbine/shared_transitive_static.jar", + "out/soong/.intermediates/direct/android_common/turbine/direct.jar", + "out/soong/.intermediates/transitive/android_common/turbine/transitive.jar", + "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar", + "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar", + "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar", + "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar", }, appCombined: []string{ "out/soong/.intermediates/app/android_common/javac/app.jar", - "out/soong/.intermediates/direct/android_common/combined/direct.jar", - "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar", + "out/soong/.intermediates/direct/android_common/javac/direct.jar", + "out/soong/.intermediates/transitive/android_common/javac/transitive.jar", + "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar", + "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar", + "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar", + "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar", }, directResources: nil, @@ -908,21 +917,23 @@ func TestAndroidResourceProcessor(t *testing.T) { directImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"}, directSrcJars: []string{"out/soong/.intermediates/direct/android_common/gen/android/R.srcjar"}, directClasspath: []string{ - "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", - "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar", - "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar", + "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar", + "out/soong/.intermediates/transitive/android_common/turbine/transitive.jar", + "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar", + "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar", }, directCombined: []string{ "out/soong/.intermediates/direct/android_common/javac/direct.jar", "out/soong/.intermediates/transitive/android_common/javac/transitive.jar", - "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar", + "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar", + "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar", }, transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"}, transitiveOverlays: nil, transitiveImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"}, transitiveSrcJars: []string{"out/soong/.intermediates/transitive/android_common/gen/android/R.srcjar"}, - transitiveClasspath: []string{"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar"}, + transitiveClasspath: []string{"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar"}, transitiveCombined: nil, sharedResources: nil, @@ -936,9 +947,9 @@ func TestAndroidResourceProcessor(t *testing.T) { }, sharedSrcJars: []string{"out/soong/.intermediates/shared/android_common/gen/android/R.srcjar"}, sharedClasspath: []string{ - "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", - "out/soong/.intermediates/shared_transitive_shared/android_common/turbine-combined/shared_transitive_shared.jar", - "out/soong/.intermediates/shared_transitive_static/android_common/turbine-combined/shared_transitive_static.jar", + "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar", + "out/soong/.intermediates/shared_transitive_shared/android_common/turbine/shared_transitive_shared.jar", + "out/soong/.intermediates/shared_transitive_static/android_common/turbine/shared_transitive_static.jar", }, sharedCombined: []string{ "out/soong/.intermediates/shared/android_common/javac/shared.jar", @@ -985,17 +996,26 @@ func TestAndroidResourceProcessor(t *testing.T) { }, appSrcJars: nil, appClasspath: []string{ - "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", + "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar", "out/soong/.intermediates/app/android_common/busybox/R.jar", - "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar", - "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar", - "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar", + "out/soong/.intermediates/shared/android_common/turbine/shared.jar", + "out/soong/.intermediates/shared_transitive_static/android_common/turbine/shared_transitive_static.jar", + "out/soong/.intermediates/direct/android_common/turbine/direct.jar", + "out/soong/.intermediates/transitive/android_common/turbine/transitive.jar", + "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar", + "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar", + "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar", + "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar", }, appCombined: []string{ "out/soong/.intermediates/app/android_common/javac/app.jar", "out/soong/.intermediates/app/android_common/busybox/R.jar", - "out/soong/.intermediates/direct/android_common/combined/direct.jar", - "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar", + "out/soong/.intermediates/direct/android_common/javac/direct.jar", + "out/soong/.intermediates/transitive/android_common/javac/transitive.jar", + "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar", + "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar", + "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar", + "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar", }, directResources: nil, @@ -1008,18 +1028,20 @@ func TestAndroidResourceProcessor(t *testing.T) { }, directSrcJars: nil, directClasspath: []string{ - "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", + "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar", "out/soong/.intermediates/direct/android_common/busybox/R.jar", "out/soong/.intermediates/transitive/android_common/busybox/R.jar", "out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar", "out/soong/.intermediates/transitive_import/android_common/busybox/R.jar", - "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar", - "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar", + "out/soong/.intermediates/transitive/android_common/turbine/transitive.jar", + "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar", + "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar", }, directCombined: []string{ "out/soong/.intermediates/direct/android_common/javac/direct.jar", "out/soong/.intermediates/transitive/android_common/javac/transitive.jar", - "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar", + "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar", + "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar", }, transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"}, @@ -1027,7 +1049,7 @@ func TestAndroidResourceProcessor(t *testing.T) { transitiveImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"}, transitiveSrcJars: nil, transitiveClasspath: []string{ - "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", + "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar", "out/soong/.intermediates/transitive/android_common/busybox/R.jar", }, transitiveCombined: nil, @@ -1041,12 +1063,12 @@ func TestAndroidResourceProcessor(t *testing.T) { }, sharedSrcJars: nil, sharedClasspath: []string{ - "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", + "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar", "out/soong/.intermediates/shared/android_common/busybox/R.jar", "out/soong/.intermediates/shared_transitive_static/android_common/busybox/R.jar", "out/soong/.intermediates/shared_transitive_shared/android_common/busybox/R.jar", - "out/soong/.intermediates/shared_transitive_shared/android_common/turbine-combined/shared_transitive_shared.jar", - "out/soong/.intermediates/shared_transitive_static/android_common/turbine-combined/shared_transitive_static.jar", + "out/soong/.intermediates/shared_transitive_shared/android_common/turbine/shared_transitive_shared.jar", + "out/soong/.intermediates/shared_transitive_static/android_common/turbine/shared_transitive_static.jar", }, sharedCombined: []string{ "out/soong/.intermediates/shared/android_common/javac/shared.jar", @@ -1090,18 +1112,27 @@ func TestAndroidResourceProcessor(t *testing.T) { }, appSrcJars: nil, appClasspath: []string{ - "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", + "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar", // R.jar has to come before direct.jar "out/soong/.intermediates/app/android_common/busybox/R.jar", - "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar", - "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar", - "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar", + "out/soong/.intermediates/shared/android_common/turbine/shared.jar", + "out/soong/.intermediates/shared_transitive_static/android_common/turbine/shared_transitive_static.jar", + "out/soong/.intermediates/direct/android_common/turbine/direct.jar", + "out/soong/.intermediates/transitive/android_common/turbine/transitive.jar", + "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar", + "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar", + "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar", + "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar", }, appCombined: []string{ "out/soong/.intermediates/app/android_common/javac/app.jar", "out/soong/.intermediates/app/android_common/busybox/R.jar", - "out/soong/.intermediates/direct/android_common/combined/direct.jar", - "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar", + "out/soong/.intermediates/direct/android_common/javac/direct.jar", + "out/soong/.intermediates/transitive/android_common/javac/transitive.jar", + "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar", + "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar", + "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar", + "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar", }, dontVerifyDirect: true, @@ -1133,15 +1164,24 @@ func TestAndroidResourceProcessor(t *testing.T) { }, appSrcJars: []string{"out/soong/.intermediates/app/android_common/gen/android/R.srcjar"}, appClasspath: []string{ - "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", - "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar", - "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar", - "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar", + "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar", + "out/soong/.intermediates/shared/android_common/turbine/shared.jar", + "out/soong/.intermediates/shared_transitive_static/android_common/turbine/shared_transitive_static.jar", + "out/soong/.intermediates/direct/android_common/turbine/direct.jar", + "out/soong/.intermediates/transitive/android_common/turbine/transitive.jar", + "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar", + "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar", + "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar", + "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar", }, appCombined: []string{ "out/soong/.intermediates/app/android_common/javac/app.jar", - "out/soong/.intermediates/direct/android_common/combined/direct.jar", - "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar", + "out/soong/.intermediates/direct/android_common/javac/direct.jar", + "out/soong/.intermediates/transitive/android_common/javac/transitive.jar", + "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar", + "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar", + "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar", + "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar", }, directResources: nil, @@ -1154,17 +1194,19 @@ func TestAndroidResourceProcessor(t *testing.T) { }, directSrcJars: nil, directClasspath: []string{ - "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", + "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar", "out/soong/.intermediates/direct/android_common/busybox/R.jar", "out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar", "out/soong/.intermediates/transitive_import/android_common/busybox/R.jar", - "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar", - "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar", + "out/soong/.intermediates/transitive/android_common/turbine/transitive.jar", + "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar", + "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar", }, directCombined: []string{ "out/soong/.intermediates/direct/android_common/javac/direct.jar", "out/soong/.intermediates/transitive/android_common/javac/transitive.jar", - "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar", + "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar", + "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar", }, dontVerifyTransitive: true, @@ -1195,15 +1237,24 @@ func TestAndroidResourceProcessor(t *testing.T) { }, appSrcJars: []string{"out/soong/.intermediates/app/android_common/gen/android/R.srcjar"}, appClasspath: []string{ - "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", - "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar", - "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar", - "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar", + "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar", + "out/soong/.intermediates/shared/android_common/turbine/shared.jar", + "out/soong/.intermediates/shared_transitive_static/android_common/turbine/shared_transitive_static.jar", + "out/soong/.intermediates/direct/android_common/turbine/direct.jar", + "out/soong/.intermediates/transitive/android_common/turbine/transitive.jar", + "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar", + "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar", + "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar", + "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar", }, appCombined: []string{ "out/soong/.intermediates/app/android_common/javac/app.jar", - "out/soong/.intermediates/direct/android_common/combined/direct.jar", - "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar", + "out/soong/.intermediates/direct/android_common/javac/direct.jar", + "out/soong/.intermediates/transitive/android_common/javac/transitive.jar", + "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar", + "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar", + "out/soong/.intermediates/direct_import/android_common/aar/direct_import.jar", + "out/soong/.intermediates/direct_import_dep/android_common/aar/direct_import_dep.jar", }, directResources: nil, @@ -1216,14 +1267,16 @@ func TestAndroidResourceProcessor(t *testing.T) { directImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"}, directSrcJars: []string{"out/soong/.intermediates/direct/android_common/gen/android/R.srcjar"}, directClasspath: []string{ - "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", - "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar", - "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar", + "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar", + "out/soong/.intermediates/transitive/android_common/turbine/transitive.jar", + "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar", + "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar", }, directCombined: []string{ "out/soong/.intermediates/direct/android_common/javac/direct.jar", "out/soong/.intermediates/transitive/android_common/javac/transitive.jar", - "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar", + "out/soong/.intermediates/transitive_import/android_common/aar/transitive_import.jar", + "out/soong/.intermediates/transitive_import_dep/android_common/aar/transitive_import_dep.jar", }, transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"}, @@ -1231,7 +1284,7 @@ func TestAndroidResourceProcessor(t *testing.T) { transitiveImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"}, transitiveSrcJars: nil, transitiveClasspath: []string{ - "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", + "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine/android_stubs_current.jar", "out/soong/.intermediates/transitive/android_common/busybox/R.jar", }, transitiveCombined: nil, @@ -1480,7 +1533,6 @@ func TestAndroidResourceOverlays(t *testing.T) { "device/vendor/blah/overlay/bar/res/values/strings.xml", }, {"lib", "android_common"}: { - "out/soong/.intermediates/lib2/android_common/package-res.apk", "lib/res/res/values/strings.xml", "device/vendor/blah/overlay/lib/res/values/strings.xml", }, @@ -1515,12 +1567,10 @@ func TestAndroidResourceOverlays(t *testing.T) { "device/vendor/blah/overlay/bar/res/values/strings.xml", }, {"lib", "android_common"}: { - "out/soong/.intermediates/lib2/android_common/package-res.apk", "lib/res/res/values/strings.xml", "device/vendor/blah/overlay/lib/res/values/strings.xml", }, {"lib", "android_common_rro"}: { - "out/soong/.intermediates/lib2/android_common_rro/package-res.apk", "lib/res/res/values/strings.xml", }, }, @@ -1560,7 +1610,6 @@ func TestAndroidResourceOverlays(t *testing.T) { }, {"bar", "android_common"}: {"device/vendor/blah/static_overlay/bar/res/values/strings.xml"}, {"lib", "android_common"}: { - "out/soong/.intermediates/lib2/android_common/package-res.apk", "lib/res/res/values/strings.xml", }, }, @@ -3000,14 +3049,14 @@ func TestOverrideAndroidAppDependency(t *testing.T) { // Verify baz, which depends on the overridden module foo, has the correct classpath javac arg. javac := ctx.ModuleForTests(t, "baz", "android_common").Rule("javac") - fooTurbine := "out/soong/.intermediates/foo/android_common/turbine-combined/foo.jar" + fooTurbine := "out/soong/.intermediates/foo/android_common/turbine/foo.jar" if !strings.Contains(javac.Args["classpath"], fooTurbine) { t.Errorf("baz classpath %v does not contain %q", javac.Args["classpath"], fooTurbine) } // Verify qux, which depends on the overriding module bar, has the correct classpath javac arg. javac = ctx.ModuleForTests(t, "qux", "android_common").Rule("javac") - barTurbine := "out/soong/.intermediates/foo/android_common_bar/turbine-combined/foo.jar" + barTurbine := "out/soong/.intermediates/foo/android_common_bar/turbine/foo.jar" if !strings.Contains(javac.Args["classpath"], barTurbine) { t.Errorf("qux classpath %v does not contain %q", javac.Args["classpath"], barTurbine) } @@ -3084,7 +3133,7 @@ func TestOverrideAndroidTest(t *testing.T) { // Check if javac classpath has the correct jar file path. This checks instrumentation_for overrides. javac := variant.Rule("javac") - turbine := filepath.Join("out", "soong", ".intermediates", "foo", expected.targetVariant, "turbine-combined", "foo.jar") + turbine := filepath.Join("out", "soong", ".intermediates", "foo", expected.targetVariant, "turbine", "foo.jar") if !strings.Contains(javac.Args["classpath"], turbine) { t.Errorf("classpath %q does not contain %q", javac.Args["classpath"], turbine) } diff --git a/java/base.go b/java/base.go index 21ad73f84..0833831fc 100644 --- a/java/base.go +++ b/java/base.go @@ -658,11 +658,11 @@ func (j *Module) checkSdkVersions(ctx android.ModuleContext) { // See rank() for details. ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) { tag := ctx.OtherModuleDependencyTag(module) - _, isJavaLibrary := android.OtherModuleProvider(ctx, module, JavaLibraryInfoProvider) + libInfo, isJavaLibrary := android.OtherModuleProvider(ctx, module, JavaLibraryInfoProvider) _, isAndroidLibrary := android.OtherModuleProvider(ctx, module, AndroidLibraryInfoProvider) _, isJavaAconfigLibrary := android.OtherModuleProvider(ctx, module, android.CodegenInfoProvider) // Exclude java_aconfig_library modules to maintain consistency with existing behavior. - if (isJavaLibrary && !isJavaAconfigLibrary) || isAndroidLibrary { + if (isJavaLibrary && !libInfo.Prebuilt && !isJavaAconfigLibrary) || isAndroidLibrary { // TODO(satayev): cover other types as well, e.g. imports switch tag { case bootClasspathTag, sdkLibTag, libTag, staticLibTag, java9LibTag: @@ -1298,15 +1298,11 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath } j.headerJarFile = combinedHeaderJarFile - if ctx.Config().UseTransitiveJarsInClasspath() { - if len(localHeaderJars) > 0 { - ctx.CheckbuildFile(localHeaderJars...) - } else { - // There are no local sources or resources in this module, so there is nothing to checkbuild. - ctx.UncheckedModule() - } + if len(localHeaderJars) > 0 { + ctx.CheckbuildFile(localHeaderJars...) } else { - ctx.CheckbuildFile(j.headerJarFile) + // There are no local sources or resources in this module, so there is nothing to checkbuild. + ctx.UncheckedModule() } j.outputFile = j.headerJarFile @@ -1604,12 +1600,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath completeStaticLibsResourceJars := depset.New(depset.PREORDER, localResourceJars, deps.transitiveStaticLibsResourceJars) var combinedResourceJar android.Path - var resourceJars android.Paths - if ctx.Config().UseTransitiveJarsInClasspath() { - resourceJars = completeStaticLibsResourceJars.ToList() - } else { - resourceJars = append(slices.Clone(localResourceJars), deps.staticResourceJars...) - } + resourceJars := completeStaticLibsResourceJars.ToList() if len(resourceJars) == 1 { combinedResourceJar = resourceJars[0] } else if len(resourceJars) > 0 { @@ -1630,12 +1621,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath completeStaticLibsImplementationJars := depset.New(depset.PREORDER, localImplementationJars, deps.transitiveStaticLibsImplementationJars) - var jars android.Paths - if ctx.Config().UseTransitiveJarsInClasspath() { - jars = completeStaticLibsImplementationJars.ToList() - } else { - jars = append(slices.Clone(localImplementationJars), deps.staticJars...) - } + jars := completeStaticLibsImplementationJars.ToList() jars = append(jars, extraDepCombinedJars...) @@ -1766,7 +1752,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath headerJarFile := android.PathForModuleOut(ctx, "javac-header", jarName) convertImplementationJarToHeaderJar(ctx, j.implementationJarFile, headerJarFile) j.headerJarFile = headerJarFile - if len(localImplementationJars) == 1 && ctx.Config().UseTransitiveJarsInClasspath() { + if len(localImplementationJars) == 1 { localHeaderJarFile := android.PathForModuleOut(ctx, "local-javac-header", jarName) convertImplementationJarToHeaderJar(ctx, localImplementationJars[0], localHeaderJarFile) localHeaderJars = append(localHeaderJars, localHeaderJarFile) @@ -1796,16 +1782,10 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath // merge implementation jar with resources if necessary var implementationAndResourcesJarsToCombine android.Paths - if ctx.Config().UseTransitiveJarsInClasspath() { - resourceJars := completeStaticLibsResourceJars.ToList() - if len(resourceJars) > 0 { - implementationAndResourcesJarsToCombine = append(resourceJars, completeStaticLibsImplementationJarsToCombine.ToList()...) - implementationAndResourcesJarsToCombine = append(implementationAndResourcesJarsToCombine, extraDepCombinedJars...) - } - } else { - if combinedResourceJar != nil { - implementationAndResourcesJarsToCombine = android.Paths{combinedResourceJar, outputFile} - } + combinedResourceJars := completeStaticLibsResourceJars.ToList() + if len(combinedResourceJars) > 0 { + implementationAndResourcesJarsToCombine = slices.Concat(combinedResourceJars, + completeStaticLibsImplementationJarsToCombine.ToList(), extraDepCombinedJars) } if len(implementationAndResourcesJarsToCombine) > 0 { @@ -1855,18 +1835,9 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath } // merge dex jar with resources if necessary - var dexAndResourceJarsToCombine android.Paths - if ctx.Config().UseTransitiveJarsInClasspath() { - resourceJars := completeStaticLibsResourceJars.ToList() - if len(resourceJars) > 0 { - dexAndResourceJarsToCombine = append(android.Paths{dexOutputFile}, resourceJars...) - } - } else { - if combinedResourceJar != nil { - dexAndResourceJarsToCombine = android.Paths{dexOutputFile, combinedResourceJar} - } - } - if len(dexAndResourceJarsToCombine) > 0 { + if len(combinedResourceJars) > 0 { + dexAndResourceJarsToCombine := append(android.Paths{dexOutputFile}, combinedResourceJars...) + combinedJar := android.PathForModuleOut(ctx, "dex-withres", jarName) TransformJarsToJar(ctx, combinedJar, "for dex resources", dexAndResourceJarsToCombine, android.OptionalPath{}, false, nil, nil) @@ -1938,18 +1909,13 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath j.collectTransitiveSrcFiles(ctx, srcFiles) - if ctx.Config().UseTransitiveJarsInClasspath() { - if len(localImplementationJars) > 0 || len(localResourceJars) > 0 || len(localHeaderJars) > 0 { - ctx.CheckbuildFile(localImplementationJars...) - ctx.CheckbuildFile(localResourceJars...) - ctx.CheckbuildFile(localHeaderJars...) - } else { - // There are no local sources or resources in this module, so there is nothing to checkbuild. - ctx.UncheckedModule() - } + if len(localImplementationJars) > 0 || len(localResourceJars) > 0 || len(localHeaderJars) > 0 { + ctx.CheckbuildFile(localImplementationJars...) + ctx.CheckbuildFile(localResourceJars...) + ctx.CheckbuildFile(localHeaderJars...) } else { - ctx.CheckbuildFile(j.implementationJarFile) - ctx.CheckbuildFile(j.headerJarFile) + // There are no local sources or resources in this module, so there is nothing to checkbuild. + ctx.UncheckedModule() } // Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource @@ -2116,13 +2082,8 @@ func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars // Combine any static header libraries into classes-header.jar. If there is only // one input jar this step will be skipped. - var jars android.Paths - if ctx.Config().UseTransitiveJarsInClasspath() { - depSet := depset.New(depset.PREORDER, localHeaderJars, deps.transitiveStaticLibsHeaderJars) - jars = depSet.ToList() - } else { - jars = append(slices.Clone(localHeaderJars), deps.staticHeaderJars...) - } + depSet := depset.New(depset.PREORDER, localHeaderJars, deps.transitiveStaticLibsHeaderJars) + jars := depSet.ToList() // we cannot skip the combine step for now if there is only one jar // since we have to strip META-INF/TRANSITIVE dir from turbine.jar @@ -2634,14 +2595,12 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { deps.transitiveStaticLibsImplementationJars = transitiveStaticJarsImplementationLibs deps.transitiveStaticLibsResourceJars = transitiveStaticJarsResourceLibs - if ctx.Config().UseTransitiveJarsInClasspath() { - depSet := depset.New(depset.PREORDER, nil, transitiveClasspathHeaderJars) - deps.classpath = depSet.ToList() - depSet = depset.New(depset.PREORDER, nil, transitiveBootClasspathHeaderJars) - deps.bootClasspath = depSet.ToList() - depSet = depset.New(depset.PREORDER, nil, transitiveJava9ClasspathHeaderJars) - deps.java9Classpath = depSet.ToList() - } + depSet := depset.New(depset.PREORDER, nil, transitiveClasspathHeaderJars) + deps.classpath = depSet.ToList() + depSet = depset.New(depset.PREORDER, nil, transitiveBootClasspathHeaderJars) + deps.bootClasspath = depSet.ToList() + depSet = depset.New(depset.PREORDER, nil, transitiveJava9ClasspathHeaderJars) + deps.java9Classpath = depSet.ToList() if ctx.Device() { sdkDep := decodeSdkDep(ctx, android.SdkContext(j)) diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go index 7a3c21e44..a09416dc4 100644 --- a/java/bootclasspath_fragment.go +++ b/java/bootclasspath_fragment.go @@ -41,6 +41,10 @@ func registerBootclasspathFragmentBuildComponents(ctx android.RegistrationContex ctx.RegisterModuleType("prebuilt_bootclasspath_fragment", prebuiltBootclasspathFragmentFactory) } +type BootclasspathFragmentInfo struct{} + +var BootclasspathFragmentInfoProvider = blueprint.NewProvider[BootclasspathFragmentInfo]() + // BootclasspathFragmentSdkMemberType is the member type used to add bootclasspath_fragments to // the SDK snapshot. It is exported for use by apex. var BootclasspathFragmentSdkMemberType = &bootclasspathFragmentMemberType{ @@ -557,6 +561,8 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo if !ctx.IsFinalModule(ctx.Module()) { b.HideFromMake() } + + android.SetProvider(ctx, BootclasspathFragmentInfoProvider, BootclasspathFragmentInfo{}) } // getProfileProviderApex returns the name of the apex that provides a boot image profile, or an diff --git a/java/device_host_converter_test.go b/java/device_host_converter_test.go index 197bb9f95..42e3b4678 100644 --- a/java/device_host_converter_test.go +++ b/java/device_host_converter_test.go @@ -15,10 +15,11 @@ package java import ( - "android/soong/android" "slices" "strings" "testing" + + "android/soong/android" ) func TestDeviceForHost(t *testing.T) { @@ -54,12 +55,12 @@ func TestDeviceForHost(t *testing.T) { ctx, config := testJava(t, bp) deviceModule := ctx.ModuleForTests(t, "device_module", "android_common") - deviceTurbineCombined := deviceModule.Output("turbine-combined/device_module.jar") + deviceTurbine := deviceModule.Output("turbine/device_module.jar") deviceJavac := deviceModule.Output("javac/device_module.jar") deviceRes := deviceModule.Output("res/device_module.jar") deviceImportModule := ctx.ModuleForTests(t, "device_import_module", "android_common") - deviceImportCombined := deviceImportModule.Output("combined/device_import_module.jar") + deviceImportCombined := deviceImportModule.Output("local-combined/device_import_module.jar") hostModule := ctx.ModuleForTests(t, "host_module", config.BuildOSCommonTarget.String()) hostJavac := hostModule.Output("javac/host_module.jar") @@ -69,7 +70,7 @@ func TestDeviceForHost(t *testing.T) { // check classpath of host module with dependency on device_for_host_module expectedClasspath := "-classpath " + strings.Join(android.Paths{ - deviceTurbineCombined.Output, + deviceTurbine.Output, deviceImportCombined.Output, }.Strings(), ":") @@ -137,11 +138,11 @@ func TestHostForDevice(t *testing.T) { hostModule := ctx.ModuleForTests(t, "host_module", config.BuildOSCommonTarget.String()) hostJavac := hostModule.Output("javac/host_module.jar") - hostJavacHeader := hostModule.Output("javac-header/host_module.jar") + hostJavacHeader := hostModule.Output("local-javac-header/host_module.jar") hostRes := hostModule.Output("res/host_module.jar") hostImportModule := ctx.ModuleForTests(t, "host_import_module", config.BuildOSCommonTarget.String()) - hostImportCombined := hostImportModule.Output("combined/host_import_module.jar") + hostImportCombined := hostImportModule.Output("local-combined/host_import_module.jar") deviceModule := ctx.ModuleForTests(t, "device_module", "android_common") deviceJavac := deviceModule.Output("javac/device_module.jar") diff --git a/java/dex.go b/java/dex.go index 64465a2de..ed2df2103 100644 --- a/java/dex.go +++ b/java/dex.go @@ -63,6 +63,14 @@ type DexProperties struct { // Defaults to false for apps and tests, true for libraries. Proguard_compatibility *bool + // If true, R8 will not add public or protected members (fields or methods) to + // the API surface of the compilation unit, i.e., classes that are kept or + // have kept subclasses will not expose any members added by R8 for internal + // use. That includes renamed members if obfuscation is enabled. + // This should only be used for building targets that go on the bootclasspath. + // Defaults to false. + Protect_api_surface *bool + // If true, optimize for size by removing unused code. Defaults to true for apps, // false for libraries and tests. Shrink *bool @@ -170,6 +178,71 @@ var d8, d8RE = pctx.MultiCommandRemoteStaticRules("d8", }, }, []string{"outDir", "d8Flags", "zipFlags", "mergeZipsFlags"}, nil) +// Include all of the args for d8r8, so that we can generate the partialcompileclean target's build using the same list. +var d8r8Clean = pctx.AndroidStaticRule("d8r8-partialcompileclean", + blueprint.RuleParams{ + Command: `rm -rf "${outDir}" "${outDict}" "${outConfig}" "${outUsage}" "${outUsageZip}" "${outUsageDir}" ` + + `"${resourcesOutput}" "${outR8ArtProfile}" ${builtOut}`, + }, "outDir", "outDict", "outConfig", "outUsage", "outUsageZip", "outUsageDir", "builtOut", + "d8Flags", "r8Flags", "zipFlags", "mergeZipsFlags", "resourcesOutput", "outR8ArtProfile", "implicits", +) + +var d8r8, d8r8RE = pctx.MultiCommandRemoteStaticRules("d8r8", + blueprint.RuleParams{ + Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` + + `rm -f "$outDict" && rm -f "$outConfig" && rm -rf "${outUsageDir}" && ` + + `mkdir -p $$(dirname ${outUsage}) && ` + + `if [ -n "$${SOONG_USE_PARTIAL_COMPILE}" ]; then ` + + ` for f in "${outConfig}" "${outDict}" "${outUsage}" "${resourcesOutput}"; do ` + + ` test -n "$${f}" && test ! -f "$${f}" && mkdir -p "$$(dirname "$${f}")" && touch "$${f}" || true; ` + + ` done && ` + + ` $d8Template${config.D8Cmd} ${config.D8Flags} $d8Flags --output $outDir --no-dex-input-jar $in; ` + + `else ` + + ` $r8Template${config.R8Cmd} ${config.R8Flags} $r8Flags -injars $in --output $outDir ` + + ` --no-data-resources ` + + ` -printmapping ${outDict} ` + + ` -printconfiguration ${outConfig} ` + + ` -printusage ${outUsage} ` + + ` --deps-file ${out}.d && ` + + ` touch "${outDict}" "${outConfig}" "${outUsage}"; ` + + `fi && ` + + `${config.SoongZipCmd} -o ${outUsageZip} -C ${outUsageDir} -f ${outUsage} && ` + + `rm -rf ${outUsageDir} && ` + + `$zipTemplate${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` + + `${config.MergeZipsCmd} -D -stripFile "**/*.class" $mergeZipsFlags $out $outDir/classes.dex.jar $in && ` + + `rm -f "$outDir"/classes*.dex "$outDir/classes.dex.jar" `, + CommandDeps: []string{ + "${config.D8Cmd}", + "${config.R8Cmd}", + "${config.SoongZipCmd}", + "${config.MergeZipsCmd}", + }, + }, map[string]*remoteexec.REParams{ + "$d8Template": &remoteexec.REParams{ + Labels: map[string]string{"type": "compile", "compiler": "d8"}, + Inputs: []string{"${config.D8Jar}"}, + ExecStrategy: "${config.RED8ExecStrategy}", + ToolchainInputs: []string{"${config.JavaCmd}"}, + Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"}, + }, + "$r8Template": &remoteexec.REParams{ + Labels: map[string]string{"type": "compile", "compiler": "r8"}, + Inputs: []string{"$implicits", "${config.R8Jar}"}, + OutputFiles: []string{"${outUsage}", "${outConfig}", "${outDict}", "${resourcesOutput}", "${outR8ArtProfile}"}, + ExecStrategy: "${config.RER8ExecStrategy}", + ToolchainInputs: []string{"${config.JavaCmd}"}, + Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"}, + }, + "$zipTemplate": &remoteexec.REParams{ + Labels: map[string]string{"type": "tool", "name": "soong_zip"}, + Inputs: []string{"${config.SoongZipCmd}", "$outDir"}, + OutputFiles: []string{"$outDir/classes.dex.jar"}, + ExecStrategy: "${config.RED8ExecStrategy}", + Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"}, + }, + }, []string{"outDir", "outDict", "outConfig", "outUsage", "outUsageZip", "outUsageDir", + "d8Flags", "r8Flags", "zipFlags", "mergeZipsFlags", "resourcesOutput", "outR8ArtProfile"}, []string{"implicits"}) + var r8, r8RE = pctx.MultiCommandRemoteStaticRules("r8", blueprint.RuleParams{ Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` + @@ -362,6 +435,11 @@ func (d *dexer) r8Flags(ctx android.ModuleContext, dexParams *compileDexParams, android.PathForSource(ctx, "build/make/core/proguard.flags"), } + if ctx.Config().UseR8GlobalCheckNotNullFlags() { + flagFiles = append(flagFiles, android.PathForSource(ctx, + "build/make/core/proguard/checknotnull.flags")) + } + flagFiles = append(flagFiles, d.extraProguardFlagsFiles...) // TODO(ccross): static android library proguard files @@ -390,6 +468,10 @@ func (d *dexer) r8Flags(ctx android.ModuleContext, dexParams *compileDexParams, r8Flags = append(r8Flags, "--force-proguard-compatibility") } + if BoolDefault(opt.Protect_api_surface, false) { + r8Flags = append(r8Flags, "--protect-api-surface") + } + // Avoid unnecessary stack frame noise by only injecting source map ids for non-debug // optimized or obfuscated targets. if (Bool(opt.Optimize) || Bool(opt.Obfuscate)) && !debugMode { @@ -482,6 +564,7 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam // Compile classes.jar into classes.dex and then javalib.jar javalibJar := android.PathForModuleOut(ctx, "dex", dexParams.jarName).OutputPath + cleanPhonyPath := android.PathForModuleOut(ctx, "dex", dexParams.jarName+"-partialcompileclean").OutputPath outDir := android.PathForModuleOut(ctx, "dex") zipFlags := "--ignore_missing_files" @@ -498,7 +581,19 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam } useR8 := d.effectiveOptimizeEnabled() + useD8 := !useR8 || ctx.Config().PartialCompileFlags().Use_d8 + rbeR8 := ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_R8") + rbeD8 := ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_D8") + var rule blueprint.Rule + var description string var artProfileOutputPath *android.OutputPath + var implicitOutputs android.WritablePaths + var deps android.Paths + args := map[string]string{ + "zipFlags": zipFlags, + "outDir": outDir.String(), + "mergeZipsFlags": mergeZipsFlags, + } if useR8 { proguardDictionary := android.PathForModuleOut(ctx, "proguard_dictionary") d.proguardDictionary = android.OptionalPathForPath(proguardDictionary) @@ -511,83 +606,89 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam d.proguardUsageZip = android.OptionalPathForPath(proguardUsageZip) resourcesOutput := android.PathForModuleOut(ctx, "package-res-shrunken.apk") d.resourcesOutput = android.OptionalPathForPath(resourcesOutput) - implicitOutputs := android.WritablePaths{ + implicitOutputs = append(implicitOutputs, android.WritablePaths{ proguardDictionary, proguardUsageZip, proguardConfiguration, - } + }...) + description = "r8" debugMode := android.InList("--debug", commonFlags) r8Flags, r8Deps, r8ArtProfileOutputPath := d.r8Flags(ctx, dexParams, debugMode) - rule := r8 - args := map[string]string{ - "r8Flags": strings.Join(append(commonFlags, r8Flags...), " "), - "zipFlags": zipFlags, - "outDict": proguardDictionary.String(), - "outConfig": proguardConfiguration.String(), - "outUsageDir": proguardUsageDir.String(), - "outUsage": proguardUsage.String(), - "outUsageZip": proguardUsageZip.String(), - "outDir": outDir.String(), - "mergeZipsFlags": mergeZipsFlags, - } + deps = append(deps, r8Deps...) + args["r8Flags"] = strings.Join(append(commonFlags, r8Flags...), " ") if r8ArtProfileOutputPath != nil { artProfileOutputPath = r8ArtProfileOutputPath - implicitOutputs = append( - implicitOutputs, - artProfileOutputPath, - ) // Add the implicit r8 Art profile output to args so that r8RE knows // about this implicit output - args["outR8ArtProfile"] = artProfileOutputPath.String() - } - - if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_R8") { - rule = r8RE - args["implicits"] = strings.Join(r8Deps.Strings(), ",") + args["outR8ArtProfile"] = r8ArtProfileOutputPath.String() } + args["outDict"] = proguardDictionary.String() + args["outConfig"] = proguardConfiguration.String() + args["outUsageDir"] = proguardUsageDir.String() + args["outUsage"] = proguardUsage.String() + args["outUsageZip"] = proguardUsageZip.String() if d.resourcesInput.Valid() { implicitOutputs = append(implicitOutputs, resourcesOutput) args["resourcesOutput"] = resourcesOutput.String() } - ctx.Build(pctx, android.BuildParams{ - Rule: rule, - Description: "r8", - Output: javalibJar, - ImplicitOutputs: implicitOutputs, - Input: dexParams.classesJar, - Implicits: r8Deps, - Args: args, - }) - } else { - implicitOutputs := android.WritablePaths{} + + rule = r8 + if rbeR8 { + rule = r8RE + args["implicits"] = strings.Join(deps.Strings(), ",") + } + } + if useD8 { + description = "d8" d8Flags, d8Deps, d8ArtProfileOutputPath := d.d8Flags(ctx, dexParams) + deps = append(deps, d8Deps...) + deps = append(deps, commonDeps...) + args["d8Flags"] = strings.Join(append(commonFlags, d8Flags...), " ") if d8ArtProfileOutputPath != nil { artProfileOutputPath = d8ArtProfileOutputPath - implicitOutputs = append( - implicitOutputs, - artProfileOutputPath, - ) } - d8Deps = append(d8Deps, commonDeps...) - rule := d8 - if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_D8") { + // If we are generating both d8 and r8, only use RBE when both are enabled. + switch { + case useR8 && rule == r8: + rule = d8r8 + description = "d8r8" + case useR8 && rule == r8RE && rbeD8: + rule = d8r8RE + description = "d8r8" + case rbeD8: rule = d8RE + default: + rule = d8 } + } + if artProfileOutputPath != nil { + implicitOutputs = append( + implicitOutputs, + artProfileOutputPath, + ) + } + ctx.Build(pctx, android.BuildParams{ + Rule: rule, + Description: description, + Output: javalibJar, + ImplicitOutputs: implicitOutputs, + Input: dexParams.classesJar, + Implicits: deps, + Args: args, + }) + if useR8 && useD8 { + // Generate the rule for partial compile clean. + args["builtOut"] = javalibJar.String() ctx.Build(pctx, android.BuildParams{ - Rule: rule, - Description: "d8", - Output: javalibJar, - Input: dexParams.classesJar, - ImplicitOutputs: implicitOutputs, - Implicits: d8Deps, - Args: map[string]string{ - "d8Flags": strings.Join(append(commonFlags, d8Flags...), " "), - "zipFlags": zipFlags, - "outDir": outDir.String(), - "mergeZipsFlags": mergeZipsFlags, - }, + Rule: d8r8Clean, + Description: "d8r8Clean", + Output: cleanPhonyPath, + Args: args, + PhonyOutput: true, }) + ctx.Phony("partialcompileclean", cleanPhonyPath) } + if proptools.Bool(d.dexProperties.Uncompress_dex) { alignedJavalibJar := android.PathForModuleOut(ctx, "aligned", dexParams.jarName).OutputPath TransformZipAlign(ctx, alignedJavalibJar, javalibJar, nil) @@ -596,3 +697,13 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam return javalibJar, artProfileOutputPath } + +type ProguardInfo struct { + ModuleName string + Class string + ProguardDictionary android.Path + ProguardUsageZip android.Path + ClassesJar android.Path +} + +var ProguardProvider = blueprint.NewProvider[ProguardInfo]() diff --git a/java/dex_test.go b/java/dex_test.go index 2126e42e8..66d801dcc 100644 --- a/java/dex_test.go +++ b/java/dex_test.go @@ -70,16 +70,17 @@ func TestR8(t *testing.T) { appR8 := app.Rule("r8") stableAppR8 := stableApp.Rule("r8") corePlatformAppR8 := corePlatformApp.Rule("r8") - libHeader := lib.Output("turbine-combined/lib.jar").Output - staticLibHeader := staticLib.Output("turbine-combined/static_lib.jar").Output + libHeader := lib.Output("turbine/lib.jar").Output + libCombinedHeader := lib.Output("turbine-combined/lib.jar").Output + staticLibHeader := staticLib.Output("turbine/static_lib.jar").Output android.AssertStringDoesContain(t, "expected lib header jar in app javac classpath", appJavac.Args["classpath"], libHeader.String()) android.AssertStringDoesContain(t, "expected static_lib header jar in app javac classpath", appJavac.Args["classpath"], staticLibHeader.String()) - android.AssertStringDoesContain(t, "expected lib header jar in app r8 classpath", - appR8.Args["r8Flags"], libHeader.String()) + android.AssertStringDoesContain(t, "expected lib combined header jar in app r8 classpath", + appR8.Args["r8Flags"], libCombinedHeader.String()) android.AssertStringDoesNotContain(t, "expected no static_lib header jar in app r8 classpath", appR8.Args["r8Flags"], staticLibHeader.String()) android.AssertStringDoesContain(t, "expected -ignorewarnings in app r8 flags", @@ -331,16 +332,17 @@ func TestD8(t *testing.T) { fooJavac := foo.Rule("javac") fooD8 := foo.Rule("d8") appD8 := app.Rule("d8") - libHeader := lib.Output("turbine-combined/lib.jar").Output - staticLibHeader := staticLib.Output("turbine-combined/static_lib.jar").Output + libHeader := lib.Output("turbine/lib.jar").Output + libCombinedHeader := lib.Output("turbine-combined/lib.jar").Output + staticLibHeader := staticLib.Output("turbine/static_lib.jar").Output android.AssertStringDoesContain(t, "expected lib header jar in foo javac classpath", fooJavac.Args["classpath"], libHeader.String()) android.AssertStringDoesContain(t, "expected static_lib header jar in foo javac classpath", fooJavac.Args["classpath"], staticLibHeader.String()) - android.AssertStringDoesContain(t, "expected lib header jar in foo d8 classpath", - fooD8.Args["d8Flags"], libHeader.String()) + android.AssertStringDoesContain(t, "expected lib combined header jar in foo d8 classpath", + fooD8.Args["d8Flags"], libCombinedHeader.String()) android.AssertStringDoesNotContain(t, "expected no static_lib header jar in foo javac classpath", fooD8.Args["d8Flags"], staticLibHeader.String()) diff --git a/java/fuzz_test.go b/java/fuzz_test.go index 8cbe873ad..735b8da93 100644 --- a/java/fuzz_test.go +++ b/java/fuzz_test.go @@ -72,8 +72,8 @@ func TestJavaFuzz(t *testing.T) { } baz := result.ModuleForTests(t, "baz", osCommonTarget).Rule("javac").Output.String() - barOut := filepath.Join("out", "soong", ".intermediates", "bar", osCommonTarget, "javac-header", "bar.jar") - bazOut := filepath.Join("out", "soong", ".intermediates", "baz", osCommonTarget, "javac-header", "baz.jar") + barOut := filepath.Join("out", "soong", ".intermediates", "bar", osCommonTarget, "local-javac-header", "bar.jar") + bazOut := filepath.Join("out", "soong", ".intermediates", "baz", osCommonTarget, "local-javac-header", "baz.jar") android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], barOut) android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], bazOut) diff --git a/java/java.go b/java/java.go index 36601e02d..b18c56130 100644 --- a/java/java.go +++ b/java/java.go @@ -259,7 +259,6 @@ type AndroidLibraryDependencyInfo struct { } type UsesLibraryDependencyInfo struct { - DexJarBuildPath OptionalDexJarPath DexJarInstallPath android.Path ClassLoaderContexts dexpreopt.ClassLoaderContextMap } @@ -403,13 +402,6 @@ type JavaInfo struct { BuiltInstalled string - // ApexSystemServerDexpreoptInstalls stores the list of dexpreopt artifacts if this is a system server - // jar in an apex. - ApexSystemServerDexpreoptInstalls []DexpreopterInstall - - // ApexSystemServerDexJars stores the list of dex jars if this is a system server jar in an apex. - ApexSystemServerDexJars android.Paths - // The config is used for two purposes: // - Passing dexpreopt information about libraries from Soong to Make. This is needed when // a <uses-library> is defined in Android.bp, but used in Android.mk (see dex_preopt_config_merger.py). @@ -418,10 +410,6 @@ type JavaInfo struct { // dexpreopt another partition). ConfigPath android.WritablePath - // The path to the profile on host that dexpreopter generates. This is used as the input for - // dex2oat. - OutputProfilePathOnHost android.Path - LogtagsSrcs android.Paths ProguardDictionary android.OptionalPath @@ -438,14 +426,39 @@ type JavaInfo struct { // True if profile-guided optimization is actually enabled. ProfileGuided bool + + Stem string + + DexJarBuildPath OptionalDexJarPath + + DexpreopterInfo *DexpreopterInfo } var JavaInfoProvider = blueprint.NewProvider[*JavaInfo]() -type JavaLibraryInfo struct{} +type DexpreopterInfo struct { + // The path to the profile on host that dexpreopter generates. This is used as the input for + // dex2oat. + OutputProfilePathOnHost android.Path + // If the java module is to be installed into an APEX, this list contains information about the + // dexpreopt outputs to be installed on devices. Note that these dexpreopt outputs are installed + // outside of the APEX. + ApexSystemServerDexpreoptInstalls []DexpreopterInstall + + // ApexSystemServerDexJars returns the list of dex jars if this is an apex system server jar. + ApexSystemServerDexJars android.Paths +} + +type JavaLibraryInfo struct { + Prebuilt bool +} var JavaLibraryInfoProvider = blueprint.NewProvider[JavaLibraryInfo]() +type JavaDexImportInfo struct{} + +var JavaDexImportInfoProvider = blueprint.NewProvider[JavaDexImportInfo]() + // SyspropPublicStubInfo contains info about the sysprop public stub library that corresponds to // the sysprop implementation library. type SyspropPublicStubInfo struct { @@ -1127,7 +1140,9 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { TopLevelTarget: j.sourceProperties.Top_level_test_target, }) - android.SetProvider(ctx, JavaLibraryInfoProvider, JavaLibraryInfo{}) + android.SetProvider(ctx, JavaLibraryInfoProvider, JavaLibraryInfo{ + Prebuilt: false, + }) if javaInfo != nil { setExtraJavaInfo(ctx, j, javaInfo) @@ -1137,11 +1152,8 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { javaInfo.BootDexJarPath = j.bootDexJarPath javaInfo.UncompressDexState = j.uncompressDexState javaInfo.Active = j.active - javaInfo.ApexSystemServerDexpreoptInstalls = j.apexSystemServerDexpreoptInstalls - javaInfo.ApexSystemServerDexJars = j.apexSystemServerDexJars javaInfo.BuiltInstalled = j.builtInstalled javaInfo.ConfigPath = j.configPath - javaInfo.OutputProfilePathOnHost = j.outputProfilePathOnHost javaInfo.LogtagsSrcs = j.logtagsSrcs javaInfo.ProguardDictionary = j.proguardDictionary javaInfo.ProguardUsageZip = j.proguardUsageZip @@ -1160,6 +1172,16 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { buildComplianceMetadata(ctx) j.createApiXmlFile(ctx) + + if j.dexer.proguardDictionary.Valid() { + android.SetProvider(ctx, ProguardProvider, ProguardInfo{ + ModuleName: ctx.ModuleName(), + Class: "JAVA_LIBRARIES", + ProguardDictionary: j.dexer.proguardDictionary.Path(), + ProguardUsageZip: j.dexer.proguardUsageZip.Path(), + ClassesJar: j.implementationAndResourcesJar, + }) + } } func (j *Library) javaLibraryModuleInfoJSON(ctx android.ModuleContext) *android.ModuleInfoJSON { @@ -1916,6 +1938,10 @@ func (j *Test) generateAndroidBuildActionsWithConfig(ctx android.ModuleContext, if j.testConfig != nil { ctx.InstallFile(pathInTestCases, ctx.ModuleName()+".config", j.testConfig) } + dynamicConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml") + if dynamicConfig.Valid() { + ctx.InstallFile(pathInTestCases, ctx.ModuleName()+".dynamic", dynamicConfig.Path()) + } testDeps := append(j.data, j.extraTestConfigs...) for _, data := range android.SortedUniquePaths(testDeps) { dataPath := android.DataPath{SrcPath: data} @@ -3062,12 +3088,7 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { // file of the module to be named jarName. var outputFile android.Path combinedImplementationJar := android.PathForModuleOut(ctx, "combined", jarName) - var implementationJars android.Paths - if ctx.Config().UseTransitiveJarsInClasspath() { - implementationJars = completeStaticLibsImplementationJars.ToList() - } else { - implementationJars = append(slices.Clone(localJars), staticJars...) - } + implementationJars := completeStaticLibsImplementationJars.ToList() TransformJarsToJar(ctx, combinedImplementationJar, "combine prebuilt implementation jars", implementationJars, android.OptionalPath{}, false, j.properties.Exclude_files, j.properties.Exclude_dirs) outputFile = combinedImplementationJar @@ -3090,12 +3111,7 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { if reuseImplementationJarAsHeaderJar { headerJar = outputFile } else { - var headerJars android.Paths - if ctx.Config().UseTransitiveJarsInClasspath() { - headerJars = completeStaticLibsHeaderJars.ToList() - } else { - headerJars = append(slices.Clone(localJars), staticHeaderJars...) - } + headerJars := completeStaticLibsHeaderJars.ToList() headerOutputFile := android.PathForModuleOut(ctx, "turbine-combined", jarName) TransformJarsToJar(ctx, headerOutputFile, "combine prebuilt header jars", headerJars, android.OptionalPath{}, false, j.properties.Exclude_files, j.properties.Exclude_dirs) @@ -3159,11 +3175,7 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.properties.Aidl.Export_include_dirs) - if ctx.Config().UseTransitiveJarsInClasspath() { - ctx.CheckbuildFile(localJars...) - } else { - ctx.CheckbuildFile(outputFile) - } + ctx.CheckbuildFile(localJars...) if ctx.Device() { // Shared libraries deapexed from prebuilt apexes are no longer supported. @@ -3235,6 +3247,10 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { setExtraJavaInfo(ctx, j, javaInfo) android.SetProvider(ctx, JavaInfoProvider, javaInfo) + android.SetProvider(ctx, JavaLibraryInfoProvider, JavaLibraryInfo{ + Prebuilt: true, + }) + ctx.SetOutputFiles(android.Paths{j.combinedImplementationFile}, "") ctx.SetOutputFiles(android.Paths{j.combinedImplementationFile}, ".jar") @@ -3514,6 +3530,12 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), j.Stem()+".jar", dexOutputFile) } + + javaInfo := &JavaInfo{} + setExtraJavaInfo(ctx, j, javaInfo) + android.SetProvider(ctx, JavaInfoProvider, javaInfo) + + android.SetProvider(ctx, JavaDexImportInfoProvider, JavaDexImportInfo{}) } func (j *DexImport) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath { @@ -3701,7 +3723,7 @@ func addCLCFromDep(ctx android.ModuleContext, depModule android.ModuleProxy, } } clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, optional, - dep.UsesLibraryDependencyInfo.DexJarBuildPath.PathOrNil(), + dep.DexJarBuildPath.PathOrNil(), dep.UsesLibraryDependencyInfo.DexJarInstallPath, dep.UsesLibraryDependencyInfo.ClassLoaderContexts) } else { clcMap.AddContextMap(dep.UsesLibraryDependencyInfo.ClassLoaderContexts, depName) @@ -3785,7 +3807,6 @@ func setExtraJavaInfo(ctx android.ModuleContext, module android.Module, javaInfo if ulDep, ok := module.(UsesLibraryDependency); ok { javaInfo.UsesLibraryDependencyInfo = &UsesLibraryDependencyInfo{ - DexJarBuildPath: ulDep.DexJarBuildPath(ctx), DexJarInstallPath: ulDep.DexJarInstallPath(), ClassLoaderContexts: ulDep.ClassLoaderContexts(), } @@ -3814,4 +3835,22 @@ func setExtraJavaInfo(ctx android.ModuleContext, module android.Module, javaInfo Stubs: stubs, } } + + if st, ok := module.(ModuleWithStem); ok { + javaInfo.Stem = st.Stem() + } + + if mm, ok := module.(interface { + DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath + }); ok { + javaInfo.DexJarBuildPath = mm.DexJarBuildPath(ctx) + } + + if di, ok := module.(DexpreopterInterface); ok { + javaInfo.DexpreopterInfo = &DexpreopterInfo{ + OutputProfilePathOnHost: di.OutputProfilePathOnHost(), + ApexSystemServerDexpreoptInstalls: di.ApexSystemServerDexpreoptInstalls(), + ApexSystemServerDexJars: di.ApexSystemServerDexJars(), + } + } } diff --git a/java/java_test.go b/java/java_test.go index b04ab1780..a6290a628 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -110,7 +110,7 @@ func defaultModuleToPath(name string) string { case strings.HasSuffix(name, ".jar"): return name default: - return filepath.Join("out", "soong", ".intermediates", defaultJavaDir, name, "android_common", "turbine-combined", name+".jar") + return filepath.Join("out", "soong", ".intermediates", defaultJavaDir, name, "android_common", "turbine", name+".jar") } } @@ -240,11 +240,6 @@ func TestSimple(t *testing.T) { srcs: ["d.java"], }` - frameworkTurbineCombinedJars := []string{ - "out/soong/.intermediates/default/java/ext/android_common/turbine-combined/ext.jar", - "out/soong/.intermediates/default/java/framework/android_common/turbine-combined/framework.jar", - } - frameworkTurbineJars := []string{ "out/soong/.intermediates/default/java/ext/android_common/turbine/ext.jar", "out/soong/.intermediates/default/java/framework/android_common/turbine/framework.jar", @@ -270,43 +265,6 @@ func TestSimple(t *testing.T) { preparer: android.NullFixturePreparer, fooJavacInputs: []string{"a.java"}, fooJavacClasspath: slices.Concat( - frameworkTurbineCombinedJars, - []string{ - "out/soong/.intermediates/bar/android_common/turbine-combined/bar.jar", - "out/soong/.intermediates/baz/android_common/turbine-combined/baz.jar", - }, - ), - fooCombinedInputs: []string{ - "out/soong/.intermediates/foo/android_common/javac/foo.jar", - "out/soong/.intermediates/baz/android_common/combined/baz.jar", - }, - - fooHeaderCombinedInputs: []string{ - "out/soong/.intermediates/foo/android_common/turbine/foo.jar", - "out/soong/.intermediates/baz/android_common/turbine-combined/baz.jar", - }, - - barJavacInputs: []string{"b.java"}, - barJavacClasspath: slices.Concat( - frameworkTurbineCombinedJars, - []string{ - "out/soong/.intermediates/quz/android_common/turbine-combined/quz.jar", - }, - ), - barCombinedInputs: []string{ - "out/soong/.intermediates/bar/android_common/javac/bar.jar", - "out/soong/.intermediates/quz/android_common/javac/quz.jar", - }, - barHeaderCombinedInputs: []string{ - "out/soong/.intermediates/bar/android_common/turbine/bar.jar", - "out/soong/.intermediates/quz/android_common/turbine-combined/quz.jar", - }, - }, - { - name: "transitive classpath", - preparer: PrepareForTestWithTransitiveClasspathEnabled, - fooJavacInputs: []string{"a.java"}, - fooJavacClasspath: slices.Concat( frameworkTurbineJars, []string{ "out/soong/.intermediates/bar/android_common/turbine/bar.jar", @@ -749,11 +707,11 @@ func TestPrebuilts(t *testing.T) { javac := fooModule.Rule("javac") combineJar := ctx.ModuleForTests(t, "foo", "android_common").Description("for javac") barModule := ctx.ModuleForTests(t, "bar", "android_common") - barJar := barModule.Output("combined/bar.jar").Output + barJar := barModule.Output("local-combined/bar.jar").Output bazModule := ctx.ModuleForTests(t, "baz", "android_common") - bazJar := bazModule.Output("combined/baz.jar").Output + bazJar := bazModule.Output("local-combined/baz.jar").Output sdklibStubsJar := ctx.ModuleForTests(t, "sdklib.stubs", "android_common"). - Output("combined/sdklib.stubs.jar").Output + Output("local-combined/sdklib.stubs.jar").Output fooLibrary := fooModule.Module().(*Library) assertDeepEquals(t, "foo unique sources incorrect", @@ -881,7 +839,7 @@ func TestDefaults(t *testing.T) { t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs) } - barTurbine := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine-combined", "bar.jar") + barTurbine := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine", "bar.jar") if !strings.Contains(javac.Args["classpath"], barTurbine) { t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], barTurbine) } @@ -1070,7 +1028,7 @@ func TestIncludeSrcs(t *testing.T) { t.Errorf("bar combined resource jars %v does not contain %q", w, g) } - if g, w := barResCombined.Output.String(), bar.Inputs.Strings(); !inList(g, w) { + if g, w := barRes.Output.String(), bar.Inputs.Strings(); !inList(g, w) { t.Errorf("bar combined jars %v does not contain %q", w, g) } @@ -1154,7 +1112,7 @@ func TestTurbine(t *testing.T) { android.AssertPathsRelativeToTopEquals(t, "foo inputs", []string{"a.java"}, fooTurbine.Inputs) - fooHeaderJar := filepath.Join("out", "soong", ".intermediates", "foo", "android_common", "turbine-combined", "foo.jar") + fooHeaderJar := filepath.Join("out", "soong", ".intermediates", "foo", "android_common", "turbine", "foo.jar") barTurbineJar := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine", "bar.jar") android.AssertStringDoesContain(t, "bar turbine classpath", barTurbine.Args["turbineFlags"], fooHeaderJar) android.AssertStringDoesContain(t, "bar javac classpath", barJavac.Args["classpath"], fooHeaderJar) @@ -1274,16 +1232,18 @@ func TestJavaImport(t *testing.T) { source := ctx.ModuleForTests(t, "source_library", "android_common") sourceJar := source.Output("javac/source_library.jar") - sourceHeaderJar := source.Output("turbine-combined/source_library.jar") + sourceHeaderJar := source.Output("turbine/source_library.jar") + sourceCombinedHeaderJar := source.Output("turbine-combined/source_library.jar") sourceJavaInfo, _ := android.OtherModuleProvider(ctx, source.Module(), JavaInfoProvider) // The source library produces separate implementation and header jars android.AssertPathsRelativeToTopEquals(t, "source library implementation jar", []string{sourceJar.Output.String()}, sourceJavaInfo.ImplementationAndResourcesJars) android.AssertPathsRelativeToTopEquals(t, "source library header jar", - []string{sourceHeaderJar.Output.String()}, sourceJavaInfo.HeaderJars) + []string{sourceCombinedHeaderJar.Output.String()}, sourceJavaInfo.HeaderJars) importWithNoDeps := ctx.ModuleForTests(t, "import_with_no_deps", "android_common") + importWithNoDepsLocalJar := importWithNoDeps.Output("local-combined/import_with_no_deps.jar") importWithNoDepsJar := importWithNoDeps.Output("combined/import_with_no_deps.jar") importWithNoDepsJavaInfo, _ := android.OtherModuleProvider(ctx, importWithNoDeps.Module(), JavaInfoProvider) @@ -1293,10 +1253,14 @@ func TestJavaImport(t *testing.T) { android.AssertPathsRelativeToTopEquals(t, "import with no deps header jar", []string{importWithNoDepsJar.Output.String()}, importWithNoDepsJavaInfo.HeaderJars) android.AssertPathsRelativeToTopEquals(t, "import with no deps combined inputs", - []string{"no_deps.jar"}, importWithNoDepsJar.Inputs) + []string{importWithNoDepsLocalJar.Output.String()}, importWithNoDepsJar.Inputs) + android.AssertPathsRelativeToTopEquals(t, "import with no deps local combined inputs", + []string{"no_deps.jar"}, importWithNoDepsLocalJar.Inputs) importWithSourceDeps := ctx.ModuleForTests(t, "import_with_source_deps", "android_common") + importWithSourceDepsLocalJar := importWithSourceDeps.Output("local-combined/import_with_source_deps.jar") importWithSourceDepsJar := importWithSourceDeps.Output("combined/import_with_source_deps.jar") + importWithSourceDepsLocalHeaderJar := importWithSourceDeps.Output("local-combined/import_with_source_deps.jar") importWithSourceDepsHeaderJar := importWithSourceDeps.Output("turbine-combined/import_with_source_deps.jar") importWithSourceDepsJavaInfo, _ := android.OtherModuleProvider(ctx, importWithSourceDeps.Module(), JavaInfoProvider) @@ -1306,11 +1270,16 @@ func TestJavaImport(t *testing.T) { android.AssertPathsRelativeToTopEquals(t, "import with source deps header jar", []string{importWithSourceDepsHeaderJar.Output.String()}, importWithSourceDepsJavaInfo.HeaderJars) android.AssertPathsRelativeToTopEquals(t, "import with source deps combined implementation jar inputs", - []string{"source_deps.jar", sourceJar.Output.String()}, importWithSourceDepsJar.Inputs) + []string{importWithSourceDepsLocalJar.Output.String(), sourceJar.Output.String()}, importWithSourceDepsJar.Inputs) android.AssertPathsRelativeToTopEquals(t, "import with source deps combined header jar inputs", - []string{"source_deps.jar", sourceHeaderJar.Output.String()}, importWithSourceDepsHeaderJar.Inputs) + []string{importWithSourceDepsLocalHeaderJar.Output.String(), sourceHeaderJar.Output.String()}, importWithSourceDepsHeaderJar.Inputs) + android.AssertPathsRelativeToTopEquals(t, "import with source deps local combined implementation jar inputs", + []string{"source_deps.jar"}, importWithSourceDepsLocalJar.Inputs) + android.AssertPathsRelativeToTopEquals(t, "import with source deps local combined header jar inputs", + []string{"source_deps.jar"}, importWithSourceDepsLocalHeaderJar.Inputs) importWithImportDeps := ctx.ModuleForTests(t, "import_with_import_deps", "android_common") + importWithImportDepsLocalJar := importWithImportDeps.Output("local-combined/import_with_import_deps.jar") importWithImportDepsJar := importWithImportDeps.Output("combined/import_with_import_deps.jar") importWithImportDepsJavaInfo, _ := android.OtherModuleProvider(ctx, importWithImportDeps.Module(), JavaInfoProvider) @@ -1320,7 +1289,9 @@ func TestJavaImport(t *testing.T) { android.AssertPathsRelativeToTopEquals(t, "import with import deps header jar", []string{importWithImportDepsJar.Output.String()}, importWithImportDepsJavaInfo.HeaderJars) android.AssertPathsRelativeToTopEquals(t, "import with import deps combined implementation jar inputs", - []string{"import_deps.jar", importWithNoDepsJar.Output.String()}, importWithImportDepsJar.Inputs) + []string{importWithImportDepsLocalJar.Output.String(), importWithNoDepsLocalJar.Output.String()}, importWithImportDepsJar.Inputs) + android.AssertPathsRelativeToTopEquals(t, "import with import deps local combined implementation jar inputs", + []string{"import_deps.jar"}, importWithImportDepsLocalJar.Inputs) } var compilerFlagsTestCases = []struct { @@ -1387,6 +1358,7 @@ func TestCompilerFlags(t *testing.T) { // TODO(jungjw): Consider making this more robust by ignoring path order. func checkPatchModuleFlag(t *testing.T, ctx *android.TestContext, moduleName string, expected string) { + t.Helper() variables := ctx.ModuleForTests(t, moduleName, "android_common").VariablesForTestsRelativeToTop() flags := strings.Split(variables["javacFlags"], " ") got := "" @@ -3130,7 +3102,6 @@ func TestCoverage(t *testing.T) { result := android.GroupFixturePreparers( PrepareForTestWithJavaDefaultModules, prepareForTestWithFrameworkJacocoInstrumentation, - PrepareForTestWithTransitiveClasspathEnabled, ).RunTestWithBp(t, ` android_app { name: "foo", diff --git a/java/jdeps.go b/java/jdeps.go index 927c1694d..07f8c4378 100644 --- a/java/jdeps.go +++ b/java/jdeps.go @@ -99,7 +99,7 @@ func (j *jdepsGeneratorSingleton) GenerateBuildActions(ctx android.SingletonCont Rule: android.Touch, Output: jfpath, }) - ctx.DistForGoal("general-tests", j.outputPath) + ctx.DistForGoals([]string{"general-tests", "dist_files"}, j.outputPath) } func createJsonFile(moduleInfos map[string]android.IdeInfo, jfpath android.WritablePath) error { diff --git a/java/kotlin_test.go b/java/kotlin_test.go index c7b1ece98..4b56cff1c 100644 --- a/java/kotlin_test.go +++ b/java/kotlin_test.go @@ -50,13 +50,6 @@ func TestKotlin(t *testing.T) { srcs: ["d.kt"], }` - kotlinStdlibTurbineCombinedJars := []string{ - "out/soong/.intermediates/default/java/kotlin-stdlib/android_common/turbine-combined/kotlin-stdlib.jar", - "out/soong/.intermediates/default/java/kotlin-stdlib-jdk7/android_common/turbine-combined/kotlin-stdlib-jdk7.jar", - "out/soong/.intermediates/default/java/kotlin-stdlib-jdk8/android_common/turbine-combined/kotlin-stdlib-jdk8.jar", - "out/soong/.intermediates/default/java/kotlin-annotations/android_common/turbine-combined/kotlin-annotations.jar", - } - kotlinStdlibTurbineJars := []string{ "out/soong/.intermediates/default/java/kotlin-stdlib/android_common/turbine/kotlin-stdlib.jar", "out/soong/.intermediates/default/java/kotlin-stdlib-jdk7/android_common/turbine/kotlin-stdlib-jdk7.jar", @@ -71,21 +64,11 @@ func TestKotlin(t *testing.T) { "out/soong/.intermediates/default/java/kotlin-annotations/android_common/javac/kotlin-annotations.jar", } - bootclasspathTurbineCombinedJars := []string{ - "out/soong/.intermediates/default/java/stable.core.platform.api.stubs/android_common/turbine-combined/stable.core.platform.api.stubs.jar", - "out/soong/.intermediates/default/java/core-lambda-stubs/android_common/turbine-combined/core-lambda-stubs.jar", - } - bootclasspathTurbineJars := []string{ "out/soong/.intermediates/default/java/stable.core.platform.api.stubs/android_common/turbine/stable.core.platform.api.stubs.jar", "out/soong/.intermediates/default/java/core-lambda-stubs/android_common/turbine/core-lambda-stubs.jar", } - frameworkTurbineCombinedJars := []string{ - "out/soong/.intermediates/default/java/ext/android_common/turbine-combined/ext.jar", - "out/soong/.intermediates/default/java/framework/android_common/turbine-combined/framework.jar", - } - frameworkTurbineJars := []string{ "out/soong/.intermediates/default/java/ext/android_common/turbine/ext.jar", "out/soong/.intermediates/default/java/framework/android_common/turbine/framework.jar", @@ -109,68 +92,8 @@ func TestKotlin(t *testing.T) { barHeaderCombinedInputs []string }{ { - name: "normal", - preparer: android.NullFixturePreparer, - fooKotlincInputs: []string{"a.java", "b.kt"}, - fooJavacInputs: []string{"a.java"}, - fooKotlincClasspath: slices.Concat( - bootclasspathTurbineCombinedJars, - frameworkTurbineCombinedJars, - []string{"out/soong/.intermediates/quz/android_common/turbine-combined/quz.jar"}, - kotlinStdlibTurbineCombinedJars, - ), - fooJavacClasspath: slices.Concat( - []string{"out/soong/.intermediates/foo/android_common/kotlin_headers/foo.jar"}, - frameworkTurbineCombinedJars, - []string{"out/soong/.intermediates/quz/android_common/turbine-combined/quz.jar"}, - kotlinStdlibTurbineCombinedJars, - ), - fooCombinedInputs: slices.Concat( - []string{ - "out/soong/.intermediates/foo/android_common/kotlin/foo.jar", - "out/soong/.intermediates/foo/android_common/javac/foo.jar", - "out/soong/.intermediates/quz/android_common/combined/quz.jar", - }, - kotlinStdlibJavacJars, - ), - fooHeaderCombinedInputs: slices.Concat( - []string{ - "out/soong/.intermediates/foo/android_common/turbine/foo.jar", - "out/soong/.intermediates/foo/android_common/kotlin_headers/foo.jar", - "out/soong/.intermediates/quz/android_common/turbine-combined/quz.jar", - }, - kotlinStdlibTurbineCombinedJars, - ), - - barKotlincInputs: []string{"b.kt"}, - barKotlincClasspath: slices.Concat( - bootclasspathTurbineCombinedJars, - frameworkTurbineCombinedJars, - []string{ - "out/soong/.intermediates/foo/android_common/turbine-combined/foo.jar", - "out/soong/.intermediates/baz/android_common/turbine-combined/baz.jar", - }, - kotlinStdlibTurbineCombinedJars, - ), - barCombinedInputs: slices.Concat( - []string{ - "out/soong/.intermediates/bar/android_common/kotlin/bar.jar", - "out/soong/.intermediates/baz/android_common/combined/baz.jar", - }, - kotlinStdlibJavacJars, - []string{}, - ), - barHeaderCombinedInputs: slices.Concat( - []string{ - "out/soong/.intermediates/bar/android_common/kotlin_headers/bar.jar", - "out/soong/.intermediates/baz/android_common/turbine-combined/baz.jar", - }, - kotlinStdlibTurbineCombinedJars, - ), - }, - { name: "transitive classpath", - preparer: PrepareForTestWithTransitiveClasspathEnabled, + preparer: android.NullFixturePreparer, fooKotlincInputs: []string{"a.java", "b.kt"}, fooJavacInputs: []string{"a.java"}, fooKotlincClasspath: slices.Concat( diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go index d4d2fb5bb..363521a7f 100644 --- a/java/platform_compat_config.go +++ b/java/platform_compat_config.go @@ -43,6 +43,13 @@ func registerPlatformCompatConfigBuildComponents(ctx android.RegistrationContext ctx.RegisterModuleType("global_compat_config", globalCompatConfigFactory) } +type PlatformCompatConfigInfo struct { + CompatConfig android.OutputPath + SubDir string +} + +var PlatformCompatConfigInfoProvider = blueprint.NewProvider[PlatformCompatConfigInfo]() + var PrepareForTestWithPlatformCompatConfig = android.FixtureRegisterWithContext(registerPlatformCompatConfigBuildComponents) func platformCompatConfigPath(ctx android.PathContext) android.OutputPath { @@ -124,6 +131,11 @@ func (p *platformCompatConfig) GenerateAndroidBuildActions(ctx android.ModuleCon rule.Build(configFileName, "Extract compat/compat_config.xml and install it") ctx.InstallFile(p.installDirPath, p.configFile.Base(), p.configFile) ctx.SetOutputFiles(android.Paths{p.configFile}, "") + + android.SetProvider(ctx, PlatformCompatConfigInfoProvider, PlatformCompatConfigInfo{ + CompatConfig: p.CompatConfig(), + SubDir: p.SubDir(), + }) } func (p *platformCompatConfig) AndroidMkEntries() []android.AndroidMkEntries { diff --git a/java/ravenwood.go b/java/ravenwood.go index 3b6c80bc6..c4078c587 100644 --- a/java/ravenwood.go +++ b/java/ravenwood.go @@ -267,6 +267,10 @@ func (r *ravenwoodTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, r.testConfig.String()) } moduleInfoJSON.CompatibilitySuites = []string{"general-tests", "ravenwood-tests"} + + android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ + TestSuites: r.TestSuites(), + }) } func (r *ravenwoodTest) AndroidMkEntries() []android.AndroidMkEntries { @@ -384,6 +388,10 @@ func (r *ravenwoodLibgroup) GenerateAndroidBuildActions(ctx android.ModuleContex // Normal build should perform install steps ctx.Phony(r.BaseModuleName(), android.PathForPhony(ctx, r.BaseModuleName()+"-install")) + + android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ + TestSuites: r.TestSuites(), + }) } // collectTransitiveJniDeps returns all JNI dependencies, including transitive diff --git a/java/robolectric.go b/java/robolectric.go index e3df329f5..be369f780 100644 --- a/java/robolectric.go +++ b/java/robolectric.go @@ -280,6 +280,10 @@ func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext) } else { moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") } + + android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ + TestSuites: r.TestSuites(), + }) } func generateSameDirRoboTestConfigJar(ctx android.ModuleContext, outputFile android.ModuleOutPath) { @@ -417,6 +421,10 @@ func (r *robolectricRuntimes) GenerateAndroidBuildActions(ctx android.ModuleCont android.SetProvider(ctx, RobolectricRuntimesInfoProvider, RobolectricRuntimesInfo{ Runtimes: r.runtimes, }) + + android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ + TestSuites: r.TestSuites(), + }) } func (r *robolectricRuntimes) InstallInTestcases() bool { return true } diff --git a/java/rro.go b/java/rro.go index d9f4ff7c8..f7f85f001 100644 --- a/java/rro.go +++ b/java/rro.go @@ -34,6 +34,15 @@ func RegisterRuntimeResourceOverlayBuildComponents(ctx android.RegistrationConte ctx.RegisterModuleType("override_runtime_resource_overlay", OverrideRuntimeResourceOverlayModuleFactory) } +type RuntimeResourceOverlayInfo struct { + OutputFile android.Path + Certificate Certificate + Theme string + OverriddenManifestPackageName string +} + +var RuntimeResourceOverlayInfoProvider = blueprint.NewProvider[RuntimeResourceOverlayInfo]() + type RuntimeResourceOverlay struct { android.ModuleBase android.DefaultableModuleBase @@ -207,6 +216,12 @@ func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleC AconfigTextFiles: aconfigTextFilePaths, }) + android.SetProvider(ctx, RuntimeResourceOverlayInfoProvider, RuntimeResourceOverlayInfo{ + OutputFile: r.OutputFile(), + Certificate: r.Certificate(), + Theme: r.Theme(), + }) + buildComplianceMetadata(ctx) } diff --git a/java/sdk.go b/java/sdk.go index 27b2434c5..8510959df 100644 --- a/java/sdk.go +++ b/java/sdk.go @@ -358,7 +358,7 @@ func createAPIFingerprint(ctx android.SingletonContext) { "api_fingerprint", } count := 0 - ctx.VisitAllModules(func(module android.Module) { + ctx.VisitAllModuleProxies(func(module android.ModuleProxy) { name := ctx.ModuleName(module) if android.InList(name, apiTxtFileModules) { cmd.Inputs(android.OutputFilesForModule(ctx, module, "")) diff --git a/java/sdk_library.go b/java/sdk_library.go index cf31b5095..7944bb2a8 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -702,7 +702,7 @@ func (paths *scopePaths) extractStubsLibraryInfoFromDependency(ctx android.Modul paths.stubsHeaderPath = lib.HeaderJars paths.stubsImplPath = lib.ImplementationJars - libDep := android.OtherModuleProviderOrDefault(ctx, dep, JavaInfoProvider).UsesLibraryDependencyInfo + libDep := android.OtherModuleProviderOrDefault(ctx, dep, JavaInfoProvider) paths.stubsDexJarPath = libDep.DexJarBuildPath paths.exportableStubsDexJarPath = libDep.DexJarBuildPath return nil @@ -718,7 +718,7 @@ func (paths *scopePaths) extractEverythingStubsLibraryInfoFromDependency(ctx and paths.stubsImplPath = lib.ImplementationJars } - libDep := android.OtherModuleProviderOrDefault(ctx, dep, JavaInfoProvider).UsesLibraryDependencyInfo + libDep := android.OtherModuleProviderOrDefault(ctx, dep, JavaInfoProvider) paths.stubsDexJarPath = libDep.DexJarBuildPath return nil } else { @@ -732,7 +732,7 @@ func (paths *scopePaths) extractExportableStubsLibraryInfoFromDependency(ctx and paths.stubsImplPath = lib.ImplementationJars } - libDep := android.OtherModuleProviderOrDefault(ctx, dep, JavaInfoProvider).UsesLibraryDependencyInfo + libDep := android.OtherModuleProviderOrDefault(ctx, dep, JavaInfoProvider) paths.exportableStubsDexJarPath = libDep.DexJarBuildPath return nil } else { @@ -1017,10 +1017,6 @@ func (c *commonToSdkLibraryAndImport) generateCommonBuildActions(ctx android.Mod removedApiFilePaths[kind] = removedApiFilePath } - javaInfo := &JavaInfo{} - setExtraJavaInfo(ctx, ctx.Module(), javaInfo) - android.SetProvider(ctx, JavaInfoProvider, javaInfo) - return SdkLibraryInfo{ EverythingStubDexJarPaths: everythingStubPaths, ExportableStubDexJarPaths: exportableStubPaths, @@ -1227,6 +1223,8 @@ type SdkLibraryInfo struct { // Whether if this can be used as a shared library. SharedLibrary bool + + Prebuilt bool } var SdkLibraryInfoProvider = blueprint.NewProvider[SdkLibraryInfo]() @@ -1513,10 +1511,10 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) module.dexJarFile = makeDexJarPathFromPath(module.implLibraryInfo.DexJarFile.Path()) module.headerJarFile = module.implLibraryInfo.HeaderJars[0] module.implementationAndResourcesJar = module.implLibraryInfo.ImplementationAndResourcesJars[0] - module.apexSystemServerDexpreoptInstalls = module.implLibraryInfo.ApexSystemServerDexpreoptInstalls - module.apexSystemServerDexJars = module.implLibraryInfo.ApexSystemServerDexJars + module.apexSystemServerDexpreoptInstalls = module.implLibraryInfo.DexpreopterInfo.ApexSystemServerDexpreoptInstalls + module.apexSystemServerDexJars = module.implLibraryInfo.DexpreopterInfo.ApexSystemServerDexJars module.dexpreopter.configPath = module.implLibraryInfo.ConfigPath - module.dexpreopter.outputProfilePathOnHost = module.implLibraryInfo.OutputProfilePathOnHost + module.dexpreopter.outputProfilePathOnHost = module.implLibraryInfo.DexpreopterInfo.OutputProfilePathOnHost // Properties required for Library.AndroidMkEntries module.logtagsSrcs = module.implLibraryInfo.LogtagsSrcs @@ -1582,7 +1580,12 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) setOutputFilesFromJavaInfo(ctx, module.implLibraryInfo) } + javaInfo := &JavaInfo{} + setExtraJavaInfo(ctx, ctx.Module(), javaInfo) + android.SetProvider(ctx, JavaInfoProvider, javaInfo) + sdkLibInfo.GeneratingLibs = generatingLibs + sdkLibInfo.Prebuilt = false android.SetProvider(ctx, SdkLibraryInfoProvider, sdkLibInfo) } @@ -2236,7 +2239,12 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo setOutputFilesFromJavaInfo(ctx, module.implLibraryInfo) } + javaInfo := &JavaInfo{} + setExtraJavaInfo(ctx, ctx.Module(), javaInfo) + android.SetProvider(ctx, JavaInfoProvider, javaInfo) + sdkLibInfo.GeneratingLibs = generatingLibs + sdkLibInfo.Prebuilt = true android.SetProvider(ctx, SdkLibraryInfoProvider, sdkLibInfo) } diff --git a/java/sdk_library_internal.go b/java/sdk_library_internal.go index 578969223..f5feabeb4 100644 --- a/java/sdk_library_internal.go +++ b/java/sdk_library_internal.go @@ -936,6 +936,8 @@ func (module *sdkLibraryXml) GenerateAndroidBuildActions(ctx android.ModuleConte ctx.PackageFile(module.installDirPath, libName+".xml", module.outputFilePath) ctx.SetOutputFiles(android.OutputPaths{module.outputFilePath}.Paths(), "") + + etc.SetCommonPrebuiltEtcInfo(ctx, module) } func (module *sdkLibraryXml) AndroidMkEntries() []android.AndroidMkEntries { diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go index 2cb827dc2..431bbacfd 100644 --- a/java/sdk_library_test.go +++ b/java/sdk_library_test.go @@ -149,7 +149,7 @@ func TestJavaSdkLibrary(t *testing.T) { bazJavac := result.ModuleForTests(t, "baz", "android_common").Rule("javac") // tests if baz is actually linked to the stubs lib - android.AssertStringDoesContain(t, "baz javac classpath", bazJavac.Args["classpath"], "foo.stubs.system.jar") + android.AssertStringDoesContain(t, "baz javac classpath", bazJavac.Args["classpath"], "foo.stubs.system.from-text.jar") // ... and not to the impl lib android.AssertStringDoesNotContain(t, "baz javac classpath", bazJavac.Args["classpath"], "foo.jar") // test if baz is not linked to the system variant of foo @@ -157,15 +157,15 @@ func TestJavaSdkLibrary(t *testing.T) { bazTestJavac := result.ModuleForTests(t, "baz-test", "android_common").Rule("javac") // tests if baz-test is actually linked to the test stubs lib - android.AssertStringDoesContain(t, "baz-test javac classpath", bazTestJavac.Args["classpath"], "foo.stubs.test.jar") + android.AssertStringDoesContain(t, "baz-test javac classpath", bazTestJavac.Args["classpath"], "foo.stubs.test.from-text.jar") baz29Javac := result.ModuleForTests(t, "baz-29", "android_common").Rule("javac") // tests if baz-29 is actually linked to the system 29 stubs lib - android.AssertStringDoesContain(t, "baz-29 javac classpath", baz29Javac.Args["classpath"], "prebuilts/sdk/sdk_system_29_foo/android_common/combined/sdk_system_29_foo.jar") + android.AssertStringDoesContain(t, "baz-29 javac classpath", baz29Javac.Args["classpath"], "prebuilts/sdk/sdk_system_29_foo/android_common/local-combined/sdk_system_29_foo.jar") bazModule30Javac := result.ModuleForTests(t, "baz-module-30", "android_common").Rule("javac") // tests if "baz-module-30" is actually linked to the module 30 stubs lib - android.AssertStringDoesContain(t, "baz-module-30 javac classpath", bazModule30Javac.Args["classpath"], "prebuilts/sdk/sdk_module-lib_30_foo/android_common/combined/sdk_module-lib_30_foo.jar") + android.AssertStringDoesContain(t, "baz-module-30 javac classpath", bazModule30Javac.Args["classpath"], "prebuilts/sdk/sdk_module-lib_30_foo/android_common/local-combined/sdk_module-lib_30_foo.jar") // test if baz has exported SDK lib names foo and bar to qux qux := result.ModuleForTests(t, "qux", "android_common") @@ -422,7 +422,7 @@ func TestJavaSdkLibrary_StubOrImplOnlyLibs(t *testing.T) { android.AssertStringContainsEquals(t, "bad classpath for "+sdklib, sdklibCp, "/"+dep+".jar", expected) combineJarInputs := result.ModuleForTests(t, sdklib, "android_common").Rule("combineJar").Inputs.Strings() - depPath := filepath.Join("out", "soong", ".intermediates", dep, "android_common", "turbine-combined", dep+".jar") + depPath := filepath.Join("out", "soong", ".intermediates", dep, "android_common", "turbine", dep+".jar") android.AssertStringListContainsEquals(t, "bad combined inputs for "+sdklib, combineJarInputs, depPath, combined) } for _, expectation := range expectations { @@ -458,7 +458,7 @@ func TestJavaSdkLibrary_DoNotAccessImplWhenItIsNotBuilt(t *testing.T) { // The bar library should depend on the stubs jar. barLibrary := result.ModuleForTests(t, "bar", "android_common").Rule("javac") - if expected, actual := `^-classpath .*:out/soong/[^:]*/turbine-combined/foo\.stubs\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) { + if expected, actual := `^-classpath .*:out/soong/[^:]*/foo\.stubs\.from-text/foo\.stubs\.from-text\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) { t.Errorf("expected %q, found %#q", expected, actual) } } @@ -791,7 +791,7 @@ func TestJavaSdkLibrary_SystemServer_AccessToStubScopeLibs(t *testing.T) { stubsPath := func(name string, scope *apiScope) string { name = scope.stubsLibraryModuleName(name) - return fmt.Sprintf("out/soong/.intermediates/%[1]s/android_common/turbine-combined/%[1]s.jar", name) + return fmt.Sprintf("out/soong/.intermediates/%[1]s.from-text/android_common/%[1]s.from-text/%[1]s.from-text.jar", name) } // The bar library should depend on the highest (where system server is highest and public is @@ -853,7 +853,7 @@ func TestJavaSdkLibraryImport(t *testing.T) { fooModule := result.ModuleForTests(t, "foo"+scope, "android_common") javac := fooModule.Rule("javac") - sdklibStubsJar := result.ModuleForTests(t, "sdklib.stubs"+scope, "android_common").Output("combined/sdklib.stubs" + scope + ".jar").Output + sdklibStubsJar := result.ModuleForTests(t, "sdklib.stubs"+scope, "android_common").Output("local-combined/sdklib.stubs" + scope + ".jar").Output android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], sdklibStubsJar.String()) } @@ -1002,7 +1002,7 @@ func testJavaSdkLibraryImport_Preferred(t *testing.T, prefer string, preparer an public := result.ModuleForTests(t, "public", "android_common") rule := public.Output("javac/public.jar") inputs := rule.Implicits.Strings() - expected := "out/soong/.intermediates/prebuilt_sdklib.stubs/android_common/combined/sdklib.stubs.jar" + expected := "out/soong/.intermediates/prebuilt_sdklib.stubs/android_common/local-combined/sdklib.stubs.jar" if !android.InList(expected, inputs) { t.Errorf("expected %q to contain %q", inputs, expected) } @@ -1124,12 +1124,12 @@ func TestSdkLibraryImport_MetadataModuleSupersedesPreferred(t *testing.T) { inputs := rule.Implicits.Strings() expectedInputs := []string{ // source - "out/soong/.intermediates/sdklib.prebuilt_preferred_using_legacy_flags.stubs/android_common/turbine-combined/sdklib.prebuilt_preferred_using_legacy_flags.stubs.jar", - "out/soong/.intermediates/sdklib.prebuilt_preferred_using_legacy_flags.stubs.system/android_common/turbine-combined/sdklib.prebuilt_preferred_using_legacy_flags.stubs.system.jar", + "out/soong/.intermediates/sdklib.prebuilt_preferred_using_legacy_flags.stubs.from-text/android_common/sdklib.prebuilt_preferred_using_legacy_flags.stubs.from-text/sdklib.prebuilt_preferred_using_legacy_flags.stubs.from-text.jar", + "out/soong/.intermediates/sdklib.prebuilt_preferred_using_legacy_flags.stubs.system.from-text/android_common/sdklib.prebuilt_preferred_using_legacy_flags.stubs.system.from-text/sdklib.prebuilt_preferred_using_legacy_flags.stubs.system.from-text.jar", // prebuilt - "out/soong/.intermediates/prebuilt_sdklib.source_preferred_using_legacy_flags.stubs/android_common/combined/sdklib.source_preferred_using_legacy_flags.stubs.jar", - "out/soong/.intermediates/prebuilt_sdklib.source_preferred_using_legacy_flags.stubs.system/android_common/combined/sdklib.source_preferred_using_legacy_flags.stubs.system.jar", + "out/soong/.intermediates/prebuilt_sdklib.source_preferred_using_legacy_flags.stubs/android_common/local-combined/sdklib.source_preferred_using_legacy_flags.stubs.jar", + "out/soong/.intermediates/prebuilt_sdklib.source_preferred_using_legacy_flags.stubs.system/android_common/local-combined/sdklib.source_preferred_using_legacy_flags.stubs.system.jar", } for _, expected := range expectedInputs { if !android.InList(expected, inputs) { @@ -1578,7 +1578,8 @@ func TestStubResolutionOfJavaSdkLibraryInLibs(t *testing.T) { public := result.ModuleForTests(t, "mymodule", "android_common") rule := public.Output("javac/mymodule.jar") inputs := rule.Implicits.Strings() - android.AssertStringListContains(t, "Could not find the expected stub on classpath", inputs, "out/soong/.intermediates/sdklib.stubs/android_common/turbine-combined/sdklib.stubs.jar") + android.AssertStringListContains(t, "Could not find the expected stub on classpath", inputs, + "out/soong/.intermediates/sdklib.stubs.from-text/android_common/sdklib.stubs.from-text/sdklib.stubs.from-text.jar") } // test that rdep gets resolved to the correct version of a java_sdk_library (source or a specific prebuilt) @@ -1636,17 +1637,17 @@ func TestMultipleSdkLibraryPrebuilts(t *testing.T) { { desc: "Source library is selected using apex_contributions", selectedDependencyName: "sdklib", - expectedStubPath: "out/soong/.intermediates/sdklib.stubs/android_common/turbine-combined/sdklib.stubs.jar", + expectedStubPath: "out/soong/.intermediates/sdklib.stubs.from-text/android_common/sdklib.stubs.from-text/sdklib.stubs.from-text.jar", }, { desc: "Prebuilt library v1 is selected using apex_contributions", selectedDependencyName: "prebuilt_sdklib.v1", - expectedStubPath: "out/soong/.intermediates/prebuilt_sdklib.v1.stubs/android_common/combined/sdklib.stubs.jar", + expectedStubPath: "out/soong/.intermediates/prebuilt_sdklib.v1.stubs/android_common/local-combined/sdklib.stubs.jar", }, { desc: "Prebuilt library v2 is selected using apex_contributions", selectedDependencyName: "prebuilt_sdklib.v2", - expectedStubPath: "out/soong/.intermediates/prebuilt_sdklib.v2.stubs/android_common/combined/sdklib.stubs.jar", + expectedStubPath: "out/soong/.intermediates/prebuilt_sdklib.v2.stubs/android_common/local-combined/sdklib.stubs.jar", }, } diff --git a/java/sdk_test.go b/java/sdk_test.go index 49983ada2..6386a00d5 100644 --- a/java/sdk_test.go +++ b/java/sdk_test.go @@ -391,21 +391,16 @@ func TestClasspath(t *testing.T) { t.Run("basic", func(t *testing.T) { t.Parallel() - testClasspathTestCases(t, classpathTestcases, false, false) + testClasspathTestCases(t, classpathTestcases, false) }) t.Run("Always_use_prebuilt_sdks=true", func(t *testing.T) { t.Parallel() - testClasspathTestCases(t, classpathTestcases, true, false) - }) - - t.Run("UseTransitiveJarsInClasspath", func(t *testing.T) { - t.Parallel() - testClasspathTestCases(t, classpathTestcases, false, true) + testClasspathTestCases(t, classpathTestcases, true) }) } -func testClasspathTestCases(t *testing.T, classpathTestcases []classpathTestCase, alwaysUsePrebuiltSdks, useTransitiveJarsInClasspath bool) { +func testClasspathTestCases(t *testing.T, classpathTestcases []classpathTestCase, alwaysUsePrebuiltSdks bool) { for _, testcase := range classpathTestcases { if testcase.forAlwaysUsePrebuiltSdks != nil && *testcase.forAlwaysUsePrebuiltSdks != alwaysUsePrebuiltSdks { continue @@ -446,10 +441,8 @@ func testClasspathTestCases(t *testing.T, classpathTestcases []classpathTestCase switch { case e == `""`, strings.HasSuffix(e, ".jar"): ret[i] = e - case useTransitiveJarsInClasspath: - ret[i] = filepath.Join("out", "soong", ".intermediates", defaultJavaDir, e, "android_common", "turbine", e+".jar") default: - ret[i] = filepath.Join("out", "soong", ".intermediates", defaultJavaDir, e, "android_common", "turbine-combined", e+".jar") + ret[i] = filepath.Join("out", "soong", ".intermediates", defaultJavaDir, e, "android_common", "turbine", e+".jar") } } return ret @@ -544,9 +537,6 @@ func testClasspathTestCases(t *testing.T, classpathTestcases []classpathTestCase variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true) }) } - if useTransitiveJarsInClasspath { - preparer = PrepareForTestWithTransitiveClasspathEnabled - } fixtureFactory := android.GroupFixturePreparers( prepareForJavaTest, diff --git a/java/testing.go b/java/testing.go index 35319ae58..3abbb8453 100644 --- a/java/testing.go +++ b/java/testing.go @@ -825,5 +825,3 @@ func FixtureSetBootImageInstallDirOnDevice(name string, installDir string) andro config.installDir = installDir }) } - -var PrepareForTestWithTransitiveClasspathEnabled = android.PrepareForTestWithBuildFlag("RELEASE_USE_TRANSITIVE_JARS_IN_CLASSPATH", "true") diff --git a/linkerconfig/linkerconfig.go b/linkerconfig/linkerconfig.go index 4f1ef9d66..43fe8aa33 100644 --- a/linkerconfig/linkerconfig.go +++ b/linkerconfig/linkerconfig.go @@ -86,6 +86,8 @@ func (l *linkerConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.InstallFile(l.installDirPath, l.outputFilePath.Base(), l.outputFilePath) ctx.SetOutputFiles(android.Paths{l.outputFilePath}, "") + + etc.SetCommonPrebuiltEtcInfo(ctx, l) } func BuildLinkerConfig( diff --git a/python/binary.go b/python/binary.go index 4d6e11816..feac72a26 100644 --- a/python/binary.go +++ b/python/binary.go @@ -114,6 +114,12 @@ func (p *PythonBinaryModule) GenerateAndroidBuildActions(ctx android.ModuleConte android.SetProvider(ctx, PythonBinaryInfoProvider, PythonBinaryInfo{}) ctx.SetOutputFiles(android.Paths{p.installSource}, "") + + moduleInfoJSON := ctx.ModuleInfoJSON() + moduleInfoJSON.Class = []string{"EXECUTABLES"} + moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, p.androidMkSharedLibs...) + moduleInfoJSON.SharedLibs = append(moduleInfoJSON.SharedLibs, p.androidMkSharedLibs...) + moduleInfoJSON.SystemSharedLibs = []string{"none"} } func (p *PythonBinaryModule) buildBinary(ctx android.ModuleContext) { diff --git a/python/test.go b/python/test.go index 5e70fc185..df62ab794 100644 --- a/python/test.go +++ b/python/test.go @@ -224,6 +224,10 @@ func (p *PythonTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext if p.testConfig != nil { ctx.InstallFile(testCases, ctx.ModuleName()+".config", p.testConfig) } + dynamicConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml") + if dynamicConfig.Valid() { + ctx.InstallFile(testCases, ctx.ModuleName()+".dynamic", dynamicConfig.Path()) + } } // Install tests and data in arch specific subdir $PRODUCT_OUT/testcases/$module/$arch testCases = testCases.Join(ctx, ctx.Target().Arch.ArchType.String()) diff --git a/rust/library.go b/rust/library.go index 7f5861fe8..415785a16 100644 --- a/rust/library.go +++ b/rust/library.go @@ -744,10 +744,16 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa } if library.rlib() { ccExporter.RustRlibDeps = append(ccExporter.RustRlibDeps, deps.reexportedCcRlibDeps...) + ccExporter.RustRlibDeps = append(ccExporter.RustRlibDeps, deps.reexportedWholeCcRlibDeps...) } android.SetProvider(ctx, cc.FlagExporterInfoProvider, ccExporter) } + if library.dylib() { + // reexport whole-static'd dependencies for dylibs. + library.flagExporter.wholeRustRlibDeps = append(library.flagExporter.wholeRustRlibDeps, deps.reexportedWholeCcRlibDeps...) + } + if library.shared() || library.stubs() { // Optimize out relinking against shared libraries whose interface hasn't changed by // depending on a table of contents file instead of the library itself. diff --git a/rust/rust.go b/rust/rust.go index 7a7b1064c..4eebda301 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -496,8 +496,9 @@ type PathDeps struct { depLinkFlags []string // track cc static-libs that have Rlib dependencies - reexportedCcRlibDeps []cc.RustRlibDep - ccRlibDeps []cc.RustRlibDep + reexportedCcRlibDeps []cc.RustRlibDep + reexportedWholeCcRlibDeps []cc.RustRlibDep + ccRlibDeps []cc.RustRlibDep // linkDirs are link paths passed via -L to rustc. linkObjects are objects passed directly to the linker // Both of these are exported and propagate to dependencies. @@ -555,6 +556,7 @@ type flagExporter struct { staticLibObjects []string sharedLibObjects []string wholeStaticLibObjects []string + wholeRustRlibDeps []cc.RustRlibDep } func (flagExporter *flagExporter) exportLinkDirs(dirs ...string) { @@ -584,6 +586,7 @@ func (flagExporter *flagExporter) setRustProvider(ctx ModuleContext) { StaticLibObjects: flagExporter.staticLibObjects, WholeStaticLibObjects: flagExporter.wholeStaticLibObjects, SharedLibPaths: flagExporter.sharedLibObjects, + WholeRustRlibDeps: flagExporter.wholeRustRlibDeps, }) } @@ -600,6 +603,7 @@ type RustFlagExporterInfo struct { StaticLibObjects []string WholeStaticLibObjects []string SharedLibPaths []string + WholeRustRlibDeps []cc.RustRlibDep } var RustFlagExporterInfoProvider = blueprint.NewProvider[RustFlagExporterInfo]() @@ -841,7 +845,7 @@ func (mod *Module) getSharedFlags() *cc.SharedFlags { return shared } -func (mod *Module) ImplementationModuleNameForMake(ctx android.BaseModuleContext) string { +func (mod *Module) ImplementationModuleNameForMake() string { name := mod.BaseModuleName() if versioned, ok := mod.compiler.(cc.VersionedInterface); ok { name = versioned.ImplementationModuleName(name) @@ -1411,7 +1415,7 @@ func rustMakeLibName(rustInfo *RustInfo, linkableInfo *cc.LinkableInfo, commonIn if rustInfo != nil { // Use base module name for snapshots when exporting to Makefile. if rustInfo.SnapshotInfo != nil { - baseName := linkableInfo.BaseModuleName + baseName := commonInfo.BaseModuleName return baseName + rustInfo.SnapshotInfo.SnapshotAndroidMkSuffix + rustInfo.AndroidMkSuffix } } @@ -1585,8 +1589,8 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { directSrcProvidersDeps = append(directSrcProvidersDeps, &dep) } + exportedRustInfo, _ := android.OtherModuleProvider(ctx, dep, RustFlagExporterInfoProvider) exportedInfo, _ := android.OtherModuleProvider(ctx, dep, RustFlagExporterInfoProvider) - //Append the dependencies exported objects, except for proc-macros which target a different arch/OS if depTag != procMacroDepTag { depPaths.depFlags = append(depPaths.depFlags, exportedInfo.Flags...) @@ -1595,6 +1599,11 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { depPaths.staticLibObjects = append(depPaths.staticLibObjects, exportedInfo.StaticLibObjects...) depPaths.wholeStaticLibObjects = append(depPaths.wholeStaticLibObjects, exportedInfo.WholeStaticLibObjects...) depPaths.linkDirs = append(depPaths.linkDirs, exportedInfo.LinkDirs...) + + depPaths.reexportedWholeCcRlibDeps = append(depPaths.reexportedWholeCcRlibDeps, exportedRustInfo.WholeRustRlibDeps...) + if !mod.Rlib() { + depPaths.ccRlibDeps = append(depPaths.ccRlibDeps, exportedRustInfo.WholeRustRlibDeps...) + } } if depTag == dylibDepTag || depTag == rlibDepTag || depTag == procMacroDepTag { @@ -1656,17 +1665,26 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { } } + exportedInfo, _ := android.OtherModuleProvider(ctx, dep, cc.FlagExporterInfoProvider) if cc.IsWholeStaticLib(depTag) { // Add whole staticlibs to wholeStaticLibObjects to propagate to Rust all dependents. depPaths.wholeStaticLibObjects = append(depPaths.wholeStaticLibObjects, ccLibPath.String()) + + // We also propagate forward whole-static'd cc staticlibs with rust_ffi_rlib dependencies + // We don't need to check a hypothetical exportedRustInfo.WholeRustRlibDeps because we + // wouldn't expect a rust_ffi_rlib to be listed in `static_libs` (Soong explicitly disallows this) + depPaths.reexportedWholeCcRlibDeps = append(depPaths.reexportedWholeCcRlibDeps, exportedInfo.RustRlibDeps...) } else { - // Otherwise add to staticLibObjects, which only propagate through rlibs to their dependents. + // If not whole_static, add to staticLibObjects, which only propagate through rlibs to their dependents. depPaths.staticLibObjects = append(depPaths.staticLibObjects, ccLibPath.String()) + + if mod.Rlib() { + // rlibs propagate their inherited rust_ffi_rlibs forward. + depPaths.reexportedCcRlibDeps = append(depPaths.reexportedCcRlibDeps, exportedInfo.RustRlibDeps...) + } } depPaths.linkDirs = append(depPaths.linkDirs, linkPath) - - exportedInfo, _ := android.OtherModuleProvider(ctx, dep, cc.FlagExporterInfoProvider) depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...) depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...) depPaths.depClangFlags = append(depPaths.depClangFlags, exportedInfo.Flags...) @@ -1675,8 +1693,6 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { if !mod.Rlib() { // rlibs don't need to build the generated static library, so they don't need to track these. depPaths.ccRlibDeps = append(depPaths.ccRlibDeps, exportedInfo.RustRlibDeps...) - } else { - depPaths.reexportedCcRlibDeps = append(depPaths.reexportedCcRlibDeps, exportedInfo.RustRlibDeps...) } directStaticLibDeps = append(directStaticLibDeps, linkableInfo) @@ -1835,6 +1851,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { depPaths.depSystemIncludePaths = android.FirstUniquePaths(depPaths.depSystemIncludePaths) depPaths.depLinkFlags = android.FirstUniqueStrings(depPaths.depLinkFlags) depPaths.reexportedCcRlibDeps = android.FirstUniqueFunc(depPaths.reexportedCcRlibDeps, cc.EqRustRlibDeps) + depPaths.reexportedWholeCcRlibDeps = android.FirstUniqueFunc(depPaths.reexportedWholeCcRlibDeps, cc.EqRustRlibDeps) depPaths.ccRlibDeps = android.FirstUniqueFunc(depPaths.ccRlibDeps, cc.EqRustRlibDeps) return depPaths diff --git a/rust/rust_test.go b/rust/rust_test.go index fbb994752..f634bb5cd 100644 --- a/rust/rust_test.go +++ b/rust/rust_test.go @@ -456,6 +456,13 @@ func TestRustFFIRlibs(t *testing.T) { } rust_ffi_static { + name: "libfoo_from_rlib_whole", + crate_name: "foo_from_rlib_whole", + srcs: ["src/lib.rs"], + export_include_dirs: ["foo_includes"] + } + + rust_ffi_static { name: "libbuzz", crate_name: "buzz", srcs: ["src/lib.rs"], @@ -469,6 +476,13 @@ func TestRustFFIRlibs(t *testing.T) { export_include_dirs: ["buzz_includes"] } + rust_ffi_static { + name: "libbuzz_from_rlib_whole", + crate_name: "buzz_from_rlib_whole", + srcs: ["src/lib.rs"], + export_include_dirs: ["buzz_includes"] + } + cc_library_shared { name: "libcc_shared", srcs:["foo.c"], @@ -489,6 +503,13 @@ func TestRustFFIRlibs(t *testing.T) { whole_static_libs: ["libfoo_from_rlib"], } + cc_library_static { + name: "libcc_whole_static_from_rlib", + srcs:["foo.c"], + static_libs: ["libbuzz_from_rlib_whole"], + whole_static_libs: ["libfoo_from_rlib_whole"], + } + cc_binary { name: "ccBin", srcs:["foo.c"], @@ -500,6 +521,14 @@ func TestRustFFIRlibs(t *testing.T) { srcs:["src/foo.rs"], crate_name: "rs", static_libs: ["libcc_static_from_rlib"], + whole_static_libs: ["libcc_whole_static_from_rlib"], + } + + rust_library { + name: "librs2", + srcs:["src/foo.rs"], + crate_name: "rs", + rustlibs: ["librs"], } rust_binary { @@ -509,7 +538,7 @@ func TestRustFFIRlibs(t *testing.T) { rlibs: ["librs", "libbar"], static_libs: ["libcc_static"], } - `) + `) libbar := ctx.ModuleForTests(t, "libbar", "android_arm64_armv8-a_rlib_rlib-std").Rule("rustc") libcc_shared_rustc := ctx.ModuleForTests(t, "libcc_shared", "android_arm64_armv8-a_shared").Rule("rustc") @@ -521,6 +550,10 @@ func TestRustFFIRlibs(t *testing.T) { rustbin_genlib := ctx.ModuleForTests(t, "rsBin", "android_arm64_armv8-a").Output("generated_rust_staticlib/librustlibs.a") rustbin := ctx.ModuleForTests(t, "rsBin", "android_arm64_armv8-a").Output("unstripped/rsBin") librs_rlib := ctx.ModuleForTests(t, "librs", "android_arm64_armv8-a_rlib_dylib-std").MaybeOutput("generated_rust_staticlib/librustlibs.a") + librs2_rlib := ctx.ModuleForTests(t, "librs2", "android_arm64_armv8-a_rlib_dylib-std").MaybeOutput("generated_rust_staticlib/librustlibs.a") + librs_genlib := ctx.ModuleForTests(t, "librs", "android_arm64_armv8-a_dylib").Output("generated_rust_staticlib/librustlibs.a") + librs2_genlib := ctx.ModuleForTests(t, "librs2", "android_arm64_armv8-a_dylib").Output("generated_rust_staticlib/librustlibs.a") + librs2_dylib := ctx.ModuleForTests(t, "librs2", "android_arm64_armv8-a_dylib").Output("unstripped/librs2.dylib.so") if !strings.Contains(libbar.Args["rustcFlags"], "crate-type=rlib") { t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", "rlib", libbar.Args["rustcFlags"]) @@ -578,6 +611,10 @@ func TestRustFFIRlibs(t *testing.T) { t.Errorf("missing generated static library in linker step libFlags in Rust module, expecting %#v, libFlags: %#v", "generated_rust_staticlib/librustlibs.a", rustbin.Args["libFlags"]) } + if !strings.Contains(librs2_dylib.Args["linkFlags"], "generated_rust_staticlib/librustlibs.a") { + t.Errorf("missing generated static library in linker step libFlags in Rust module, expecting %#v, libFlags: %#v", + "generated_rust_staticlib/librustlibs.a", librs2_dylib.Args["libFlags"]) + } // Make sure that direct dependencies and indirect whole static dependencies are // propagating correctly for the rlib -> cc_library_static -> rust_* generated library example. @@ -610,6 +647,31 @@ func TestRustFFIRlibs(t *testing.T) { if librs_rlib.Rule != nil { t.Error("rlibs should not be generating mto staticlibs", "rlib", libbar.Args["rustcFlags"]) } + if librs2_rlib.Rule != nil { + t.Error("rlibs should not be generating mto staticlibs", "rlib", libbar.Args["rustcFlags"]) + } + + // Make sure that direct whole static dependencies are propagating correctly downstream + // foo_from_rlib_whole --(ws)--> libcc_whole_static_from_rlib --(ws)--> librs + if !strings.Contains(librs_genlib.Args["libFlags"], "--extern foo_from_rlib_whole=") { + t.Errorf("Missing direct whole_static_lib dependency libfoo_from_rlib_whole from rust dylib when writing generated Rust staticlib: %#v", librs_genlib.Args["libFlags"]) + } + + // Make sure that indirect whole static dependencies are propagating correctly downstream + // foo_from_rlib_whole --(ws)--> libcc_whole_static_from_rlib --(ws)--> librs --> rust_* + if !strings.Contains(librs2_genlib.Args["libFlags"], "--extern foo_from_rlib_whole=") { + t.Errorf("Missing indirect whole_static_lib dependency libfoo_from_rlib_whole from rust dylib when writing generated Rust staticlib: %#v", librs2_genlib.Args["libFlags"]) + } + if !strings.Contains(rustbin_genlib.Args["libFlags"], "--extern foo_from_rlib_whole=") { + t.Errorf("Missing indirect whole_static_lib dependency libfoo_from_rlib_whole from rust dylib in rust binary when writing generated Rust staticlib: %#v", rustbin_genlib.Args["libFlags"]) + } + + // Make sure that normal static dependencies are not propagating through dylib dependencies + // buzz_from_rlib_whole --(s)--> libcc_whole_static_from_rlib --(ws)--> librs --> rust_* + if strings.Contains(librs2_genlib.Args["libFlags"], "--extern buzz_from_rlib_whole=") { + t.Errorf("dependency from indirect cc staticlib from direct dylib dep found in rust dylib when writing generated Rust staticlib: %#v", librs2_genlib.Args["libFlags"]) + } + } func assertString(t *testing.T, got, expected string) { diff --git a/rust/test.go b/rust/test.go index 99f365f4c..9833ffdb6 100644 --- a/rust/test.go +++ b/rust/test.go @@ -216,6 +216,10 @@ func (test *testDecorator) install(ctx ModuleContext) { if test.testConfig != nil { ctx.InstallFile(testCases, ctx.ModuleName()+".config", test.testConfig) } + dynamicConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml") + if dynamicConfig.Valid() { + ctx.InstallFile(testCases, ctx.ModuleName()+".dynamic", dynamicConfig.Path()) + } } // Install tests and data in arch specific subdir $PRODUCT_OUT/testcases/$module/$arch testCases = testCases.Join(ctx, ctx.Target().Arch.ArchType.String()) diff --git a/scripts/strip.sh b/scripts/strip.sh index 8d69f0d12..5320ef620 100755 --- a/scripts/strip.sh +++ b/scripts/strip.sh @@ -101,7 +101,12 @@ do_strip_keep_mini_debug_info_darwin() { do_strip_keep_mini_debug_info_linux() { rm -f "${outfile}.mini_debuginfo.xz" local fail= - "${CLANG_BIN}/llvm-strip" --strip-all --keep-section=.ARM.attributes --remove-section=.comment "${infile}" -o "${outfile}.tmp" || fail=true + if [ -z "${windows}" ]; then + "${CLANG_BIN}/llvm-strip" --strip-all --keep-section=.ARM.attributes --remove-section=.comment "${infile}" -o "${outfile}.tmp" || fail=true + else + # --keep-section not supported for Windows COFF. + fail=true + fi if [ -z $fail ]; then # create_minidebuginfo has issues with compressed debug sections. Just diff --git a/sh/sh_binary.go b/sh/sh_binary.go index 129ef0475..f8d1ce523 100644 --- a/sh/sh_binary.go +++ b/sh/sh_binary.go @@ -41,6 +41,14 @@ func init() { registerShBuildComponents(android.InitRegistrationContext) } +type ShBinaryInfo struct { + SubDir string + OutputFile android.Path + Symlinks []string +} + +var ShBinaryInfoProvider = blueprint.NewProvider[ShBinaryInfo]() + func registerShBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("sh_binary", ShBinaryFactory) ctx.RegisterModuleType("sh_binary_host", ShBinaryHostFactory) @@ -319,6 +327,12 @@ func (s *ShBinary) generateAndroidBuildActions(ctx android.ModuleContext) { s.properties.SubName = s.GetSubname(ctx) + android.SetProvider(ctx, ShBinaryInfoProvider, ShBinaryInfo{ + SubDir: s.SubDir(), + OutputFile: s.OutputFile(), + Symlinks: s.Symlinks(), + }) + ctx.SetOutputFiles(android.Paths{s.outputFilePath}, "") } @@ -536,6 +550,28 @@ func (s *ShTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { MkAppClass: mkEntries.Class, InstallDir: s.installDir, }) + + moduleInfoJSON := ctx.ModuleInfoJSON() + moduleInfoJSON.Class = []string{"NATIVE_TESTS"} + if len(s.testProperties.Test_suites) > 0 { + moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, s.testProperties.Test_suites...) + } else { + moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") + } + if proptools.Bool(s.testProperties.Test_options.Unit_test) { + moduleInfoJSON.IsUnitTest = "true" + if ctx.Host() { + moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "host-unit-tests") + } + } + moduleInfoJSON.DataDependencies = append(moduleInfoJSON.DataDependencies, s.testProperties.Data_bins...) + if s.testConfig != nil { + if _, ok := s.testConfig.(android.WritablePath); ok { + moduleInfoJSON.AutoTestConfig = []string{"true"} + } + moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, s.testConfig.String()) + } + moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, s.extraTestConfigs.Strings()...) } func addArch(archType string, paths android.Paths) []string { diff --git a/sysprop/sysprop_test.go b/sysprop/sysprop_test.go index 06c5e9c9c..b2cfaa7dc 100644 --- a/sysprop/sysprop_test.go +++ b/sysprop/sysprop_test.go @@ -339,7 +339,7 @@ func TestSyspropLibrary(t *testing.T) { // Java modules linking against system API should use public stub javaSystemApiClient := result.ModuleForTests(t, "java-platform", "android_common").Rule("javac") - syspropPlatformPublic := result.ModuleForTests(t, "sysprop-platform_public", "android_common").Description("for turbine") + syspropPlatformPublic := result.ModuleForTests(t, "sysprop-platform_public", "android_common").Description("turbine") if g, w := javaSystemApiClient.Implicits.Strings(), syspropPlatformPublic.Output.String(); !android.InList(w, g) { t.Errorf("system api client should use public stub %q, got %q", w, g) } diff --git a/zip/cmd/main.go b/zip/cmd/main.go index 831f6d421..37537ab8b 100644 --- a/zip/cmd/main.go +++ b/zip/cmd/main.go @@ -164,7 +164,6 @@ func main() { directories := flags.Bool("d", false, "include directories in zip") compLevel := flags.Int("L", 5, "deflate compression level (0-9)") emulateJar := flags.Bool("jar", false, "modify the resultant .zip to emulate the output of 'jar'") - sortEntries := flags.Bool("sort_entries", false, "sort the zip entries") writeIfChanged := flags.Bool("write_if_changed", false, "only update resultant .zip if it has changed") ignoreMissingFiles := flags.Bool("ignore_missing_files", false, "continue if a requested file does not exist") symlinks := flags.Bool("symlinks", true, "store symbolic links in zip instead of following them") @@ -229,7 +228,6 @@ func main() { FileArgs: fileArgsBuilder.FileArgs(), OutputFilePath: *out, EmulateJar: *emulateJar, - SortEntries: *sortEntries, SrcJar: *srcJar, AddDirectoryEntriesToZip: *directories, CompressionLevel: *compLevel, diff --git a/zip/zip.go b/zip/zip.go index e4e9585d5..22b770474 100644 --- a/zip/zip.go +++ b/zip/zip.go @@ -272,7 +272,6 @@ type ZipArgs struct { FileArgs []FileArg OutputFilePath string EmulateJar bool - SortEntries bool SrcJar bool AddDirectoryEntriesToZip bool CompressionLevel int @@ -395,7 +394,7 @@ func zipTo(args ZipArgs, w io.Writer) error { } } - return z.write(w, pathMappings, args.ManifestSourcePath, args.EmulateJar, args.SortEntries, args.SrcJar, args.NumParallelJobs) + return z.write(w, pathMappings, args.ManifestSourcePath, args.EmulateJar, args.SrcJar, args.NumParallelJobs) } // Zip creates an output zip archive from given sources. @@ -476,6 +475,42 @@ func fillPathPairs(fa FileArg, src string, pathMappings *[]pathMapping, return nil } +func (z *ZipWriter) moveJavaFileBasedOnPackage(mapping *pathMapping) error { + src := mapping.src + var s os.FileInfo + var err error + if z.followSymlinks { + s, err = z.fs.Stat(src) + } else { + s, err = z.fs.Lstat(src) + } + if err != nil { + if os.IsNotExist(err) && z.ignoreMissingFiles { + return nil + } + return err + } + if !s.Mode().IsRegular() { + return nil + } + r, err := z.fs.Open(src) + if err != nil { + return err + } + // rewrite the destination using the package path if it can be determined + pkg, err := jar.JavaPackage(r, src) + err2 := r.Close() + if err2 != nil { + return err2 + } + if err != nil { + // ignore errors for now, leaving the file at in its original location in the zip + } else { + mapping.dest = filepath.Join(filepath.Join(strings.Split(pkg, ".")...), filepath.Base(src)) + } + return nil +} + func jarSort(mappings []pathMapping) { sort.SliceStable(mappings, func(i int, j int) bool { return jar.EntryNamesLess(mappings[i].dest, mappings[j].dest) @@ -483,7 +518,7 @@ func jarSort(mappings []pathMapping) { } func (z *ZipWriter) write(f io.Writer, pathMappings []pathMapping, manifest string, - emulateJar, sortEntries, srcJar bool, + emulateJar, srcJar bool, parallelJobs int) error { z.errors = make(chan error) @@ -513,16 +548,38 @@ func (z *ZipWriter) write(f io.Writer, pathMappings []pathMapping, manifest stri return errors.New("must specify --jar when specifying a manifest via -m") } - if emulateJar && sortEntries { - return errors.New("Cannot specify both --jar and --sort_entries (--jar implies sorting with a different algorithm)") + // move java source files to the correct folder based on the package statement inside of them. + // This is done before the entry sorting so that they're still in the right order. + if srcJar { + var javaMoveErrors []error + var javaMoveErrorsLock sync.Mutex + var wg sync.WaitGroup + for i := range pathMappings { + if filepath.Ext(pathMappings[i].src) == ".java" { + wg.Add(1) + go func() { + err := z.moveJavaFileBasedOnPackage(&pathMappings[i]) + if err != nil { + javaMoveErrorsLock.Lock() + javaMoveErrors = append(javaMoveErrors, err) + javaMoveErrorsLock.Unlock() + } + wg.Done() + }() + } + } + wg.Wait() + if len(javaMoveErrors) > 0 { + return errors.Join(javaMoveErrors...) + } } + if emulateJar { // manifest may be empty, in which case addManifest will fill in a default pathMappings = append(pathMappings, pathMapping{jar.ManifestFile, manifest, zip.Deflate}) jarSort(pathMappings) - } - if sortEntries { + } else { sort.SliceStable(pathMappings, func(i int, j int) bool { return pathMappings[i].dest < pathMappings[j].dest }) @@ -536,7 +593,7 @@ func (z *ZipWriter) write(f io.Writer, pathMappings []pathMapping, manifest stri if emulateJar && ele.dest == jar.ManifestFile { err = z.addManifest(ele.dest, ele.src, ele.zipMethod) } else { - err = z.addFile(ele.dest, ele.src, ele.zipMethod, emulateJar, srcJar) + err = z.addFile(ele.dest, ele.src, ele.zipMethod, emulateJar) } if err != nil { z.errors <- err @@ -635,7 +692,7 @@ func (z *ZipWriter) write(f io.Writer, pathMappings []pathMapping, manifest stri } // imports (possibly with compression) <src> into the zip at sub-path <dest> -func (z *ZipWriter) addFile(dest, src string, method uint16, emulateJar, srcJar bool) error { +func (z *ZipWriter) addFile(dest, src string, method uint16, emulateJar bool) error { var fileSize int64 var executable bool @@ -709,21 +766,6 @@ func (z *ZipWriter) addFile(dest, src string, method uint16, emulateJar, srcJar return err } - if srcJar && filepath.Ext(src) == ".java" { - // rewrite the destination using the package path if it can be determined - pkg, err := jar.JavaPackage(r, src) - if err != nil { - // ignore errors for now, leaving the file at in its original location in the zip - } else { - dest = filepath.Join(filepath.Join(strings.Split(pkg, ".")...), filepath.Base(src)) - } - - _, err = r.Seek(0, io.SeekStart) - if err != nil { - return err - } - } - fileSize = s.Size() executable = s.Mode()&0100 != 0 diff --git a/zip/zip_test.go b/zip/zip_test.go index c64c3f499..8f100d8dc 100644 --- a/zip/zip_test.go +++ b/zip/zip_test.go @@ -159,10 +159,10 @@ func TestZip(t *testing.T) { compressionLevel: 9, files: []zip.FileHeader{ + fh("[", fileEmpty, zip.Store), fh("a/a/a", fileA, zip.Deflate), fh("a/a/b", fileB, zip.Deflate), fh("c", fileC, zip.Deflate), - fh("[", fileEmpty, zip.Store), }, }, { @@ -261,10 +261,10 @@ func TestZip(t *testing.T) { compressionLevel: 9, files: []zip.FileHeader{ + fh("[", fileEmpty, zip.Store), fh("a/a/a", fileA, zip.Deflate), fh("a/a/b", fileB, zip.Deflate), fh("c", fileC, zip.Deflate), - fh("[", fileEmpty, zip.Store), }, }, { @@ -274,10 +274,10 @@ func TestZip(t *testing.T) { compressionLevel: 9, files: []zip.FileHeader{ + fh("[", fileEmpty, zip.Store), fh("a/a/a", fileA, zip.Deflate), fh("a/a/b", fileB, zip.Deflate), fh("c", fileC, zip.Deflate), - fh("[", fileEmpty, zip.Store), }, }, { @@ -287,11 +287,11 @@ func TestZip(t *testing.T) { compressionLevel: 9, files: []zip.FileHeader{ + fh("@", fileC, zip.Deflate), + fh("[", fileEmpty, zip.Store), fh("a/a/a", fileA, zip.Deflate), fh("a/a/b", fileB, zip.Deflate), - fh("@", fileC, zip.Deflate), fh("foo'bar", fileC, zip.Deflate), - fh("[", fileEmpty, zip.Store), }, }, { @@ -463,8 +463,8 @@ func TestZip(t *testing.T) { compressionLevel: 9, files: []zip.FileHeader{ - fh("foo", fileA, zip.Deflate), fh("a/a/b", fileB, zip.Deflate), + fh("foo", fileA, zip.Deflate), }, }, { @@ -477,8 +477,8 @@ func TestZip(t *testing.T) { compressionLevel: 9, files: []zip.FileHeader{ - fh("prefix/foo", fileA, zip.Deflate), fh("prefix/a/a/b", fileB, zip.Deflate), + fh("prefix/foo", fileA, zip.Deflate), }, }, { @@ -490,8 +490,8 @@ func TestZip(t *testing.T) { compressionLevel: 9, files: []zip.FileHeader{ - fh("foo", fileA, zip.Deflate), fh("a/a/b", fileB, zip.Deflate), + fh("foo", fileA, zip.Deflate), }, }, { @@ -504,8 +504,8 @@ func TestZip(t *testing.T) { compressionLevel: 9, files: []zip.FileHeader{ - fh("foo/bar", fileA, zip.Deflate), fh("b", fileB, zip.Deflate), + fh("foo/bar", fileA, zip.Deflate), }, }, @@ -688,8 +688,8 @@ func TestSrcJar(t *testing.T) { want := []string{ "foo/", - "foo/wrong_package.java", "foo/correct_package.java", + "foo/wrong_package.java", "no_package.java", "src2/", "src2/parse_error.java", |