diff options
-rw-r--r-- | android/Android.bp | 1 | ||||
-rw-r--r-- | android/aconfig_providers.go | 48 | ||||
-rw-r--r-- | android/androidmk.go | 102 | ||||
-rw-r--r-- | android/module.go | 33 | ||||
-rw-r--r-- | android/path_properties.go | 9 | ||||
-rw-r--r-- | android/test_mapping_zip.go | 49 | ||||
-rw-r--r-- | android/testing.go | 5 | ||||
-rw-r--r-- | apex/systemserver_classpath_fragment_test.go | 117 | ||||
-rw-r--r-- | cc/fuzz.go | 1 | ||||
-rw-r--r-- | cc/test.go | 6 | ||||
-rw-r--r-- | ci_tests/ci_test_package_zip.go | 4 | ||||
-rw-r--r-- | cmd/symbols_map/symbols_map.go | 5 | ||||
-rw-r--r-- | dexpreopt/dexpreopt.go | 28 | ||||
-rw-r--r-- | filesystem/android_device.go | 58 | ||||
-rw-r--r-- | filesystem/filesystem.go | 5 | ||||
-rw-r--r-- | fuzz/fuzz_common.go | 6 | ||||
-rw-r--r-- | java/app.go | 11 | ||||
-rw-r--r-- | java/dex.go | 10 | ||||
-rw-r--r-- | java/dexpreopt.go | 31 | ||||
-rw-r--r-- | java/java.go | 16 | ||||
-rw-r--r-- | java/java_test.go | 23 | ||||
-rw-r--r-- | java/jdeps.go | 2 | ||||
-rw-r--r-- | java/robolectric.go | 1 | ||||
-rw-r--r-- | rust/test.go | 10 | ||||
-rw-r--r-- | sh/sh_binary.go | 6 |
25 files changed, 497 insertions, 90 deletions
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 c081ba372..d9d78f349 100644 --- a/android/androidmk.go +++ b/android/androidmk.go @@ -775,6 +775,8 @@ 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 +// 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) @@ -895,28 +897,29 @@ func getSoongOnlyDataFromMods(ctx fillInEntriesContext, mods []Module) ([]distCo } } - if shouldSkipAndroidMkProcessing(ctx, mod.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) } } @@ -1333,9 +1336,12 @@ 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 Module, providerInfo *AndroidMkProviderInfo) error { - if shouldSkipAndroidMkProcessing(ctx, mod.base()) { + commonInfo, _ := OtherModuleProvider(ctx, mod, CommonModuleInfoKey) + if commonInfo.SkipAndroidMkProcessing { return nil } @@ -1345,11 +1351,11 @@ func translateAndroidMkEntriesInfoModule(ctx SingletonContext, w io.Writer, modu aconfigUpdateAndroidMkInfos(ctx, mod, &info) // Any new or special cases here need review to verify correct propagation of license information. - info.PrimaryInfo.fillInEntries(ctx, mod) + 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) } } @@ -1478,13 +1484,14 @@ func (a *AndroidMkInfo) AddCompatibilityTestSuites(suites ...string) { a.AddStrings("LOCAL_COMPATIBILITY_SUITE", suites...) } -func (a *AndroidMkInfo) fillInEntries(ctx fillInEntriesContext, mod 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), } - base := mod.base() - name := base.BaseModuleName() + name := commonInfo.BaseModuleName if a.OverrideName != "" { name = a.OverrideName } @@ -1492,16 +1499,16 @@ func (a *AndroidMkInfo) fillInEntries(ctx fillInEntriesContext, mod Module) { if a.Include == "" { a.Include = "$(BUILD_PREBUILT)" } - 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()...) + 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)) @@ -1526,7 +1533,7 @@ func (a *AndroidMkInfo) fillInEntries(ctx fillInEntriesContext, mod Module) { // 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 { @@ -1541,31 +1548,31 @@ func (a *AndroidMkInfo) fillInEntries(ctx fillInEntriesContext, mod Module) { 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) } @@ -1574,27 +1581,28 @@ func (a *AndroidMkInfo) fillInEntries(ctx fillInEntriesContext, mod Module) { } } - 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) @@ -1652,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 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 } @@ -1662,9 +1672,11 @@ func (a *AndroidMkInfo) GetDistForGoals(ctx fillInEntriesContext, mod Module) [] } // Compute the contributions that the module makes to the dist. -func (a *AndroidMkInfo) getDistContributions(ctx fillInEntriesContext, mod Module) *distContributions { - amod := mod.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. @@ -1700,12 +1712,12 @@ func (a *AndroidMkInfo) getDistContributions(ctx fillInEntriesContext, mod Modul // Collate the contributions this module makes to the dist. distContributions := &distContributions{} - if !exemptFromRequiredApplicableLicensesProperty(mod) { + 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/module.go b/android/module.go index f359e9f4d..996c64e52 100644 --- a/android/module.go +++ b/android/module.go @@ -1922,6 +1922,23 @@ type CommonModuleInfo struct { // 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 { @@ -2266,7 +2283,21 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) SkipInstall: m.commonProperties.SkipInstall, Host: m.Host(), PrimaryLicensesProperty: m.primaryLicensesProperty, - Owner: m.Owner(), + 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 diff --git a/android/path_properties.go b/android/path_properties.go index 55a4dc066..d769d58c4 100644 --- a/android/path_properties.go +++ b/android/path_properties.go @@ -54,12 +54,14 @@ func addPathDepsForProps(ctx BottomUpMutatorContext, props []interface{}) { var pathDeviceFirstPrefer32Properties []string var pathDeviceCommonProperties []string var pathCommonOsProperties []string + var pathHostCommonProperties []string for _, ps := range props { pathProperties = append(pathProperties, taggedPropertiesForPropertyStruct(ctx, ps, "path")...) pathDeviceFirstProperties = append(pathDeviceFirstProperties, taggedPropertiesForPropertyStruct(ctx, ps, "path_device_first")...) pathDeviceFirstPrefer32Properties = append(pathDeviceFirstPrefer32Properties, taggedPropertiesForPropertyStruct(ctx, ps, "path_device_first_prefer32")...) pathDeviceCommonProperties = append(pathDeviceCommonProperties, taggedPropertiesForPropertyStruct(ctx, ps, "path_device_common")...) pathCommonOsProperties = append(pathCommonOsProperties, taggedPropertiesForPropertyStruct(ctx, ps, "path_common_os")...) + pathHostCommonProperties = append(pathHostCommonProperties, taggedPropertiesForPropertyStruct(ctx, ps, "path_host_common")...) } // Remove duplicates to avoid multiple dependencies. @@ -68,6 +70,7 @@ func addPathDepsForProps(ctx BottomUpMutatorContext, props []interface{}) { pathDeviceFirstPrefer32Properties = FirstUniqueStrings(pathDeviceFirstPrefer32Properties) pathDeviceCommonProperties = FirstUniqueStrings(pathDeviceCommonProperties) pathCommonOsProperties = FirstUniqueStrings(pathCommonOsProperties) + pathHostCommonProperties = FirstUniqueStrings(pathHostCommonProperties) // Add dependencies to anything that is a module reference. for _, s := range pathProperties { @@ -108,6 +111,12 @@ func addPathDepsForProps(ctx BottomUpMutatorContext, props []interface{}) { ctx.AddVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), sourceOrOutputDepTag(m, t), m) } } + // properties tagged "path_host_common" get the host common variant + for _, s := range pathHostCommonProperties { + if m, t := SrcIsModuleWithTag(s); m != "" { + ctx.AddVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), sourceOrOutputDepTag(m, t), m) + } + } // properties tagged "path_common_os" get the CommonOs variant for _, s := range pathCommonOsProperties { if m, t := SrcIsModuleWithTag(s); m != "" { 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/testing.go b/android/testing.go index 0cab0abdf..1962fdea5 100644 --- a/android/testing.go +++ b/android/testing.go @@ -1197,10 +1197,11 @@ func AndroidMkInfoForTest(t *testing.T, ctx *TestContext, mod Module) *AndroidMk info := OtherModuleProviderOrDefault(ctx, mod, AndroidMkInfoProvider) aconfigUpdateAndroidMkInfos(ctx, mod, info) - info.PrimaryInfo.fillInEntries(ctx, mod) + 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) } } diff --git a/apex/systemserver_classpath_fragment_test.go b/apex/systemserver_classpath_fragment_test.go index cf7ea8af9..61f79d695 100644 --- a/apex/systemserver_classpath_fragment_test.go +++ b/apex/systemserver_classpath_fragment_test.go @@ -471,3 +471,120 @@ func assertProfileGuidedPrebuilt(t *testing.T, ctx *android.TestContext, apexNam t.Fatalf("Expected profile-guided to be %v, got %v", expected, actual) } } + +func TestCheckSystemServerOrderWithArtApex(t *testing.T) { + preparers := android.GroupFixturePreparers( + java.PrepareForTestWithDexpreopt, + java.PrepareForTestWithJavaSdkLibraryFiles, + PrepareForTestWithApexBuildComponents, + prepareForTestWithArtApex, + java.FixtureConfigureBootJars("com.android.art:framework-art"), + dexpreopt.FixtureSetApexSystemServerJars("com.android.apex1:service-apex1", "com.android.art:service-art"), + java.FixtureWithLastReleaseApis("baz"), + ) + + // Creates a com.android.art apex with a bootclasspath fragment and a systemserverclasspath fragment, and a + // com.android.apex1 prebuilt whose bootclasspath fragment depends on the com.android.art bootclasspath fragment. + // Verifies that the checkSystemServerOrder doesn't get confused by the bootclasspath dependencies and report + // that service-apex1 depends on service-art. + result := preparers.RunTestWithBp(t, ` + apex { + name: "com.android.art", + key: "com.android.art.key", + bootclasspath_fragments: ["art-bootclasspath-fragment"], + systemserverclasspath_fragments: ["art-systemserverclasspath-fragment"], + updatable: false, + } + + apex_key { + name: "com.android.art.key", + public_key: "com.android.art.avbpubkey", + private_key: "com.android.art.pem", + } + + bootclasspath_fragment { + name: "art-bootclasspath-fragment", + image_name: "art", + contents: ["framework-art"], + apex_available: [ + "com.android.art", + ], + hidden_api: { + split_packages: ["*"], + }, + } + + java_library { + name: "framework-art", + apex_available: ["com.android.art"], + srcs: ["a.java"], + compile_dex: true, + } + + systemserverclasspath_fragment { + name: "art-systemserverclasspath-fragment", + apex_available: ["com.android.art"], + contents: ["service-art"], + } + + java_library { + name: "service-art", + srcs: ["a.java"], + apex_available: ["com.android.art"], + compile_dex: true, + } + + prebuilt_apex { + name: "com.android.apex1", + arch: { + arm64: { + src: "myapex-arm64.apex", + }, + arm: { + src: "myapex-arm.apex", + }, + }, + exported_bootclasspath_fragments: ["com.android.apex1-bootclasspath-fragment"], + exported_systemserverclasspath_fragments: ["com.android.apex1-systemserverclasspath-fragment"], + } + + prebuilt_bootclasspath_fragment { + name: "com.android.apex1-bootclasspath-fragment", + visibility: ["//visibility:public"], + apex_available: ["com.android.apex1"], + contents: ["framework-apex1"], + fragments: [ + { + apex: "com.android.art", + module: "art-bootclasspath-fragment", + }, + ], + hidden_api: { + annotation_flags: "hiddenapi/annotation-flags.csv", + metadata: "hiddenapi/metadata.csv", + index: "hiddenapi/index.csv", + stub_flags: "hiddenapi/stub-flags.csv", + all_flags: "hiddenapi/all-flags.csv", + }, + } + + java_import { + name: "framework-apex1", + apex_available: ["com.android.apex1"], + } + + prebuilt_systemserverclasspath_fragment { + name: "com.android.apex1-systemserverclasspath-fragment", + apex_available: ["com.android.apex1"], + contents: ["service-apex1"], + } + + java_import { + name: "service-apex1", + installable: true, + apex_available: ["com.android.apex1"], + sdk_version: "current", + }`) + + _ = result +} diff --git a/cc/fuzz.go b/cc/fuzz.go index a8e4cb70a..bd3d8e431 100644 --- a/cc/fuzz.go +++ b/cc/fuzz.go @@ -353,6 +353,7 @@ func PackageFuzzModule(ctx android.ModuleContext, fuzzPackagedModule fuzz.FuzzPa fuzzPackagedModule.Data = android.PathsForModuleSrc(ctx, fuzzPackagedModule.FuzzProperties.Data) fuzzPackagedModule.Data = append(fuzzPackagedModule.Data, android.PathsForModuleSrc(ctx, fuzzPackagedModule.FuzzProperties.Device_common_data)...) fuzzPackagedModule.Data = append(fuzzPackagedModule.Data, android.PathsForModuleSrc(ctx, fuzzPackagedModule.FuzzProperties.Device_first_data)...) + fuzzPackagedModule.Data = append(fuzzPackagedModule.Data, android.PathsForModuleSrc(ctx, fuzzPackagedModule.FuzzProperties.Host_common_data)...) if fuzzPackagedModule.FuzzProperties.Dictionary != nil { fuzzPackagedModule.Dictionary = android.PathForModuleSrc(ctx, *fuzzPackagedModule.FuzzProperties.Dictionary) diff --git a/cc/test.go b/cc/test.go index 2c5c36eac..d2c4b28e8 100644 --- a/cc/test.go +++ b/cc/test.go @@ -94,6 +94,11 @@ type TestBinaryProperties struct { // of a host test. Device_first_data []string `android:"path_device_first"` + // Same as data, but will add dependencies on modules using the host's os variation and + // the common arch variation. Useful for a device test that wants to depend on a host + // module, for example to include a custom Tradefed test runner. + Host_common_data []string `android:"path_host_common"` + // list of shared library modules that should be installed alongside the test Data_libs []string `android:"arch_variant"` @@ -345,6 +350,7 @@ func (test *testBinary) install(ctx ModuleContext, file android.Path) { dataSrcPaths := android.PathsForModuleSrc(ctx, test.Properties.Data) dataSrcPaths = append(dataSrcPaths, android.PathsForModuleSrc(ctx, test.Properties.Device_common_data)...) dataSrcPaths = append(dataSrcPaths, android.PathsForModuleSrc(ctx, test.Properties.Device_first_data)...) + dataSrcPaths = append(dataSrcPaths, android.PathsForModuleSrc(ctx, test.Properties.Host_common_data)...) for _, dataSrcPath := range dataSrcPaths { test.data = append(test.data, android.DataPath{SrcPath: dataSrcPath}) diff --git a/ci_tests/ci_test_package_zip.go b/ci_tests/ci_test_package_zip.go index d9573a3e3..acfa8e073 100644 --- a/ci_tests/ci_test_package_zip.go +++ b/ci_tests/ci_test_package_zip.go @@ -190,6 +190,10 @@ func createOutput(ctx android.ModuleContext, pctx android.PackageContext) androi } 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") { 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/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go index 1452b412e..699a6757d 100644 --- a/dexpreopt/dexpreopt.go +++ b/dexpreopt/dexpreopt.go @@ -283,10 +283,7 @@ func dexpreoptCommand(ctx android.BuilderContext, globalSoong *GlobalSoongConfig clcHostString := "PCL[" + strings.Join(clcHost.Strings(), ":") + "]" clcTargetString := "PCL[" + strings.Join(clcTarget, ":") + "]" - if systemServerClasspathJars.ContainsJar(module.Name) { - // TODO(b/397461231): renable this check - //checkSystemServerOrder(ctx, jarIndex) - } else { + if !systemServerClasspathJars.ContainsJar(module.Name) { // Standalone jars are loaded by separate class loaders with SYSTEMSERVERCLASSPATH as the // parent. clcHostString = "PCL[];" + clcHostString @@ -578,29 +575,6 @@ func SystemServerDexJarHostPath(ctx android.PathContext, jar string) android.Out } } -// Check the order of jars on the system server classpath and give a warning/error if a jar precedes -// one of its dependencies. This is not an error, but a missed optimization, as dexpreopt won't -// have the dependency jar in the class loader context, and it won't be able to resolve any -// references to its classes and methods. -func checkSystemServerOrder(ctx android.PathContext, jarIndex int) { - mctx, isModule := ctx.(android.ModuleContext) - if isModule { - config := GetGlobalConfig(ctx) - jars := config.AllSystemServerClasspathJars(ctx) - mctx.WalkDeps(func(dep android.Module, parent android.Module) bool { - depIndex := jars.IndexOfJar(dep.Name()) - if jarIndex < depIndex && !config.BrokenSuboptimalOrderOfSystemServerJars { - jar := jars.Jar(jarIndex) - dep := jars.Jar(depIndex) - mctx.ModuleErrorf("non-optimal order of jars on the system server classpath:"+ - " '%s' precedes its dependency '%s', so dexpreopt is unable to resolve any"+ - " references from '%s' to '%s'.\n", jar, dep, jar, dep) - } - return true - }) - } -} - // Returns path to a file containing the reult of verify_uses_libraries check (empty if the check // has succeeded, or an error message if it failed). func UsesLibrariesStatusFile(ctx android.ModuleContext) android.WritablePath { diff --git a/filesystem/android_device.go b/filesystem/android_device.go index 959ef37e1..3b8bf9381 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -17,16 +17,24 @@ 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 @@ -161,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) @@ -305,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 diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index 1ce6131aa..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) { @@ -576,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() { diff --git a/fuzz/fuzz_common.go b/fuzz/fuzz_common.go index 3fd79a719..83ccd89ae 100644 --- a/fuzz/fuzz_common.go +++ b/fuzz/fuzz_common.go @@ -427,6 +427,12 @@ type FuzzProperties struct { // device's first architecture's variant. Can be useful to add device-built apps to the data // of a host test. Device_first_data []string `android:"path_device_first"` + + // Same as data, but will add dependencies on modules using the host's os variation and + // the common arch variation. Useful for a device test that wants to depend on a host + // module, for example to include a custom Tradefed test runner. + Host_common_data []string `android:"path_host_common"` + // Optional dictionary to be installed to the fuzz target's output directory. Dictionary *string `android:"path"` // Define the fuzzing frameworks this fuzz target can be built for. If diff --git a/java/app.go b/java/app.go index 9b10bf3cd..17548e74a 100644 --- a/java/app.go +++ b/java/app.go @@ -452,6 +452,16 @@ func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) { 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 { @@ -1636,6 +1646,7 @@ func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_common_data)...) a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_data)...) a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_prefer32_data)...) + a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Host_common_data)...) // Install test deps if !ctx.Config().KatiEnabled() { diff --git a/java/dex.go b/java/dex.go index 311657fa6..ed2df2103 100644 --- a/java/dex.go +++ b/java/dex.go @@ -697,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/dexpreopt.go b/java/dexpreopt.go index 5755dec23..b21cfc968 100644 --- a/java/dexpreopt.go +++ b/java/dexpreopt.go @@ -565,6 +565,10 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, libName string, dexJa if !isApexSystemServerJar { d.builtInstalled = dexpreoptRule.Installs().String() } + + if isSystemServerJar { + checkSystemServerOrder(ctx, libName) + } } func getModuleInstallPathInfo(ctx android.ModuleContext, fullInstallPath string) (android.InstallPath, string, string) { @@ -631,3 +635,30 @@ func (d *dexpreopter) GetRewrittenProfile() android.Path { func (d *dexpreopter) SetRewrittenProfile(p android.Path) { d.rewrittenProfile = p } + +// Check the order of jars on the system server classpath and give a warning/error if a jar precedes +// one of its dependencies. This is not an error, but a missed optimization, as dexpreopt won't +// have the dependency jar in the class loader context, and it won't be able to resolve any +// references to its classes and methods. +func checkSystemServerOrder(ctx android.ModuleContext, libName string) { + config := dexpreopt.GetGlobalConfig(ctx) + jars := config.AllSystemServerClasspathJars(ctx) + jarIndex := config.AllSystemServerJars(ctx).IndexOfJar(libName) + ctx.WalkDeps(func(dep android.Module, parent android.Module) bool { + tag := ctx.OtherModuleDependencyTag(dep) + // Ideally this should only be walking relevant dependencies, but to maintain existing behavior + // for now just exclude any known irrelevant dependencies that would lead to incorrect errors. + if _, ok := tag.(bootclasspathDependencyTag); ok { + return false + } + depIndex := jars.IndexOfJar(dep.Name()) + if jarIndex < depIndex && !config.BrokenSuboptimalOrderOfSystemServerJars { + jar := jars.Jar(jarIndex) + dep := jars.Jar(depIndex) + ctx.ModuleErrorf("non-optimal order of jars on the system server classpath:"+ + " '%s' precedes its dependency '%s', so dexpreopt is unable to resolve any"+ + " references from '%s' to '%s'.\n", jar, dep, jar, dep) + } + return true + }) +} diff --git a/java/java.go b/java/java.go index b9109ee94..b18c56130 100644 --- a/java/java.go +++ b/java/java.go @@ -1172,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 { @@ -1539,6 +1549,11 @@ type testProperties struct { // host test. Device_first_prefer32_data []string `android:"path_device_first_prefer32"` + // Same as data, but will add dependencies on modules using the host's os variation and + // the common arch variation. Useful for a device test that wants to depend on a host + // module, for example to include a custom Tradefed test runner. + Host_common_data []string `android:"path_host_common"` + // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true // explicitly. @@ -1837,6 +1852,7 @@ func (j *Test) generateAndroidBuildActionsWithConfig(ctx android.ModuleContext, j.data = append(j.data, android.PathsForModuleSrc(ctx, j.testProperties.Device_common_data)...) j.data = append(j.data, android.PathsForModuleSrc(ctx, j.testProperties.Device_first_data)...) j.data = append(j.data, android.PathsForModuleSrc(ctx, j.testProperties.Device_first_prefer32_data)...) + j.data = append(j.data, android.PathsForModuleSrc(ctx, j.testProperties.Host_common_data)...) j.extraTestConfigs = android.PathsForModuleSrc(ctx, j.testProperties.Test_options.Extra_test_configs) diff --git a/java/java_test.go b/java/java_test.go index 636a0c891..a6290a628 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -585,6 +585,29 @@ func TestTest(t *testing.T) { } } +func TestHostCommonData(t *testing.T) { + t.Parallel() + ctx, _ := testJava(t, ` + java_library_host { + name: "host", + srcs: ["a.java"], + } + + java_test { + name: "foo", + srcs: ["a.java"], + host_common_data: [":host"], + } + `) + + foo := ctx.ModuleForTests(t, "foo", "android_common").Module().(*Test) + host := ctx.ModuleForTests(t, "host", ctx.Config().BuildOSCommonTarget.String()).Module().(*Library) + + if g, w := foo.data.RelativeToTop().Strings(), []string{host.outputFile.RelativeToTop().String()}; !slices.Equal(g, w) { + t.Errorf("expected test data %q, got %q\n", w, g) + } +} + func TestHostBinaryNoJavaDebugInfoOverride(t *testing.T) { t.Parallel() bp := ` 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/robolectric.go b/java/robolectric.go index 5dcc7dd81..be369f780 100644 --- a/java/robolectric.go +++ b/java/robolectric.go @@ -168,6 +168,7 @@ func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext) r.data = append(r.data, android.PathsForModuleSrc(ctx, r.testProperties.Device_common_data)...) r.data = append(r.data, android.PathsForModuleSrc(ctx, r.testProperties.Device_first_data)...) r.data = append(r.data, android.PathsForModuleSrc(ctx, r.testProperties.Device_first_prefer32_data)...) + r.data = append(r.data, android.PathsForModuleSrc(ctx, r.testProperties.Host_common_data)...) var ok bool var instrumentedApp *JavaInfo diff --git a/rust/test.go b/rust/test.go index 5c183bc67..9833ffdb6 100644 --- a/rust/test.go +++ b/rust/test.go @@ -46,9 +46,16 @@ type TestProperties struct { // the test Data []string `android:"path,arch_variant"` - // Same as data, but will add dependencies on the device's + // Same as data, but adds dependencies on modules using the device's os variant, and common + // architecture's variant. Can be useful to add device-built apps to the data of a host + // test. Device_common_data []string `android:"path_device_common"` + // Same as data, but will add dependencies on modules using the host's os variation and + // the common arch variation. Useful for a device test that wants to depend on a host + // module, for example to include a custom Tradefed test runner. + Host_common_data []string `android:"path_host_common"` + // list of shared library modules that should be installed alongside the test Data_libs []string `android:"arch_variant"` @@ -147,6 +154,7 @@ func (test *testDecorator) install(ctx ModuleContext) { dataSrcPaths := android.PathsForModuleSrc(ctx, test.Properties.Data) dataSrcPaths = append(dataSrcPaths, android.PathsForModuleSrc(ctx, test.Properties.Device_common_data)...) + dataSrcPaths = append(dataSrcPaths, android.PathsForModuleSrc(ctx, test.Properties.Host_common_data)...) ctx.VisitDirectDepsProxyWithTag(dataLibDepTag, func(dep android.ModuleProxy) { depName := ctx.OtherModuleName(dep) diff --git a/sh/sh_binary.go b/sh/sh_binary.go index c0c6ff2ae..f8d1ce523 100644 --- a/sh/sh_binary.go +++ b/sh/sh_binary.go @@ -138,6 +138,11 @@ type TestProperties struct { // host test. Device_first_data []string `android:"path_device_first"` + // Same as data, but will add dependencies on modules using the host's os variation and + // the common arch variation. Useful for a device test that wants to depend on a host + // module, for example to include a custom Tradefed test runner. + Host_common_data []string `android:"path_host_common"` + // Add RootTargetPreparer to auto generated test config. This guarantees the test to run // with root permission. Require_root *bool @@ -436,6 +441,7 @@ func (s *ShTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { expandedData := android.PathsForModuleSrc(ctx, s.testProperties.Data) expandedData = append(expandedData, android.PathsForModuleSrc(ctx, s.testProperties.Device_common_data)...) expandedData = append(expandedData, android.PathsForModuleSrc(ctx, s.testProperties.Device_first_data)...) + expandedData = append(expandedData, android.PathsForModuleSrc(ctx, s.testProperties.Host_common_data)...) // Emulate the data property for java_data dependencies. for _, javaData := range ctx.GetDirectDepsProxyWithTag(shTestJavaDataTag) { expandedData = append(expandedData, android.OutputFilesForModule(ctx, javaData, "")...) |