From 69f8ca9c25796b395a944cfba90bb390a0858b06 Mon Sep 17 00:00:00 2001 From: Siarhei Vishniakou Date: Fri, 21 Mar 2025 20:15:39 -0700 Subject: Build input config files for host This will allow input tests to run on host. Bug: 253299089 Test: TEST=libinput_tests; m $TEST && $ANDROID_HOST_OUT/nativetest64/$TEST/$TEST --gtest_filter="*InputDeviceKeyMapTest*" Flag: TEST_ONLY Change-Id: I48396c91f4c5f708293fcc8d7ba0ff70c98466cc --- etc/prebuilt_etc.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go index 7820047ab..2d2281159 100644 --- a/etc/prebuilt_etc.go +++ b/etc/prebuilt_etc.go @@ -752,7 +752,7 @@ func PrebuiltUserShareFactory() android.Module { return module } -// prebuild_usr_share_host is for a host prebuilt artifact that is installed in +// prebuilt_usr_share_host is for a host prebuilt artifact that is installed in // $(HOST_OUT)/usr/share/ directory. func PrebuiltUserShareHostFactory() android.Module { module := &PrebuiltEtc{} @@ -780,7 +780,7 @@ func PrebuiltUserKeyLayoutFactory() android.Module { module := &PrebuiltEtc{} InitPrebuiltEtcModule(module, "usr/keylayout") // This module is device-only - android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) + android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibFirst) android.InitDefaultableModule(module) return module } @@ -791,7 +791,7 @@ func PrebuiltUserKeyCharsFactory() android.Module { module := &PrebuiltEtc{} InitPrebuiltEtcModule(module, "usr/keychars") // This module is device-only - android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) + android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibFirst) android.InitDefaultableModule(module) return module } @@ -802,7 +802,7 @@ func PrebuiltUserIdcFactory() android.Module { module := &PrebuiltEtc{} InitPrebuiltEtcModule(module, "usr/idc") // This module is device-only - android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) + android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibFirst) android.InitDefaultableModule(module) return module } -- cgit v1.2.3 From 4ee862c4f17b04ee8a848f5ea8ac905be42e5209 Mon Sep 17 00:00:00 2001 From: LaMont Jones Date: Mon, 24 Mar 2025 13:07:01 -0700 Subject: Make d8-on-eng a stand-alone opt-in feature Allow a module to override optimization on eng builds only. This adds `optimize.d8_on_eng` so that the module does not need to check the build variant itself, but can override the calculation of `optimize.enabled` for eng builds. Bug: b/374975543 Test: manual, TH Change-Id: I5284072e91063520cece0050eef0a7eefff54323 --- java/dex.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/java/dex.go b/java/dex.go index dd6467546..e3058e9bf 100644 --- a/java/dex.go +++ b/java/dex.go @@ -42,6 +42,10 @@ type DexProperties struct { // True if the module containing this has it set by default. EnabledByDefault bool `blueprint:"mutated"` + // If true, then `d8` will be used on eng builds instead of `r8`, even though + // optimize.enabled is true. + D8_on_eng *bool + // Whether to allow that library classes inherit from program classes. // Defaults to false. Ignore_library_extends_program *bool @@ -162,7 +166,12 @@ type dexer struct { } func (d *dexer) effectiveOptimizeEnabled(ctx android.EarlyModuleContext) bool { - return BoolDefault(d.dexProperties.Optimize.Enabled, d.dexProperties.Optimize.EnabledByDefault && !ctx.Config().Eng()) + // For eng builds, if Optimize.D8_on_eng is true, then disable optimization. + if ctx.Config().Eng() && proptools.Bool(d.dexProperties.Optimize.D8_on_eng) { + return false + } + // Otherwise, use the legacy logic of a default value which can be explicitly overridden by the module. + return BoolDefault(d.dexProperties.Optimize.Enabled, d.dexProperties.Optimize.EnabledByDefault) } func (d *DexProperties) resourceShrinkingEnabled(ctx android.ModuleContext) bool { -- cgit v1.2.3 From 544540a3a218924f230413c4b34580a548525e7a Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Fri, 21 Mar 2025 00:04:29 +0000 Subject: Create a validation action to assert `apps` matches prebuilt apex contents apkcerts.txt built by Make currently contains an entry app in the tree, but is being migrated to be limited to the list of installed apps for the device. This unfortunately breaks signing for prebuilt_apex with apks, since it silently relied on an entry being created by the source `android_app` module. https://r.android.com/3552560 introduces a new `apps` property that will be used to declare this dependency between prebuilt_apex and the cert of the android app. This CL introduces a validation action to ensure that the `apps` property is uptodate. It uses apex-ls to get the actual list of installed apks, and compares it against the contents of the AppInfo providers gathered from `apps` property. To support development in minimal branches like art which might not contain the source app, the validation action will be triggered when building apkcerts.txt (either in Soong or Make), and will not be in the transitive closure of `m $my_prebuilt_apex`. Test: m Bug: 399788149 Change-Id: Idb8ec3ca3bbeee9bd4c09a7d5cd981cc35d765dc --- apex/prebuilt.go | 65 +++++++++++++++++++++++++++++++++++--------- filesystem/android_device.go | 8 ++++++ 2 files changed, 60 insertions(+), 13 deletions(-) diff --git a/apex/prebuilt.go b/apex/prebuilt.go index fdd9a75d7..a1c866160 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -48,6 +48,16 @@ var ( CommandDeps: []string{"${deapexer}"}, Description: "decompress $out", }) + // Compares the declared apps of `prebuilt_apex` with the actual apks + validateApkInPrebuiltApex = pctx.StaticRule("validateApkinPrebuiltApex", blueprint.RuleParams{ + Command: `rm -rf ${out} ${actualApks} &&` + + ` ${apex_ls} ${in} | grep apk$$ | awk -F '/' '{print $$NF}' | sort -u > ${actualApks} &&` + + ` cmp -s ${expectedApks} ${actualApks} && touch ${out}` + + ` || (echo "Found diffs between "apps" property of ${apexName} and actual contents of ${in}.` + + ` Please ensure that all apk-in-apexes are declared in 'apps' property." && exit 1)`, + CommandDeps: []string{"${apex_ls}"}, + Description: "validate apk in prebuilt_apex $out", + }, "expectedApks", "actualApks", "apexName") ) type prebuilt interface { @@ -711,6 +721,38 @@ func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) { android.SetProvider(ctx, filesystem.ApexKeyPathInfoProvider, filesystem.ApexKeyPathInfo{p.apexKeysPath}) } +// Creates a timestamp file that will be used to validate that there is no mismtach +// between apks declared via `apps` and the actual apks inside the apex. +func (p *Prebuilt) validateApkInPrebuiltApex(ctx android.ModuleContext, appInfos java.AppInfos) android.Path { + timestamp := android.PathForModuleOut(ctx, "apk_in_prebuilt_apex.timestamp") + // Create a list of expected installed apks. + var installedApks []string + for _, appInfo := range appInfos { + installedApks = append(installedApks, appInfo.InstallApkName+".apk") + } + expectedApksFile := android.PathForModuleOut(ctx, "expected_apk_in_prebuilt_apex.txt") + if len(installedApks) == 0 { + android.WriteFileRuleVerbatim(ctx, expectedApksFile, "") // Without newline + } else { + android.WriteFileRule(ctx, expectedApksFile, strings.Join(android.SortedUniqueStrings(installedApks), "\n")) // With newline + } + + actualApksFile := android.PathForModuleOut(ctx, "actual_apk_in_prebuilt_apex.txt") + ctx.Build(pctx, android.BuildParams{ + Rule: validateApkInPrebuiltApex, + Input: p.inputApex, + Output: timestamp, + Implicit: expectedApksFile, + ImplicitOutput: actualApksFile, + Args: map[string]string{ + "expectedApks": expectedApksFile.String(), + "actualApks": actualApksFile.String(), + "apexName": p.Name(), + }, + }) + return timestamp +} + // `addApkCertsInfo` sets a provider that will be used to create apkcerts.txt func (p *Prebuilt) addApkCertsInfo(ctx android.ModuleContext) { formatLine := func(cert java.Certificate, name, partition string) string { @@ -737,24 +779,21 @@ func (p *Prebuilt) addApkCertsInfo(ctx android.ModuleContext) { return appInfos[i].InstallApkName < appInfos[j].InstallApkName }) - if len(appInfos) == 0 { - return - } - - // Set a provider for use by `android_device`. - // `android_device` will create an apkcerts.txt with the list of installed apps for that device. - android.SetProvider(ctx, java.AppInfosProvider, appInfos) - - // Set a Make variable for legacy apkcerts.txt creation - // p.apkCertsFile will become `LOCAL_APKCERTS_FILE` + // Create p.apkCertsFile with information about apk-in-apex + // p.apkCertsFile will become `LOCAL_APKCERTS_FILE` for Make packaging system + // p.apkCertsFile will be propagated to android_device for Soong packaging system var lines []string for _, appInfo := range appInfos { lines = append(lines, formatLine(appInfo.Certificate, appInfo.InstallApkName+".apk", p.PartitionTag(ctx.DeviceConfig()))) } - if len(lines) > 0 { - p.apkCertsFile = android.PathForModuleOut(ctx, "apkcerts.txt") - android.WriteFileRule(ctx, p.apkCertsFile, strings.Join(lines, "\n")) + p.apkCertsFile = android.PathForModuleOut(ctx, "apkcerts.txt") + var validations android.Paths + if p.IsInstallable() { + // Skip the validation for non-installable prebuilt apexes (e.g. used in CTS tests). + validations = append(validations, p.validateApkInPrebuiltApex(ctx, appInfos)) } + android.WriteFileRuleVerbatim(ctx, p.apkCertsFile, strings.Join(lines, "\n"), validations...) + android.SetProvider(ctx, filesystem.ApkCertsInfoProvider, filesystem.ApkCertsInfo{p.apkCertsFile}) } func (p *Prebuilt) ProvenanceMetaDataFile() android.Path { diff --git a/filesystem/android_device.go b/filesystem/android_device.go index b96c5eae3..4aaffd81f 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -1107,6 +1107,8 @@ func (a *androidDevice) buildApkCertsInfo(ctx android.ModuleContext, allInstalle } } else if info, ok := android.OtherModuleProvider(ctx, installedModule, java.RuntimeResourceOverlayInfoProvider); ok { apkCerts = append(apkCerts, formatLine(info.Certificate, info.OutputFile.Base(), partition)) + } else if info, ok := android.OtherModuleProvider(ctx, installedModule, ApkCertsInfoProvider); ok { + apkCertsFiles = append(apkCertsFiles, info.ApkCertsFile) } } slices.Sort(apkCerts) // sort by name @@ -1130,3 +1132,9 @@ func (a *androidDevice) buildApkCertsInfo(ctx android.ModuleContext, allInstalle }) return apkCertsInfo } + +type ApkCertsInfo struct { + ApkCertsFile android.Path +} + +var ApkCertsInfoProvider = blueprint.NewProvider[ApkCertsInfo]() -- cgit v1.2.3 From 34b970c0d062383bf7a3a429754151db645e0e55 Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Wed, 19 Mar 2025 18:01:41 +0000 Subject: Remove prebuilt module info provider ...and embed the prebuilt module info provider's infos in common module info provider. Test: CI Change-Id: Ia8584424cefd5ba1cbb5e01348af5cda454f7d9d --- android/module.go | 20 ++++++++------------ android/prebuilt.go | 6 +++--- cc/fuzz.go | 2 +- dexpreopt/config.go | 8 ++++++-- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/android/module.go b/android/module.go index 1538861d3..10c69df8a 100644 --- a/android/module.go +++ b/android/module.go @@ -1951,6 +1951,9 @@ type CommonModuleInfo struct { ExportedToMake bool Team string PartitionTag string + IsPrebuilt bool + PrebuiltSourceExists bool + UsePrebuilt bool } type ApiLevelOrPlatform struct { @@ -1960,13 +1963,6 @@ type ApiLevelOrPlatform struct { var CommonModuleInfoProvider = blueprint.NewProvider[*CommonModuleInfo]() -type PrebuiltModuleInfo struct { - SourceExists bool - UsePrebuilt bool -} - -var PrebuiltModuleInfoProvider = blueprint.NewProvider[PrebuiltModuleInfo]() - type HostToolProviderInfo struct { HostToolPath OptionalPath } @@ -2366,13 +2362,13 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) if mm, ok := m.module.(interface{ BaseModuleName() string }); ok { commonData.BaseModuleName = mm.BaseModuleName() } - SetProvider(ctx, CommonModuleInfoProvider, &commonData) if p, ok := m.module.(PrebuiltInterface); ok && p.Prebuilt() != nil { - SetProvider(ctx, PrebuiltModuleInfoProvider, PrebuiltModuleInfo{ - SourceExists: p.Prebuilt().SourceExists(), - UsePrebuilt: p.Prebuilt().UsePrebuilt(), - }) + commonData.IsPrebuilt = true + commonData.PrebuiltSourceExists = p.Prebuilt().SourceExists() + commonData.UsePrebuilt = p.Prebuilt().UsePrebuilt() } + SetProvider(ctx, CommonModuleInfoProvider, &commonData) + if h, ok := m.module.(HostToolProvider); ok { SetProvider(ctx, HostToolProviderInfoProvider, HostToolProviderInfo{ HostToolPath: h.HostToolPath()}) diff --git a/android/prebuilt.go b/android/prebuilt.go index 1ff009bf5..a13c8d0bd 100644 --- a/android/prebuilt.go +++ b/android/prebuilt.go @@ -362,8 +362,8 @@ func IsModulePreferredProxy(ctx OtherModuleProviderContext, module ModuleProxy) // A source module that has been replaced by a prebuilt counterpart. return false } - if p, ok := OtherModuleProvider(ctx, module, PrebuiltModuleInfoProvider); ok { - return p.UsePrebuilt + if commonInfo, ok := OtherModuleProvider(ctx, module, CommonModuleInfoProvider); ok && commonInfo.IsPrebuilt { + return commonInfo.UsePrebuilt } return true } @@ -400,7 +400,7 @@ func PrebuiltGetPreferred(ctx BaseModuleContext, module Module) Module { if !OtherModulePointerProviderOrDefault(ctx, module, CommonModuleInfoProvider).ReplacedByPrebuilt { return module } - if _, ok := OtherModuleProvider(ctx, module, PrebuiltModuleInfoProvider); ok { + if commonInfo, ok := OtherModuleProvider(ctx, module, CommonModuleInfoProvider); ok && commonInfo.IsPrebuilt { // If we're given a prebuilt then assume there's no source module around. return module } diff --git a/cc/fuzz.go b/cc/fuzz.go index 79874fc80..4a57cae87 100644 --- a/cc/fuzz.go +++ b/cc/fuzz.go @@ -257,7 +257,7 @@ func isValidSharedDependency(ctx android.ModuleContext, dependency android.Modul // If the same library is present both as source and a prebuilt we must pick // only one to avoid a conflict. Always prefer the source since the prebuilt // probably won't be built with sanitizers enabled. - if prebuilt, ok := android.OtherModuleProvider(ctx, dependency, android.PrebuiltModuleInfoProvider); ok && prebuilt.SourceExists { + if commonInfo, ok := android.OtherModuleProvider(ctx, dependency, android.CommonModuleInfoProvider); ok && commonInfo.IsPrebuilt && commonInfo.PrebuiltSourceExists { return false } diff --git a/dexpreopt/config.go b/dexpreopt/config.go index af09dbcca..692a97919 100644 --- a/dexpreopt/config.go +++ b/dexpreopt/config.go @@ -514,7 +514,11 @@ func dex2oatPathFromDep(ctx android.ModuleContext) android.Path { // prebuilt explicitly here instead. var dex2oatModule android.ModuleProxy ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool { - prebuiltInfo, isPrebuilt := android.OtherModuleProvider(ctx, child, android.PrebuiltModuleInfoProvider) + var isPrebuilt, usePrebuilt bool + if commonInfo, ok := android.OtherModuleProvider(ctx, child, android.CommonModuleInfoProvider); ok { + isPrebuilt = commonInfo.IsPrebuilt + usePrebuilt = commonInfo.UsePrebuilt + } if android.EqualModules(parent, ctx.Module()) && ctx.OtherModuleDependencyTag(child) == Dex2oatDepTag { // Found the source module, or prebuilt module that has replaced the source. dex2oatModule = child @@ -525,7 +529,7 @@ func dex2oatPathFromDep(ctx android.ModuleContext) android.Path { } } if android.EqualModules(parent, dex2oatModule) && ctx.OtherModuleDependencyTag(child) == android.PrebuiltDepTag { - if isPrebuilt && prebuiltInfo.UsePrebuilt { + if isPrebuilt && usePrebuilt { dex2oatModule = child // Found a prebuilt that should be used. } } -- cgit v1.2.3 From 2f08699082b9deeff1c564412f74616e01fffb21 Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Wed, 19 Mar 2025 19:43:47 +0000 Subject: More accurate all installed modules in android_device This change makes gathering of all installed modules in android_device with the following modifications: - Check whether the owner is a prebuilt module or not and if it matches the dependency of android_device that is being visited. - Check if the module is exported to make (i.e. the module is within the exported namespace) -- this prevents a module with the same name from a different namespace being confused with an actual installed module. - Propagate subpartitions' owners info in filesystem info provider. Test: CI Bug: 395989947 Change-Id: Ia11ba0fd5abdbcac674e67c2d578fbf70ff4bf43 --- android/module_context.go | 3 +++ android/packaging.go | 10 ++++++++++ filesystem/android_device.go | 25 +++++++++++++++++++++---- filesystem/filesystem.go | 25 ++++++++++++++++++++----- 4 files changed, 54 insertions(+), 9 deletions(-) diff --git a/android/module_context.go b/android/module_context.go index 0a23a745f..e30afd637 100644 --- a/android/module_context.go +++ b/android/module_context.go @@ -661,6 +661,7 @@ func (m *moduleContext) packageFile(fullInstallPath InstallPath, srcPath Path, e requiresFullInstall: requiresFullInstall, fullInstallPath: fullInstallPath, variation: m.ModuleSubDir(), + prebuilt: IsModulePrebuilt(m.Module()), } m.packagingSpecs = append(m.packagingSpecs, spec) return spec @@ -816,6 +817,7 @@ func (m *moduleContext) InstallSymlink(installPath InstallPath, name string, src requiresFullInstall: m.requiresFullInstall(), fullInstallPath: fullInstallPath, variation: m.ModuleSubDir(), + prebuilt: IsModulePrebuilt(m.Module()), }) return fullInstallPath @@ -867,6 +869,7 @@ func (m *moduleContext) InstallAbsoluteSymlink(installPath InstallPath, name str requiresFullInstall: m.requiresFullInstall(), fullInstallPath: fullInstallPath, variation: m.ModuleSubDir(), + prebuilt: IsModulePrebuilt(m.Module()), }) return fullInstallPath diff --git a/android/packaging.go b/android/packaging.go index bf1840929..aae7806d7 100644 --- a/android/packaging.go +++ b/android/packaging.go @@ -75,6 +75,9 @@ type PackagingSpec struct { // String representation of the variation of the module where this packaging spec is output of variation string + + // Whether the owner module is a prebuilt module or not + prebuilt bool } type packagingSpecGob struct { @@ -92,6 +95,7 @@ type packagingSpecGob struct { RequiresFullInstall bool FullInstallPath InstallPath Variation string + Prebuilt bool } func (p *PackagingSpec) Owner() string { @@ -102,6 +106,10 @@ func (p *PackagingSpec) Variation() string { return p.variation } +func (p *PackagingSpec) Prebuilt() bool { + return p.prebuilt +} + func (p *PackagingSpec) ToGob() *packagingSpecGob { return &packagingSpecGob{ RelPathInPackage: p.relPathInPackage, @@ -118,6 +126,7 @@ func (p *PackagingSpec) ToGob() *packagingSpecGob { RequiresFullInstall: p.requiresFullInstall, FullInstallPath: p.fullInstallPath, Variation: p.variation, + Prebuilt: p.prebuilt, } } @@ -136,6 +145,7 @@ func (p *PackagingSpec) FromGob(data *packagingSpecGob) { p.requiresFullInstall = data.RequiresFullInstall p.fullInstallPath = data.FullInstallPath p.variation = data.Variation + p.prebuilt = data.Prebuilt } func (p *PackagingSpec) GobEncode() ([]byte, error) { diff --git a/filesystem/android_device.go b/filesystem/android_device.go index 8b6ea4937..bc002795a 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -323,21 +323,38 @@ func buildComplianceMetadata(ctx android.ModuleContext, tags ...blueprint.Depend complianceMetadataInfo.SetPrebuiltFilesCopied(prebuiltFilesCopied) } +type installedOwnerInfo struct { + Variation string + Prebuilt bool +} + // 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) + allOwners := make(map[string][]installedOwnerInfo) + for _, partition := range android.SortedKeys(fsInfoMap) { fsInfo := fsInfoMap[partition] - for _, owner := range fsInfo.Owners { - allOwners[owner.Name] = append(allOwners[owner.Name], owner.Variation) + for _, owner := range fsInfo.Owners.ToList() { + allOwners[owner.Name] = append(allOwners[owner.Name], installedOwnerInfo{ + Variation: owner.Variation, + Prebuilt: owner.Prebuilt, + }) } } ret := []android.Module{} ctx.WalkDepsProxy(func(mod, _ android.ModuleProxy) bool { - if variations, ok := allOwners[ctx.OtherModuleName(mod)]; ok && android.InList(ctx.OtherModuleSubDir(mod), variations) { + commonInfo, ok := android.OtherModuleProvider(ctx, mod, android.CommonModuleInfoProvider) + if !(ok && commonInfo.ExportedToMake) { + return false + } + if variations, ok := allOwners[ctx.OtherModuleName(mod)]; ok && + android.InList(installedOwnerInfo{ + Variation: ctx.OtherModuleSubDir(mod), + Prebuilt: commonInfo.IsPrebuilt, + }, variations) { ret = append(ret, mod) } return true diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index c3c3835f6..df60a8cf7 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -401,6 +401,7 @@ type InstalledFilesStruct struct { type InstalledModuleInfo struct { Name string Variation string + Prebuilt bool } type FilesystemInfo struct { @@ -454,7 +455,7 @@ type FilesystemInfo struct { FilesystemConfig android.Path - Owners []InstalledModuleInfo + Owners depset.DepSet[InstalledModuleInfo] HasFsverity bool @@ -721,10 +722,14 @@ func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) { []InstalledFilesStruct{buildInstalledFiles(ctx, partitionNameForInstalledFiles, rootDir, f.output)}, includeFilesInstalledFiles(ctx), ), - ErofsCompressHints: erofsCompressHints, - SelinuxFc: f.selinuxFc, - FilesystemConfig: f.generateFilesystemConfig(ctx, rootDir, rebasedDir), - Owners: f.gatherOwners(specs), + ErofsCompressHints: erofsCompressHints, + SelinuxFc: f.selinuxFc, + FilesystemConfig: f.generateFilesystemConfig(ctx, rootDir, rebasedDir), + Owners: depset.New( + depset.POSTORDER, + f.gatherOwners(specs), + f.gatherSubPartitionOwners(ctx), + ), HasFsverity: f.properties.Fsverity.Inputs.GetOrDefault(ctx, nil) != nil, PropFileForMiscInfo: propFileForMiscInfo, PartitionSize: f.properties.Partition_size, @@ -1508,11 +1513,21 @@ func (f *filesystem) gatherOwners(specs map[string]android.PackagingSpec) []Inst owners = append(owners, InstalledModuleInfo{ Name: spec.Owner(), Variation: spec.Variation(), + Prebuilt: spec.Prebuilt(), }) } return owners } +func (f *filesystem) gatherSubPartitionOwners(ctx android.ModuleContext) (ret []depset.DepSet[InstalledModuleInfo]) { + ctx.VisitDirectDepsWithTag(interPartitionInstallDependencyTag, func(m android.Module) { + if fsProvider, ok := android.OtherModuleProvider(ctx, m, FilesystemProvider); ok { + ret = append(ret, fsProvider.Owners) + } + }) + return +} + // 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 { -- cgit v1.2.3 From 77361a9355d785670a6504df8b4b361438b1c0ff Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Wed, 19 Mar 2025 20:47:10 +0000 Subject: Introduce base module method NoFullInstall() The method can be used to retrieve whether the module sets `No_full_install` property. Utilization of the method will be done in a follow up change. Test: CI Bug: 395989947 Change-Id: I4673e05aff68c53bff54230f9f9dcbf3d5156569 --- android/module.go | 6 ++++++ android/module_proxy.go | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/android/module.go b/android/module.go index 10c69df8a..b2e91c3dc 100644 --- a/android/module.go +++ b/android/module.go @@ -140,6 +140,8 @@ type Module interface { // If this is true, the module must not read product-specific configurations. UseGenericConfig() bool + + NoFullInstall() bool } // Qualified id for a module @@ -1315,6 +1317,10 @@ func (m *ModuleBase) IsCommonOSVariant() bool { return m.commonProperties.CompileOS == CommonOS } +func (m *ModuleBase) NoFullInstall() bool { + return proptools.Bool(m.commonProperties.No_full_install) +} + // supportsTarget returns true if the given Target is supported by the current module. func (m *ModuleBase) supportsTarget(target Target) bool { switch target.Os.Class { diff --git a/android/module_proxy.go b/android/module_proxy.go index 81d90e9a0..b292b5c35 100644 --- a/android/module_proxy.go +++ b/android/module_proxy.go @@ -239,3 +239,7 @@ func (m ModuleProxy) VintfFragments(ctx ConfigurableEvaluatorContext) []string { func (m ModuleProxy) UseGenericConfig() bool { panic("method is not implemented on ModuleProxy") } + +func (m ModuleProxy) NoFullInstall() bool { + panic("method is not implemented on ModuleProxy") +} -- cgit v1.2.3 From dc6b03ecec73e711e27e5a23f1afe9770b276e04 Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Wed, 19 Mar 2025 20:55:07 +0000 Subject: Collect symbols info of cc modules symbols info are informations needed to copy the symbols files to the correct location within $PRODUCT_OUT/symbols directory. This change adds the logic to collect these information for cc modules. Note that the actual copying of the symbols files will be done in a follow up change. Test: CI Bug: 395989947 Change-Id: I5126e8bb5081e0c2027fc5ae522b8fce7cb3cbff --- cc/cc.go | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/cc/cc.go b/cc/cc.go index c616165c5..a5e154f46 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -22,6 +22,7 @@ import ( "errors" "fmt" "io" + "path/filepath" "slices" "strconv" "strings" @@ -966,6 +967,46 @@ type installDependencyTag struct { name string } +type SymbolInfo struct { + Name string + ModuleDir string + Uninstallable bool + UnstrippedBinaryPath android.Path + InstalledStem string + Stem string + Suffix string +} + +func (s *SymbolInfo) equals(other *SymbolInfo) bool { + return s.Name == other.Name && + s.ModuleDir == other.ModuleDir && + s.Uninstallable == other.Uninstallable && + s.UnstrippedBinaryPath == other.UnstrippedBinaryPath && + s.InstalledStem == other.InstalledStem && + s.Suffix == other.Suffix +} + +type SymbolInfos struct { + Symbols []*SymbolInfo +} + +func (si *SymbolInfos) containsSymbolInfo(other *SymbolInfo) bool { + for _, info := range si.Symbols { + if info.equals(other) { + return true + } + } + return false +} + +func (si *SymbolInfos) AppendSymbols(infos ...*SymbolInfo) { + for _, info := range infos { + if info.UnstrippedBinaryPath != nil && !si.containsSymbolInfo(info) { + si.Symbols = append(si.Symbols, infos...) + } + } +} + var ( genSourceDepTag = dependencyTag{name: "gen source"} genHeaderDepTag = dependencyTag{name: "gen header"} @@ -2083,6 +2124,79 @@ var ( } ) +func (c *Module) getSymbolInfo(ctx android.ModuleContext, t any, info *SymbolInfo) *SymbolInfo { + switch tt := t.(type) { + case *baseInstaller: + if tt.path != (android.InstallPath{}) { + path, file := filepath.Split(tt.path.String()) + stem, suffix, _ := android.SplitFileExt(file) + info.ModuleDir = path + info.Stem = stem + info.Suffix = suffix + } + case *binaryDecorator: + c.getSymbolInfo(ctx, tt.baseInstaller, info) + info.UnstrippedBinaryPath = tt.unstrippedOutputFile + case *benchmarkDecorator: + c.getSymbolInfo(ctx, tt.binaryDecorator, info) + case *testBinary: + c.getSymbolInfo(ctx, tt.binaryDecorator, info) + c.getSymbolInfo(ctx, tt.testDecorator, info) + case *fuzzBinary: + c.getSymbolInfo(ctx, tt.binaryDecorator, info) + case *testLibrary: + c.getSymbolInfo(ctx, tt.libraryDecorator, info) + c.getSymbolInfo(ctx, tt.testDecorator, info) + case *stubDecorator: + info.Uninstallable = true + case *libraryDecorator: + if tt.shared() && !tt.BuildStubs() { + if tt.unstrippedOutputFile != nil { + info.UnstrippedBinaryPath = tt.unstrippedOutputFile + } + c.getSymbolInfo(ctx, tt.baseInstaller, info) + } else { + info.Uninstallable = true + } + case *prebuiltLibraryLinker: + c.getSymbolInfo(ctx, tt.libraryDecorator, info) + if tt.shared() { + c.getSymbolInfo(ctx, &tt.prebuiltLinker, info) + } + case *prebuiltBinaryLinker: + c.getSymbolInfo(ctx, tt.binaryDecorator, info) + c.getSymbolInfo(ctx, &tt.prebuiltLinker, info) + case *vndkPrebuiltLibraryDecorator: + info.Uninstallable = true + case *kernelHeadersDecorator: + c.getSymbolInfo(ctx, tt.libraryDecorator, info) + } + return info +} + +func (c *Module) baseSymbolInfo(ctx android.ModuleContext) *SymbolInfo { + return &SymbolInfo{ + Name: c.BaseModuleName() + c.SubName(), + ModuleDir: ctx.ModuleDir(), + Uninstallable: c.IsSkipInstall() || !proptools.BoolDefault(c.Properties.Installable, true) || c.NoFullInstall(), + } +} + +func (c *Module) collectSymbolsInfo(ctx android.ModuleContext) { + if !c.hideApexVariantFromMake && !c.Properties.HideFromMake { + infos := &SymbolInfos{} + for _, feature := range c.features { + infos.AppendSymbols(c.getSymbolInfo(ctx, feature, c.baseSymbolInfo(ctx))) + } + infos.AppendSymbols(c.getSymbolInfo(ctx, c.compiler, c.baseSymbolInfo(ctx))) + infos.AppendSymbols(c.getSymbolInfo(ctx, c.linker, c.baseSymbolInfo(ctx))) + if c.sanitize != nil { + infos.AppendSymbols(c.getSymbolInfo(ctx, c.sanitize, c.baseSymbolInfo(ctx))) + } + infos.AppendSymbols(c.getSymbolInfo(ctx, c.installer, c.baseSymbolInfo(ctx))) + } +} + // Returns true if a stub library could be installed in multiple apexes func (c *Module) stubLibraryMultipleApexViolation(ctx android.ModuleContext) bool { // If this is not an apex variant, no check necessary @@ -2436,6 +2550,10 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { if c.makeVarsInfo != nil { android.SetProvider(ctx, CcMakeVarsInfoProvider, c.makeVarsInfo) } + + if !c.hideApexVariantFromMake && !c.Properties.HideFromMake { + c.collectSymbolsInfo(ctx) + } } func (c *Module) CleanupAfterBuildActions() { -- cgit v1.2.3 From 2310d5430b95bf5a63be1ec8817caf1294cfd827 Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Wed, 19 Mar 2025 21:08:54 +0000 Subject: Collect symbols info of rust modules symbols info are informations needed to copy the symbols files to the correct location within $PRODUCT_OUT/symbols directory. This change adds the logic to collect these information for rust modules. Note that the actual copying of the symbols files will be done in a follow up change. Test: CI Bug: 395989947 Change-Id: Ib3e50aad456320080b94e8b87a40230101fa870d --- rust/rust.go | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/rust/rust.go b/rust/rust.go index 54b5d92e3..5941530a6 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -16,6 +16,7 @@ package rust import ( "fmt" + "path/filepath" "strconv" "strings" @@ -1228,6 +1229,73 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { if mod.compiler != nil { mod.compiler.moduleInfoJSON(ctx, moduleInfoJSON) } + + mod.setSymbolsInfoProvider(ctx) +} + +func (mod *Module) baseSymbolInfo(ctx android.ModuleContext) *cc.SymbolInfo { + return &cc.SymbolInfo{ + Name: mod.BaseModuleName() + mod.Properties.SubName, + ModuleDir: ctx.ModuleDir(), + Uninstallable: mod.IsSkipInstall() || !proptools.BoolDefault(mod.Properties.Installable, true) || mod.NoFullInstall(), + } +} + +func (mod *Module) getSymbolInfo(ctx android.ModuleContext, t any, info *cc.SymbolInfo) *cc.SymbolInfo { + switch tt := t.(type) { + case *binaryDecorator: + mod.getSymbolInfo(ctx, tt.baseCompiler, info) + case *testDecorator: + mod.getSymbolInfo(ctx, tt.binaryDecorator, info) + case *benchmarkDecorator: + mod.getSymbolInfo(ctx, tt.binaryDecorator, info) + case *libraryDecorator: + mod.getSymbolInfo(ctx, tt.baseCompiler, info) + case *procMacroDecorator: + mod.getSymbolInfo(ctx, tt.baseCompiler, info) + case *BaseSourceProvider: + outFile := tt.OutputFiles[0] + _, file := filepath.Split(outFile.String()) + stem, suffix, _ := android.SplitFileExt(file) + info.Suffix = suffix + info.Stem = stem + info.Uninstallable = true + case *bindgenDecorator: + mod.getSymbolInfo(ctx, tt.BaseSourceProvider, info) + case *protobufDecorator: + mod.getSymbolInfo(ctx, tt.BaseSourceProvider, info) + case *baseCompiler: + if tt.path != (android.InstallPath{}) { + info.UnstrippedBinaryPath = tt.unstrippedOutputFile + path, file := filepath.Split(tt.path.String()) + stem, suffix, _ := android.SplitFileExt(file) + info.Suffix = suffix + info.ModuleDir = path + info.Stem = stem + } + case *fuzzDecorator: + mod.getSymbolInfo(ctx, tt.binaryDecorator, info) + case *prebuiltLibraryDecorator: + mod.getSymbolInfo(ctx, tt.baseCompiler, info) + case *toolchainLibraryDecorator: + mod.getSymbolInfo(ctx, tt.baseCompiler, info) + } + return info +} + +func (mod *Module) setSymbolsInfoProvider(ctx android.ModuleContext) { + if !mod.Properties.HideFromMake && !mod.hideApexVariantFromMake { + infos := &cc.SymbolInfos{} + if mod.compiler != nil && !mod.compiler.Disabled() { + infos.AppendSymbols(mod.getSymbolInfo(ctx, mod.compiler, mod.baseSymbolInfo(ctx))) + } else if mod.sourceProvider != nil { + infos.AppendSymbols(mod.getSymbolInfo(ctx, mod.sourceProvider, mod.baseSymbolInfo(ctx))) + } + + if mod.sanitize != nil { + infos.AppendSymbols(mod.getSymbolInfo(ctx, mod.sanitize, mod.baseSymbolInfo(ctx))) + } + } } func (mod *Module) setOutputFiles(ctx ModuleContext) { -- cgit v1.2.3 From 6fd2aeab8940b4a4b0189e66c57ec2d1d8e25130 Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Wed, 19 Mar 2025 21:15:08 +0000 Subject: Collect symbols info of jni libs of java modules symbols info are informations needed to copy the symbols files to the correct location within $PRODUCT_OUT/symbols directory. This change adds the logic to collect these information for the jni libs of java modules. Note that the actual copying of the symbols files will be done in a follow up change. Test: CI Bug: 395989947 Change-Id: I23d7006e2c6b18f1193bb601ab102e5c514781a5 --- java/app.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/java/app.go b/java/app.go index 05b4a9664..3a3253f04 100644 --- a/java/app.go +++ b/java/app.go @@ -432,6 +432,27 @@ func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleCon }) } +func (a *AndroidApp) baseSymbolInfo(ctx android.ModuleContext) *cc.SymbolInfo { + return &cc.SymbolInfo{ + Name: a.BaseModuleName(), + ModuleDir: ctx.ModuleDir(), + Uninstallable: a.IsSkipInstall() || !proptools.BoolDefault(a.properties.Installable, true) || a.NoFullInstall(), + } +} + +func (a *AndroidApp) GetJniSymbolInfos(ctx android.ModuleContext, JniSymbolInstallPath android.Path) []*cc.SymbolInfo { + infos := []*cc.SymbolInfo{} + for _, install := range a.JNISymbolsInstalls(JniSymbolInstallPath.String()) { + info := a.baseSymbolInfo(ctx) + info.UnstrippedBinaryPath = install.From + info.ModuleDir = filepath.Dir(install.To) + info.InstalledStem = filepath.Base(install.To) + + infos = append(infos, info) + } + return infos +} + func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.checkAppSdkVersions(ctx) a.checkEmbedJnis(ctx) -- cgit v1.2.3 From 14b946e9950320e1dc75949b190953798b79655c Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Wed, 19 Mar 2025 21:19:55 +0000 Subject: Collect symbols info of apex bundled modules symbols info are informations needed to copy the symbols files to the correct location within $PRODUCT_OUT/symbols directory. This change adds the logic to collect these information for apex modules. Note that the actual copying of the symbols files will be done in a follow up change. Test: CI Bug: 395989947 Change-Id: I5444f7f648c323359e8ffb634a9e52db07e2410d --- apex/apex.go | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/apex/apex.go b/apex/apex.go index a726098c6..0db754268 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -2237,6 +2237,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { android.SetProvider(ctx, filesystem.ApexKeyPathInfoProvider, filesystem.ApexKeyPathInfo{a.apexKeysPath}) android.SetProvider(ctx, java.AppInfosProvider, a.appInfos) + a.setSymbolInfosProvider(ctx) } // Set prebuiltInfoProvider. This will be used by `apex_prebuiltinfo_singleton` to print out a metadata file @@ -2903,3 +2904,42 @@ func (a *apexBundle) enforceNoVintfInUpdatable(ctx android.ModuleContext) { } } } + +func (a *apexBundle) setSymbolInfosProvider(ctx android.ModuleContext) { + if !a.properties.HideFromMake && a.installable() { + infos := &cc.SymbolInfos{} + for _, fi := range a.filesInfo { + linkToSystemLib := a.linkToSystemLib && fi.transitiveDep && fi.availableToPlatform() + if linkToSystemLib { + // No need to copy the file since it's linked to the system file + continue + } + moduleDir := android.PathForModuleInPartitionInstall(ctx, "apex", a.BaseModuleName(), fi.installDir) + info := &cc.SymbolInfo{ + Name: a.fullModuleName(a.BaseModuleName(), linkToSystemLib, &fi), + ModuleDir: moduleDir.String(), + Uninstallable: !a.installable(), + } + switch fi.class { + case nativeSharedLib, nativeExecutable, nativeTest: + info.Stem = fi.stem() + if ccMod, ok := fi.module.(*cc.Module); ok { + if ccMod.UnstrippedOutputFile() != nil { + info.UnstrippedBinaryPath = ccMod.UnstrippedOutputFile() + } + } else if rustMod, ok := fi.module.(*rust.Module); ok { + if rustMod.UnstrippedOutputFile() != nil { + info.UnstrippedBinaryPath = rustMod.UnstrippedOutputFile() + } + } + if info.UnstrippedBinaryPath != nil { + infos.AppendSymbols(info) + } + case app: + if app, ok := fi.module.(*java.AndroidApp); ok { + infos.AppendSymbols(app.GetJniSymbolInfos(ctx, moduleDir)...) + } + } + } + } +} -- cgit v1.2.3 From 82fcb3302db9ce988116fe627671b573c24fd4a9 Mon Sep 17 00:00:00 2001 From: Wei Li Date: Mon, 24 Mar 2025 14:02:51 -0700 Subject: Add compliance metadata for files generated in the packaging process Bug: 398039178 Test: presubmits Change-Id: I5177e0ac94e236a16890c42027edf9ef2c7dc720 --- android/compliance_metadata.go | 39 +++++++++++++++++++++++++++------------ filesystem/aconfig_files.go | 9 +++++++-- filesystem/android_device.go | 6 ++++++ filesystem/filesystem.go | 28 ++++++++++++++++++++-------- filesystem/system_image.go | 9 +++++++-- 5 files changed, 67 insertions(+), 24 deletions(-) diff --git a/android/compliance_metadata.go b/android/compliance_metadata.go index 16a385300..83f072166 100644 --- a/android/compliance_metadata.go +++ b/android/compliance_metadata.go @@ -129,30 +129,34 @@ var ( // dependencies, built/installed files, etc. It is a wrapper on a map[string]string with some utility // methods to get/set properties' values. type ComplianceMetadataInfo struct { - properties map[string]string - filesContained []string - prebuiltFilesCopied []string + properties map[string]string + filesContained []string + prebuiltFilesCopied []string + platformGeneratedFiles []string } type complianceMetadataInfoGob struct { - Properties map[string]string - FilesContained []string - PrebuiltFilesCopied []string + Properties map[string]string + FilesContained []string + PrebuiltFilesCopied []string + PlatformGeneratedFiles []string } func NewComplianceMetadataInfo() *ComplianceMetadataInfo { return &ComplianceMetadataInfo{ - properties: map[string]string{}, - filesContained: make([]string, 0), - prebuiltFilesCopied: make([]string, 0), + properties: map[string]string{}, + filesContained: make([]string, 0), + prebuiltFilesCopied: make([]string, 0), + platformGeneratedFiles: make([]string, 0), } } func (m *ComplianceMetadataInfo) ToGob() *complianceMetadataInfoGob { return &complianceMetadataInfoGob{ - Properties: m.properties, - FilesContained: m.filesContained, - PrebuiltFilesCopied: m.prebuiltFilesCopied, + Properties: m.properties, + FilesContained: m.filesContained, + PrebuiltFilesCopied: m.prebuiltFilesCopied, + PlatformGeneratedFiles: m.platformGeneratedFiles, } } @@ -160,6 +164,7 @@ func (m *ComplianceMetadataInfo) FromGob(data *complianceMetadataInfoGob) { m.properties = data.Properties m.filesContained = data.FilesContained m.prebuiltFilesCopied = data.PrebuiltFilesCopied + m.platformGeneratedFiles = data.PlatformGeneratedFiles } func (c *ComplianceMetadataInfo) GobEncode() ([]byte, error) { @@ -197,6 +202,14 @@ func (c *ComplianceMetadataInfo) GetPrebuiltFilesCopied() []string { return c.prebuiltFilesCopied } +func (c *ComplianceMetadataInfo) SetPlatformGeneratedFiles(files []string) { + c.platformGeneratedFiles = files +} + +func (c *ComplianceMetadataInfo) GetPlatformGeneratedFiles() []string { + return c.platformGeneratedFiles +} + func (c *ComplianceMetadataInfo) getStringValue(propertyName string) string { if !slices.Contains(COMPLIANCE_METADATA_PROPS, propertyName) { panic(fmt.Errorf("Unknown metadata property: %s.", propertyName)) @@ -368,6 +381,8 @@ func (c *complianceMetadataSingleton) GenerateBuildActions(ctx SingletonContext) if _, ok := prebuiltFilesSrcDest[file]; ok { srcDestPair := prebuiltFilesSrcDest[file] csvContent = append(csvContent, file+",,,,"+srcDestPair+",,,,,") + } else if slices.Contains(metadataInfo.platformGeneratedFiles, file) { + csvContent = append(csvContent, file+",,,,,,Y,,,build/soong/licenses/LICENSE") } else { csvContent = append(csvContent, file+",,Y,,,,,,,") } diff --git a/filesystem/aconfig_files.go b/filesystem/aconfig_files.go index 20a195313..66d883339 100644 --- a/filesystem/aconfig_files.go +++ b/filesystem/aconfig_files.go @@ -45,6 +45,7 @@ func (f *filesystem) buildAconfigFlagsFiles( specs map[string]android.PackagingSpec, dir android.OutputPath, fullInstallPaths *[]FullInstallPathInfo, + platformGeneratedFiles *[]string, ) { if !proptools.Bool(f.properties.Gen_aconfig_flags_pb) { return @@ -88,11 +89,13 @@ func (f *filesystem) buildAconfigFlagsFiles( installAconfigFlagsPath := installEtcDir.Join(ctx, "aconfig_flags.pb") builder.Command().Text("mkdir -p ").Text(installEtcDir.String()) builder.Command().Text("cp").Input(aconfigFlagsPb).Text(installAconfigFlagsPath.String()) + installPath := fullInstallPath.Join(ctx, "etc/aconfig_flags.pb") *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{ - FullInstallPath: fullInstallPath.Join(ctx, "etc/aconfig_flags.pb"), + FullInstallPath: installPath, SourcePath: aconfigFlagsPb, }) f.appendToEntry(ctx, installAconfigFlagsPath) + *platformGeneratedFiles = append(*platformGeneratedFiles, installPath.String()) // To enable fingerprint, we need to have v2 storage files. The default version is 1. storageFilesVersion := 1 @@ -118,11 +121,13 @@ func (f *filesystem) buildAconfigFlagsFiles( }) builder.Command(). Text("cp").Input(outPath).Text(installPath.String()) + fip := fullInstallPath.Join(ctx, "etc/aconfig", fileName) *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{ SourcePath: outPath, - FullInstallPath: fullInstallPath.Join(ctx, "etc/aconfig", fileName), + FullInstallPath: fip, }) f.appendToEntry(ctx, installPath) + *platformGeneratedFiles = append(*platformGeneratedFiles, fip.String()) } if ctx.Config().ReleaseCreateAconfigStorageFile() { diff --git a/filesystem/android_device.go b/filesystem/android_device.go index 9a085a628..65880d5c9 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -302,11 +302,13 @@ func buildComplianceMetadata(ctx android.ModuleContext, tags ...blueprint.Depend // Collect metadata from deps filesContained := make([]string, 0) prebuiltFilesCopied := make([]string, 0) + platformGeneratedFiles := make([]string, 0) for _, tag := range tags { ctx.VisitDirectDepsProxyWithTag(tag, func(m android.ModuleProxy) { if complianceMetadataInfo, ok := android.OtherModuleProvider(ctx, m, android.ComplianceMetadataProvider); ok { filesContained = append(filesContained, complianceMetadataInfo.GetFilesContained()...) prebuiltFilesCopied = append(prebuiltFilesCopied, complianceMetadataInfo.GetPrebuiltFilesCopied()...) + platformGeneratedFiles = append(platformGeneratedFiles, complianceMetadataInfo.GetPlatformGeneratedFiles()...) } }) } @@ -319,6 +321,10 @@ func buildComplianceMetadata(ctx android.ModuleContext, tags ...blueprint.Depend prebuiltFilesCopied = append(prebuiltFilesCopied, complianceMetadataInfo.GetPrebuiltFilesCopied()...) sort.Strings(prebuiltFilesCopied) complianceMetadataInfo.SetPrebuiltFilesCopied(prebuiltFilesCopied) + + platformGeneratedFiles = append(platformGeneratedFiles, complianceMetadataInfo.GetPlatformGeneratedFiles()...) + sort.Strings(platformGeneratedFiles) + complianceMetadataInfo.SetPlatformGeneratedFiles(platformGeneratedFiles) } // Returns a list of modules that are installed, which are collected from the dependency diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index fd1c784ec..b1b0c7d7e 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -104,7 +104,7 @@ type filesystem struct { } type filesystemBuilder interface { - BuildLinkerConfigFile(ctx android.ModuleContext, builder *android.RuleBuilder, rebasedDir android.OutputPath, fullInstallPaths *[]FullInstallPathInfo) + BuildLinkerConfigFile(ctx android.ModuleContext, builder *android.RuleBuilder, rebasedDir android.OutputPath, fullInstallPaths *[]FullInstallPathInfo, platformGeneratedFiles *[]string) // Function that filters PackagingSpec in PackagingBase.GatherPackagingSpecs() FilterPackagingSpec(spec android.PackagingSpec) bool // Function that modifies PackagingSpec in PackagingBase.GatherPackagingSpecs() to customize. @@ -632,12 +632,13 @@ func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) { }) } + platformGeneratedFiles := []string{} f.entries = f.copyPackagingSpecs(ctx, builder, specs, rootDir, rebasedDir) - f.buildNonDepsFiles(ctx, builder, rootDir, rebasedDir, &fullInstallPaths) + f.buildNonDepsFiles(ctx, builder, rootDir, rebasedDir, &fullInstallPaths, &platformGeneratedFiles) f.buildFsverityMetadataFiles(ctx, builder, specs, rootDir, rebasedDir, &fullInstallPaths) - f.buildEventLogtagsFile(ctx, builder, rebasedDir, &fullInstallPaths) - f.buildAconfigFlagsFiles(ctx, builder, specs, rebasedDir, &fullInstallPaths) - f.filesystemBuilder.BuildLinkerConfigFile(ctx, builder, rebasedDir, &fullInstallPaths) + f.buildEventLogtagsFile(ctx, builder, rebasedDir, &fullInstallPaths, &platformGeneratedFiles) + f.buildAconfigFlagsFiles(ctx, builder, specs, rebasedDir, &fullInstallPaths, &platformGeneratedFiles) + f.filesystemBuilder.BuildLinkerConfigFile(ctx, builder, rebasedDir, &fullInstallPaths, &platformGeneratedFiles) // Assemeble the staging dir and output a timestamp builder.Command().Text("touch").Output(f.fileystemStagingDirTimestamp(ctx)) builder.Build("assemble_filesystem_staging_dir", fmt.Sprintf("Assemble filesystem staging dir %s", f.BaseModuleName())) @@ -756,6 +757,7 @@ func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) { filesContained = append(filesContained, file.FullInstallPath.String()) } complianceMetadataInfo.SetFilesContained(filesContained) + complianceMetadataInfo.SetPlatformGeneratedFiles(platformGeneratedFiles) } func (f *filesystem) fileystemStagingDirTimestamp(ctx android.ModuleContext) android.WritablePath { @@ -894,6 +896,7 @@ func (f *filesystem) buildNonDepsFiles( rootDir android.OutputPath, rebasedDir android.OutputPath, fullInstallPaths *[]FullInstallPathInfo, + platformGeneratedFiles *[]string, ) { rebasedPrefix, err := filepath.Rel(rootDir.String(), rebasedDir.String()) if err != nil || strings.HasPrefix(rebasedPrefix, "../") { @@ -947,16 +950,19 @@ func (f *filesystem) buildNonDepsFiles( if !strings.HasPrefix(name, rebasedPrefix) { installPath = android.PathForModuleInPartitionInstall(ctx, "root", name) } + *platformGeneratedFiles = append(*platformGeneratedFiles, installPath.String()) *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{ FullInstallPath: installPath, SymlinkTarget: target, }) } else { if strings.HasPrefix(name, rebasedPrefix) { + installPath := android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), strings.TrimPrefix(name, rebasedPrefix)) *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{ - FullInstallPath: android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), strings.TrimPrefix(name, rebasedPrefix)), + FullInstallPath: installPath, SymlinkTarget: target, }) + *platformGeneratedFiles = append(*platformGeneratedFiles, installPath.String()) } } } @@ -1391,6 +1397,7 @@ func (f *filesystem) buildEventLogtagsFile( builder *android.RuleBuilder, rebasedDir android.OutputPath, fullInstallPaths *[]FullInstallPathInfo, + platformGeneratedFiles *[]string, ) { if !proptools.Bool(f.properties.Build_logtags) { return @@ -1401,12 +1408,14 @@ func (f *filesystem) buildEventLogtagsFile( builder.Command().Text("mkdir").Flag("-p").Text(etcPath.String()) builder.Command().Text("cp").Input(android.MergedLogtagsPath(ctx)).Text(eventLogtagsPath.String()) + installPath := android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), "etc", "event-log-tags") *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{ - FullInstallPath: android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), "etc", "event-log-tags"), + FullInstallPath: installPath, SourcePath: android.MergedLogtagsPath(ctx), }) f.appendToEntry(ctx, eventLogtagsPath) + *platformGeneratedFiles = append(*platformGeneratedFiles, installPath.String()) } func (f *filesystem) BuildLinkerConfigFile( @@ -1414,6 +1423,7 @@ func (f *filesystem) BuildLinkerConfigFile( builder *android.RuleBuilder, rebasedDir android.OutputPath, fullInstallPaths *[]FullInstallPathInfo, + platformGeneratedFiles *[]string, ) { if !proptools.Bool(f.properties.Linker_config.Gen_linker_config) { return @@ -1425,10 +1435,12 @@ func (f *filesystem) BuildLinkerConfigFile( output := rebasedDir.Join(ctx, "etc", "linker.config.pb") builder.Command().Text("cp").Input(intermediateOutput).Output(output) + installPath := android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), "etc", "linker.config.pb") *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{ - FullInstallPath: android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), "etc", "linker.config.pb"), + FullInstallPath: installPath, SourcePath: intermediateOutput, }) + *platformGeneratedFiles = append(*platformGeneratedFiles, installPath.String()) f.appendToEntry(ctx, output) } diff --git a/filesystem/system_image.go b/filesystem/system_image.go index cc9093f9b..166b052f8 100644 --- a/filesystem/system_image.go +++ b/filesystem/system_image.go @@ -49,6 +49,7 @@ func (s *systemImage) BuildLinkerConfigFile( builder *android.RuleBuilder, rebasedDir android.OutputPath, fullInstallPaths *[]FullInstallPathInfo, + platformGeneratedFiles *[]string, ) { if !proptools.Bool(s.filesystem.properties.Linker_config.Gen_linker_config) { return @@ -61,10 +62,12 @@ func (s *systemImage) BuildLinkerConfigFile( linkerconfig.BuildLinkerConfig(ctx, android.PathsForModuleSrc(ctx, s.filesystem.properties.Linker_config.Linker_config_srcs), provideModules, requireModules, intermediateOutput) builder.Command().Text("cp").Input(intermediateOutput).Output(output) + installPath := android.PathForModuleInPartitionInstall(ctx, s.PartitionType(), "etc", "linker.config.pb") *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{ - FullInstallPath: android.PathForModuleInPartitionInstall(ctx, s.PartitionType(), "etc", "linker.config.pb"), + FullInstallPath: installPath, SourcePath: intermediateOutput, }) + *platformGeneratedFiles = append(*platformGeneratedFiles, installPath.String()) } else { // TODO: This branch is the logic that make uses for the linker config file, which is // different than linkerconfig.BuildLinkerConfig used above. Keeping both branches for now @@ -98,10 +101,12 @@ func (s *systemImage) BuildLinkerConfigFile( // TODO: Make also supports adding an extra append command with PRODUCT_EXTRA_STUB_LIBRARIES, // but that variable appears to have no usages. + installPath := android.PathForModuleInPartitionInstall(ctx, s.PartitionType(), "etc", "linker.config.pb") *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{ - FullInstallPath: android.PathForModuleInPartitionInstall(ctx, s.PartitionType(), "etc", "linker.config.pb"), + FullInstallPath: installPath, SourcePath: output, }) + *platformGeneratedFiles = append(*platformGeneratedFiles, installPath.String()) } s.appendToEntry(ctx, output) -- cgit v1.2.3 From 59035117bd824bc38edbc6a49ea00b32edc0c716 Mon Sep 17 00:00:00 2001 From: Jonas Larsson Date: Mon, 24 Mar 2025 14:15:57 -0700 Subject: Add Android.mk allowlist for more partner branches Partner branches don't have vendor/google/build/ Bug: 406040050 Change-Id: Ib4b775c726abdd66523e69758be2850c613e6ac4 --- ui/build/androidmk_denylist.go | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/build/androidmk_denylist.go b/ui/build/androidmk_denylist.go index 4134cf5de..eda8ed74b 100644 --- a/ui/build/androidmk_denylist.go +++ b/ui/build/androidmk_denylist.go @@ -81,6 +81,7 @@ func blockAndroidMks(ctx Context, androidMks []string) { "vendor/google/build/androidmk/allowlist.txt", "device/google/clockwork/build/androidmk/allowlist.txt", "device/google/sdv/androidmk/allowlist.txt", + "device/google/harriet/androidmk/allowlist.txt", } for _, allowlist_file := range allowlist_files { allowlist := getAllLines(ctx, allowlist_file) -- cgit v1.2.3 From effb464e30da10acdeb9c65d3cfd4303a2430dd2 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Mon, 24 Mar 2025 18:03:30 -0700 Subject: Revert "Clear as much of cc.Module as possible after GenerateBuildActions" This reverts commit b790b9cb8f891bf21755ccc97a5405b2ed0687d2. Reason for revert: b/406023737 Change-Id: If8b6862d43bb3328045a7625471742420b540d69 --- android/module.go | 12 ------------ android/module_proxy.go | 4 ---- cc/cc.go | 21 --------------------- rust/fuzz_test.go | 25 +++++++++---------------- 4 files changed, 9 insertions(+), 53 deletions(-) diff --git a/android/module.go b/android/module.go index c0abfd0a3..ecd0f239c 100644 --- a/android/module.go +++ b/android/module.go @@ -45,14 +45,6 @@ type Module interface { // For more information, see Module.GenerateBuildActions within Blueprint's module_ctx.go GenerateAndroidBuildActions(ModuleContext) - // CleanupAfterBuildActions is called after ModuleBase.GenerateBuildActions is finished. - // If all interactions with this module are handled via providers instead of direct access - // to the module then it can free memory attached to the module. - // This is a temporary measure to reduce memory usage, eventually blueprint's reference - // to the Module should be dropped after GenerateAndroidBuildActions once all accesses - // can be done through providers. - CleanupAfterBuildActions() - // Add dependencies to the components of a module, i.e. modules that are created // by the module and which are considered to be part of the creating module. // @@ -2395,12 +2387,8 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) }) } } - - m.module.CleanupAfterBuildActions() } -func (m *ModuleBase) CleanupAfterBuildActions() {} - func SetJarJarPrefixHandler(handler func(ModuleContext)) { if jarJarPrefixHandler != nil { panic("jarJarPrefixHandler already set") diff --git a/android/module_proxy.go b/android/module_proxy.go index 81d90e9a0..561c4770c 100644 --- a/android/module_proxy.go +++ b/android/module_proxy.go @@ -27,10 +27,6 @@ func (m ModuleProxy) GenerateAndroidBuildActions(context ModuleContext) { panic("method is not implemented on ModuleProxy") } -func (m ModuleProxy) CleanupAfterBuildActions() { - panic("method is not implemented on ModuleProxy") -} - func (m ModuleProxy) ComponentDepsMutator(ctx BottomUpMutatorContext) { panic("method is not implemented on ModuleProxy") } diff --git a/cc/cc.go b/cc/cc.go index c616165c5..85d2ebfbb 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -2438,27 +2438,6 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { } } -func (c *Module) CleanupAfterBuildActions() { - // Clear as much of Module as possible to reduce memory usage. - c.generators = nil - c.compiler = nil - c.installer = nil - c.features = nil - c.coverage = nil - c.fuzzer = nil - c.sabi = nil - c.lto = nil - c.afdo = nil - c.orderfile = nil - - // TODO: these can be cleared after nativeBinaryInfoProperties and nativeLibInfoProperties are switched to - // using providers. - // c.linker = nil - // c.stl = nil - // c.sanitize = nil - // c.library = nil -} - func CreateCommonLinkableInfo(ctx android.ModuleContext, mod VersionedLinkableInterface) *LinkableInfo { info := &LinkableInfo{ StaticExecutable: mod.StaticExecutable(), diff --git a/rust/fuzz_test.go b/rust/fuzz_test.go index f462795aa..bdcfbbba1 100644 --- a/rust/fuzz_test.go +++ b/rust/fuzz_test.go @@ -134,24 +134,17 @@ func TestCCFuzzDepBundling(t *testing.T) { } `) - fuzz_shared_libtest := ctx.ModuleForTests(t, "fuzz_shared_libtest", "android_arm64_armv8-a_fuzzer").Module() - fuzz_static_libtest := ctx.ModuleForTests(t, "fuzz_static_libtest", "android_arm64_armv8-a_fuzzer").Module() - fuzz_staticffi_libtest := ctx.ModuleForTests(t, "fuzz_staticffi_libtest", "android_arm64_armv8-a_fuzzer").Module() + fuzz_shared_libtest := ctx.ModuleForTests(t, "fuzz_shared_libtest", "android_arm64_armv8-a_fuzzer").Module().(cc.LinkableInterface) + fuzz_static_libtest := ctx.ModuleForTests(t, "fuzz_static_libtest", "android_arm64_armv8-a_fuzzer").Module().(cc.LinkableInterface) + fuzz_staticffi_libtest := ctx.ModuleForTests(t, "fuzz_staticffi_libtest", "android_arm64_armv8-a_fuzzer").Module().(cc.LinkableInterface) - fuzzSharedLibraries := func(module android.Module) string { - if info, ok := android.OtherModuleProvider(ctx, module, cc.LinkableInfoProvider); ok { - return info.FuzzSharedLibraries.String() - } - return "" + if !strings.Contains(fuzz_shared_libtest.FuzzSharedLibraries().String(), ":libcc_transitive_dep.so") { + t.Errorf("cc_fuzz does not contain the expected bundled transitive shared libs from rust_ffi_shared ('libcc_transitive_dep'): %#v", fuzz_shared_libtest.FuzzSharedLibraries().String()) } - - if libs := fuzzSharedLibraries(fuzz_shared_libtest); !strings.Contains(libs, ":libcc_transitive_dep.so") { - t.Errorf("cc_fuzz does not contain the expected bundled transitive shared libs from rust_ffi_shared ('libcc_transitive_dep'): %#v", libs) - } - if libs := fuzzSharedLibraries(fuzz_static_libtest); !strings.Contains(libs, ":libcc_transitive_dep.so") { - t.Errorf("cc_fuzz does not contain the expected bundled transitive shared libs from rust_ffi_static ('libcc_transitive_dep'): %#v", libs) + if !strings.Contains(fuzz_static_libtest.FuzzSharedLibraries().String(), ":libcc_transitive_dep.so") { + t.Errorf("cc_fuzz does not contain the expected bundled transitive shared libs from rust_ffi_static ('libcc_transitive_dep'): %#v", fuzz_static_libtest.FuzzSharedLibraries().String()) } - if libs := fuzzSharedLibraries(fuzz_staticffi_libtest); !strings.Contains(libs, ":libcc_transitive_dep.so") { - t.Errorf("cc_fuzz does not contain the expected bundled transitive shared libs from rust_ffi_static ('libcc_transitive_dep'): %#v", libs) + if !strings.Contains(fuzz_staticffi_libtest.FuzzSharedLibraries().String(), ":libcc_transitive_dep.so") { + t.Errorf("cc_fuzz does not contain the expected bundled transitive shared libs from rust_ffi_static ('libcc_transitive_dep'): %#v", fuzz_staticffi_libtest.FuzzSharedLibraries().String()) } } -- cgit v1.2.3 From 8461cd8585572d50612087a1bac6839d8179eb7e Mon Sep 17 00:00:00 2001 From: kellyhung Date: Thu, 13 Mar 2025 01:54:55 +0000 Subject: Add a module type prebuilt_lib target output dirs: vendor_ramdisk/lib/* Bug: 396027199 Test: m drv2624.bin-ramdisk Flag: EXEMPT bugfix Change-Id: I5febd67cf95714a4749d732b13bee22004c23d2a --- android/neverallow.go | 1 + etc/prebuilt_etc.go | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/android/neverallow.go b/android/neverallow.go index 5c90501d7..b6f457c21 100644 --- a/android/neverallow.go +++ b/android/neverallow.go @@ -253,6 +253,7 @@ func createInstallInRootAllowingRules() []Rule { NotModuleType("prebuilt_first_stage_ramdisk"). NotModuleType("prebuilt_res"). NotModuleType("prebuilt_any"). + NotModuleType("prebuilt_lib"). Because("install_in_root is only for init_first_stage or librecovery_ui_ext."), } } diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go index 3b0c0329d..c465d1464 100644 --- a/etc/prebuilt_etc.go +++ b/etc/prebuilt_etc.go @@ -91,6 +91,7 @@ func RegisterPrebuiltEtcBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("prebuilt_system", PrebuiltSystemFactory) ctx.RegisterModuleType("prebuilt_first_stage_ramdisk", PrebuiltFirstStageRamdiskFactory) ctx.RegisterModuleType("prebuilt_any", PrebuiltAnyFactory) + ctx.RegisterModuleType("prebuilt_lib", PrebuiltLibFactory) ctx.RegisterModuleType("prebuilt_defaults", defaultsFactory) @@ -861,6 +862,20 @@ func PrebuiltFirmwareFactory() android.Module { return module } +// prebuilt_lib installs a prebuilt file to /lib directory for system +// image. +// If soc_specific property is set to true, the prebuilt file is installed to the +// vendor /lib directory for vendor image. +func PrebuiltLibFactory() android.Module { + module := &PrebuiltEtc{} + module.socInstallDirBase = "lib" + InitPrebuiltEtcModule(module, "lib") + // This module is device-only + android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) + android.InitDefaultableModule(module) + return module +} + // prebuilt_gpu is for a prebuilt artifact in /gpu directory. func PrebuiltGPUFactory() android.Module { module := &PrebuiltEtc{} -- cgit v1.2.3 From 892efc9b672ce47fa7f2d173d8dfa24b68bab56b Mon Sep 17 00:00:00 2001 From: Justin Yun Date: Tue, 25 Mar 2025 10:55:55 +0900 Subject: Remove PRODUCT_SHIPPING_VENDOR_API_LEVEL variable PRODUCT_SHIPPING_VENDOR_API_LEVEL was used to set ro.vendor.api_level manually. This was only for the testing and must not be used for the product release. To avoid this risk, remove this variable. Bug: 391726494 Test: m Change-Id: Ifeade8c4494536adaa02ace58d3d13e27fdc95e0 --- scripts/gen_build_prop.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/scripts/gen_build_prop.py b/scripts/gen_build_prop.py index a0d25465c..c7b52f8e8 100644 --- a/scripts/gen_build_prop.py +++ b/scripts/gen_build_prop.py @@ -428,9 +428,6 @@ def append_additional_vendor_props(args): if config["ShippingApiLevel"]: props.append(f"ro.product.first_api_level={config['ShippingApiLevel']}") - if config["ShippingVendorApiLevel"]: - props.append(f"ro.vendor.api_level={config['ShippingVendorApiLevel']}") - if config["BuildVariant"] != "user" and config["BuildDebugfsRestrictionsEnabled"]: props.append(f"ro.product.debugfs_restrictions.enabled=true") -- cgit v1.2.3 From 3c14a05cc13167fe4f38b92dbf6c04b66cb727bc Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Mon, 24 Mar 2025 17:24:44 -0700 Subject: Dist installed-files-system-other.txt in soong only build installed-files-system-other.{txt|json} are built in the system_other module, then disted in the android_device module like other partitions' installed-files-* artifacts. Test: m out/dist/installed-files-system-other.txt dist --soong-only Bug: 395162005 Change-Id: I443f7fbc59c51930c3a0ca7625f02f5d15b85e21 --- filesystem/system_other.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/filesystem/system_other.go b/filesystem/system_other.go index 32a6cc784..67e5f2fce 100644 --- a/filesystem/system_other.go +++ b/filesystem/system_other.go @@ -23,6 +23,7 @@ import ( "time" "github.com/google/blueprint" + "github.com/google/blueprint/depset" "github.com/google/blueprint/proptools" ) @@ -93,7 +94,7 @@ func (m *systemOtherImage) GenerateAndroidBuildActions(ctx android.ModuleContext } output := android.PathForModuleOut(ctx, "system_other.img") - stagingDir := android.PathForModuleOut(ctx, "staging_dir") + stagingDir := android.PathForModuleOut(ctx, "system_other") stagingDirTimestamp := android.PathForModuleOut(ctx, "staging_dir.timestamp") builder := android.NewRuleBuilder(pctx, ctx) @@ -183,6 +184,11 @@ func (m *systemOtherImage) GenerateAndroidBuildActions(ctx android.ModuleContext RootDir: stagingDir, FilesystemConfig: m.generateFilesystemConfig(ctx, stagingDir, stagingDirTimestamp), PropFileForMiscInfo: m.buildPropFileForMiscInfo(ctx), + InstalledFilesDepSet: depset.New( + depset.POSTORDER, + []InstalledFilesStruct{buildInstalledFiles(ctx, "system-other", stagingDir, output)}, + nil, + ), } android.SetProvider(ctx, FilesystemProvider, fsInfo) -- cgit v1.2.3 From e621c22e6cafd154d8146d63301e252e254474f2 Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Mon, 24 Mar 2025 17:55:01 -0700 Subject: Use rebased dir in installed-files.* generation ... instead of root dir, so that base_dir property is respected. This is especially important for installed-files.txt (i.e. for system partition), so that `system/system/` prefix is not shown in the generated artifact. Test: m out/dist/installed-files.txt dist --soong-only && inspect file content Bug: 395162005 Change-Id: Ifa0bf48d81b29922e75047a33cc7d1e5f0444245 --- filesystem/filesystem.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index c3c3835f6..7af5606e6 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -718,7 +718,7 @@ func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) { FullInstallPaths: fullInstallPaths, InstalledFilesDepSet: depset.New( depset.POSTORDER, - []InstalledFilesStruct{buildInstalledFiles(ctx, partitionNameForInstalledFiles, rootDir, f.output)}, + []InstalledFilesStruct{buildInstalledFiles(ctx, partitionNameForInstalledFiles, rebasedDir, f.output)}, includeFilesInstalledFiles(ctx), ), ErofsCompressHints: erofsCompressHints, -- cgit v1.2.3 From 9ad1336b0e912ced204f0b68b894b06a4dbeece6 Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Mon, 24 Mar 2025 18:04:45 -0700 Subject: Dist installed-files-root.txt in soong only build No separate root partition is currently generated in soong only build. The ones listed in `installed-files-root.txt` in soong+make build are the files listed in the intermediates path one level above of the rebased root dir (i.e. `system/system/..`) of the system partition filesystem module. This change proposes to generate the "root" intermediates path by copying the non-`system/system` intermediates to `root_for_installed_files/root` and generate the installed files list of "root" from there. Given that the installed files list of "root" partition can be retrieved from the system partition filesystem module, this change builds the `installed-files-root.{txt|json}` in the system filesystem module and include them in the `InstalledFilesDepSet`. Test: m out/dist/installed-files-root.txt dist --soong-only && inspect content Bug: 395162005 Change-Id: Ifd69e106d642dccd3bfe938cd4c3bdf23a362b27 --- filesystem/filesystem.go | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index 7af5606e6..0a8dedc2c 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -702,6 +702,29 @@ func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) { erofsCompressHints = android.PathForModuleSrc(ctx, *f.properties.Erofs.Compress_hints) } + installedFilesStructList := []InstalledFilesStruct{buildInstalledFiles(ctx, partitionNameForInstalledFiles, rebasedDir, f.output)} + if f.partitionName() == "system" { + rootDirForInstalledFiles := android.PathForModuleOut(ctx, "root_for_installed_files", "root") + copyToRootTimestamp := android.PathForModuleOut(ctx, "root_copy_timestamp") + + builder := android.NewRuleBuilder(pctx, ctx) + builder.Command().Text("touch").Text(copyToRootTimestamp.String()) + builder.Command().Text("rm -rf").Text(rootDirForInstalledFiles.String()) + builder.Command().Text("mkdir -p").Text(rootDirForInstalledFiles.String()) + builder.Command(). + Text("rsync"). + Flag("-a"). + Flag("--checksum"). + Flag("--exclude='system/'"). + Text(rootDir.String() + "/"). + Text(rootDirForInstalledFiles.String()). + Implicit(f.output). + ImplicitOutput(copyToRootTimestamp) + builder.Build("system_root_dir", "Construct system partition root dir") + + installedFilesStructList = append(installedFilesStructList, buildInstalledFiles(ctx, "root", rootDirForInstalledFiles, copyToRootTimestamp)) + } + fsInfo := FilesystemInfo{ Output: f.OutputPath(), SignedOutputPath: f.SignedOutputPath(), @@ -718,7 +741,7 @@ func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) { FullInstallPaths: fullInstallPaths, InstalledFilesDepSet: depset.New( depset.POSTORDER, - []InstalledFilesStruct{buildInstalledFiles(ctx, partitionNameForInstalledFiles, rebasedDir, f.output)}, + installedFilesStructList, includeFilesInstalledFiles(ctx), ), ErofsCompressHints: erofsCompressHints, -- cgit v1.2.3 From 61a176a497feebbb7a068a1ac211a3f4e245bfe9 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Wed, 26 Mar 2025 00:02:40 +0000 Subject: Fix fsgen's implicit override dep handling for prebuilts https://r.android.com/3317812 added support to fsgen to implicitly remove any overridden modules from the resolved deps of the autogenerated android_filesystem modules, but did not handle the prebuilt modules correctly. For prebuilts without sources, - fsGenState.fsDeps contains the module name without prebuilt_ prefix - fsGenState.moduleToInstallationProps contains the module name with prebuilt_ prefix This CL updates both of them to use mctx.ModuleName() for consistency. Test: m nothing --no-skip-soong-tests Change-Id: Ic575a929043bb102f9c506d529264d25c4fe24ab --- fsgen/filesystem_creator_test.go | 11 ++++++++++- fsgen/fsgen_mutators.go | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/fsgen/filesystem_creator_test.go b/fsgen/filesystem_creator_test.go index 2c4d3c817..06a8599d5 100644 --- a/fsgen/filesystem_creator_test.go +++ b/fsgen/filesystem_creator_test.go @@ -252,7 +252,7 @@ func TestRemoveOverriddenModulesFromDeps(t *testing.T) { `), }), android.FixtureModifyConfig(func(config android.Config) { - config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.ProductPackages = []string{"libfoo", "libbar"} + config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.ProductPackages = []string{"libfoo", "libbar", "prebuiltA", "prebuiltB"} }), ).RunTestWithBp(t, ` java_library { @@ -265,11 +265,20 @@ java_library { java_library { name: "libbaz", overrides: ["libfoo"], // overrides libfoo +} +java_import { + name: "prebuiltA", +} +java_import { + name: "prebuiltB", + overrides: ["prebuiltA"], // overrides prebuiltA } `) resolvedSystemDeps := result.TestContext.Config().Get(fsGenStateOnceKey).(*FsGenState).fsDeps["system"] _, libFooInDeps := (*resolvedSystemDeps)["libfoo"] android.AssertBoolEquals(t, "libfoo should not appear in deps because it has been overridden by libbaz. The latter is a required dep of libbar, which is listed in PRODUCT_PACKAGES", false, libFooInDeps) + _, prebuiltAInDeps := (*resolvedSystemDeps)["prebuiltA"] + android.AssertBoolEquals(t, "prebuiltA should not appear in deps because it has been overridden by prebuiltB. The latter is listed in PRODUCT_PACKAGES", false, prebuiltAInDeps) } func TestPrebuiltEtcModuleGen(t *testing.T) { diff --git a/fsgen/fsgen_mutators.go b/fsgen/fsgen_mutators.go index 4f3d2a750..bef37121a 100644 --- a/fsgen/fsgen_mutators.go +++ b/fsgen/fsgen_mutators.go @@ -248,7 +248,7 @@ func collectDepsMutator(mctx android.BottomUpMutatorContext) { // store the map of module to (required,overrides) even if the module is not in PRODUCT_PACKAGES. // the module might be installed transitively. if m.Enabled(mctx) && m.ExportedToMake() { - fsGenState.moduleToInstallationProps[m.Name()] = installationProperties{ + fsGenState.moduleToInstallationProps[mctx.ModuleName()] = installationProperties{ Required: m.RequiredModuleNames(mctx), Overrides: m.Overrides(), } -- cgit v1.2.3 From 288e5647b921bac966cda1393d7a078082c0842c Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Tue, 25 Mar 2025 18:30:22 +0000 Subject: Disallow cross partition overrides in android_device Make supports cross partition overrides, but this functionality will not be supported in Soong due to the technical complexities required in querying/providing this information to the filesystem dependencies. Add a check on `android_device` to prevent this unsupported behavior. Long term when we have `android_device` and `android_fileystem` modules checked into the tree, `android_filesystem_defaults` might be a good solution if a cross partition override is required. Bug: 375035189 Test: m nothing --no-skip-soong-tests Change-Id: Ibd2c32dffc4fed5a50fff233a3b86e87901d534c --- android/packaging.go | 4 +++ filesystem/Android.bp | 1 + filesystem/android_device.go | 31 ++++++++++++++++++++++ filesystem/android_device_test.go | 54 +++++++++++++++++++++++++++++++++++++++ filesystem/filesystem.go | 4 +++ filesystem/testing.go | 17 ++++++++++-- 6 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 filesystem/android_device_test.go diff --git a/android/packaging.go b/android/packaging.go index aae7806d7..f06e6fbd8 100644 --- a/android/packaging.go +++ b/android/packaging.go @@ -110,6 +110,10 @@ func (p *PackagingSpec) Prebuilt() bool { return p.prebuilt } +func (p *PackagingSpec) Overrides() uniquelist.UniqueList[string] { + return p.overrides +} + func (p *PackagingSpec) ToGob() *packagingSpecGob { return &packagingSpecGob{ RelPathInPackage: p.relPathInPackage, diff --git a/filesystem/Android.bp b/filesystem/Android.bp index cb76df2d9..2ddaed052 100644 --- a/filesystem/Android.bp +++ b/filesystem/Android.bp @@ -33,6 +33,7 @@ bootstrap_go_package { "testing.go", ], testSrcs: [ + "android_device_test.go", "filesystem_test.go", ], pluginFor: ["soong_build"], diff --git a/filesystem/android_device.go b/filesystem/android_device.go index bc002795a..fea75dc21 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -182,6 +182,8 @@ func (a *androidDevice) addDepsForTargetFilesMetadata(ctx android.BottomUpMutato } func (a *androidDevice) GenerateAndroidBuildActions(ctx android.ModuleContext) { + a.validateNoCrossPartitionOverrides(ctx) + if proptools.Bool(a.deviceProps.Main_device) { numMainAndroidDevices := ctx.Config().Once(numMainAndroidDevicesOnceKey, func() interface{} { return &atomic.Int32{} @@ -1189,3 +1191,32 @@ func (a *androidDevice) buildApkCertsInfo(ctx android.ModuleContext, allInstalle }) return apkCertsInfo } + +// Validate that a soong module in one `android_filesystem` dep cannot override a soong module +// in another `android_filesystem` dep of this device. +func (a *androidDevice) validateNoCrossPartitionOverrides(ctx android.ModuleContext) { + // Collect packaging specs of all partitions, keyed on the owning module + ownerToPackagingSpec := map[string]android.PackagingSpec{} + for _, fsInfo := range a.getFsInfos(ctx) { + for _, spec := range fsInfo.Specs { + ownerToPackagingSpec[spec.Owner()] = spec + } + } + + // Iterate over all packaging specs. For each spec, + // 1. If overrides is empty, no work to do. + // 2. If overrides is non-empty, and the partition of the overrides and overridden module are same, no error. + // 3. If overrides is non-empty, and the partition of the overrides and overridden module are different, error. + for owner, packagingSpec := range ownerToPackagingSpec { + for override := range packagingSpec.Overrides().Iter() { + overridePackagingSpec, ok := ownerToPackagingSpec[override] + if !ok { + // Ignore if the overridden module is not installed + continue + } + if packagingSpec.Partition() != overridePackagingSpec.Partition() { + ctx.ModuleErrorf("%s overrides %s, but they belong to separate android_filesystem. Please remove %s from %s", owner, override, override, overridePackagingSpec.Partition()) + } + } + } +} diff --git a/filesystem/android_device_test.go b/filesystem/android_device_test.go new file mode 100644 index 000000000..9f0b90d7d --- /dev/null +++ b/filesystem/android_device_test.go @@ -0,0 +1,54 @@ +// 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 filesystem + +import ( + "android/soong/android" + "testing" +) + +func TestCrossPartitionOverridesError(t *testing.T) { + fixture.ExtendWithErrorHandler( + android.FixtureExpectsOneErrorPattern("vendorlib_overrides_systemlib overrides systemlib, but they belong to separate android_filesystem."), + ).RunTestWithBp(t, ` + android_device { + name: "my_android_device", + system_partition_name: "systemimage", + vendor_partition_name: "vendorimage", + } + + android_filesystem { + name: "systemimage", + deps: ["systemlib"], + compile_multilib: "both", + } + android_filesystem { + name: "vendorimage", + partition_type: "vendor", + deps: ["vendorlib_overrides_systemlib"], + compile_multilib: "both", + } + + cc_binary { + name: "systemlib", + } + + cc_binary { + name: "vendorlib_overrides_systemlib", + vendor: true, + overrides: ["systemlib"], + } + `) +} diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index df60a8cf7..2ff2d9442 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -45,6 +45,7 @@ func init() { } func registerBuildComponents(ctx android.RegistrationContext) { + ctx.RegisterModuleType("android_device", AndroidDeviceFactory) ctx.RegisterModuleType("android_filesystem", FilesystemFactory) ctx.RegisterModuleType("android_filesystem_defaults", filesystemDefaultsFactory) ctx.RegisterModuleType("android_system_image", SystemImageFactory) @@ -439,6 +440,8 @@ type FilesystemInfo struct { BuildImagePropFile android.Path // Paths to all the tools referenced inside of the build image property file. BuildImagePropFileDeps android.Paths + // Packaging specs to be installed in this filesystem. + Specs map[string]android.PackagingSpec // Packaging specs to be installed on the system_other image, for the initial boot's dexpreopt. SpecsForSystemOther map[string]android.PackagingSpec @@ -715,6 +718,7 @@ func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) { ModuleName: ctx.ModuleName(), BuildImagePropFile: buildImagePropFile, BuildImagePropFileDeps: buildImagePropFileDeps, + Specs: specs, SpecsForSystemOther: f.systemOtherFiles(ctx), FullInstallPaths: fullInstallPaths, InstalledFilesDepSet: depset.New( diff --git a/filesystem/testing.go b/filesystem/testing.go index 631f1b1c8..bcbe8842e 100644 --- a/filesystem/testing.go +++ b/filesystem/testing.go @@ -14,6 +14,19 @@ package filesystem -import "android/soong/android" +import ( + "android/soong/android" + "android/soong/cc" +) -var PrepareForTestWithFilesystemBuildComponents = android.FixtureRegisterWithContext(registerBuildComponents) +var PrepareForTestWithFilesystemBuildComponents = android.GroupFixturePreparers( + android.FixtureRegisterWithContext(registerBuildComponents), + cc.PrepareForIntegrationTestWithCc, + android.FixtureAddTextFile("testdeps/Android.bp", + ` +cc_library_shared { + name: "liblz4", + host_supported: true, +} +`), +) -- cgit v1.2.3 From fe09b758536cca49b19868f5af6fd31e5287a11d Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Wed, 12 Mar 2025 18:36:46 -0700 Subject: Always install test files with soong We're converting some test suite zips to soong, and they package files from the /testcases folder. These files are currently installed by make (except in soong-only builds), so the soong-built test suites don't see them. Build them with soong instead. Bug: 388850000 Test: Presubmits Change-Id: I28c75cdc1e238797b5f36228b58761bf3d13beff --- android/arch_module_context.go | 18 ++- android/module.go | 198 +++++++++++++++++++++++++++++++-- android/module_context.go | 15 +++ android/test_suites.go | 76 +++++++++++++ android/variable.go | 7 ++ cc/binary.go | 4 - cc/cc.go | 4 - cc/library.go | 4 - cc/object.go | 4 - cc/test.go | 91 ++++++++------- java/app.go | 71 +++++++----- java/app_import.go | 14 ++- java/base.go | 5 +- java/fuzz.go | 27 ++++- java/java.go | 58 ++++++---- python/binary.go | 10 +- python/test.go | 32 +++--- rust/benchmark.go | 13 ++- rust/test.go | 38 ++----- sh/sh_binary.go | 15 ++- tradefed_modules/test_module_config.go | 17 ++- 21 files changed, 539 insertions(+), 182 deletions(-) diff --git a/android/arch_module_context.go b/android/arch_module_context.go index a3a03af02..7c440ad00 100644 --- a/android/arch_module_context.go +++ b/android/arch_module_context.go @@ -30,17 +30,19 @@ type ArchModuleContext interface { Darwin() bool Windows() bool PrimaryArch() bool + PrimaryNativeBridgeArch() bool } type archModuleContext struct { // TODO: these should eventually go through a (possibly cached) provider like any other configuration instead // of being special cased. - ready bool - os OsType - target Target - targetPrimary bool - multiTargets []Target - primaryArch bool + ready bool + os OsType + target Target + targetPrimary bool + multiTargets []Target + primaryArch bool + primaryNativeBridgeArch bool } // ArchReady returns true if the arch mutator has run on the module. Before this returns @@ -89,3 +91,7 @@ func (a *archModuleContext) Windows() bool { func (b *archModuleContext) PrimaryArch() bool { return b.primaryArch } + +func (b *archModuleContext) PrimaryNativeBridgeArch() bool { + return b.primaryNativeBridgeArch +} diff --git a/android/module.go b/android/module.go index 55f170cfe..593041aba 100644 --- a/android/module.go +++ b/android/module.go @@ -28,6 +28,7 @@ import ( "github.com/google/blueprint" "github.com/google/blueprint/depset" "github.com/google/blueprint/gobtools" + "github.com/google/blueprint/pathtools" "github.com/google/blueprint/proptools" ) @@ -1836,14 +1837,27 @@ func (m *ModuleBase) archModuleContextFactory(ctx archModuleContextFactoryContex } else { primaryArch = target.Arch.ArchType == config.Targets[target.Os][0].Arch.ArchType } + primaryNativeBridgeArch := false + if target.NativeBridge { + for _, t := range config.Targets[target.Os] { + if t.NativeBridge { + if target.Arch.ArchType == t.Arch.ArchType { + primaryNativeBridgeArch = true + } + // Don't consider further nativebridge targets + break + } + } + } return archModuleContext{ - ready: m.commonProperties.ArchReady, - os: m.commonProperties.CompileOS, - target: m.commonProperties.CompileTarget, - targetPrimary: m.commonProperties.CompilePrimary, - multiTargets: m.commonProperties.CompileMultiTargets, - primaryArch: primaryArch, + ready: m.commonProperties.ArchReady, + os: m.commonProperties.CompileOS, + target: m.commonProperties.CompileTarget, + targetPrimary: m.commonProperties.CompilePrimary, + multiTargets: m.commonProperties.CompileMultiTargets, + primaryArch: primaryArch, + primaryNativeBridgeArch: primaryNativeBridgeArch, } } @@ -2140,6 +2154,10 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) m.generateVariantTarget(ctx) + testData := FirstUniqueFunc(ctx.testData, func(a, b DataPath) bool { + return a == b + }) + installFiles.LicenseMetadataFile = ctx.licenseMetadataFile installFiles.InstallFiles = ctx.installFiles installFiles.CheckbuildFiles = ctx.checkbuildFiles @@ -2148,7 +2166,7 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) installFiles.PackagingSpecs = ctx.packagingSpecs installFiles.KatiInstalls = ctx.katiInstalls installFiles.KatiSymlinks = ctx.katiSymlinks - installFiles.TestData = ctx.testData + installFiles.TestData = testData } else if ctx.Config().AllowMissingDependencies() { // If the module is not enabled it will not create any build rules, nothing will call // ctx.GetMissingDependencies(), and blueprint will consider the missing dependencies to be unhandled @@ -2180,6 +2198,10 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) SetProvider(ctx, InstallFilesProvider, installFiles) buildLicenseMetadata(ctx, ctx.licenseMetadataFile) + if ctx.testSuiteInfoSet { + m.setupTestSuites(ctx, ctx.testSuiteInfo) + } + if len(ctx.moduleInfoJSON) > 0 { for _, moduleInfoJSON := range ctx.moduleInfoJSON { if moduleInfoJSON.Disabled { @@ -2397,6 +2419,168 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) } } +func (m *ModuleBase) CleanupAfterBuildActions() {} + +func (m *ModuleBase) setupTestSuites(ctx ModuleContext, info TestSuiteInfo) { + if shouldSkipAndroidMkProcessing(ctx, m) || m.IsSkipInstall() { + return + } + overriddenBy := "" + if b, ok := ctx.Module().(OverridableModule); ok { + overriddenBy = b.GetOverriddenBy() + } + + // M(C)TS supports a full test suite and partial per-module MTS test suites, with naming mts-${MODULE}. + // To reduce repetition, if we find a partial M(C)TS test suite without an full M(C)TS test suite, + // we add the full test suite to our list. + if PrefixInList(info.TestSuites, "mts-") && !InList("mts", info.TestSuites) { + info.TestSuites = append(info.TestSuites, "mts") + } + if PrefixInList(info.TestSuites, "mcts-") && !InList("mcts", info.TestSuites) { + info.TestSuites = append(info.TestSuites, "mcts") + } + + if len(info.TestSuites) == 0 { + info.TestSuites = []string{"null-suite"} + } + info.TestSuites = SortedUniqueStrings(info.TestSuites) + + name := ctx.ModuleName() + if overriddenBy != "" { + name = overriddenBy + } + name += info.NameSuffix + + type testSuiteInfo struct { + name string + dir WritablePath + includeModuleFolder bool + } + + suites := []testSuiteInfo{{ + dir: PathForModuleInPartitionInstall(ctx, "testcases", name), + includeModuleFolder: true, + }} + for _, suite := range info.TestSuites { + if suiteInfo, ok := ctx.Config().productVariables.CompatibilityTestcases[suite]; ok { + rel, err := filepath.Rel(ctx.Config().OutDir(), suiteInfo.OutDir) + if err != nil { + panic(fmt.Sprintf("Could not make COMPATIBILITY_TESTCASES_OUT_%s (%s) relative to the out dir (%s)", suite, suiteInfo.OutDir, ctx.Config().OutDir())) + } + if suiteInfo.IncludeModuleFolder || info.PerTestcaseDirectory { + rel = filepath.Join(rel, name) + } + suites = append(suites, testSuiteInfo{ + name: suite, + dir: PathForArbitraryOutput(ctx, rel), + includeModuleFolder: suiteInfo.IncludeModuleFolder || info.PerTestcaseDirectory, + }) + } + } + + var archDir string + if info.NeedsArchFolder { + archDir = ctx.Arch().ArchType.Name + if archDir == "common" { + archDir = ctx.DeviceConfig().DeviceArch() + } + if ctx.Target().NativeBridge { + archDir = ctx.Target().NativeBridgeHostArchName + } + } + + var installs []filePair + + for _, suite := range suites { + mainFileName := name + if info.MainFileStem != "" { + mainFileName = info.MainFileStem + } + mainFileName += info.MainFileExt + mainFileInstall := joinWriteablePath(ctx, suite.dir, archDir, mainFileName) + if !suite.includeModuleFolder { + mainFileInstall = joinWriteablePath(ctx, suite.dir, mainFileName) + } + if info.MainFile == nil { + panic("mainfile was nil") + } + + installs = append(installs, filePair{ + src: info.MainFile, + dst: mainFileInstall, + }) + + for _, data := range info.Data { + dataOut := joinWriteablePath(ctx, suite.dir, archDir, data.ToRelativeInstallPath()) + if !suite.includeModuleFolder { + dataOut = joinWriteablePath(ctx, suite.dir, data.ToRelativeInstallPath()) + } + installs = append(installs, filePair{ + src: data.SrcPath, + dst: dataOut, + }) + } + for _, data := range info.NonArchData { + dataOut := joinWriteablePath(ctx, suite.dir, data.ToRelativeInstallPath()) + installs = append(installs, filePair{ + src: data.SrcPath, + dst: dataOut, + }) + } + for _, data := range info.CompatibilitySupportFiles { + dataOut := joinWriteablePath(ctx, suite.dir, data.Rel()) + installs = append(installs, filePair{ + src: data, + dst: dataOut, + }) + } + + if ctx.TargetPrimary() || ctx.PrimaryNativeBridgeArch() { + if info.ConfigFile != nil { + installs = append(installs, filePair{ + src: info.ConfigFile, + dst: joinWriteablePath(ctx, suite.dir, name+".config"+info.ConfigFileSuffix), + }) + } else if config := ExistentPathForSource(ctx, ctx.ModuleDir(), "AndroidTest.xml"); config.Valid() { + installs = append(installs, filePair{ + src: config.Path(), + dst: joinWriteablePath(ctx, suite.dir, name+".config"), + }) + } + dynamicConfig := ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml") + if dynamicConfig.Valid() { + installs = append(installs, filePair{ + src: dynamicConfig.Path(), + dst: joinWriteablePath(ctx, suite.dir, name+".dynamic"), + }) + } + for _, extraTestConfig := range info.ExtraConfigs { + if extraTestConfig == nil { + panic("ExtraTestConfig was nil") + } + installs = append(installs, filePair{ + src: extraTestConfig, + dst: joinWriteablePath(ctx, suite.dir, pathtools.ReplaceExtension(extraTestConfig.Base(), "config")), + }) + } + } + } + + SetProvider(ctx, TestSuiteInfoProvider, info) + SetProvider(ctx, testSuiteInstallsInfoProvider, testSuiteInstallsInfo{installs}) +} + +func joinWriteablePath(ctx PathContext, path WritablePath, toJoin ...string) WritablePath { + switch p := path.(type) { + case InstallPath: + return p.Join(ctx, toJoin...) + case OutputPath: + return p.Join(ctx, toJoin...) + default: + panic("unhandled path type") + } +} + func SetJarJarPrefixHandler(handler func(ModuleContext)) { if jarJarPrefixHandler != nil { panic("jarJarPrefixHandler already set") diff --git a/android/module_context.go b/android/module_context.go index e30afd637..3542671ac 100644 --- a/android/module_context.go +++ b/android/module_context.go @@ -275,6 +275,10 @@ type ModuleContext interface { // directory on the build server with the given filename when any of the // specified goals are built. DistForGoalsWithFilename(goals []string, path Path, filename string) + + // Defines this module as a compatibility suite test and gives all the information needed + // to build the suite. + SetTestSuiteInfo(info TestSuiteInfo) } type moduleContext struct { @@ -334,6 +338,9 @@ type moduleContext struct { complianceMetadataInfo *ComplianceMetadataInfo dists []dist + + testSuiteInfo TestSuiteInfo + testSuiteInfoSet bool } var _ ModuleContext = &moduleContext{} @@ -1041,3 +1048,11 @@ func (c *moduleContext) DistForGoalsWithFilename(goals []string, path Path, file paths: distCopies{{from: path, dest: filename}}, }) } + +func (c *moduleContext) SetTestSuiteInfo(info TestSuiteInfo) { + if c.testSuiteInfoSet { + panic("Cannot call SetTestSuiteInfo twice") + } + c.testSuiteInfo = info + c.testSuiteInfoSet = true +} diff --git a/android/test_suites.go b/android/test_suites.go index dbcd48c79..88a410eb1 100644 --- a/android/test_suites.go +++ b/android/test_suites.go @@ -16,6 +16,8 @@ package android import ( "path/filepath" + "slices" + "sort" "strings" "github.com/google/blueprint" @@ -37,7 +39,34 @@ type TestSuiteModule interface { } type TestSuiteInfo struct { + // A suffix to append to the name of the test. + // Useful because historically different variants of soong modules became differently-named + // make modules, like "my_test.vendor" for the vendor variant. + NameSuffix string + TestSuites []string + + NeedsArchFolder bool + + MainFile Path + + MainFileStem string + + MainFileExt string + + ConfigFile Path + + ConfigFileSuffix string + + ExtraConfigs Paths + + PerTestcaseDirectory bool + + Data []DataPath + + NonArchData []DataPath + + CompatibilitySupportFiles []Path } var TestSuiteInfoProvider = blueprint.NewProvider[TestSuiteInfo]() @@ -48,8 +77,20 @@ type SupportFilesInfo struct { var SupportFilesInfoProvider = blueprint.NewProvider[SupportFilesInfo]() +type filePair struct { + src Path + dst WritablePath +} + +type testSuiteInstallsInfo struct { + Files []filePair +} + +var testSuiteInstallsInfoProvider = blueprint.NewProvider[testSuiteInstallsInfo]() + func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) { files := make(map[string]map[string]InstallPaths) + var toInstall []filePair ctx.VisitAllModuleProxies(func(m ModuleProxy) { if tsm, ok := OtherModuleProvider(ctx, m, TestSuiteInfoProvider); ok { @@ -62,7 +103,42 @@ func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) { OtherModuleProviderOrDefault(ctx, m, InstallFilesProvider).InstallFiles...) } } + if testSuiteInstalls, ok := OtherModuleProvider(ctx, m, testSuiteInstallsInfoProvider); ok { + installs := OtherModuleProviderOrDefault(ctx, m, InstallFilesProvider).InstallFiles + for _, f := range testSuiteInstalls.Files { + alreadyInstalled := false + for _, install := range installs { + if install.String() == f.dst.String() { + alreadyInstalled = true + break + } + } + if !alreadyInstalled { + toInstall = append(toInstall, f) + } + } + } + }) + + sort.Slice(toInstall, func(i, j int) bool { + c := strings.Compare(toInstall[i].src.String(), toInstall[j].src.String()) + if c < 0 { + return true + } else if c > 0 { + return false + } + return toInstall[i].dst.String() < toInstall[j].dst.String() }) + // Dedup, as multiple tests may install the same test data to the same folder + toInstall = slices.Compact(toInstall) + + for _, install := range toInstall { + ctx.Build(pctx, BuildParams{ + Rule: Cp, + Input: install.src, + Output: install.dst, + }) + } robolectricZip, robolectrictListZip := buildTestSuite(ctx, "robolectric-tests", files["robolectric-tests"]) ctx.Phony("robolectric-tests", robolectricZip, robolectrictListZip) diff --git a/android/variable.go b/android/variable.go index 5980efda4..8e6706182 100644 --- a/android/variable.go +++ b/android/variable.go @@ -550,6 +550,13 @@ type ProductVariables struct { UseSoongNoticeXML *bool `json:",omitempty"` StripByDefault *bool `json:",omitempty"` + + CompatibilityTestcases map[string]CompatibilityTestcaseJSON +} + +type CompatibilityTestcaseJSON struct { + OutDir string `json:",omitempty"` + IncludeModuleFolder bool `json:",omitempty"` } type PartitionQualifiedVariablesType struct { diff --git a/cc/binary.go b/cc/binary.go index 608251afc..627d5e560 100644 --- a/cc/binary.go +++ b/cc/binary.go @@ -551,10 +551,6 @@ func (binary *binaryDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON binary.baseLinker.moduleInfoJSON(ctx, moduleInfoJSON) } -func (binary *binaryDecorator) testSuiteInfo(ctx ModuleContext) { - // not a test -} - var _ overridable = (*binaryDecorator)(nil) func init() { diff --git a/cc/cc.go b/cc/cc.go index dc9b831f9..c50cb64a0 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -798,8 +798,6 @@ type linker interface { defaultDistFiles() []android.Path moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) - - testSuiteInfo(ctx ModuleContext) } // specifiedDeps is a tuple struct representing dependencies of a linked binary owned by the linker. @@ -2524,8 +2522,6 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { name := v.ImplementationModuleName(ctx.OtherModuleName(c)) ccInfo.LinkerInfo.ImplementationModuleName = &name } - - c.linker.testSuiteInfo(ctx) } if c.library != nil { ccInfo.LibraryInfo = &LibraryInfo{ diff --git a/cc/library.go b/cc/library.go index 5299771ca..b248224bd 100644 --- a/cc/library.go +++ b/cc/library.go @@ -1078,10 +1078,6 @@ func (library *libraryDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSO library.baseLinker.moduleInfoJSON(ctx, moduleInfoJSON) } -func (library *libraryDecorator) testSuiteInfo(ctx ModuleContext) { - // not a test -} - func (library *libraryDecorator) linkStatic(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path { diff --git a/cc/object.go b/cc/object.go index ea3ed6151..95a8beb52 100644 --- a/cc/object.go +++ b/cc/object.go @@ -250,7 +250,3 @@ func (object *objectLinker) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *an object.baseLinker.moduleInfoJSON(ctx, moduleInfoJSON) moduleInfoJSON.Class = []string{"STATIC_LIBRARIES"} } - -func (object *objectLinker) testSuiteInfo(ctx ModuleContext) { - // not a test -} diff --git a/cc/test.go b/cc/test.go index 9c276b81a..fed24671d 100644 --- a/cc/test.go +++ b/cc/test.go @@ -274,12 +274,6 @@ func (test *testDecorator) moduleInfoJSON(ctx android.ModuleContext, moduleInfoJ } } -func (test *testDecorator) testSuiteInfo(ctx ModuleContext) { - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: test.InstallerProperties.Test_suites, - }) -} - func NewTestInstaller() *baseInstaller { return NewBaseInstaller("nativetest", "nativetest64", InstallInData) } @@ -348,10 +342,6 @@ func (test *testBinary) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *androi } -func (test *testBinary) testSuiteInfo(ctx ModuleContext) { - test.testDecorator.testSuiteInfo(ctx) -} - func (test *testBinary) installerProps() []interface{} { return append(test.baseInstaller.installerProps(), test.testDecorator.installerProps()...) } @@ -422,32 +412,24 @@ func (test *testBinary) install(ctx ModuleContext, file android.Path) { test.Properties.Test_options.Unit_test = proptools.BoolPtr(true) } - if !ctx.Config().KatiEnabled() { // TODO(spandandas): Remove the special case for kati - // Install the test config in testcases/ directory for atest. - c, ok := ctx.Module().(*Module) - if !ok { - ctx.ModuleErrorf("Not a cc_test module") - } - // Install configs in the root of $PRODUCT_OUT/testcases/$module - testCases := android.PathForModuleInPartitionInstall(ctx, "testcases", ctx.ModuleName()+c.SubName()) - if ctx.PrimaryArch() { - 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) - } - } - // Install tests and data in arch specific subdir $PRODUCT_OUT/testcases/$module/$arch - testCases = testCases.Join(ctx, ctx.Target().Arch.ArchType.String()) - ctx.InstallTestData(testCases, test.data) - ctx.InstallFile(testCases, file.Base(), file) + // Install the test config in testcases/ directory for atest. + c, ok := ctx.Module().(*Module) + if !ok { + ctx.ModuleErrorf("Not a cc_test module") } + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + NameSuffix: c.SubName(), + TestSuites: test.InstallerProperties.Test_suites, + MainFile: file, + MainFileStem: file.Base(), + ConfigFile: test.testConfig, + ExtraConfigs: test.extraTestConfigs, + Data: test.data, + NeedsArchFolder: true, + PerTestcaseDirectory: Bool(test.Properties.Per_testcase_directory), + }) + test.binaryDecorator.baseInstaller.installTestData(ctx, test.data) test.binaryDecorator.baseInstaller.install(ctx, file) if Bool(test.Properties.Standalone_test) { @@ -588,8 +570,24 @@ func (test *testLibrary) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *andro test.testDecorator.moduleInfoJSON(ctx, moduleInfoJSON) } -func (test *testLibrary) testSuiteInfo(ctx ModuleContext) { - test.testDecorator.testSuiteInfo(ctx) +func (test *testLibrary) install(ctx ModuleContext, file android.Path) { + test.libraryDecorator.install(ctx, file) + + c, ok := ctx.Module().(*Module) + if !ok { + ctx.ModuleErrorf("Expected a cc module") + } + // host tests are not installed to testcases/ as per: + // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/base_rules.mk;l=251;drc=45efec6797cbf812df34dac9d05e43a9fe7217e0 + if test.shared() { + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + NameSuffix: c.SubName(), + TestSuites: test.InstallerProperties.Test_suites, + NeedsArchFolder: true, + MainFile: file, + MainFileStem: file.Base(), + }) + } } func (test *testLibrary) installerProps() []interface{} { @@ -684,6 +682,21 @@ func (benchmark *benchmarkDecorator) install(ctx ModuleContext, file android.Pat benchmark.binaryDecorator.baseInstaller.dir64 = filepath.Join("benchmarktest64", ctx.ModuleName()) benchmark.binaryDecorator.baseInstaller.installTestData(ctx, benchmark.data) benchmark.binaryDecorator.baseInstaller.install(ctx, file) + + c, ok := ctx.Module().(*Module) + if !ok { + ctx.ModuleErrorf("Not a cc module") + } + + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + NameSuffix: c.SubName(), + TestSuites: benchmark.Properties.Test_suites, + MainFile: file, + MainFileStem: file.Base(), + ConfigFile: benchmark.testConfig, + Data: benchmark.data, + NeedsArchFolder: true, + }) } func (benchmark *benchmarkDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) { @@ -709,12 +722,6 @@ func (benchmark *benchmarkDecorator) moduleInfoJSON(ctx ModuleContext, moduleInf } } -func (benchmark *benchmarkDecorator) testSuiteInfo(ctx ModuleContext) { - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: benchmark.Properties.Test_suites, - }) -} - func NewBenchmark(hod android.HostOrDeviceSupported) *Module { module, binary := newBinary(hod) module.multilib = android.MultilibBoth diff --git a/java/app.go b/java/app.go index 3a3253f04..6c1e4f6a5 100644 --- a/java/app.go +++ b/java/app.go @@ -427,8 +427,22 @@ func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleCon moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") } - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: a.appTestHelperAppProperties.Test_suites, + outputFile := a.installedOutputFile + if outputFile == nil { + outputFile = a.outputFile + } + var data []android.DataPath + for _, d := range a.extraOutputFiles { + data = append(data, android.DataPath{SrcPath: d}) + } + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: a.appTestHelperAppProperties.Test_suites, + MainFile: outputFile, + MainFileStem: a.installApkName, + MainFileExt: ".apk", + NeedsArchFolder: true, + NonArchData: data, + PerTestcaseDirectory: proptools.Bool(a.appTestHelperAppProperties.Per_testcase_directory), }) } @@ -980,10 +994,10 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { if ctx.ModuleName() == "framework-res" { // framework-res.apk is installed as system/framework/framework-res.apk a.installDir = android.PathForModuleInstall(ctx, "framework") - } else if a.Privileged() { - a.installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName) } else if ctx.InstallInTestcases() { a.installDir = android.PathForModuleInstall(ctx, a.installApkName, ctx.DeviceConfig().DeviceArch()) + } else if a.Privileged() { + a.installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName) } else { a.installDir = android.PathForModuleInstall(ctx, "app", a.installApkName) } @@ -1130,7 +1144,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { } } } - ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...) + a.installedOutputFile = ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...) } ctx.CheckbuildFile(a.outputFile) @@ -1679,22 +1693,33 @@ func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { 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() { - pathInTestCases := android.PathForModuleInstall(ctx, ctx.Module().Name()) - 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} - ctx.InstallTestData(pathInTestCases, []android.DataPath{dataPath}) - } - } + a.data = android.SortedUniquePaths(a.data) + a.extraTestConfigs = android.SortedUniquePaths(a.extraTestConfigs) + + testOutputFile := a.installedOutputFile + if testOutputFile == nil { + testOutputFile = a.outputFile + } + var testData []android.DataPath + for _, data := range a.data { + dataPath := android.DataPath{SrcPath: data} + testData = append(testData, dataPath) + } + for _, d := range a.extraOutputFiles { + testData = append(testData, android.DataPath{SrcPath: d}) + } + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: a.testProperties.Test_suites, + MainFile: testOutputFile, + MainFileStem: a.installApkName, + MainFileExt: ".apk", + ConfigFile: a.testConfig, + ExtraConfigs: a.extraTestConfigs, + NonArchData: testData, + CompatibilitySupportFiles: a.data, + NeedsArchFolder: true, + PerTestcaseDirectory: proptools.Bool(a.testProperties.Per_testcase_directory), + }) android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{ TestcaseRelDataFiles: testcaseRel(a.data), @@ -1729,10 +1754,6 @@ func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { moduleInfoJSON.AutoTestConfig = []string{"true"} } moduleInfoJSON.TestMainlineModules = append(moduleInfoJSON.TestMainlineModules, a.testProperties.Test_mainline_modules...) - - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: a.testProperties.Test_suites, - }) } func testcaseRel(paths android.Paths) []string { diff --git a/java/app_import.go b/java/app_import.go index 9fb13ba3c..837ab529b 100644 --- a/java/app_import.go +++ b/java/app_import.go @@ -788,8 +788,18 @@ func (a *AndroidTestImport) GenerateAndroidBuildActions(ctx android.ModuleContex a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data) - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: a.testProperties.Test_suites, + var data []android.DataPath + for _, d := range a.data { + data = append(data, android.DataPath{SrcPath: d}) + } + + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: a.testProperties.Test_suites, + MainFile: a.outputFile, + MainFileStem: a.outputFile.Base(), + NeedsArchFolder: true, + Data: data, + CompatibilitySupportFiles: a.data, }) } diff --git a/java/base.go b/java/base.go index 8aa0109d0..86d6b30ac 100644 --- a/java/base.go +++ b/java/base.go @@ -508,8 +508,9 @@ type Module struct { jacocoReportClassesFile android.Path // output file of the module, which may be a classes jar or a dex jar - outputFile android.Path - extraOutputFiles android.Paths + outputFile android.Path + installedOutputFile android.Path + extraOutputFiles android.Paths exportAidlIncludeDirs android.Paths ignoredAidlPermissionList android.Paths diff --git a/java/fuzz.go b/java/fuzz.go index 0e239f0ec..7271b9737 100644 --- a/java/fuzz.go +++ b/java/fuzz.go @@ -131,7 +131,32 @@ func (j *JavaFuzzTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { } - j.Test.GenerateAndroidBuildActions(ctx) + checkMinSdkVersionMts(ctx, j.MinSdkVersion(ctx)) + j.Test.generateAndroidBuildActionsWithConfig(ctx, nil) + + var compatibilitySupportFiles android.Paths + compatibilitySupportFiles = append(compatibilitySupportFiles, j.implementationJarFile) + compatibilitySupportFiles = append(compatibilitySupportFiles, j.jniFilePaths...) + compatibilitySupportFiles = append(compatibilitySupportFiles, j.fuzzPackagedModule.Corpus...) + if j.fuzzPackagedModule.Dictionary != nil { + compatibilitySupportFiles = append(compatibilitySupportFiles, j.fuzzPackagedModule.Dictionary) + } + + outputFile := j.installedOutputFile + if outputFile == nil { + outputFile = j.outputFile + } + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: j.testProperties.Test_suites, + MainFile: outputFile, + MainFileStem: j.Stem(), + MainFileExt: ".jar", + ConfigFile: j.testConfig, + ExtraConfigs: j.extraTestConfigs, + NeedsArchFolder: ctx.Device(), + CompatibilitySupportFiles: compatibilitySupportFiles, + PerTestcaseDirectory: proptools.Bool(j.testProperties.Per_testcase_directory), + }) fuzz.SetFuzzPackagedModuleInfo(ctx, &j.fuzzPackagedModule) } diff --git a/java/java.go b/java/java.go index 07e38a17e..d7b4d1c22 100644 --- a/java/java.go +++ b/java/java.go @@ -1809,6 +1809,7 @@ func (j *TestHost) GenerateAndroidBuildActions(ctx android.ModuleContext) { } j.Test.generateAndroidBuildActionsWithConfig(ctx, configs) + j.Test.javaTestSetTestsuiteInfo(ctx) android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{ TestcaseRelDataFiles: testcaseRel(j.data), OutputFile: j.outputFile, @@ -1831,6 +1832,7 @@ func (j *TestHost) GenerateAndroidBuildActions(ctx android.ModuleContext) { func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) { checkMinSdkVersionMts(ctx, j.MinSdkVersion(ctx)) j.generateAndroidBuildActionsWithConfig(ctx, nil) + j.javaTestSetTestsuiteInfo(ctx) } func (j *Test) generateAndroidBuildActionsWithConfig(ctx android.ModuleContext, configs []tradefed.Config) { @@ -1936,29 +1938,29 @@ func (j *Test) generateAndroidBuildActionsWithConfig(ctx android.ModuleContext, } } moduleInfoJSON.TestMainlineModules = append(moduleInfoJSON.TestMainlineModules, j.testProperties.Test_mainline_modules...) +} +func (j *Test) javaTestSetTestsuiteInfo(ctx android.ModuleContext) { // Install test deps - if !ctx.Config().KatiEnabled() { - pathInTestCases := android.PathForModuleInstall(ctx, "testcases", ctx.ModuleName()) - 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} - ctx.InstallTestData(pathInTestCases, []android.DataPath{dataPath}) - } - if j.outputFile != nil { - ctx.InstallFile(pathInTestCases, ctx.ModuleName()+".jar", j.outputFile) - } + outputFile := j.installedOutputFile + if outputFile == nil { + outputFile = j.outputFile } - - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: j.testProperties.Test_suites, + var testData []android.DataPath + for _, data := range j.data { + dataPath := android.DataPath{SrcPath: data} + testData = append(testData, dataPath) + } + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: j.testProperties.Test_suites, + MainFile: outputFile, + MainFileStem: j.Stem(), + MainFileExt: ".jar", + ConfigFile: j.testConfig, + ExtraConfigs: j.extraTestConfigs, + NeedsArchFolder: ctx.Device(), + NonArchData: testData, + PerTestcaseDirectory: proptools.Bool(j.testProperties.Per_testcase_directory), }) } @@ -1973,12 +1975,24 @@ func (j *TestHelperLibrary) GenerateAndroidBuildActions(ctx android.ModuleContex moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") } optionalConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "AndroidTest.xml") + var config android.Path if optionalConfig.Valid() { + config = optionalConfig.Path() moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, optionalConfig.String()) } - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: j.testHelperLibraryProperties.Test_suites, + outputFile := j.installedOutputFile + if outputFile == nil { + outputFile = j.outputFile + } + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: j.testHelperLibraryProperties.Test_suites, + MainFile: outputFile, + MainFileStem: j.Stem(), + MainFileExt: ".jar", + ConfigFile: config, + NeedsArchFolder: ctx.Device(), + PerTestcaseDirectory: proptools.Bool(j.testHelperLibraryProperties.Per_testcase_directory), }) } diff --git a/python/binary.go b/python/binary.go index f894299f9..abcef73fb 100644 --- a/python/binary.go +++ b/python/binary.go @@ -115,6 +115,12 @@ func (p *PythonBinaryModule) GenerateAndroidBuildActions(ctx android.ModuleConte ctx.SetOutputFiles(android.Paths{p.installSource}, "") + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: p.binaryProperties.Test_suites, + MainFile: p.installSource, + MainFileStem: p.installSource.Base(), + }) + moduleInfoJSON := ctx.ModuleInfoJSON() moduleInfoJSON.Class = []string{"EXECUTABLES"} moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, p.androidMkSharedLibs...) @@ -165,10 +171,6 @@ func (p *PythonBinaryModule) buildBinary(ctx android.ModuleContext) { sharedLibs = append(sharedLibs, ctx.OtherModuleName(dep)) } p.androidMkSharedLibs = sharedLibs - - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: p.binaryProperties.Test_suites, - }) } func (p *PythonBinaryModule) AndroidMkEntries() []android.AndroidMkEntries { diff --git a/python/test.go b/python/test.go index df62ab794..d6670c3c4 100644 --- a/python/test.go +++ b/python/test.go @@ -215,25 +215,21 @@ func (p *PythonTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext installedData := ctx.InstallTestData(installDir, p.data) p.installedDest = ctx.InstallFile(installDir, p.installSource.Base(), p.installSource, installedData...) - // TODO: Remove the special case for kati - if !ctx.Config().KatiEnabled() { - // Install the test config in testcases/ directory for atest. - // Install configs in the root of $PRODUCT_OUT/testcases/$module - testCases := android.PathForModuleInPartitionInstall(ctx, "testcases", ctx.ModuleName()) - if ctx.PrimaryArch() { - 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()) - installedData := ctx.InstallTestData(testCases, p.data) - ctx.InstallFile(testCases, p.installSource.Base(), p.installSource, installedData...) + configFileSuffix := "" + // ATS 2.0 is the test harness for mobly tests and the test config is for ATS 2.0. + // Add "v2" suffix to test config name to distinguish it from the config for TF. + if proptools.String(p.testProperties.Test_options.Runner) == "mobly" { + configFileSuffix = "v2" } + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: p.binaryProperties.Test_suites, + MainFile: p.installSource, + MainFileStem: p.installSource.Base(), + ConfigFile: p.testConfig, + ConfigFileSuffix: configFileSuffix, + Data: p.data, + NeedsArchFolder: true, + }) moduleInfoJSON := ctx.ModuleInfoJSON() moduleInfoJSON.Class = []string{"NATIVE_TESTS"} diff --git a/rust/benchmark.go b/rust/benchmark.go index 3aa2f1779..85aa6a52e 100644 --- a/rust/benchmark.go +++ b/rust/benchmark.go @@ -129,6 +129,15 @@ func (benchmark *benchmarkDecorator) install(ctx ModuleContext) { } benchmark.binaryDecorator.install(ctx) + + mainFile := ctx.RustModule().OutputFile().Path() + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: benchmark.Properties.Test_suites, + MainFile: mainFile, + MainFileExt: mainFile.Ext(), + ConfigFile: benchmark.testConfig, + NeedsArchFolder: true, + }) } func (benchmark *benchmarkDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) { @@ -146,8 +155,4 @@ func (benchmark *benchmarkDecorator) moduleInfoJSON(ctx ModuleContext, moduleInf } else { moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") } - - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: benchmark.Properties.Test_suites, - }) } diff --git a/rust/test.go b/rust/test.go index cedced260..72eaaae81 100644 --- a/rust/test.go +++ b/rust/test.go @@ -204,29 +204,17 @@ func (test *testDecorator) install(ctx ModuleContext) { test.Properties.Test_options.Unit_test = proptools.BoolPtr(true) } - if !ctx.Config().KatiEnabled() { // TODO(spandandas): Remove the special case for kati - // Install the test config in testcases/ directory for atest. - r, ok := ctx.Module().(*Module) - if !ok { - ctx.ModuleErrorf("Not a rust test module") - } - // Install configs in the root of $PRODUCT_OUT/testcases/$module - testCases := android.PathForModuleInPartitionInstall(ctx, "testcases", ctx.ModuleName()+r.SubName()) - if ctx.PrimaryArch() { - 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()) - ctx.InstallTestData(testCases, test.data) - testPath := ctx.RustModule().OutputFile().Path() - ctx.InstallFile(testCases, testPath.Base(), testPath) - } + // Install the test config in testcases/ directory for atest. + mainFile := ctx.RustModule().OutputFile().Path() + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + NameSuffix: ctx.RustModule().SubName(), + TestSuites: test.Properties.Test_suites, + MainFile: mainFile, + MainFileStem: mainFile.Base(), + ConfigFile: test.testConfig, + Data: test.data, + NeedsArchFolder: true, + }) test.binaryDecorator.installTestData(ctx, test.data) test.binaryDecorator.install(ctx) @@ -320,10 +308,6 @@ func (test *testDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *and } else { moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") } - - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: test.Properties.Test_suites, - }) } func rustTestHostMultilib(ctx android.LoadHookContext) { diff --git a/sh/sh_binary.go b/sh/sh_binary.go index 57f5ad1c7..257d60936 100644 --- a/sh/sh_binary.go +++ b/sh/sh_binary.go @@ -540,6 +540,17 @@ func (s *ShTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { installedData := ctx.InstallTestData(s.installDir, s.data) s.installedFile = ctx.InstallExecutable(s.installDir, s.outputFilePath.Base(), s.outputFilePath, installedData...) + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: s.testProperties.Test_suites, + MainFile: s.outputFilePath, + MainFileStem: s.outputFilePath.Base(), + ConfigFile: s.testConfig, + ExtraConfigs: s.extraTestConfigs, + Data: s.data, + NeedsArchFolder: true, + PerTestcaseDirectory: proptools.Bool(s.testProperties.Per_testcase_directory), + }) + mkEntries := s.AndroidMkEntries()[0] android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{ TestcaseRelDataFiles: addArch(ctx.Arch().ArchType.String(), installedData.Paths()), @@ -574,10 +585,6 @@ func (s *ShTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, s.testConfig.String()) } moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, s.extraTestConfigs.Strings()...) - - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: s.testProperties.Test_suites, - }) } func addArch(archType string, paths android.Paths) []string { diff --git a/tradefed_modules/test_module_config.go b/tradefed_modules/test_module_config.go index e833df293..6b30a7a38 100644 --- a/tradefed_modules/test_module_config.go +++ b/tradefed_modules/test_module_config.go @@ -435,9 +435,22 @@ func (m *testModuleConfigModule) generateManifestAndConfig(ctx android.ModuleCon IsUnitTest: m.provider.IsUnitTest, }) - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: m.tradefedProperties.Test_suites, + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: m.tradefedProperties.Test_suites, + MainFile: baseApk, + MainFileExt: ".apk", + ConfigFile: m.testConfig, + NeedsArchFolder: ctx.Device(), }) + + // Install the UNUSED- file to match the UNUSED- stem specified in javaExtraEntries + if m.provider.MkAppClass == "APPS" { + installDir2 := android.PathForModuleInstall(ctx, ctx.ModuleName(), ctx.DeviceConfig().DeviceArch()) + ctx.InstallFile(installDir2, fmt.Sprintf("UNUSED-%s.apk", *m.Base), m.manifest) + } else if m.provider.MkAppClass == "JAVA_LIBRARIES" { + installDir2 := android.PathForModuleInstall(ctx, ctx.ModuleName()) + ctx.InstallFile(installDir2, fmt.Sprintf("UNUSED-%s.jar", *m.Base), m.manifest) + } } var _ android.AndroidMkEntriesProvider = (*testModuleConfigHostModule)(nil) -- cgit v1.2.3 From b03eb9a430ad389e259b1017fdfe5e8ff359c3c3 Mon Sep 17 00:00:00 2001 From: Bill Yang Date: Tue, 25 Mar 2025 05:55:31 +0000 Subject: Update test_packages for converting continuous_instrumentation_tests Introdue a new attribute for test_packages to add tests for the first supported arch variant if exist. Also update the test_packages dependencies package rule, always packed apps and frameworks if they are direct dependencies of the test_packages. Ignore-AOSP-First: Because the continuous_instrumentation_tests conversion is in internal branch currently. Bug: 399246722 Test: m dist continuous_instrumentation_tests Change-Id: I7b18d22ed26c5a9831846f3cbfa416779cc0fec5 --- ci_tests/ci_test_package_zip.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/ci_tests/ci_test_package_zip.go b/ci_tests/ci_test_package_zip.go index 4cadffddc..bee8e9d2f 100644 --- a/ci_tests/ci_test_package_zip.go +++ b/ci_tests/ci_test_package_zip.go @@ -56,6 +56,8 @@ type CITestPackageProperties struct { 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"` + // git-main only test modules. Will only be added as dependencies based on the first supported arch variant and the device os variant if exists. + Tests_if_exist_device_first proptools.Configurable[[]string] `android:"arch_variant"` } type testPackageZipDepTagType struct { @@ -96,6 +98,11 @@ func (p *testPackageZip) DepsMutator(ctx android.BottomUpMutatorContext) { ctx.AddVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), testPackageZipDepTag, t) } } + for _, t := range p.properties.Tests_if_exist_device_first.GetOrDefault(ctx, nil) { + if ctx.OtherModuleExists(t) { + ctx.AddVariationDependencies(ctx.Config().AndroidFirstDeviceTarget.Variations(), testPackageZipDepTag, t) + } + } p.addDeviceBothDeps(ctx, true) } @@ -234,8 +241,11 @@ func extendBuilderCommand(ctx android.ModuleContext, m android.Module, builder * } name := removeFileExtension(installedFile.Base()) // some apks have other apk as installed files, these additional files shouldn't be included + // But due to for override_android_test or override_android_app it will have OtherModuleName deps for the module + // it wants to override, to prevent it being ignored only skip this deps if it not the direct dependency of the + // test_packages. isAppOrFramework := class == "app" || class == "framework" - if isAppOrFramework && name != ctx.OtherModuleName(m) { + if ctx.OtherModuleDependencyTag(m) != testPackageZipDepTag && isAppOrFramework && name != ctx.OtherModuleName(m) { continue } -- cgit v1.2.3 From 496838f661caba64797f60ebd1b2f556cfc5f837 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Wed, 26 Mar 2025 17:31:35 +0000 Subject: Sort Soong built apkcerts.txt This reduces noise from bit-identical comparison on target_files.zip Bug: 406344416 Test: Make and Soong apkcerts.txt have the same shasum now Change-Id: I8fe0581d26aa759c324249cb08177464b3ce1de3 --- android/defs.go | 6 ++++++ filesystem/android_device.go | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/android/defs.go b/android/defs.go index 57fcc9b13..c4591b01c 100644 --- a/android/defs.go +++ b/android/defs.go @@ -126,6 +126,12 @@ var ( Description: "concatenate files to $out", }) + CatAndSort = pctx.AndroidStaticRule("CatAndSort", + blueprint.RuleParams{ + Command: "rm -f $out && cat $in > $out && sort -o $out $out", + Description: "concatenate sorted file contents to $out", + }) + // Used only when USE_GOMA=true is set, to restrict non-goma jobs to the local parallelism value localPool = blueprint.NewBuiltinPool("local_pool") diff --git a/filesystem/android_device.go b/filesystem/android_device.go index 4cabb2317..58aaaea4d 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -1188,7 +1188,7 @@ func (a *androidDevice) buildApkCertsInfo(ctx android.ModuleContext, allInstalle android.WriteFileRuleVerbatim(ctx, apkCertsInfoWithoutAppSets, strings.Join(apkCerts, "\n")+"\n") apkCertsInfo := android.PathForModuleOut(ctx, "apkcerts.txt") ctx.Build(pctx, android.BuildParams{ - Rule: android.Cat, + Rule: android.CatAndSort, Description: "combine apkcerts.txt", Output: apkCertsInfo, Inputs: append(apkCertsFiles, apkCertsInfoWithoutAppSets), -- cgit v1.2.3 From 0d7022ac6d70c1f1953d7958e9cb4b0522f7d153 Mon Sep 17 00:00:00 2001 From: "Liana Kazanova (xWF)" Date: Wed, 26 Mar 2025 10:46:59 -0700 Subject: Revert "Create a validation action to assert `apps` matches prebuilt apex" This reverts commit 544540a3a218924f230413c4b34580a548525e7a. Reason for revert: DroidMonitor: Potential culprit for http://b/406520783 - verifying through ABTD before revert submission. This is part of the standard investigation process, and does not mean your CL will be reverted. Change-Id: If7f6fdc3b7d8337faba26e12d59fa9b05a496570 --- apex/prebuilt.go | 65 +++++++++----------------------------------- filesystem/android_device.go | 8 ------ 2 files changed, 13 insertions(+), 60 deletions(-) diff --git a/apex/prebuilt.go b/apex/prebuilt.go index a1c866160..fdd9a75d7 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -48,16 +48,6 @@ var ( CommandDeps: []string{"${deapexer}"}, Description: "decompress $out", }) - // Compares the declared apps of `prebuilt_apex` with the actual apks - validateApkInPrebuiltApex = pctx.StaticRule("validateApkinPrebuiltApex", blueprint.RuleParams{ - Command: `rm -rf ${out} ${actualApks} &&` + - ` ${apex_ls} ${in} | grep apk$$ | awk -F '/' '{print $$NF}' | sort -u > ${actualApks} &&` + - ` cmp -s ${expectedApks} ${actualApks} && touch ${out}` + - ` || (echo "Found diffs between "apps" property of ${apexName} and actual contents of ${in}.` + - ` Please ensure that all apk-in-apexes are declared in 'apps' property." && exit 1)`, - CommandDeps: []string{"${apex_ls}"}, - Description: "validate apk in prebuilt_apex $out", - }, "expectedApks", "actualApks", "apexName") ) type prebuilt interface { @@ -721,38 +711,6 @@ func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) { android.SetProvider(ctx, filesystem.ApexKeyPathInfoProvider, filesystem.ApexKeyPathInfo{p.apexKeysPath}) } -// Creates a timestamp file that will be used to validate that there is no mismtach -// between apks declared via `apps` and the actual apks inside the apex. -func (p *Prebuilt) validateApkInPrebuiltApex(ctx android.ModuleContext, appInfos java.AppInfos) android.Path { - timestamp := android.PathForModuleOut(ctx, "apk_in_prebuilt_apex.timestamp") - // Create a list of expected installed apks. - var installedApks []string - for _, appInfo := range appInfos { - installedApks = append(installedApks, appInfo.InstallApkName+".apk") - } - expectedApksFile := android.PathForModuleOut(ctx, "expected_apk_in_prebuilt_apex.txt") - if len(installedApks) == 0 { - android.WriteFileRuleVerbatim(ctx, expectedApksFile, "") // Without newline - } else { - android.WriteFileRule(ctx, expectedApksFile, strings.Join(android.SortedUniqueStrings(installedApks), "\n")) // With newline - } - - actualApksFile := android.PathForModuleOut(ctx, "actual_apk_in_prebuilt_apex.txt") - ctx.Build(pctx, android.BuildParams{ - Rule: validateApkInPrebuiltApex, - Input: p.inputApex, - Output: timestamp, - Implicit: expectedApksFile, - ImplicitOutput: actualApksFile, - Args: map[string]string{ - "expectedApks": expectedApksFile.String(), - "actualApks": actualApksFile.String(), - "apexName": p.Name(), - }, - }) - return timestamp -} - // `addApkCertsInfo` sets a provider that will be used to create apkcerts.txt func (p *Prebuilt) addApkCertsInfo(ctx android.ModuleContext) { formatLine := func(cert java.Certificate, name, partition string) string { @@ -779,21 +737,24 @@ func (p *Prebuilt) addApkCertsInfo(ctx android.ModuleContext) { return appInfos[i].InstallApkName < appInfos[j].InstallApkName }) - // Create p.apkCertsFile with information about apk-in-apex - // p.apkCertsFile will become `LOCAL_APKCERTS_FILE` for Make packaging system - // p.apkCertsFile will be propagated to android_device for Soong packaging system + if len(appInfos) == 0 { + return + } + + // Set a provider for use by `android_device`. + // `android_device` will create an apkcerts.txt with the list of installed apps for that device. + android.SetProvider(ctx, java.AppInfosProvider, appInfos) + + // Set a Make variable for legacy apkcerts.txt creation + // p.apkCertsFile will become `LOCAL_APKCERTS_FILE` var lines []string for _, appInfo := range appInfos { lines = append(lines, formatLine(appInfo.Certificate, appInfo.InstallApkName+".apk", p.PartitionTag(ctx.DeviceConfig()))) } - p.apkCertsFile = android.PathForModuleOut(ctx, "apkcerts.txt") - var validations android.Paths - if p.IsInstallable() { - // Skip the validation for non-installable prebuilt apexes (e.g. used in CTS tests). - validations = append(validations, p.validateApkInPrebuiltApex(ctx, appInfos)) + if len(lines) > 0 { + p.apkCertsFile = android.PathForModuleOut(ctx, "apkcerts.txt") + android.WriteFileRule(ctx, p.apkCertsFile, strings.Join(lines, "\n")) } - android.WriteFileRuleVerbatim(ctx, p.apkCertsFile, strings.Join(lines, "\n"), validations...) - android.SetProvider(ctx, filesystem.ApkCertsInfoProvider, filesystem.ApkCertsInfo{p.apkCertsFile}) } func (p *Prebuilt) ProvenanceMetaDataFile() android.Path { diff --git a/filesystem/android_device.go b/filesystem/android_device.go index 4aaffd81f..b96c5eae3 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -1107,8 +1107,6 @@ func (a *androidDevice) buildApkCertsInfo(ctx android.ModuleContext, allInstalle } } else if info, ok := android.OtherModuleProvider(ctx, installedModule, java.RuntimeResourceOverlayInfoProvider); ok { apkCerts = append(apkCerts, formatLine(info.Certificate, info.OutputFile.Base(), partition)) - } else if info, ok := android.OtherModuleProvider(ctx, installedModule, ApkCertsInfoProvider); ok { - apkCertsFiles = append(apkCertsFiles, info.ApkCertsFile) } } slices.Sort(apkCerts) // sort by name @@ -1132,9 +1130,3 @@ func (a *androidDevice) buildApkCertsInfo(ctx android.ModuleContext, allInstalle }) return apkCertsInfo } - -type ApkCertsInfo struct { - ApkCertsFile android.Path -} - -var ApkCertsInfoProvider = blueprint.NewProvider[ApkCertsInfo]() -- cgit v1.2.3 From 311d7fa32c1f8f5aa86a7e01886bf7f02ff36844 Mon Sep 17 00:00:00 2001 From: LaMont Jones Date: Fri, 21 Mar 2025 12:19:27 -0700 Subject: Add java_library.header_jar_override This overrides header jar generation and simply uses the header jar from the named module instead. Bug: 396137333 Test: Manual, TH Ignore-AOSP-First: will CP later Flag: build.RELEASE_JAVA_HEADER_JAR_OVERRIDE Change-Id: Ie51807090fc1433dadfcecf138b884112e8193f4 --- android/config.go | 4 ++++ java/base.go | 26 ++++++++++++++++++++++++-- java/java.go | 5 +++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/android/config.go b/android/config.go index b92eb7ed9..1feda08a3 100644 --- a/android/config.go +++ b/android/config.go @@ -2299,6 +2299,10 @@ func (c *config) GetBuildFlag(name string) (string, bool) { return val, ok } +func (c *config) GetBuildFlagBool(name string) bool { + return c.productVariables.GetBuildFlagBool(name) +} + func (c *config) UseOptimizedResourceShrinkingByDefault() bool { return c.productVariables.GetBuildFlagBool("RELEASE_USE_OPTIMIZED_RESOURCE_SHRINKING_BY_DEFAULT") } diff --git a/java/base.go b/java/base.go index 8aa0109d0..a69733866 100644 --- a/java/base.go +++ b/java/base.go @@ -229,6 +229,11 @@ type CommonProperties struct { // If true, then only the headers are built and not the implementation jar. Headers_only *bool + // If specified, this is used for this library's header jar, rather than generating it. This + // should only be used if the library adds nothing new to the header jars vs the provided path. + // For example, this could be used if the module only adds implementation code. + Header_jar_override string `android:"path,arch_variant"` + // A list of files or dependencies to make available to the build sandbox. This is // useful if source files are symlinks, the targets of the symlinks must be listed here. // Note that currently not all actions implemented by android_apps are sandboxed, so you @@ -1301,6 +1306,9 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath return nil } j.headerJarFile = combinedHeaderJarFile + if deps.headerJarOverride.Valid() { + j.headerJarFile = deps.headerJarOverride.Path() + } if len(localHeaderJars) > 0 { ctx.CheckbuildFile(localHeaderJars...) @@ -1925,6 +1933,9 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath // Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource j.outputFile = outputFile.WithoutRel() + if deps.headerJarOverride.Valid() { + j.headerJarFile = deps.headerJarOverride.Path() + } return &JavaInfo{ HeaderJars: android.PathsIfNonNil(j.headerJarFile), RepackagedHeaderJars: android.PathsIfNonNil(repackagedHeaderJarFile), @@ -2075,7 +2086,9 @@ func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars deps deps, flags javaBuilderFlags, jarName string, extraJars android.Paths) (localHeaderJars android.Paths, combinedHeaderJar android.Path) { - if len(srcFiles) > 0 || len(srcJars) > 0 { + if deps.headerJarOverride.Valid() { + localHeaderJars = append(localHeaderJars, deps.headerJarOverride.Path()) + } else if len(srcFiles) > 0 || len(srcJars) > 0 { // Compile java sources into turbine.jar. turbineJar := android.PathForModuleOut(ctx, "turbine", jarName) TransformJavaToHeaderClasses(ctx, turbineJar, srcFiles, srcJars, flags) @@ -2089,9 +2102,10 @@ func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars depSet := depset.New(depset.PREORDER, localHeaderJars, deps.transitiveStaticLibsHeaderJars) jars := depSet.ToList() + var combinedHeaderJarOutputPath android.WritablePath // 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 - combinedHeaderJarOutputPath := android.PathForModuleOut(ctx, "turbine-combined", jarName) + combinedHeaderJarOutputPath = android.PathForModuleOut(ctx, "turbine-combined", jarName) TransformJarsToJar(ctx, combinedHeaderJarOutputPath, "for turbine", jars, android.OptionalPath{}, false, nil, []string{"META-INF/TRANSITIVE"}) @@ -2463,6 +2477,14 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars) + case headerJarOverrideTag: + if dep.HeaderJars == nil { + ctx.ModuleErrorf("%s does not provide header jars", otherName) + } else if len(dep.HeaderJars) > 1 { + ctx.ModuleErrorf("%s does not provides too many header jars", otherName) + } else { + deps.headerJarOverride = android.OptionalPathForPath(dep.HeaderJars[0]) + } case java9LibTag: deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars...) transitiveJava9ClasspathHeaderJars = append(transitiveJava9ClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars) diff --git a/java/java.go b/java/java.go index 07e38a17e..5593c9909 100644 --- a/java/java.go +++ b/java/java.go @@ -574,6 +574,7 @@ var ( kotlinPluginTag = dependencyTag{name: "kotlin-plugin", toolchain: true} proguardRaiseTag = dependencyTag{name: "proguard-raise"} certificateTag = dependencyTag{name: "certificate"} + headerJarOverrideTag = dependencyTag{name: "header-jar-override"} instrumentationForTag = dependencyTag{name: "instrumentation_for"} extraLintCheckTag = dependencyTag{name: "extra-lint-check", toolchain: true} jniLibTag = dependencyTag{name: "jnilib", runtimeLinked: true} @@ -717,6 +718,7 @@ type deps struct { aidlPreprocess android.OptionalPath kotlinPlugins android.Paths aconfigProtoFiles android.Paths + headerJarOverride android.OptionalPath disableTurbine bool @@ -1280,6 +1282,9 @@ func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) { j.usesLibrary.deps(ctx, false) j.deps(ctx) + if ctx.Config().GetBuildFlagBool("RELEASE_JAVA_HEADER_JAR_OVERRIDE") && j.properties.Header_jar_override != "" { + ctx.AddVariationDependencies(nil, headerJarOverrideTag, j.properties.Header_jar_override) + } if j.SdkLibraryName() != nil && strings.HasSuffix(j.Name(), ".impl") { if dexpreopt.IsDex2oatNeeded(ctx) { dexpreopt.RegisterToolDeps(ctx) -- cgit v1.2.3 From 370b79f02edc74a0c45f162fbe258453a36451f8 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Tue, 25 Mar 2025 16:09:57 -0700 Subject: Fix long GenerateBuildActions time in android_device FirstUniqueFunc was taking 10 seconds by calling Module.String() N^2 times. There's no need to convert to string to compare the modules, expose FirstUniqueInPlace and use that on the Module interfaces instead. Test: builds Change-Id: I037f8b6ea078634a8d7b4d34554f5a98ff418863 --- android/util.go | 20 ++++++++++---------- filesystem/android_device.go | 4 +--- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/android/util.go b/android/util.go index 4520f400e..197bbcacb 100644 --- a/android/util.go +++ b/android/util.go @@ -209,8 +209,8 @@ func PrettyConcat(list []string, quote bool, lastSep string) string { // that are in l1 but not l2, and l2 but not l1. func ListSetDifference[T comparable](l1, l2 []T) (bool, []T, []T) { listsDiffer := false - l1 = firstUnique(l1) - l2 = firstUnique(l2) + l1 = FirstUnique(l1) + l2 = FirstUnique(l2) diff1 := []T{} diff2 := []T{} m1 := setFromList(l1) @@ -379,21 +379,21 @@ outer: // FirstUniqueStrings returns all unique elements of a slice of strings, keeping the first copy of // each. It does not modify the input slice. func FirstUniqueStrings(list []string) []string { - return firstUnique(list) + return FirstUnique(list) } -// firstUnique returns all unique elements of a slice, keeping the first copy of each. It +// FirstUnique returns all unique elements of a slice, keeping the first copy of each. It // does not modify the input slice. -func firstUnique[T comparable](slice []T) []T { +func FirstUnique[T comparable](slice []T) []T { // Do not modify the input in-place, operate on a copy instead. slice = CopyOf(slice) - return firstUniqueInPlace(slice) + return FirstUniqueInPlace(slice) } -// firstUniqueInPlace returns all unique elements of a slice, keeping the first copy of +// FirstUniqueInPlace returns all unique elements of a slice, keeping the first copy of // each. It modifies the slice contents in place, and returns a subslice of the original // slice. -func firstUniqueInPlace[T comparable](slice []T) []T { +func FirstUniqueInPlace[T comparable](slice []T) []T { // 128 was chosen based on BenchmarkFirstUniqueStrings results. if len(slice) > 128 { return firstUniqueMap(slice) @@ -401,7 +401,7 @@ func firstUniqueInPlace[T comparable](slice []T) []T { return firstUniqueList(slice) } -// firstUniqueList is an implementation of firstUnique using an O(N^2) list comparison to look for +// firstUniqueList is an implementation of FirstUnique using an O(N^2) list comparison to look for // duplicates. func firstUniqueList[T any](in []T) []T { writeIndex := 0 @@ -422,7 +422,7 @@ outer: return in[0:writeIndex] } -// firstUniqueMap is an implementation of firstUnique using an O(N) hash set lookup to look for +// firstUniqueMap is an implementation of FirstUnique using an O(N) hash set lookup to look for // duplicates. func firstUniqueMap[T comparable](in []T) []T { writeIndex := 0 diff --git a/filesystem/android_device.go b/filesystem/android_device.go index 58aaaea4d..9b0159ddb 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -367,9 +367,7 @@ func (a *androidDevice) allInstalledModules(ctx android.ModuleContext) []android }) // Remove duplicates - ret = android.FirstUniqueFunc(ret, func(a, b android.Module) bool { - return a.String() == b.String() - }) + ret = android.FirstUniqueInPlace(ret) // Sort the modules by their names and variants slices.SortFunc(ret, func(a, b android.Module) int { -- cgit v1.2.3 From 57be51489ac3e2086b99850e9ffcb1dedaaed478 Mon Sep 17 00:00:00 2001 From: LaMont Jones Date: Wed, 26 Mar 2025 14:05:28 -0700 Subject: make find_input_delta's internal state more opaque As far as callers are concerned, the file name is the only visibility they have. Bug: b/376287012 Test: Manual, TH Ignore-AOSP-First: will CP later Change-Id: I7e50506c4551c15957f2a03e6a68cde1b5f779ec --- cmd/find_input_delta/find_input_delta/main.go | 22 +---------- .../find_input_delta_lib/internal_state.go | 46 +++++++++++++++++----- .../find_input_delta_lib/internal_state_test.go | 6 +-- 3 files changed, 41 insertions(+), 33 deletions(-) diff --git a/cmd/find_input_delta/find_input_delta/main.go b/cmd/find_input_delta/find_input_delta/main.go index 65ef88145..cbdcdae9d 100644 --- a/cmd/find_input_delta/find_input_delta/main.go +++ b/cmd/find_input_delta/find_input_delta/main.go @@ -70,31 +70,11 @@ func main() { inputs = append(inputs, fileSepRegex.FindAllString(string(data), -1)...) } - // Read the prior state - prior_state, err := fid_lib.LoadState(prior_state_file, fid_lib.OsFs) + file_list, err := fid_lib.GenerateFileList(target, prior_state_file, new_state_file, inputs, inspect, fid_lib.OsFs) if err != nil { panic(err) } - // Create the new state - new_state, err := fid_lib.CreateState(inputs, inspect, fid_lib.OsFs) - if err != nil { - panic(err) - } - if err = fid_lib.WriteState(new_state, new_state_file); err != nil { - panic(err) - } - - file_list := fid_lib.CompareInternalState(prior_state, new_state, target) - if err = file_list.Format(os.Stdout, template); err != nil { panic(err) } - - metrics_dir := os.Getenv("SOONG_METRICS_AGGREGATION_DIR") - out_dir := os.Getenv("OUT_DIR") - if metrics_dir != "" { - if err = file_list.WriteMetrics(metrics_dir, out_dir); err != nil { - panic(err) - } - } } diff --git a/cmd/find_input_delta/find_input_delta_lib/internal_state.go b/cmd/find_input_delta/find_input_delta_lib/internal_state.go index 0f88159be..cc7e17499 100644 --- a/cmd/find_input_delta/find_input_delta_lib/internal_state.go +++ b/cmd/find_input_delta/find_input_delta_lib/internal_state.go @@ -18,6 +18,7 @@ import ( "errors" "fmt" "io/fs" + "os" "regexp" "slices" @@ -29,7 +30,7 @@ import ( // Load the internal state from a file. // If the file does not exist, an empty state is returned. -func LoadState(filename string, fsys fs.ReadFileFS) (*fid_proto.PartialCompileInputs, error) { +func loadState(filename string, fsys fs.ReadFileFS) (*fid_proto.PartialCompileInputs, error) { var message = &fid_proto.PartialCompileInputs{} data, err := fsys.ReadFile(filename) if err != nil && !errors.Is(err, fs.ErrNotExist) { @@ -45,7 +46,7 @@ type StatReadFileFS interface { } // Create the internal state by examining the inputs. -func CreateState(inputs []string, inspect_contents bool, fsys StatReadFileFS) (*fid_proto.PartialCompileInputs, error) { +func createState(inputs []string, inspect_contents bool, fsys StatReadFileFS) (*fid_proto.PartialCompileInputs, error) { ret := &fid_proto.PartialCompileInputs{} slices.Sort(inputs) for _, input := range inputs { @@ -63,7 +64,7 @@ func CreateState(inputs []string, inspect_contents bool, fsys StatReadFileFS) (* } if inspect_contents { // NOTE: When we find it useful, we can parallelize the file inspection for speed. - contents, err := InspectFileContents(input) + contents, err := inspectFileContents(input) if err != nil { return ret, err } @@ -81,7 +82,7 @@ var InspectExtsZipRegexp = regexp.MustCompile("\\.(jar|apex|apk)[0-9]*$") // Inspect the file and extract the state of the elements in the archive. // If this is not an archive of some sort, nil is returned. -func InspectFileContents(name string) ([]*fid_proto.PartialCompileInput, error) { +func inspectFileContents(name string) ([]*fid_proto.PartialCompileInput, error) { if InspectExtsZipRegexp.Match([]byte(name)) { return inspectZipFileContents(name) } @@ -111,7 +112,7 @@ func inspectZipFileContents(name string) ([]*fid_proto.PartialCompileInput, erro return ret, nil } -func WriteState(s *fid_proto.PartialCompileInputs, path string) error { +func writeState(s *fid_proto.PartialCompileInputs, path string) error { data, err := proto.Marshal(s) if err != nil { return err @@ -119,11 +120,11 @@ func WriteState(s *fid_proto.PartialCompileInputs, path string) error { return pathtools.WriteFileIfChanged(path, data, 0644) } -func CompareInternalState(prior, other *fid_proto.PartialCompileInputs, target string) *FileList { - return CompareInputFiles(prior.GetInputFiles(), other.GetInputFiles(), target) +func compareInternalState(prior, other *fid_proto.PartialCompileInputs, target string) *FileList { + return compareInputFiles(prior.GetInputFiles(), other.GetInputFiles(), target) } -func CompareInputFiles(prior, other []*fid_proto.PartialCompileInput, name string) *FileList { +func compareInputFiles(prior, other []*fid_proto.PartialCompileInput, name string) *FileList { fl := FileListFactory(name) PriorMap := make(map[string]*fid_proto.PartialCompileInput, len(prior)) // We know that the lists are properly sorted, so we can simply compare them. @@ -139,7 +140,7 @@ func CompareInputFiles(prior, other []*fid_proto.PartialCompileInput, name strin fl.addFile(name) } else if !proto.Equal(PriorMap[name], v) { // Changed file - fl.changeFile(name, CompareInputFiles(PriorMap[name].GetContents(), v.GetContents(), name)) + fl.changeFile(name, compareInputFiles(PriorMap[name].GetContents(), v.GetContents(), name)) } } for _, v := range prior { @@ -151,3 +152,30 @@ func CompareInputFiles(prior, other []*fid_proto.PartialCompileInput, name strin } return fl } + +func GenerateFileList(target, prior_state_file, new_state_file string, inputs []string, inspect bool, fsys StatReadFileFS) (file_list *FileList, err error) { + // Read the prior state + prior_state, err := loadState(prior_state_file, fsys) + if err != nil { + return + } + // Create the new state + new_state, err := createState(inputs, inspect, fsys) + if err != nil { + return + } + if err = writeState(new_state, new_state_file); err != nil { + return + } + + file_list = compareInternalState(prior_state, new_state, target) + + metrics_dir := os.Getenv("SOONG_METRICS_AGGREGATION_DIR") + out_dir := os.Getenv("OUT_DIR") + if metrics_dir != "" { + if err = file_list.WriteMetrics(metrics_dir, out_dir); err != nil { + return + } + } + return +} diff --git a/cmd/find_input_delta/find_input_delta_lib/internal_state_test.go b/cmd/find_input_delta/find_input_delta_lib/internal_state_test.go index c168d5a6b..a729193aa 100644 --- a/cmd/find_input_delta/find_input_delta_lib/internal_state_test.go +++ b/cmd/find_input_delta/find_input_delta_lib/internal_state_test.go @@ -116,7 +116,7 @@ func TestLoadState(t *testing.T) { }, } for _, tc := range testCases { - actual, err := LoadState(tc.Filename, tc.Mapfs) + actual, err := loadState(tc.Filename, tc.Mapfs) if tc.Err == nil { android.AssertSame(t, tc.Name, tc.Err, err) } else if err == nil { @@ -164,7 +164,7 @@ func TestCreateState(t *testing.T) { }, } for _, tc := range testCases { - actual, err := CreateState(tc.Inputs, tc.Inspect, tc.Mapfs) + actual, err := createState(tc.Inputs, tc.Inspect, tc.Mapfs) if tc.Err == nil { android.AssertSame(t, tc.Name, tc.Err, err) } else if err == nil { @@ -253,7 +253,7 @@ func TestCompareInternalState(t *testing.T) { }, } for _, tc := range testCases { - actual := CompareInternalState(tc.Prior, tc.New, tc.Target) + actual := compareInternalState(tc.Prior, tc.New, tc.Target) if !tc.Expected.Equal(actual) { t.Errorf("%s: expected %v, actual %v", tc.Name, tc.Expected, actual) } -- cgit v1.2.3 From fa403882d5aa0fa3d4f7a77e4e52409357626938 Mon Sep 17 00:00:00 2001 From: "Priyanka Advani (xWF)" Date: Wed, 26 Mar 2025 17:35:36 -0700 Subject: Revert "Always install test files with soong" Revert submission 3540409-install_test_files_with_soong Reason for revert: Droidmonitor created revert due to b/406602299. Will be verifying through ABTD before submission. Reverted changes: /q/submissionid:3540409-install_test_files_with_soong Change-Id: I162ea2833640cf4cfa0afd6e6804851e869b7c40 --- android/arch_module_context.go | 18 +-- android/module.go | 198 ++------------------------------- android/module_context.go | 15 --- android/test_suites.go | 76 ------------- android/variable.go | 7 -- cc/binary.go | 4 + cc/cc.go | 4 + cc/library.go | 4 + cc/object.go | 4 + cc/test.go | 91 +++++++-------- java/app.go | 71 +++++------- java/app_import.go | 14 +-- java/base.go | 5 +- java/fuzz.go | 27 +---- java/java.go | 58 ++++------ python/binary.go | 10 +- python/test.go | 32 +++--- rust/benchmark.go | 13 +-- rust/test.go | 38 +++++-- sh/sh_binary.go | 15 +-- tradefed_modules/test_module_config.go | 17 +-- 21 files changed, 182 insertions(+), 539 deletions(-) diff --git a/android/arch_module_context.go b/android/arch_module_context.go index 7c440ad00..a3a03af02 100644 --- a/android/arch_module_context.go +++ b/android/arch_module_context.go @@ -30,19 +30,17 @@ type ArchModuleContext interface { Darwin() bool Windows() bool PrimaryArch() bool - PrimaryNativeBridgeArch() bool } type archModuleContext struct { // TODO: these should eventually go through a (possibly cached) provider like any other configuration instead // of being special cased. - ready bool - os OsType - target Target - targetPrimary bool - multiTargets []Target - primaryArch bool - primaryNativeBridgeArch bool + ready bool + os OsType + target Target + targetPrimary bool + multiTargets []Target + primaryArch bool } // ArchReady returns true if the arch mutator has run on the module. Before this returns @@ -91,7 +89,3 @@ func (a *archModuleContext) Windows() bool { func (b *archModuleContext) PrimaryArch() bool { return b.primaryArch } - -func (b *archModuleContext) PrimaryNativeBridgeArch() bool { - return b.primaryNativeBridgeArch -} diff --git a/android/module.go b/android/module.go index 593041aba..55f170cfe 100644 --- a/android/module.go +++ b/android/module.go @@ -28,7 +28,6 @@ import ( "github.com/google/blueprint" "github.com/google/blueprint/depset" "github.com/google/blueprint/gobtools" - "github.com/google/blueprint/pathtools" "github.com/google/blueprint/proptools" ) @@ -1837,27 +1836,14 @@ func (m *ModuleBase) archModuleContextFactory(ctx archModuleContextFactoryContex } else { primaryArch = target.Arch.ArchType == config.Targets[target.Os][0].Arch.ArchType } - primaryNativeBridgeArch := false - if target.NativeBridge { - for _, t := range config.Targets[target.Os] { - if t.NativeBridge { - if target.Arch.ArchType == t.Arch.ArchType { - primaryNativeBridgeArch = true - } - // Don't consider further nativebridge targets - break - } - } - } return archModuleContext{ - ready: m.commonProperties.ArchReady, - os: m.commonProperties.CompileOS, - target: m.commonProperties.CompileTarget, - targetPrimary: m.commonProperties.CompilePrimary, - multiTargets: m.commonProperties.CompileMultiTargets, - primaryArch: primaryArch, - primaryNativeBridgeArch: primaryNativeBridgeArch, + ready: m.commonProperties.ArchReady, + os: m.commonProperties.CompileOS, + target: m.commonProperties.CompileTarget, + targetPrimary: m.commonProperties.CompilePrimary, + multiTargets: m.commonProperties.CompileMultiTargets, + primaryArch: primaryArch, } } @@ -2154,10 +2140,6 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) m.generateVariantTarget(ctx) - testData := FirstUniqueFunc(ctx.testData, func(a, b DataPath) bool { - return a == b - }) - installFiles.LicenseMetadataFile = ctx.licenseMetadataFile installFiles.InstallFiles = ctx.installFiles installFiles.CheckbuildFiles = ctx.checkbuildFiles @@ -2166,7 +2148,7 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) installFiles.PackagingSpecs = ctx.packagingSpecs installFiles.KatiInstalls = ctx.katiInstalls installFiles.KatiSymlinks = ctx.katiSymlinks - installFiles.TestData = testData + installFiles.TestData = ctx.testData } else if ctx.Config().AllowMissingDependencies() { // If the module is not enabled it will not create any build rules, nothing will call // ctx.GetMissingDependencies(), and blueprint will consider the missing dependencies to be unhandled @@ -2198,10 +2180,6 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) SetProvider(ctx, InstallFilesProvider, installFiles) buildLicenseMetadata(ctx, ctx.licenseMetadataFile) - if ctx.testSuiteInfoSet { - m.setupTestSuites(ctx, ctx.testSuiteInfo) - } - if len(ctx.moduleInfoJSON) > 0 { for _, moduleInfoJSON := range ctx.moduleInfoJSON { if moduleInfoJSON.Disabled { @@ -2419,168 +2397,6 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) } } -func (m *ModuleBase) CleanupAfterBuildActions() {} - -func (m *ModuleBase) setupTestSuites(ctx ModuleContext, info TestSuiteInfo) { - if shouldSkipAndroidMkProcessing(ctx, m) || m.IsSkipInstall() { - return - } - overriddenBy := "" - if b, ok := ctx.Module().(OverridableModule); ok { - overriddenBy = b.GetOverriddenBy() - } - - // M(C)TS supports a full test suite and partial per-module MTS test suites, with naming mts-${MODULE}. - // To reduce repetition, if we find a partial M(C)TS test suite without an full M(C)TS test suite, - // we add the full test suite to our list. - if PrefixInList(info.TestSuites, "mts-") && !InList("mts", info.TestSuites) { - info.TestSuites = append(info.TestSuites, "mts") - } - if PrefixInList(info.TestSuites, "mcts-") && !InList("mcts", info.TestSuites) { - info.TestSuites = append(info.TestSuites, "mcts") - } - - if len(info.TestSuites) == 0 { - info.TestSuites = []string{"null-suite"} - } - info.TestSuites = SortedUniqueStrings(info.TestSuites) - - name := ctx.ModuleName() - if overriddenBy != "" { - name = overriddenBy - } - name += info.NameSuffix - - type testSuiteInfo struct { - name string - dir WritablePath - includeModuleFolder bool - } - - suites := []testSuiteInfo{{ - dir: PathForModuleInPartitionInstall(ctx, "testcases", name), - includeModuleFolder: true, - }} - for _, suite := range info.TestSuites { - if suiteInfo, ok := ctx.Config().productVariables.CompatibilityTestcases[suite]; ok { - rel, err := filepath.Rel(ctx.Config().OutDir(), suiteInfo.OutDir) - if err != nil { - panic(fmt.Sprintf("Could not make COMPATIBILITY_TESTCASES_OUT_%s (%s) relative to the out dir (%s)", suite, suiteInfo.OutDir, ctx.Config().OutDir())) - } - if suiteInfo.IncludeModuleFolder || info.PerTestcaseDirectory { - rel = filepath.Join(rel, name) - } - suites = append(suites, testSuiteInfo{ - name: suite, - dir: PathForArbitraryOutput(ctx, rel), - includeModuleFolder: suiteInfo.IncludeModuleFolder || info.PerTestcaseDirectory, - }) - } - } - - var archDir string - if info.NeedsArchFolder { - archDir = ctx.Arch().ArchType.Name - if archDir == "common" { - archDir = ctx.DeviceConfig().DeviceArch() - } - if ctx.Target().NativeBridge { - archDir = ctx.Target().NativeBridgeHostArchName - } - } - - var installs []filePair - - for _, suite := range suites { - mainFileName := name - if info.MainFileStem != "" { - mainFileName = info.MainFileStem - } - mainFileName += info.MainFileExt - mainFileInstall := joinWriteablePath(ctx, suite.dir, archDir, mainFileName) - if !suite.includeModuleFolder { - mainFileInstall = joinWriteablePath(ctx, suite.dir, mainFileName) - } - if info.MainFile == nil { - panic("mainfile was nil") - } - - installs = append(installs, filePair{ - src: info.MainFile, - dst: mainFileInstall, - }) - - for _, data := range info.Data { - dataOut := joinWriteablePath(ctx, suite.dir, archDir, data.ToRelativeInstallPath()) - if !suite.includeModuleFolder { - dataOut = joinWriteablePath(ctx, suite.dir, data.ToRelativeInstallPath()) - } - installs = append(installs, filePair{ - src: data.SrcPath, - dst: dataOut, - }) - } - for _, data := range info.NonArchData { - dataOut := joinWriteablePath(ctx, suite.dir, data.ToRelativeInstallPath()) - installs = append(installs, filePair{ - src: data.SrcPath, - dst: dataOut, - }) - } - for _, data := range info.CompatibilitySupportFiles { - dataOut := joinWriteablePath(ctx, suite.dir, data.Rel()) - installs = append(installs, filePair{ - src: data, - dst: dataOut, - }) - } - - if ctx.TargetPrimary() || ctx.PrimaryNativeBridgeArch() { - if info.ConfigFile != nil { - installs = append(installs, filePair{ - src: info.ConfigFile, - dst: joinWriteablePath(ctx, suite.dir, name+".config"+info.ConfigFileSuffix), - }) - } else if config := ExistentPathForSource(ctx, ctx.ModuleDir(), "AndroidTest.xml"); config.Valid() { - installs = append(installs, filePair{ - src: config.Path(), - dst: joinWriteablePath(ctx, suite.dir, name+".config"), - }) - } - dynamicConfig := ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml") - if dynamicConfig.Valid() { - installs = append(installs, filePair{ - src: dynamicConfig.Path(), - dst: joinWriteablePath(ctx, suite.dir, name+".dynamic"), - }) - } - for _, extraTestConfig := range info.ExtraConfigs { - if extraTestConfig == nil { - panic("ExtraTestConfig was nil") - } - installs = append(installs, filePair{ - src: extraTestConfig, - dst: joinWriteablePath(ctx, suite.dir, pathtools.ReplaceExtension(extraTestConfig.Base(), "config")), - }) - } - } - } - - SetProvider(ctx, TestSuiteInfoProvider, info) - SetProvider(ctx, testSuiteInstallsInfoProvider, testSuiteInstallsInfo{installs}) -} - -func joinWriteablePath(ctx PathContext, path WritablePath, toJoin ...string) WritablePath { - switch p := path.(type) { - case InstallPath: - return p.Join(ctx, toJoin...) - case OutputPath: - return p.Join(ctx, toJoin...) - default: - panic("unhandled path type") - } -} - func SetJarJarPrefixHandler(handler func(ModuleContext)) { if jarJarPrefixHandler != nil { panic("jarJarPrefixHandler already set") diff --git a/android/module_context.go b/android/module_context.go index 3542671ac..e30afd637 100644 --- a/android/module_context.go +++ b/android/module_context.go @@ -275,10 +275,6 @@ type ModuleContext interface { // directory on the build server with the given filename when any of the // specified goals are built. DistForGoalsWithFilename(goals []string, path Path, filename string) - - // Defines this module as a compatibility suite test and gives all the information needed - // to build the suite. - SetTestSuiteInfo(info TestSuiteInfo) } type moduleContext struct { @@ -338,9 +334,6 @@ type moduleContext struct { complianceMetadataInfo *ComplianceMetadataInfo dists []dist - - testSuiteInfo TestSuiteInfo - testSuiteInfoSet bool } var _ ModuleContext = &moduleContext{} @@ -1048,11 +1041,3 @@ func (c *moduleContext) DistForGoalsWithFilename(goals []string, path Path, file paths: distCopies{{from: path, dest: filename}}, }) } - -func (c *moduleContext) SetTestSuiteInfo(info TestSuiteInfo) { - if c.testSuiteInfoSet { - panic("Cannot call SetTestSuiteInfo twice") - } - c.testSuiteInfo = info - c.testSuiteInfoSet = true -} diff --git a/android/test_suites.go b/android/test_suites.go index 88a410eb1..dbcd48c79 100644 --- a/android/test_suites.go +++ b/android/test_suites.go @@ -16,8 +16,6 @@ package android import ( "path/filepath" - "slices" - "sort" "strings" "github.com/google/blueprint" @@ -39,34 +37,7 @@ type TestSuiteModule interface { } type TestSuiteInfo struct { - // A suffix to append to the name of the test. - // Useful because historically different variants of soong modules became differently-named - // make modules, like "my_test.vendor" for the vendor variant. - NameSuffix string - TestSuites []string - - NeedsArchFolder bool - - MainFile Path - - MainFileStem string - - MainFileExt string - - ConfigFile Path - - ConfigFileSuffix string - - ExtraConfigs Paths - - PerTestcaseDirectory bool - - Data []DataPath - - NonArchData []DataPath - - CompatibilitySupportFiles []Path } var TestSuiteInfoProvider = blueprint.NewProvider[TestSuiteInfo]() @@ -77,20 +48,8 @@ type SupportFilesInfo struct { var SupportFilesInfoProvider = blueprint.NewProvider[SupportFilesInfo]() -type filePair struct { - src Path - dst WritablePath -} - -type testSuiteInstallsInfo struct { - Files []filePair -} - -var testSuiteInstallsInfoProvider = blueprint.NewProvider[testSuiteInstallsInfo]() - func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) { files := make(map[string]map[string]InstallPaths) - var toInstall []filePair ctx.VisitAllModuleProxies(func(m ModuleProxy) { if tsm, ok := OtherModuleProvider(ctx, m, TestSuiteInfoProvider); ok { @@ -103,42 +62,7 @@ func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) { OtherModuleProviderOrDefault(ctx, m, InstallFilesProvider).InstallFiles...) } } - if testSuiteInstalls, ok := OtherModuleProvider(ctx, m, testSuiteInstallsInfoProvider); ok { - installs := OtherModuleProviderOrDefault(ctx, m, InstallFilesProvider).InstallFiles - for _, f := range testSuiteInstalls.Files { - alreadyInstalled := false - for _, install := range installs { - if install.String() == f.dst.String() { - alreadyInstalled = true - break - } - } - if !alreadyInstalled { - toInstall = append(toInstall, f) - } - } - } - }) - - sort.Slice(toInstall, func(i, j int) bool { - c := strings.Compare(toInstall[i].src.String(), toInstall[j].src.String()) - if c < 0 { - return true - } else if c > 0 { - return false - } - return toInstall[i].dst.String() < toInstall[j].dst.String() }) - // Dedup, as multiple tests may install the same test data to the same folder - toInstall = slices.Compact(toInstall) - - for _, install := range toInstall { - ctx.Build(pctx, BuildParams{ - Rule: Cp, - Input: install.src, - Output: install.dst, - }) - } robolectricZip, robolectrictListZip := buildTestSuite(ctx, "robolectric-tests", files["robolectric-tests"]) ctx.Phony("robolectric-tests", robolectricZip, robolectrictListZip) diff --git a/android/variable.go b/android/variable.go index 8e6706182..5980efda4 100644 --- a/android/variable.go +++ b/android/variable.go @@ -550,13 +550,6 @@ type ProductVariables struct { UseSoongNoticeXML *bool `json:",omitempty"` StripByDefault *bool `json:",omitempty"` - - CompatibilityTestcases map[string]CompatibilityTestcaseJSON -} - -type CompatibilityTestcaseJSON struct { - OutDir string `json:",omitempty"` - IncludeModuleFolder bool `json:",omitempty"` } type PartitionQualifiedVariablesType struct { diff --git a/cc/binary.go b/cc/binary.go index 627d5e560..608251afc 100644 --- a/cc/binary.go +++ b/cc/binary.go @@ -551,6 +551,10 @@ func (binary *binaryDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON binary.baseLinker.moduleInfoJSON(ctx, moduleInfoJSON) } +func (binary *binaryDecorator) testSuiteInfo(ctx ModuleContext) { + // not a test +} + var _ overridable = (*binaryDecorator)(nil) func init() { diff --git a/cc/cc.go b/cc/cc.go index c50cb64a0..dc9b831f9 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -798,6 +798,8 @@ type linker interface { defaultDistFiles() []android.Path moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) + + testSuiteInfo(ctx ModuleContext) } // specifiedDeps is a tuple struct representing dependencies of a linked binary owned by the linker. @@ -2522,6 +2524,8 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { name := v.ImplementationModuleName(ctx.OtherModuleName(c)) ccInfo.LinkerInfo.ImplementationModuleName = &name } + + c.linker.testSuiteInfo(ctx) } if c.library != nil { ccInfo.LibraryInfo = &LibraryInfo{ diff --git a/cc/library.go b/cc/library.go index b248224bd..5299771ca 100644 --- a/cc/library.go +++ b/cc/library.go @@ -1078,6 +1078,10 @@ func (library *libraryDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSO library.baseLinker.moduleInfoJSON(ctx, moduleInfoJSON) } +func (library *libraryDecorator) testSuiteInfo(ctx ModuleContext) { + // not a test +} + func (library *libraryDecorator) linkStatic(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path { diff --git a/cc/object.go b/cc/object.go index 95a8beb52..ea3ed6151 100644 --- a/cc/object.go +++ b/cc/object.go @@ -250,3 +250,7 @@ func (object *objectLinker) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *an object.baseLinker.moduleInfoJSON(ctx, moduleInfoJSON) moduleInfoJSON.Class = []string{"STATIC_LIBRARIES"} } + +func (object *objectLinker) testSuiteInfo(ctx ModuleContext) { + // not a test +} diff --git a/cc/test.go b/cc/test.go index fed24671d..9c276b81a 100644 --- a/cc/test.go +++ b/cc/test.go @@ -274,6 +274,12 @@ func (test *testDecorator) moduleInfoJSON(ctx android.ModuleContext, moduleInfoJ } } +func (test *testDecorator) testSuiteInfo(ctx ModuleContext) { + android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ + TestSuites: test.InstallerProperties.Test_suites, + }) +} + func NewTestInstaller() *baseInstaller { return NewBaseInstaller("nativetest", "nativetest64", InstallInData) } @@ -342,6 +348,10 @@ func (test *testBinary) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *androi } +func (test *testBinary) testSuiteInfo(ctx ModuleContext) { + test.testDecorator.testSuiteInfo(ctx) +} + func (test *testBinary) installerProps() []interface{} { return append(test.baseInstaller.installerProps(), test.testDecorator.installerProps()...) } @@ -412,24 +422,32 @@ func (test *testBinary) install(ctx ModuleContext, file android.Path) { test.Properties.Test_options.Unit_test = proptools.BoolPtr(true) } - // Install the test config in testcases/ directory for atest. - c, ok := ctx.Module().(*Module) - if !ok { - ctx.ModuleErrorf("Not a cc_test module") + if !ctx.Config().KatiEnabled() { // TODO(spandandas): Remove the special case for kati + // Install the test config in testcases/ directory for atest. + c, ok := ctx.Module().(*Module) + if !ok { + ctx.ModuleErrorf("Not a cc_test module") + } + // Install configs in the root of $PRODUCT_OUT/testcases/$module + testCases := android.PathForModuleInPartitionInstall(ctx, "testcases", ctx.ModuleName()+c.SubName()) + if ctx.PrimaryArch() { + 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) + } + } + // Install tests and data in arch specific subdir $PRODUCT_OUT/testcases/$module/$arch + testCases = testCases.Join(ctx, ctx.Target().Arch.ArchType.String()) + ctx.InstallTestData(testCases, test.data) + ctx.InstallFile(testCases, file.Base(), file) } - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - NameSuffix: c.SubName(), - TestSuites: test.InstallerProperties.Test_suites, - MainFile: file, - MainFileStem: file.Base(), - ConfigFile: test.testConfig, - ExtraConfigs: test.extraTestConfigs, - Data: test.data, - NeedsArchFolder: true, - PerTestcaseDirectory: Bool(test.Properties.Per_testcase_directory), - }) - test.binaryDecorator.baseInstaller.installTestData(ctx, test.data) test.binaryDecorator.baseInstaller.install(ctx, file) if Bool(test.Properties.Standalone_test) { @@ -570,24 +588,8 @@ func (test *testLibrary) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *andro test.testDecorator.moduleInfoJSON(ctx, moduleInfoJSON) } -func (test *testLibrary) install(ctx ModuleContext, file android.Path) { - test.libraryDecorator.install(ctx, file) - - c, ok := ctx.Module().(*Module) - if !ok { - ctx.ModuleErrorf("Expected a cc module") - } - // host tests are not installed to testcases/ as per: - // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/base_rules.mk;l=251;drc=45efec6797cbf812df34dac9d05e43a9fe7217e0 - if test.shared() { - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - NameSuffix: c.SubName(), - TestSuites: test.InstallerProperties.Test_suites, - NeedsArchFolder: true, - MainFile: file, - MainFileStem: file.Base(), - }) - } +func (test *testLibrary) testSuiteInfo(ctx ModuleContext) { + test.testDecorator.testSuiteInfo(ctx) } func (test *testLibrary) installerProps() []interface{} { @@ -682,21 +684,6 @@ func (benchmark *benchmarkDecorator) install(ctx ModuleContext, file android.Pat benchmark.binaryDecorator.baseInstaller.dir64 = filepath.Join("benchmarktest64", ctx.ModuleName()) benchmark.binaryDecorator.baseInstaller.installTestData(ctx, benchmark.data) benchmark.binaryDecorator.baseInstaller.install(ctx, file) - - c, ok := ctx.Module().(*Module) - if !ok { - ctx.ModuleErrorf("Not a cc module") - } - - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - NameSuffix: c.SubName(), - TestSuites: benchmark.Properties.Test_suites, - MainFile: file, - MainFileStem: file.Base(), - ConfigFile: benchmark.testConfig, - Data: benchmark.data, - NeedsArchFolder: true, - }) } func (benchmark *benchmarkDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) { @@ -722,6 +709,12 @@ func (benchmark *benchmarkDecorator) moduleInfoJSON(ctx ModuleContext, moduleInf } } +func (benchmark *benchmarkDecorator) testSuiteInfo(ctx ModuleContext) { + android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ + TestSuites: benchmark.Properties.Test_suites, + }) +} + func NewBenchmark(hod android.HostOrDeviceSupported) *Module { module, binary := newBinary(hod) module.multilib = android.MultilibBoth diff --git a/java/app.go b/java/app.go index 6c1e4f6a5..3a3253f04 100644 --- a/java/app.go +++ b/java/app.go @@ -427,22 +427,8 @@ func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleCon moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") } - outputFile := a.installedOutputFile - if outputFile == nil { - outputFile = a.outputFile - } - var data []android.DataPath - for _, d := range a.extraOutputFiles { - data = append(data, android.DataPath{SrcPath: d}) - } - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - TestSuites: a.appTestHelperAppProperties.Test_suites, - MainFile: outputFile, - MainFileStem: a.installApkName, - MainFileExt: ".apk", - NeedsArchFolder: true, - NonArchData: data, - PerTestcaseDirectory: proptools.Bool(a.appTestHelperAppProperties.Per_testcase_directory), + android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ + TestSuites: a.appTestHelperAppProperties.Test_suites, }) } @@ -994,10 +980,10 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { if ctx.ModuleName() == "framework-res" { // framework-res.apk is installed as system/framework/framework-res.apk a.installDir = android.PathForModuleInstall(ctx, "framework") - } else if ctx.InstallInTestcases() { - a.installDir = android.PathForModuleInstall(ctx, a.installApkName, ctx.DeviceConfig().DeviceArch()) } else if a.Privileged() { a.installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName) + } else if ctx.InstallInTestcases() { + a.installDir = android.PathForModuleInstall(ctx, a.installApkName, ctx.DeviceConfig().DeviceArch()) } else { a.installDir = android.PathForModuleInstall(ctx, "app", a.installApkName) } @@ -1144,7 +1130,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { } } } - a.installedOutputFile = ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...) + ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...) } ctx.CheckbuildFile(a.outputFile) @@ -1693,33 +1679,22 @@ func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { 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)...) - a.data = android.SortedUniquePaths(a.data) - a.extraTestConfigs = android.SortedUniquePaths(a.extraTestConfigs) - - testOutputFile := a.installedOutputFile - if testOutputFile == nil { - testOutputFile = a.outputFile - } - var testData []android.DataPath - for _, data := range a.data { - dataPath := android.DataPath{SrcPath: data} - testData = append(testData, dataPath) - } - for _, d := range a.extraOutputFiles { - testData = append(testData, android.DataPath{SrcPath: d}) - } - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - TestSuites: a.testProperties.Test_suites, - MainFile: testOutputFile, - MainFileStem: a.installApkName, - MainFileExt: ".apk", - ConfigFile: a.testConfig, - ExtraConfigs: a.extraTestConfigs, - NonArchData: testData, - CompatibilitySupportFiles: a.data, - NeedsArchFolder: true, - PerTestcaseDirectory: proptools.Bool(a.testProperties.Per_testcase_directory), - }) + // Install test deps + if !ctx.Config().KatiEnabled() { + pathInTestCases := android.PathForModuleInstall(ctx, ctx.Module().Name()) + 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} + ctx.InstallTestData(pathInTestCases, []android.DataPath{dataPath}) + } + } android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{ TestcaseRelDataFiles: testcaseRel(a.data), @@ -1754,6 +1729,10 @@ func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { moduleInfoJSON.AutoTestConfig = []string{"true"} } moduleInfoJSON.TestMainlineModules = append(moduleInfoJSON.TestMainlineModules, a.testProperties.Test_mainline_modules...) + + android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ + TestSuites: a.testProperties.Test_suites, + }) } func testcaseRel(paths android.Paths) []string { diff --git a/java/app_import.go b/java/app_import.go index 837ab529b..9fb13ba3c 100644 --- a/java/app_import.go +++ b/java/app_import.go @@ -788,18 +788,8 @@ func (a *AndroidTestImport) GenerateAndroidBuildActions(ctx android.ModuleContex a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data) - var data []android.DataPath - for _, d := range a.data { - data = append(data, android.DataPath{SrcPath: d}) - } - - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - TestSuites: a.testProperties.Test_suites, - MainFile: a.outputFile, - MainFileStem: a.outputFile.Base(), - NeedsArchFolder: true, - Data: data, - CompatibilitySupportFiles: a.data, + android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ + TestSuites: a.testProperties.Test_suites, }) } diff --git a/java/base.go b/java/base.go index 86d6b30ac..8aa0109d0 100644 --- a/java/base.go +++ b/java/base.go @@ -508,9 +508,8 @@ type Module struct { jacocoReportClassesFile android.Path // output file of the module, which may be a classes jar or a dex jar - outputFile android.Path - installedOutputFile android.Path - extraOutputFiles android.Paths + outputFile android.Path + extraOutputFiles android.Paths exportAidlIncludeDirs android.Paths ignoredAidlPermissionList android.Paths diff --git a/java/fuzz.go b/java/fuzz.go index 7271b9737..0e239f0ec 100644 --- a/java/fuzz.go +++ b/java/fuzz.go @@ -131,32 +131,7 @@ func (j *JavaFuzzTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { } - checkMinSdkVersionMts(ctx, j.MinSdkVersion(ctx)) - j.Test.generateAndroidBuildActionsWithConfig(ctx, nil) - - var compatibilitySupportFiles android.Paths - compatibilitySupportFiles = append(compatibilitySupportFiles, j.implementationJarFile) - compatibilitySupportFiles = append(compatibilitySupportFiles, j.jniFilePaths...) - compatibilitySupportFiles = append(compatibilitySupportFiles, j.fuzzPackagedModule.Corpus...) - if j.fuzzPackagedModule.Dictionary != nil { - compatibilitySupportFiles = append(compatibilitySupportFiles, j.fuzzPackagedModule.Dictionary) - } - - outputFile := j.installedOutputFile - if outputFile == nil { - outputFile = j.outputFile - } - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - TestSuites: j.testProperties.Test_suites, - MainFile: outputFile, - MainFileStem: j.Stem(), - MainFileExt: ".jar", - ConfigFile: j.testConfig, - ExtraConfigs: j.extraTestConfigs, - NeedsArchFolder: ctx.Device(), - CompatibilitySupportFiles: compatibilitySupportFiles, - PerTestcaseDirectory: proptools.Bool(j.testProperties.Per_testcase_directory), - }) + j.Test.GenerateAndroidBuildActions(ctx) fuzz.SetFuzzPackagedModuleInfo(ctx, &j.fuzzPackagedModule) } diff --git a/java/java.go b/java/java.go index d7b4d1c22..07e38a17e 100644 --- a/java/java.go +++ b/java/java.go @@ -1809,7 +1809,6 @@ func (j *TestHost) GenerateAndroidBuildActions(ctx android.ModuleContext) { } j.Test.generateAndroidBuildActionsWithConfig(ctx, configs) - j.Test.javaTestSetTestsuiteInfo(ctx) android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{ TestcaseRelDataFiles: testcaseRel(j.data), OutputFile: j.outputFile, @@ -1832,7 +1831,6 @@ func (j *TestHost) GenerateAndroidBuildActions(ctx android.ModuleContext) { func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) { checkMinSdkVersionMts(ctx, j.MinSdkVersion(ctx)) j.generateAndroidBuildActionsWithConfig(ctx, nil) - j.javaTestSetTestsuiteInfo(ctx) } func (j *Test) generateAndroidBuildActionsWithConfig(ctx android.ModuleContext, configs []tradefed.Config) { @@ -1938,29 +1936,29 @@ func (j *Test) generateAndroidBuildActionsWithConfig(ctx android.ModuleContext, } } moduleInfoJSON.TestMainlineModules = append(moduleInfoJSON.TestMainlineModules, j.testProperties.Test_mainline_modules...) -} -func (j *Test) javaTestSetTestsuiteInfo(ctx android.ModuleContext) { // Install test deps - outputFile := j.installedOutputFile - if outputFile == nil { - outputFile = j.outputFile - } - var testData []android.DataPath - for _, data := range j.data { - dataPath := android.DataPath{SrcPath: data} - testData = append(testData, dataPath) + if !ctx.Config().KatiEnabled() { + pathInTestCases := android.PathForModuleInstall(ctx, "testcases", ctx.ModuleName()) + 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} + ctx.InstallTestData(pathInTestCases, []android.DataPath{dataPath}) + } + if j.outputFile != nil { + ctx.InstallFile(pathInTestCases, ctx.ModuleName()+".jar", j.outputFile) + } } - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - TestSuites: j.testProperties.Test_suites, - MainFile: outputFile, - MainFileStem: j.Stem(), - MainFileExt: ".jar", - ConfigFile: j.testConfig, - ExtraConfigs: j.extraTestConfigs, - NeedsArchFolder: ctx.Device(), - NonArchData: testData, - PerTestcaseDirectory: proptools.Bool(j.testProperties.Per_testcase_directory), + + android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ + TestSuites: j.testProperties.Test_suites, }) } @@ -1975,24 +1973,12 @@ func (j *TestHelperLibrary) GenerateAndroidBuildActions(ctx android.ModuleContex moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") } optionalConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "AndroidTest.xml") - var config android.Path if optionalConfig.Valid() { - config = optionalConfig.Path() moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, optionalConfig.String()) } - outputFile := j.installedOutputFile - if outputFile == nil { - outputFile = j.outputFile - } - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - TestSuites: j.testHelperLibraryProperties.Test_suites, - MainFile: outputFile, - MainFileStem: j.Stem(), - MainFileExt: ".jar", - ConfigFile: config, - NeedsArchFolder: ctx.Device(), - PerTestcaseDirectory: proptools.Bool(j.testHelperLibraryProperties.Per_testcase_directory), + android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ + TestSuites: j.testHelperLibraryProperties.Test_suites, }) } diff --git a/python/binary.go b/python/binary.go index abcef73fb..f894299f9 100644 --- a/python/binary.go +++ b/python/binary.go @@ -115,12 +115,6 @@ func (p *PythonBinaryModule) GenerateAndroidBuildActions(ctx android.ModuleConte ctx.SetOutputFiles(android.Paths{p.installSource}, "") - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - TestSuites: p.binaryProperties.Test_suites, - MainFile: p.installSource, - MainFileStem: p.installSource.Base(), - }) - moduleInfoJSON := ctx.ModuleInfoJSON() moduleInfoJSON.Class = []string{"EXECUTABLES"} moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, p.androidMkSharedLibs...) @@ -171,6 +165,10 @@ func (p *PythonBinaryModule) buildBinary(ctx android.ModuleContext) { sharedLibs = append(sharedLibs, ctx.OtherModuleName(dep)) } p.androidMkSharedLibs = sharedLibs + + android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ + TestSuites: p.binaryProperties.Test_suites, + }) } func (p *PythonBinaryModule) AndroidMkEntries() []android.AndroidMkEntries { diff --git a/python/test.go b/python/test.go index d6670c3c4..df62ab794 100644 --- a/python/test.go +++ b/python/test.go @@ -215,21 +215,25 @@ func (p *PythonTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext installedData := ctx.InstallTestData(installDir, p.data) p.installedDest = ctx.InstallFile(installDir, p.installSource.Base(), p.installSource, installedData...) - configFileSuffix := "" - // ATS 2.0 is the test harness for mobly tests and the test config is for ATS 2.0. - // Add "v2" suffix to test config name to distinguish it from the config for TF. - if proptools.String(p.testProperties.Test_options.Runner) == "mobly" { - configFileSuffix = "v2" + // TODO: Remove the special case for kati + if !ctx.Config().KatiEnabled() { + // Install the test config in testcases/ directory for atest. + // Install configs in the root of $PRODUCT_OUT/testcases/$module + testCases := android.PathForModuleInPartitionInstall(ctx, "testcases", ctx.ModuleName()) + if ctx.PrimaryArch() { + 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()) + installedData := ctx.InstallTestData(testCases, p.data) + ctx.InstallFile(testCases, p.installSource.Base(), p.installSource, installedData...) } - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - TestSuites: p.binaryProperties.Test_suites, - MainFile: p.installSource, - MainFileStem: p.installSource.Base(), - ConfigFile: p.testConfig, - ConfigFileSuffix: configFileSuffix, - Data: p.data, - NeedsArchFolder: true, - }) moduleInfoJSON := ctx.ModuleInfoJSON() moduleInfoJSON.Class = []string{"NATIVE_TESTS"} diff --git a/rust/benchmark.go b/rust/benchmark.go index 85aa6a52e..3aa2f1779 100644 --- a/rust/benchmark.go +++ b/rust/benchmark.go @@ -129,15 +129,6 @@ func (benchmark *benchmarkDecorator) install(ctx ModuleContext) { } benchmark.binaryDecorator.install(ctx) - - mainFile := ctx.RustModule().OutputFile().Path() - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - TestSuites: benchmark.Properties.Test_suites, - MainFile: mainFile, - MainFileExt: mainFile.Ext(), - ConfigFile: benchmark.testConfig, - NeedsArchFolder: true, - }) } func (benchmark *benchmarkDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) { @@ -155,4 +146,8 @@ func (benchmark *benchmarkDecorator) moduleInfoJSON(ctx ModuleContext, moduleInf } else { moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") } + + android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ + TestSuites: benchmark.Properties.Test_suites, + }) } diff --git a/rust/test.go b/rust/test.go index 72eaaae81..cedced260 100644 --- a/rust/test.go +++ b/rust/test.go @@ -204,17 +204,29 @@ func (test *testDecorator) install(ctx ModuleContext) { test.Properties.Test_options.Unit_test = proptools.BoolPtr(true) } - // Install the test config in testcases/ directory for atest. - mainFile := ctx.RustModule().OutputFile().Path() - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - NameSuffix: ctx.RustModule().SubName(), - TestSuites: test.Properties.Test_suites, - MainFile: mainFile, - MainFileStem: mainFile.Base(), - ConfigFile: test.testConfig, - Data: test.data, - NeedsArchFolder: true, - }) + if !ctx.Config().KatiEnabled() { // TODO(spandandas): Remove the special case for kati + // Install the test config in testcases/ directory for atest. + r, ok := ctx.Module().(*Module) + if !ok { + ctx.ModuleErrorf("Not a rust test module") + } + // Install configs in the root of $PRODUCT_OUT/testcases/$module + testCases := android.PathForModuleInPartitionInstall(ctx, "testcases", ctx.ModuleName()+r.SubName()) + if ctx.PrimaryArch() { + 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()) + ctx.InstallTestData(testCases, test.data) + testPath := ctx.RustModule().OutputFile().Path() + ctx.InstallFile(testCases, testPath.Base(), testPath) + } test.binaryDecorator.installTestData(ctx, test.data) test.binaryDecorator.install(ctx) @@ -308,6 +320,10 @@ func (test *testDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *and } else { moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") } + + android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ + TestSuites: test.Properties.Test_suites, + }) } func rustTestHostMultilib(ctx android.LoadHookContext) { diff --git a/sh/sh_binary.go b/sh/sh_binary.go index 257d60936..57f5ad1c7 100644 --- a/sh/sh_binary.go +++ b/sh/sh_binary.go @@ -540,17 +540,6 @@ func (s *ShTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { installedData := ctx.InstallTestData(s.installDir, s.data) s.installedFile = ctx.InstallExecutable(s.installDir, s.outputFilePath.Base(), s.outputFilePath, installedData...) - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - TestSuites: s.testProperties.Test_suites, - MainFile: s.outputFilePath, - MainFileStem: s.outputFilePath.Base(), - ConfigFile: s.testConfig, - ExtraConfigs: s.extraTestConfigs, - Data: s.data, - NeedsArchFolder: true, - PerTestcaseDirectory: proptools.Bool(s.testProperties.Per_testcase_directory), - }) - mkEntries := s.AndroidMkEntries()[0] android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{ TestcaseRelDataFiles: addArch(ctx.Arch().ArchType.String(), installedData.Paths()), @@ -585,6 +574,10 @@ func (s *ShTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, s.testConfig.String()) } moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, s.extraTestConfigs.Strings()...) + + android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ + TestSuites: s.testProperties.Test_suites, + }) } func addArch(archType string, paths android.Paths) []string { diff --git a/tradefed_modules/test_module_config.go b/tradefed_modules/test_module_config.go index 6b30a7a38..e833df293 100644 --- a/tradefed_modules/test_module_config.go +++ b/tradefed_modules/test_module_config.go @@ -435,22 +435,9 @@ func (m *testModuleConfigModule) generateManifestAndConfig(ctx android.ModuleCon IsUnitTest: m.provider.IsUnitTest, }) - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - TestSuites: m.tradefedProperties.Test_suites, - MainFile: baseApk, - MainFileExt: ".apk", - ConfigFile: m.testConfig, - NeedsArchFolder: ctx.Device(), + android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ + TestSuites: m.tradefedProperties.Test_suites, }) - - // Install the UNUSED- file to match the UNUSED- stem specified in javaExtraEntries - if m.provider.MkAppClass == "APPS" { - installDir2 := android.PathForModuleInstall(ctx, ctx.ModuleName(), ctx.DeviceConfig().DeviceArch()) - ctx.InstallFile(installDir2, fmt.Sprintf("UNUSED-%s.apk", *m.Base), m.manifest) - } else if m.provider.MkAppClass == "JAVA_LIBRARIES" { - installDir2 := android.PathForModuleInstall(ctx, ctx.ModuleName()) - ctx.InstallFile(installDir2, fmt.Sprintf("UNUSED-%s.jar", *m.Base), m.manifest) - } } var _ android.AndroidMkEntriesProvider = (*testModuleConfigHostModule)(nil) -- cgit v1.2.3 From 01ba5fe836845fd7639ade331e220d7e0b9f7f77 Mon Sep 17 00:00:00 2001 From: "Priyanka Advani (xWF)" Date: Wed, 26 Mar 2025 18:25:41 -0700 Subject: Revert "Disallow cross partition overrides in android_device" This reverts commit 288e5647b921bac966cda1393d7a078082c0842c. Reason for revert: Droidmonitor created revert due to b/406611525. Will be verifying through ABTD before submission. Change-Id: If93b6ada0f505e4d21e93f1dadf6f537c77d9237 --- android/packaging.go | 4 --- filesystem/Android.bp | 1 - filesystem/android_device.go | 31 ---------------------- filesystem/android_device_test.go | 54 --------------------------------------- filesystem/filesystem.go | 4 --- filesystem/testing.go | 17 ++---------- 6 files changed, 2 insertions(+), 109 deletions(-) delete mode 100644 filesystem/android_device_test.go diff --git a/android/packaging.go b/android/packaging.go index f06e6fbd8..aae7806d7 100644 --- a/android/packaging.go +++ b/android/packaging.go @@ -110,10 +110,6 @@ func (p *PackagingSpec) Prebuilt() bool { return p.prebuilt } -func (p *PackagingSpec) Overrides() uniquelist.UniqueList[string] { - return p.overrides -} - func (p *PackagingSpec) ToGob() *packagingSpecGob { return &packagingSpecGob{ RelPathInPackage: p.relPathInPackage, diff --git a/filesystem/Android.bp b/filesystem/Android.bp index 2ddaed052..cb76df2d9 100644 --- a/filesystem/Android.bp +++ b/filesystem/Android.bp @@ -33,7 +33,6 @@ bootstrap_go_package { "testing.go", ], testSrcs: [ - "android_device_test.go", "filesystem_test.go", ], pluginFor: ["soong_build"], diff --git a/filesystem/android_device.go b/filesystem/android_device.go index fea75dc21..bc002795a 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -182,8 +182,6 @@ func (a *androidDevice) addDepsForTargetFilesMetadata(ctx android.BottomUpMutato } func (a *androidDevice) GenerateAndroidBuildActions(ctx android.ModuleContext) { - a.validateNoCrossPartitionOverrides(ctx) - if proptools.Bool(a.deviceProps.Main_device) { numMainAndroidDevices := ctx.Config().Once(numMainAndroidDevicesOnceKey, func() interface{} { return &atomic.Int32{} @@ -1191,32 +1189,3 @@ func (a *androidDevice) buildApkCertsInfo(ctx android.ModuleContext, allInstalle }) return apkCertsInfo } - -// Validate that a soong module in one `android_filesystem` dep cannot override a soong module -// in another `android_filesystem` dep of this device. -func (a *androidDevice) validateNoCrossPartitionOverrides(ctx android.ModuleContext) { - // Collect packaging specs of all partitions, keyed on the owning module - ownerToPackagingSpec := map[string]android.PackagingSpec{} - for _, fsInfo := range a.getFsInfos(ctx) { - for _, spec := range fsInfo.Specs { - ownerToPackagingSpec[spec.Owner()] = spec - } - } - - // Iterate over all packaging specs. For each spec, - // 1. If overrides is empty, no work to do. - // 2. If overrides is non-empty, and the partition of the overrides and overridden module are same, no error. - // 3. If overrides is non-empty, and the partition of the overrides and overridden module are different, error. - for owner, packagingSpec := range ownerToPackagingSpec { - for override := range packagingSpec.Overrides().Iter() { - overridePackagingSpec, ok := ownerToPackagingSpec[override] - if !ok { - // Ignore if the overridden module is not installed - continue - } - if packagingSpec.Partition() != overridePackagingSpec.Partition() { - ctx.ModuleErrorf("%s overrides %s, but they belong to separate android_filesystem. Please remove %s from %s", owner, override, override, overridePackagingSpec.Partition()) - } - } - } -} diff --git a/filesystem/android_device_test.go b/filesystem/android_device_test.go deleted file mode 100644 index 9f0b90d7d..000000000 --- a/filesystem/android_device_test.go +++ /dev/null @@ -1,54 +0,0 @@ -// 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 filesystem - -import ( - "android/soong/android" - "testing" -) - -func TestCrossPartitionOverridesError(t *testing.T) { - fixture.ExtendWithErrorHandler( - android.FixtureExpectsOneErrorPattern("vendorlib_overrides_systemlib overrides systemlib, but they belong to separate android_filesystem."), - ).RunTestWithBp(t, ` - android_device { - name: "my_android_device", - system_partition_name: "systemimage", - vendor_partition_name: "vendorimage", - } - - android_filesystem { - name: "systemimage", - deps: ["systemlib"], - compile_multilib: "both", - } - android_filesystem { - name: "vendorimage", - partition_type: "vendor", - deps: ["vendorlib_overrides_systemlib"], - compile_multilib: "both", - } - - cc_binary { - name: "systemlib", - } - - cc_binary { - name: "vendorlib_overrides_systemlib", - vendor: true, - overrides: ["systemlib"], - } - `) -} diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index 2ff2d9442..df60a8cf7 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -45,7 +45,6 @@ func init() { } func registerBuildComponents(ctx android.RegistrationContext) { - ctx.RegisterModuleType("android_device", AndroidDeviceFactory) ctx.RegisterModuleType("android_filesystem", FilesystemFactory) ctx.RegisterModuleType("android_filesystem_defaults", filesystemDefaultsFactory) ctx.RegisterModuleType("android_system_image", SystemImageFactory) @@ -440,8 +439,6 @@ type FilesystemInfo struct { BuildImagePropFile android.Path // Paths to all the tools referenced inside of the build image property file. BuildImagePropFileDeps android.Paths - // Packaging specs to be installed in this filesystem. - Specs map[string]android.PackagingSpec // Packaging specs to be installed on the system_other image, for the initial boot's dexpreopt. SpecsForSystemOther map[string]android.PackagingSpec @@ -718,7 +715,6 @@ func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) { ModuleName: ctx.ModuleName(), BuildImagePropFile: buildImagePropFile, BuildImagePropFileDeps: buildImagePropFileDeps, - Specs: specs, SpecsForSystemOther: f.systemOtherFiles(ctx), FullInstallPaths: fullInstallPaths, InstalledFilesDepSet: depset.New( diff --git a/filesystem/testing.go b/filesystem/testing.go index bcbe8842e..631f1b1c8 100644 --- a/filesystem/testing.go +++ b/filesystem/testing.go @@ -14,19 +14,6 @@ package filesystem -import ( - "android/soong/android" - "android/soong/cc" -) +import "android/soong/android" -var PrepareForTestWithFilesystemBuildComponents = android.GroupFixturePreparers( - android.FixtureRegisterWithContext(registerBuildComponents), - cc.PrepareForIntegrationTestWithCc, - android.FixtureAddTextFile("testdeps/Android.bp", - ` -cc_library_shared { - name: "liblz4", - host_supported: true, -} -`), -) +var PrepareForTestWithFilesystemBuildComponents = android.FixtureRegisterWithContext(registerBuildComponents) -- cgit v1.2.3 From 3bb29bdd9c3110380c700c032145070586cbcef2 Mon Sep 17 00:00:00 2001 From: Todd Lee Date: Thu, 11 Apr 2024 17:10:02 +0000 Subject: Add wear-sdk bootclasspath jars Bug: b/331485125 Test: manual build/boot Flag: NONE exempt wear only config change Change-Id: Iaefc74134e842bcfd056ecd4f82796486afe8fa4 --- scripts/check_boot_jars/package_allowed_list.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/check_boot_jars/package_allowed_list.txt b/scripts/check_boot_jars/package_allowed_list.txt index 1d2fc643f..9e001ca0e 100644 --- a/scripts/check_boot_jars/package_allowed_list.txt +++ b/scripts/check_boot_jars/package_allowed_list.txt @@ -260,3 +260,8 @@ com\.google\.i18n\.phonenumbers # Packages used for Android in Chrome OS org\.chromium\.arc org\.chromium\.arc\..* + +################################################### +# Packages used for wear-sdk in Wear OS +com\.google\.wear +com\.google\.wear\..* -- cgit v1.2.3 From 55a768ff2dd2532d0c14c861a8ea0f737ad560e3 Mon Sep 17 00:00:00 2001 From: LaMont Jones Date: Thu, 27 Mar 2025 10:04:53 -0700 Subject: Turn off aosp-first check Bug: None Test: Manual Change-Id: I1fb08883c754964b781958ef64892f97b1cc03e6 --- PREUPLOAD.cfg | 1 - 1 file changed, 1 deletion(-) diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg index e8cad7d7b..317f5c434 100644 --- a/PREUPLOAD.cfg +++ b/PREUPLOAD.cfg @@ -4,4 +4,3 @@ bpfmt = true [Hook Scripts] do_not_use_DO_NOT_MERGE = ${REPO_ROOT}/build/soong/scripts/check_do_not_merge.sh ${PREUPLOAD_COMMIT} -aosp_hook = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} "." -- cgit v1.2.3 From 1547b16f9bb8a375daf5d716fe8f6dd6addf2de9 Mon Sep 17 00:00:00 2001 From: Taylor Santiago Date: Tue, 18 Mar 2025 19:25:07 -0700 Subject: Detect appropriate bindmount for ABFS cache from the mount Bug: 404596615 Change-Id: I2bd60d9ed36ca36464783b49bdf555e599bb90ac --- ui/build/sandbox_linux.go | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/ui/build/sandbox_linux.go b/ui/build/sandbox_linux.go index 95b71a794..8da0e3f2e 100644 --- a/ui/build/sandbox_linux.go +++ b/ui/build/sandbox_linux.go @@ -16,6 +16,7 @@ package build import ( "bytes" + "encoding/json" "os" "os/exec" "os/user" @@ -217,6 +218,27 @@ func (c *Cmd) workDir() string { return abfsSrcDir } +func abfsCacheFromMount(mntDir string) (string, error) { + type Config struct { + CacheDir string + } + type MountDetails struct { + Config Config + } + var m MountDetails + file, err := os.Open(filepath.Join(mntDir, ".repo/mount-details")) + if err != nil { + return "", err + } + defer file.Close() + d := json.NewDecoder(file) + if err := d.Decode(&m); err != nil { + return "", err + } + + return m.Config.CacheDir, nil +} + func (c *Cmd) wrapSandbox() { wd := c.workDir() @@ -277,7 +299,11 @@ func (c *Cmd) wrapSandbox() { "-q", ) if c.config.UseABFS() { - sandboxArgs = append(sandboxArgs, "-B", "{ABFS_DIR}") + cacheDir, err := abfsCacheFromMount(wd) + if err != nil { + c.ctx.Fatalln(err) + } + sandboxArgs = append(sandboxArgs, "-B", cacheDir) } // Mount srcDir RW allowlists as Read-Write -- cgit v1.2.3 From 766113b8adc77fa2aee1b5ae3c4661a7c9b36013 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Wed, 26 Mar 2025 18:23:42 +0000 Subject: Reapply "Create a validation action to assert `apps` matches prebuilt apex" This reapplies https://r.android.com/3555724 with a fix to create a trailing newline in p.apkcertsFile contents. It now uses `WriteFileRule` instead of `WriteFileRuleVerbatim`. Test: Verified the contents of apkcerts.txt in $ANDROID_PRODUCT_OUT Change-Id: Ia9287e2eb7852a1fdd5adb05387d8ff9895de95a --- apex/prebuilt.go | 65 +++++++++++++++++++++++++++++++++++--------- filesystem/android_device.go | 8 ++++++ 2 files changed, 60 insertions(+), 13 deletions(-) diff --git a/apex/prebuilt.go b/apex/prebuilt.go index fdd9a75d7..02b392a0a 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -48,6 +48,16 @@ var ( CommandDeps: []string{"${deapexer}"}, Description: "decompress $out", }) + // Compares the declared apps of `prebuilt_apex` with the actual apks + validateApkInPrebuiltApex = pctx.StaticRule("validateApkinPrebuiltApex", blueprint.RuleParams{ + Command: `rm -rf ${out} ${actualApks} &&` + + ` ${apex_ls} ${in} | grep apk$$ | awk -F '/' '{print $$NF}' | sort -u > ${actualApks} &&` + + ` cmp -s ${expectedApks} ${actualApks} && touch ${out}` + + ` || (echo "Found diffs between "apps" property of ${apexName} and actual contents of ${in}.` + + ` Please ensure that all apk-in-apexes are declared in 'apps' property." && exit 1)`, + CommandDeps: []string{"${apex_ls}"}, + Description: "validate apk in prebuilt_apex $out", + }, "expectedApks", "actualApks", "apexName") ) type prebuilt interface { @@ -711,6 +721,38 @@ func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) { android.SetProvider(ctx, filesystem.ApexKeyPathInfoProvider, filesystem.ApexKeyPathInfo{p.apexKeysPath}) } +// Creates a timestamp file that will be used to validate that there is no mismtach +// between apks declared via `apps` and the actual apks inside the apex. +func (p *Prebuilt) validateApkInPrebuiltApex(ctx android.ModuleContext, appInfos java.AppInfos) android.Path { + timestamp := android.PathForModuleOut(ctx, "apk_in_prebuilt_apex.timestamp") + // Create a list of expected installed apks. + var installedApks []string + for _, appInfo := range appInfos { + installedApks = append(installedApks, appInfo.InstallApkName+".apk") + } + expectedApksFile := android.PathForModuleOut(ctx, "expected_apk_in_prebuilt_apex.txt") + if len(installedApks) == 0 { + android.WriteFileRuleVerbatim(ctx, expectedApksFile, "") // Without newline + } else { + android.WriteFileRule(ctx, expectedApksFile, strings.Join(android.SortedUniqueStrings(installedApks), "\n")) // With newline + } + + actualApksFile := android.PathForModuleOut(ctx, "actual_apk_in_prebuilt_apex.txt") + ctx.Build(pctx, android.BuildParams{ + Rule: validateApkInPrebuiltApex, + Input: p.inputApex, + Output: timestamp, + Implicit: expectedApksFile, + ImplicitOutput: actualApksFile, + Args: map[string]string{ + "expectedApks": expectedApksFile.String(), + "actualApks": actualApksFile.String(), + "apexName": p.Name(), + }, + }) + return timestamp +} + // `addApkCertsInfo` sets a provider that will be used to create apkcerts.txt func (p *Prebuilt) addApkCertsInfo(ctx android.ModuleContext) { formatLine := func(cert java.Certificate, name, partition string) string { @@ -737,24 +779,21 @@ func (p *Prebuilt) addApkCertsInfo(ctx android.ModuleContext) { return appInfos[i].InstallApkName < appInfos[j].InstallApkName }) - if len(appInfos) == 0 { - return - } - - // Set a provider for use by `android_device`. - // `android_device` will create an apkcerts.txt with the list of installed apps for that device. - android.SetProvider(ctx, java.AppInfosProvider, appInfos) - - // Set a Make variable for legacy apkcerts.txt creation - // p.apkCertsFile will become `LOCAL_APKCERTS_FILE` + // Create p.apkCertsFile with information about apk-in-apex + // p.apkCertsFile will become `LOCAL_APKCERTS_FILE` for Make packaging system + // p.apkCertsFile will be propagated to android_device for Soong packaging system var lines []string for _, appInfo := range appInfos { lines = append(lines, formatLine(appInfo.Certificate, appInfo.InstallApkName+".apk", p.PartitionTag(ctx.DeviceConfig()))) } - if len(lines) > 0 { - p.apkCertsFile = android.PathForModuleOut(ctx, "apkcerts.txt") - android.WriteFileRule(ctx, p.apkCertsFile, strings.Join(lines, "\n")) + p.apkCertsFile = android.PathForModuleOut(ctx, "apkcerts.txt") + var validations android.Paths + if p.IsInstallable() { + // Skip the validation for non-installable prebuilt apexes (e.g. used in CTS tests). + validations = append(validations, p.validateApkInPrebuiltApex(ctx, appInfos)) } + android.WriteFileRule(ctx, p.apkCertsFile, strings.Join(lines, "\n"), validations...) + android.SetProvider(ctx, filesystem.ApkCertsInfoProvider, filesystem.ApkCertsInfo{p.apkCertsFile}) } func (p *Prebuilt) ProvenanceMetaDataFile() android.Path { diff --git a/filesystem/android_device.go b/filesystem/android_device.go index 9b0159ddb..dec395060 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -1170,6 +1170,8 @@ func (a *androidDevice) buildApkCertsInfo(ctx android.ModuleContext, allInstalle } } else if info, ok := android.OtherModuleProvider(ctx, installedModule, java.RuntimeResourceOverlayInfoProvider); ok { apkCerts = append(apkCerts, formatLine(info.Certificate, info.OutputFile.Base(), partition)) + } else if info, ok := android.OtherModuleProvider(ctx, installedModule, ApkCertsInfoProvider); ok { + apkCertsFiles = append(apkCertsFiles, info.ApkCertsFile) } } slices.Sort(apkCerts) // sort by name @@ -1193,3 +1195,9 @@ func (a *androidDevice) buildApkCertsInfo(ctx android.ModuleContext, allInstalle }) return apkCertsInfo } + +type ApkCertsInfo struct { + ApkCertsFile android.Path +} + +var ApkCertsInfoProvider = blueprint.NewProvider[ApkCertsInfo]() -- cgit v1.2.3 From bd9b88bc8fa65d6837ff22cba3a570f7b7cb8d78 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Mon, 17 Mar 2025 15:49:49 -0700 Subject: Replace override mutators with a TransitionMutator The override mutators were modifying dependencies to pass the override properties to them. Put the properties through an InfoBasedTransition mutator instead. Bug: 319288033 Test: TestOverrideApex Change-Id: Ic2fe013eed26e6f4de5b5ff9a8d93733495d7569 --- android/override_module.go | 191 ++++++++++++++++++--------------------------- android/prebuilt.go | 26 +++--- 2 files changed, 93 insertions(+), 124 deletions(-) diff --git a/android/override_module.go b/android/override_module.go index 96620ef7a..9a0ce9e3d 100644 --- a/android/override_module.go +++ b/android/override_module.go @@ -29,8 +29,6 @@ package android import ( "fmt" - "sort" - "sync" "github.com/google/blueprint" "github.com/google/blueprint/proptools" @@ -49,10 +47,6 @@ type OverrideModule interface { // i.e. cases where an overriding module, too, is overridden by a prebuilt module. setOverriddenByPrebuilt(prebuilt Module) getOverriddenByPrebuilt() Module - - // Directory containing the Blueprint definition of the overriding module - setModuleDir(string) - ModuleDir() string } // Base module struct for override module types @@ -62,8 +56,6 @@ type OverrideModuleBase struct { overridingProperties []interface{} overriddenByPrebuilt Module - - moduleDir string } type OverrideModuleProperties struct { @@ -73,14 +65,6 @@ type OverrideModuleProperties struct { // TODO(jungjw): Add an optional override_name bool flag. } -func (o *OverrideModuleBase) setModuleDir(d string) { - o.moduleDir = d -} - -func (o *OverrideModuleBase) ModuleDir() string { - return o.moduleDir -} - func (o *OverrideModuleBase) getOverridingProperties() []interface{} { return o.overridingProperties } @@ -118,12 +102,8 @@ type OverridableModule interface { setOverridableProperties(prop []interface{}) - addOverride(o OverrideModule) - getOverrides() []OverrideModule - - override(ctx BaseModuleContext, bm OverridableModule, o OverrideModule) + override(ctx BaseModuleContext, bm OverridableModule, info overrideTransitionMutatorInfo) GetOverriddenBy() string - GetOverriddenByModuleDir() string setOverridesProperty(overridesProperties *[]string) @@ -133,20 +113,11 @@ type OverridableModule interface { } type overridableModuleProperties struct { - OverriddenBy string `blueprint:"mutated"` - OverriddenByModuleDir string `blueprint:"mutated"` + OverriddenBy string `blueprint:"mutated"` } // Base module struct for overridable module types type OverridableModuleBase struct { - // List of OverrideModules that override this base module - overrides []OverrideModule - // Used to parallelize registerOverrideMutator executions. Note that only addOverride locks this - // mutex. It is because addOverride and getOverride are used in different mutators, and so are - // guaranteed to be not mixed. (And, getOverride only reads from overrides, and so don't require - // mutex locking.) - overridesLock sync.Mutex - overridableProperties []interface{} // If an overridable module has a property to list other modules that itself overrides, it should @@ -171,30 +142,14 @@ func (b *OverridableModuleBase) setOverridableProperties(prop []interface{}) { b.overridableProperties = prop } -func (b *OverridableModuleBase) addOverride(o OverrideModule) { - b.overridesLock.Lock() - b.overrides = append(b.overrides, o) - b.overridesLock.Unlock() -} - -// Should NOT be used in the same mutator as addOverride. -func (b *OverridableModuleBase) getOverrides() []OverrideModule { - b.overridesLock.Lock() - sort.Slice(b.overrides, func(i, j int) bool { - return b.overrides[i].Name() < b.overrides[j].Name() - }) - b.overridesLock.Unlock() - return b.overrides -} - func (b *OverridableModuleBase) setOverridesProperty(overridesProperty *[]string) { b.overridesProperty = overridesProperty } // Overrides a base module with the given OverrideModule. -func (b *OverridableModuleBase) override(ctx BaseModuleContext, bm OverridableModule, o OverrideModule) { +func (b *OverridableModuleBase) override(ctx BaseModuleContext, bm OverridableModule, info overrideTransitionMutatorInfo) { for _, p := range b.overridableProperties { - for _, op := range o.getOverridingProperties() { + for _, op := range info.overridingProperties { if proptools.TypeEqual(p, op) { err := proptools.ExtendProperties(p, op, nil, proptools.OrderReplace) if err != nil { @@ -212,8 +167,7 @@ func (b *OverridableModuleBase) override(ctx BaseModuleContext, bm OverridableMo if b.overridesProperty != nil { *b.overridesProperty = append(*b.overridesProperty, ctx.OtherModuleName(bm)) } - b.overridableModuleProperties.OverriddenBy = o.Name() - b.overridableModuleProperties.OverriddenByModuleDir = o.ModuleDir() + b.overridableModuleProperties.OverriddenBy = info.name } // GetOverriddenBy returns the name of the override module that has overridden this module. @@ -224,19 +178,14 @@ func (b *OverridableModuleBase) GetOverriddenBy() string { return b.overridableModuleProperties.OverriddenBy } -func (b *OverridableModuleBase) GetOverriddenByModuleDir() string { - return b.overridableModuleProperties.OverriddenByModuleDir -} - func (b *OverridableModuleBase) OverridablePropertiesDepsMutator(ctx BottomUpMutatorContext) { } // Mutators for override/overridable modules. All the fun happens in these functions. It is critical // to keep them in this order and not put any order mutators between them. func RegisterOverridePostDepsMutators(ctx RegisterMutatorsContext) { - ctx.BottomUp("override_deps", overrideModuleDepsMutator).MutatesDependencies() // modifies deps via addOverride - ctx.Transition("override", &overrideTransitionMutator{}) - ctx.BottomUp("override_apply", overrideApplyMutator).MutatesDependencies() + ctx.BottomUp("override_deps", overrideModuleDepsMutator) + ctx.InfoBasedTransition("override", NewGenericTransitionMutatorAdapter(&overrideTransitionMutator{})) // overridableModuleDepsMutator calls OverridablePropertiesDepsMutator so that overridable modules can // add deps from overridable properties. ctx.BottomUp("overridable_deps", overridableModuleDepsMutator) @@ -272,97 +221,111 @@ func overrideModuleDepsMutator(ctx BottomUpMutatorContext) { ctx.PropertyErrorf("base", "%q is not a valid module name", base) return } - baseModule := ctx.AddDependency(ctx.Module(), overrideBaseDepTag, *module.getOverrideModuleProperties().Base)[0] - if o, ok := baseModule.(OverridableModule); ok { - overrideModule := ctx.Module().(OverrideModule) - overrideModule.setModuleDir(ctx.ModuleDir()) - o.addOverride(overrideModule) + + ctx.AddDependency(ctx.Module(), overrideBaseDepTag, *module.getOverrideModuleProperties().Base) + + info := overrideTransitionMutatorInfo{ + name: module.Name(), + overridingProperties: module.getOverridingProperties(), + } + + prebuiltDeps := ctx.GetDirectDepsWithTag(PrebuiltDepTag) + for _, prebuiltDep := range prebuiltDeps { + prebuilt := GetEmbeddedPrebuilt(prebuiltDep) + if prebuilt == nil { + panic("PrebuiltDepTag leads to a non-prebuilt module " + prebuiltDep.Name()) + } + info.overrideModuleUsePrebuilt = info.overrideModuleUsePrebuilt || prebuilt.UsePrebuilt() + info.overrideModulePrebuiltPartitions = append(info.overrideModulePrebuiltPartitions, + prebuiltDep.PartitionTag(ctx.DeviceConfig())) + info.overrideModulePrebuiltNames = append(info.overrideModulePrebuiltNames, + ctx.OtherModuleName(prebuiltDep)) } + SetProvider(ctx, overrideModuleDefaultInfoProvider, info) } } +var overrideModuleDefaultInfoProvider = blueprint.NewMutatorProvider[overrideTransitionMutatorInfo]("override_deps") + // Now, goes through all overridable modules, finds all modules overriding them, creates a local // variant for each of them, and performs the actual overriding operation by calling override(). type overrideTransitionMutator struct{} -func (overrideTransitionMutator) Split(ctx BaseModuleContext) []string { - if b, ok := ctx.Module().(OverridableModule); ok { - overrides := b.getOverrides() - if len(overrides) == 0 { - return []string{""} - } - variants := make([]string, len(overrides)+1) - // The first variant is for the original, non-overridden, base module. - variants[0] = "" - for i, o := range overrides { - variants[i+1] = o.(Module).Name() - } - return variants - } else if o, ok := ctx.Module().(OverrideModule); ok { +var _ TransitionMutator[overrideTransitionMutatorInfo] = (*overrideTransitionMutator)(nil) + +type overrideTransitionMutatorInfo struct { + name string + overridingProperties []interface{} `blueprint:"allow_configurable_in_provider"` + + overrideModuleUsePrebuilt bool + overrideModulePrebuiltPartitions []string + overrideModulePrebuiltNames []string +} + +var overrideTransitionMutatorEmptyVariation = overrideTransitionMutatorInfo{name: ""} + +func (info overrideTransitionMutatorInfo) Variation() string { + return info.name +} + +func (overrideTransitionMutator) Split(ctx BaseModuleContext) []overrideTransitionMutatorInfo { + if _, ok := ctx.Module().(OverrideModule); ok { // Create a variant of the overriding module with its own name. This matches the above local // variant name rule for overridden modules, and thus allows ReplaceDependencies to match the // two. - return []string{o.Name()} + info, _ := ModuleProvider(ctx, overrideModuleDefaultInfoProvider) + return []overrideTransitionMutatorInfo{info} } - return []string{""} + return []overrideTransitionMutatorInfo{overrideTransitionMutatorEmptyVariation} } -func (overrideTransitionMutator) OutgoingTransition(ctx OutgoingTransitionContext, sourceVariation string) string { - if o, ok := ctx.Module().(OverrideModule); ok { +func (overrideTransitionMutator) OutgoingTransition(ctx OutgoingTransitionContext, sourceInfo overrideTransitionMutatorInfo) overrideTransitionMutatorInfo { + if _, ok := ctx.Module().(OverrideModule); ok { if ctx.DepTag() == overrideBaseDepTag { - return o.Name() + return sourceInfo } } // Variations are always local and shouldn't affect the variant used for dependencies - return "" + return overrideTransitionMutatorEmptyVariation } -func (overrideTransitionMutator) IncomingTransition(ctx IncomingTransitionContext, incomingVariation string) string { +func (overrideTransitionMutator) IncomingTransition(ctx IncomingTransitionContext, incomingInfo overrideTransitionMutatorInfo) overrideTransitionMutatorInfo { if _, ok := ctx.Module().(OverridableModule); ok { - return incomingVariation - } else if o, ok := ctx.Module().(OverrideModule); ok { + return incomingInfo + } else if _, ok := ctx.Module().(OverrideModule); ok { // To allow dependencies to be added without having to know the variation. - return o.Name() + info, _ := ModuleProvider(ctx, overrideModuleDefaultInfoProvider) + return info } - return "" -} - -func (overrideTransitionMutator) Mutate(ctx BottomUpMutatorContext, variation string) { + return overrideTransitionMutatorEmptyVariation } -func overrideApplyMutator(ctx BottomUpMutatorContext) { - if o, ok := ctx.Module().(OverrideModule); ok { - overridableDeps := ctx.GetDirectDepsWithTag(overrideBaseDepTag) - if len(overridableDeps) > 1 { - panic(fmt.Errorf("expected a single dependency with overrideBaseDepTag, found %q", overridableDeps)) - } else if len(overridableDeps) == 1 { - b := overridableDeps[0].(OverridableModule) - b.override(ctx, b, o) +func (overrideTransitionMutator) Mutate(ctx BottomUpMutatorContext, info overrideTransitionMutatorInfo) { + if info.name != "" { + if b, ok := ctx.Module().(OverridableModule); ok { + b.override(ctx, b, info) - checkPrebuiltReplacesOverride(ctx, b) + checkPrebuiltReplacesOverride(ctx, b, info) } } } -func checkPrebuiltReplacesOverride(ctx BottomUpMutatorContext, b OverridableModule) { +func (overrideTransitionMutator) TransitionInfoFromVariation(variation string) overrideTransitionMutatorInfo { + panic(fmt.Errorf("not implemented")) +} + +func checkPrebuiltReplacesOverride(ctx BottomUpMutatorContext, bm OverridableModule, info overrideTransitionMutatorInfo) { // See if there's a prebuilt module that overrides this override module with prefer flag, // in which case we call HideFromMake on the corresponding variant later. - prebuiltDeps := ctx.GetDirectDepsWithTag(PrebuiltDepTag) - for _, prebuiltDep := range prebuiltDeps { - prebuilt := GetEmbeddedPrebuilt(prebuiltDep) - if prebuilt == nil { - panic("PrebuiltDepTag leads to a non-prebuilt module " + prebuiltDep.Name()) - } - if prebuilt.UsePrebuilt() { - // The overriding module itself, too, is overridden by a prebuilt. - // Perform the same check for replacement - checkInvariantsForSourceAndPrebuilt(ctx, b, prebuiltDep) - // Copy the flag and hide it in make - b.ReplacedByPrebuilt() - } + if info.overrideModuleUsePrebuilt { + // The overriding module itself, too, is overridden by a prebuilt. + // Perform the same check for replacement + checkInvariantsForSourceAndPrebuilt(ctx, bm.PartitionTag(ctx.DeviceConfig()), info.overrideModulePrebuiltPartitions, info.overrideModulePrebuiltNames) + // Copy the flag and hide it in make + bm.ReplacedByPrebuilt() } } diff --git a/android/prebuilt.go b/android/prebuilt.go index a13c8d0bd..8ce0842fa 100644 --- a/android/prebuilt.go +++ b/android/prebuilt.go @@ -496,15 +496,13 @@ func PrebuiltSourceDepsMutator(ctx BottomUpMutatorContext) { // checkInvariantsForSourceAndPrebuilt checks if invariants are kept when replacing // source with prebuilt. Note that the current module for the context is the source module. -func checkInvariantsForSourceAndPrebuilt(ctx BaseModuleContext, s, p Module) { - if _, ok := s.(OverrideModule); ok { - // skip the check when the source module is `override_X` because it's only a placeholder - // for the actual source module. The check will be invoked for the actual module. - return - } - if sourcePartition, prebuiltPartition := s.PartitionTag(ctx.DeviceConfig()), p.PartitionTag(ctx.DeviceConfig()); sourcePartition != prebuiltPartition { - ctx.OtherModuleErrorf(p, "partition is different: %s(%s) != %s(%s)", - sourcePartition, ctx.ModuleName(), prebuiltPartition, ctx.OtherModuleName(p)) +func checkInvariantsForSourceAndPrebuilt(ctx BaseModuleContext, sourcePartition string, + prebuiltPartitions, prebuiltModuleNames []string) { + for i, prebuiltPartition := range prebuiltPartitions { + if sourcePartition != prebuiltPartition { + ctx.ModuleErrorf("partition is different: %s(%s) != %s(%s)", + sourcePartition, ctx.ModuleName(), prebuiltPartition, prebuiltModuleNames[i]) + } } } @@ -541,7 +539,15 @@ func PrebuiltSelectModuleMutator(ctx BottomUpMutatorContext) { ctx.VisitDirectDepsWithTag(PrebuiltDepTag, func(prebuiltModule Module) { p := GetEmbeddedPrebuilt(prebuiltModule) if p.usePrebuilt(ctx, s, prebuiltModule) { - checkInvariantsForSourceAndPrebuilt(ctx, s, prebuiltModule) + // skip the check when the source module is `override_X` because it's only a placeholder + // for the actual source module. The check will be invoked for the actual module. + if _, isOverride := s.(OverrideModule); !isOverride { + sourcePartition := s.PartitionTag(ctx.DeviceConfig()) + prebuiltPartition := prebuiltModule.PartitionTag(ctx.DeviceConfig()) + checkInvariantsForSourceAndPrebuilt(ctx, sourcePartition, []string{prebuiltPartition}, + []string{ctx.OtherModuleName(prebuiltModule)}) + + } p.properties.UsePrebuilt = true s.ReplacedByPrebuilt() -- cgit v1.2.3 From 0235be1e0c145d4161f050ff633c642225d04369 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kosi=C5=84ski?= Date: Thu, 27 Mar 2025 01:55:48 +0000 Subject: Put AArch64 branch protection flags in a feature. I need to add ARMv8.5-A and ARMv8.7-A and the duplication was getting out of hand. Instead of specifying these as arch variant flags, specify them as arch feature flags for a new feature called "branchprot" that is enabled on the relevant variants. This also fixes an inconsitency where armv8-a-branchprot enabled branch protection, but didn't disable the stack protector, which appears to have been an omission. Bug: 364383722 Test: inspect compilation flags in a local build, presubmit Flag: EXEMPT infeasible Change-Id: Ib5f89b5f0f7a597118edaf2b7a70dbad515616f5 --- android/arch_list.go | 8 ++++++++ cc/config/arm64_device.go | 48 +++++++++++++++------------------------------ rust/config/arm64_device.go | 39 +++++++++++++----------------------- 3 files changed, 38 insertions(+), 57 deletions(-) diff --git a/android/arch_list.go b/android/arch_list.go index 8659549ca..202416f8f 100644 --- a/android/arch_list.go +++ b/android/arch_list.go @@ -115,6 +115,7 @@ var cpuVariants = map[ArchType][]string{ var archFeatures = map[ArchType][]string{ Arm64: { + "branchprot", "dotprod", }, X86: { @@ -144,19 +145,26 @@ var archFeatures = map[ArchType][]string{ var androidArchFeatureMap = map[ArchType]map[string][]string{ Arm64: { + "armv8-a-branchprot": { + "branchprot", + }, "armv8-2a-dotprod": { "dotprod", }, "armv9-a": { + "branchprot", "dotprod", }, "armv9-2a": { + "branchprot", "dotprod", }, "armv9-3a": { + "branchprot", "dotprod", }, "armv9-4a": { + "branchprot", "dotprod", }, }, diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go index 25edb798d..8132cd807 100644 --- a/cc/config/arm64_device.go +++ b/cc/config/arm64_device.go @@ -28,38 +28,19 @@ var ( } arm64ArchVariantCflags = map[string][]string{ - "armv8-a": []string{ - "-march=armv8-a", - }, - "armv8-a-branchprot": []string{ - "-march=armv8-a", - "-mbranch-protection=standard", - }, - "armv8-2a": []string{ - "-march=armv8.2-a", - }, - "armv8-2a-dotprod": []string{ - "-march=armv8.2-a+dotprod", - }, - // On ARMv9 and later, Pointer Authentication Codes (PAC) are mandatory, - // so -fstack-protector is unnecessary. - "armv9-a": []string{ - "-march=armv9-a", - "-mbranch-protection=standard", - "-fno-stack-protector", - }, - "armv9-2a": []string{ - "-march=armv9.2-a", - "-mbranch-protection=standard", - "-fno-stack-protector", - }, - "armv9-3a": []string{ - "-march=armv9.3-a", - "-mbranch-protection=standard", - "-fno-stack-protector", - }, - "armv9-4a": []string{ - "-march=armv9.4-a", + "armv8-a": {"-march=armv8-a"}, + "armv8-a-branchprot": {"-march=armv8-a"}, + "armv8-2a": {"-march=armv8.2-a"}, + "armv8-2a-dotprod": {"-march=armv8.2-a+dotprod"}, + "armv9-a": {"-march=armv9-a"}, + "armv9-2a": {"-march=armv9.2-a"}, + "armv9-3a": {"-march=armv9.3-a"}, + "armv9-4a": {"-march=armv9.4-a"}, + } + + arm64ArchFeatureCflags = map[string][]string{ + // When Pointer Authentication Codes (PAC) are available, -fstack-protector is unnecessary. + "branchprot": { "-mbranch-protection=standard", "-fno-stack-protector", }, @@ -219,6 +200,9 @@ func arm64ToolchainFactory(arch android.Arch) Toolchain { toolchainCflags := []string{"${config.Arm64" + arch.ArchVariant + "VariantCflags}"} toolchainCflags = append(toolchainCflags, variantOrDefault(arm64CpuVariantCflagsVar, arch.CpuVariant)) + for _, feature := range arch.ArchFeatures { + toolchainCflags = append(toolchainCflags, arm64ArchFeatureCflags[feature]...) + } extraLdflags := variantOrDefault(arm64CpuVariantLdflags, arch.CpuVariant) return &toolchainArm64{ diff --git a/rust/config/arm64_device.go b/rust/config/arm64_device.go index efcd56a7b..cdbde1996 100644 --- a/rust/config/arm64_device.go +++ b/rust/config/arm64_device.go @@ -24,36 +24,25 @@ var ( Arm64RustFlags = []string{ "-C force-frame-pointers=y", } - Arm64ArchFeatureRustFlags = map[string][]string{} - Arm64LinkFlags = []string{} - - Arm64ArchVariantRustFlags = map[string][]string{ - "armv8-a": []string{}, - "armv8-a-branchprot": []string{ - // branch-protection=bti,pac-ret is equivalent to Clang's mbranch-protection=standard - "-Z branch-protection=bti,pac-ret", - }, - "armv8-2a": []string{}, - "armv8-2a-dotprod": []string{}, - + Arm64ArchFeatureRustFlags = map[string][]string{ // branch-protection=bti,pac-ret is equivalent to Clang's mbranch-protection=standard - "armv9-a": []string{ - "-Z branch-protection=bti,pac-ret", - "-Z stack-protector=none", - }, - "armv9-2a": []string{ - "-Z branch-protection=bti,pac-ret", - "-Z stack-protector=none", - }, - "armv9-3a": []string{ - "-Z branch-protection=bti,pac-ret", - "-Z stack-protector=none", - }, - "armv9-4a": []string{ + "branchprot": { "-Z branch-protection=bti,pac-ret", "-Z stack-protector=none", }, } + Arm64LinkFlags = []string{} + + Arm64ArchVariantRustFlags = map[string][]string{ + "armv8-a": {}, + "armv8-a-branchprot": {}, + "armv8-2a": {}, + "armv8-2a-dotprod": {}, + "armv9-a": {}, + "armv9-2a": {}, + "armv9-3a": {}, + "armv9-4a": {}, + } ) func init() { -- cgit v1.2.3 From 1823790ae735e2c877c46c13ef42eb98d4b6eeb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kosi=C5=84ski?= Date: Thu, 27 Mar 2025 20:26:19 +0000 Subject: Add ARMv8.5-A and ARMv8.7-A arch variants. ARMv8.5-A is approximately equivalent to ARMv9-A without SVE, and ARMv8.7-A is equivalent to ARMv9.2-A without SVE. Bug: 364383722 Test: Local build with the new arch Flag: EXEMPT no impact on production code Change-Id: I569890611fe15893f184bf42d96d095ae3ecd14d --- android/arch_list.go | 10 ++++++++++ cc/config/arm64_device.go | 2 ++ rust/config/arm64_device.go | 2 ++ 3 files changed, 14 insertions(+) diff --git a/android/arch_list.go b/android/arch_list.go index 202416f8f..4ef8e7319 100644 --- a/android/arch_list.go +++ b/android/arch_list.go @@ -25,6 +25,8 @@ var archVariants = map[ArchType][]string{ "armv8-a-branchprot", "armv8-2a", "armv8-2a-dotprod", + "armv8-5a", + "armv8-7a", "armv9-a", "armv9-2a", "armv9-3a", @@ -151,6 +153,14 @@ var androidArchFeatureMap = map[ArchType]map[string][]string{ "armv8-2a-dotprod": { "dotprod", }, + "armv8-5a": { + "branchprot", + "dotprod", + }, + "armv8-7a": { + "branchprot", + "dotprod", + }, "armv9-a": { "branchprot", "dotprod", diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go index 8132cd807..7bf5117f2 100644 --- a/cc/config/arm64_device.go +++ b/cc/config/arm64_device.go @@ -32,6 +32,8 @@ var ( "armv8-a-branchprot": {"-march=armv8-a"}, "armv8-2a": {"-march=armv8.2-a"}, "armv8-2a-dotprod": {"-march=armv8.2-a+dotprod"}, + "armv8-5a": {"-march=armv8.5-a"}, + "armv8-7a": {"-march=armv8.7-a"}, "armv9-a": {"-march=armv9-a"}, "armv9-2a": {"-march=armv9.2-a"}, "armv9-3a": {"-march=armv9.3-a"}, diff --git a/rust/config/arm64_device.go b/rust/config/arm64_device.go index cdbde1996..533ace773 100644 --- a/rust/config/arm64_device.go +++ b/rust/config/arm64_device.go @@ -38,6 +38,8 @@ var ( "armv8-a-branchprot": {}, "armv8-2a": {}, "armv8-2a-dotprod": {}, + "armv8-5a": {}, + "armv8-7a": {}, "armv9-a": {}, "armv9-2a": {}, "armv9-3a": {}, -- cgit v1.2.3 From 6f4c1f59e3916b67027640608a869ce69e362312 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Thu, 27 Mar 2025 10:58:43 -0700 Subject: Reapply "Always install test files with soong" This reverts commit fa403882d5aa0fa3d4f7a77e4e52409357626938. This is a resubmission with a change to disable building the test suites when ndk or aml abis are enabled in the config. Without this, the extra abis cause multiple variants (x86_64 and arm64) to try to install to the same testcase folder file. Bug: 388850000 Test: Presubmits Change-Id: I67c14a7cc6acb6a166ef222dd5776145e2d45e4d --- android/arch_module_context.go | 18 ++- android/module.go | 202 +++++++++++++++++++++++++++++++-- android/module_context.go | 15 +++ android/test_suites.go | 76 +++++++++++++ android/variable.go | 7 ++ cc/binary.go | 4 - cc/cc.go | 4 - cc/library.go | 4 - cc/object.go | 4 - cc/test.go | 91 ++++++++------- java/app.go | 71 ++++++++---- java/app_import.go | 14 ++- java/base.go | 5 +- java/fuzz.go | 27 ++++- java/java.go | 58 ++++++---- python/binary.go | 10 +- python/test.go | 32 +++--- rust/benchmark.go | 13 ++- rust/test.go | 38 ++----- sh/sh_binary.go | 15 ++- tradefed_modules/test_module_config.go | 17 ++- 21 files changed, 543 insertions(+), 182 deletions(-) diff --git a/android/arch_module_context.go b/android/arch_module_context.go index a3a03af02..7c440ad00 100644 --- a/android/arch_module_context.go +++ b/android/arch_module_context.go @@ -30,17 +30,19 @@ type ArchModuleContext interface { Darwin() bool Windows() bool PrimaryArch() bool + PrimaryNativeBridgeArch() bool } type archModuleContext struct { // TODO: these should eventually go through a (possibly cached) provider like any other configuration instead // of being special cased. - ready bool - os OsType - target Target - targetPrimary bool - multiTargets []Target - primaryArch bool + ready bool + os OsType + target Target + targetPrimary bool + multiTargets []Target + primaryArch bool + primaryNativeBridgeArch bool } // ArchReady returns true if the arch mutator has run on the module. Before this returns @@ -89,3 +91,7 @@ func (a *archModuleContext) Windows() bool { func (b *archModuleContext) PrimaryArch() bool { return b.primaryArch } + +func (b *archModuleContext) PrimaryNativeBridgeArch() bool { + return b.primaryNativeBridgeArch +} diff --git a/android/module.go b/android/module.go index 55f170cfe..da3c8ad70 100644 --- a/android/module.go +++ b/android/module.go @@ -28,6 +28,7 @@ import ( "github.com/google/blueprint" "github.com/google/blueprint/depset" "github.com/google/blueprint/gobtools" + "github.com/google/blueprint/pathtools" "github.com/google/blueprint/proptools" ) @@ -1836,14 +1837,27 @@ func (m *ModuleBase) archModuleContextFactory(ctx archModuleContextFactoryContex } else { primaryArch = target.Arch.ArchType == config.Targets[target.Os][0].Arch.ArchType } + primaryNativeBridgeArch := false + if target.NativeBridge { + for _, t := range config.Targets[target.Os] { + if t.NativeBridge { + if target.Arch.ArchType == t.Arch.ArchType { + primaryNativeBridgeArch = true + } + // Don't consider further nativebridge targets + break + } + } + } return archModuleContext{ - ready: m.commonProperties.ArchReady, - os: m.commonProperties.CompileOS, - target: m.commonProperties.CompileTarget, - targetPrimary: m.commonProperties.CompilePrimary, - multiTargets: m.commonProperties.CompileMultiTargets, - primaryArch: primaryArch, + ready: m.commonProperties.ArchReady, + os: m.commonProperties.CompileOS, + target: m.commonProperties.CompileTarget, + targetPrimary: m.commonProperties.CompilePrimary, + multiTargets: m.commonProperties.CompileMultiTargets, + primaryArch: primaryArch, + primaryNativeBridgeArch: primaryNativeBridgeArch, } } @@ -2140,6 +2154,10 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) m.generateVariantTarget(ctx) + testData := FirstUniqueFunc(ctx.testData, func(a, b DataPath) bool { + return a == b + }) + installFiles.LicenseMetadataFile = ctx.licenseMetadataFile installFiles.InstallFiles = ctx.installFiles installFiles.CheckbuildFiles = ctx.checkbuildFiles @@ -2148,7 +2166,7 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) installFiles.PackagingSpecs = ctx.packagingSpecs installFiles.KatiInstalls = ctx.katiInstalls installFiles.KatiSymlinks = ctx.katiSymlinks - installFiles.TestData = ctx.testData + installFiles.TestData = testData } else if ctx.Config().AllowMissingDependencies() { // If the module is not enabled it will not create any build rules, nothing will call // ctx.GetMissingDependencies(), and blueprint will consider the missing dependencies to be unhandled @@ -2180,6 +2198,10 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) SetProvider(ctx, InstallFilesProvider, installFiles) buildLicenseMetadata(ctx, ctx.licenseMetadataFile) + if ctx.testSuiteInfoSet { + m.setupTestSuites(ctx, ctx.testSuiteInfo) + } + if len(ctx.moduleInfoJSON) > 0 { for _, moduleInfoJSON := range ctx.moduleInfoJSON { if moduleInfoJSON.Disabled { @@ -2397,6 +2419,172 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) } } +func (m *ModuleBase) CleanupAfterBuildActions() {} + +func (m *ModuleBase) setupTestSuites(ctx ModuleContext, info TestSuiteInfo) { + // We skip test suites when using the ndk or aml abis, as the extra archs (x86_64 + arm64) + // both try to install to the same test file. This could be fixed by always using a per-module + // folder and an arch folder, but as you see later in this function we only conditionally use + // those. + if ctx.Config().NdkAbis() || ctx.Config().AmlAbis() || shouldSkipAndroidMkProcessing(ctx, m) || m.IsSkipInstall() { + return + } + overriddenBy := "" + if b, ok := ctx.Module().(OverridableModule); ok { + overriddenBy = b.GetOverriddenBy() + } + + // M(C)TS supports a full test suite and partial per-module MTS test suites, with naming mts-${MODULE}. + // To reduce repetition, if we find a partial M(C)TS test suite without an full M(C)TS test suite, + // we add the full test suite to our list. + if PrefixInList(info.TestSuites, "mts-") && !InList("mts", info.TestSuites) { + info.TestSuites = append(info.TestSuites, "mts") + } + if PrefixInList(info.TestSuites, "mcts-") && !InList("mcts", info.TestSuites) { + info.TestSuites = append(info.TestSuites, "mcts") + } + + if len(info.TestSuites) == 0 { + info.TestSuites = []string{"null-suite"} + } + info.TestSuites = SortedUniqueStrings(info.TestSuites) + + name := ctx.ModuleName() + if overriddenBy != "" { + name = overriddenBy + } + name += info.NameSuffix + + type testSuiteInfo struct { + name string + dir WritablePath + includeModuleFolder bool + } + + suites := []testSuiteInfo{{ + dir: PathForModuleInPartitionInstall(ctx, "testcases", name), + includeModuleFolder: true, + }} + for _, suite := range info.TestSuites { + if suiteInfo, ok := ctx.Config().productVariables.CompatibilityTestcases[suite]; ok { + rel, err := filepath.Rel(ctx.Config().OutDir(), suiteInfo.OutDir) + if err != nil { + panic(fmt.Sprintf("Could not make COMPATIBILITY_TESTCASES_OUT_%s (%s) relative to the out dir (%s)", suite, suiteInfo.OutDir, ctx.Config().OutDir())) + } + if suiteInfo.IncludeModuleFolder || info.PerTestcaseDirectory { + rel = filepath.Join(rel, name) + } + suites = append(suites, testSuiteInfo{ + name: suite, + dir: PathForArbitraryOutput(ctx, rel), + includeModuleFolder: suiteInfo.IncludeModuleFolder || info.PerTestcaseDirectory, + }) + } + } + + var archDir string + if info.NeedsArchFolder { + archDir = ctx.Arch().ArchType.Name + if archDir == "common" { + archDir = ctx.DeviceConfig().DeviceArch() + } + if ctx.Target().NativeBridge { + archDir = ctx.Target().NativeBridgeHostArchName + } + } + + var installs []filePair + + for _, suite := range suites { + mainFileName := name + if info.MainFileStem != "" { + mainFileName = info.MainFileStem + } + mainFileName += info.MainFileExt + mainFileInstall := joinWriteablePath(ctx, suite.dir, archDir, mainFileName) + if !suite.includeModuleFolder { + mainFileInstall = joinWriteablePath(ctx, suite.dir, mainFileName) + } + if info.MainFile == nil { + panic("mainfile was nil") + } + + installs = append(installs, filePair{ + src: info.MainFile, + dst: mainFileInstall, + }) + + for _, data := range info.Data { + dataOut := joinWriteablePath(ctx, suite.dir, archDir, data.ToRelativeInstallPath()) + if !suite.includeModuleFolder { + dataOut = joinWriteablePath(ctx, suite.dir, data.ToRelativeInstallPath()) + } + installs = append(installs, filePair{ + src: data.SrcPath, + dst: dataOut, + }) + } + for _, data := range info.NonArchData { + dataOut := joinWriteablePath(ctx, suite.dir, data.ToRelativeInstallPath()) + installs = append(installs, filePair{ + src: data.SrcPath, + dst: dataOut, + }) + } + for _, data := range info.CompatibilitySupportFiles { + dataOut := joinWriteablePath(ctx, suite.dir, data.Rel()) + installs = append(installs, filePair{ + src: data, + dst: dataOut, + }) + } + + if ctx.TargetPrimary() || ctx.PrimaryNativeBridgeArch() { + if info.ConfigFile != nil { + installs = append(installs, filePair{ + src: info.ConfigFile, + dst: joinWriteablePath(ctx, suite.dir, name+".config"+info.ConfigFileSuffix), + }) + } else if config := ExistentPathForSource(ctx, ctx.ModuleDir(), "AndroidTest.xml"); config.Valid() { + installs = append(installs, filePair{ + src: config.Path(), + dst: joinWriteablePath(ctx, suite.dir, name+".config"), + }) + } + dynamicConfig := ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml") + if dynamicConfig.Valid() { + installs = append(installs, filePair{ + src: dynamicConfig.Path(), + dst: joinWriteablePath(ctx, suite.dir, name+".dynamic"), + }) + } + for _, extraTestConfig := range info.ExtraConfigs { + if extraTestConfig == nil { + panic("ExtraTestConfig was nil") + } + installs = append(installs, filePair{ + src: extraTestConfig, + dst: joinWriteablePath(ctx, suite.dir, pathtools.ReplaceExtension(extraTestConfig.Base(), "config")), + }) + } + } + } + + SetProvider(ctx, TestSuiteInfoProvider, info) + SetProvider(ctx, testSuiteInstallsInfoProvider, testSuiteInstallsInfo{installs}) +} + +func joinWriteablePath(ctx PathContext, path WritablePath, toJoin ...string) WritablePath { + switch p := path.(type) { + case InstallPath: + return p.Join(ctx, toJoin...) + case OutputPath: + return p.Join(ctx, toJoin...) + default: + panic("unhandled path type") + } +} + func SetJarJarPrefixHandler(handler func(ModuleContext)) { if jarJarPrefixHandler != nil { panic("jarJarPrefixHandler already set") diff --git a/android/module_context.go b/android/module_context.go index e30afd637..3542671ac 100644 --- a/android/module_context.go +++ b/android/module_context.go @@ -275,6 +275,10 @@ type ModuleContext interface { // directory on the build server with the given filename when any of the // specified goals are built. DistForGoalsWithFilename(goals []string, path Path, filename string) + + // Defines this module as a compatibility suite test and gives all the information needed + // to build the suite. + SetTestSuiteInfo(info TestSuiteInfo) } type moduleContext struct { @@ -334,6 +338,9 @@ type moduleContext struct { complianceMetadataInfo *ComplianceMetadataInfo dists []dist + + testSuiteInfo TestSuiteInfo + testSuiteInfoSet bool } var _ ModuleContext = &moduleContext{} @@ -1041,3 +1048,11 @@ func (c *moduleContext) DistForGoalsWithFilename(goals []string, path Path, file paths: distCopies{{from: path, dest: filename}}, }) } + +func (c *moduleContext) SetTestSuiteInfo(info TestSuiteInfo) { + if c.testSuiteInfoSet { + panic("Cannot call SetTestSuiteInfo twice") + } + c.testSuiteInfo = info + c.testSuiteInfoSet = true +} diff --git a/android/test_suites.go b/android/test_suites.go index dbcd48c79..88a410eb1 100644 --- a/android/test_suites.go +++ b/android/test_suites.go @@ -16,6 +16,8 @@ package android import ( "path/filepath" + "slices" + "sort" "strings" "github.com/google/blueprint" @@ -37,7 +39,34 @@ type TestSuiteModule interface { } type TestSuiteInfo struct { + // A suffix to append to the name of the test. + // Useful because historically different variants of soong modules became differently-named + // make modules, like "my_test.vendor" for the vendor variant. + NameSuffix string + TestSuites []string + + NeedsArchFolder bool + + MainFile Path + + MainFileStem string + + MainFileExt string + + ConfigFile Path + + ConfigFileSuffix string + + ExtraConfigs Paths + + PerTestcaseDirectory bool + + Data []DataPath + + NonArchData []DataPath + + CompatibilitySupportFiles []Path } var TestSuiteInfoProvider = blueprint.NewProvider[TestSuiteInfo]() @@ -48,8 +77,20 @@ type SupportFilesInfo struct { var SupportFilesInfoProvider = blueprint.NewProvider[SupportFilesInfo]() +type filePair struct { + src Path + dst WritablePath +} + +type testSuiteInstallsInfo struct { + Files []filePair +} + +var testSuiteInstallsInfoProvider = blueprint.NewProvider[testSuiteInstallsInfo]() + func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) { files := make(map[string]map[string]InstallPaths) + var toInstall []filePair ctx.VisitAllModuleProxies(func(m ModuleProxy) { if tsm, ok := OtherModuleProvider(ctx, m, TestSuiteInfoProvider); ok { @@ -62,7 +103,42 @@ func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) { OtherModuleProviderOrDefault(ctx, m, InstallFilesProvider).InstallFiles...) } } + if testSuiteInstalls, ok := OtherModuleProvider(ctx, m, testSuiteInstallsInfoProvider); ok { + installs := OtherModuleProviderOrDefault(ctx, m, InstallFilesProvider).InstallFiles + for _, f := range testSuiteInstalls.Files { + alreadyInstalled := false + for _, install := range installs { + if install.String() == f.dst.String() { + alreadyInstalled = true + break + } + } + if !alreadyInstalled { + toInstall = append(toInstall, f) + } + } + } + }) + + sort.Slice(toInstall, func(i, j int) bool { + c := strings.Compare(toInstall[i].src.String(), toInstall[j].src.String()) + if c < 0 { + return true + } else if c > 0 { + return false + } + return toInstall[i].dst.String() < toInstall[j].dst.String() }) + // Dedup, as multiple tests may install the same test data to the same folder + toInstall = slices.Compact(toInstall) + + for _, install := range toInstall { + ctx.Build(pctx, BuildParams{ + Rule: Cp, + Input: install.src, + Output: install.dst, + }) + } robolectricZip, robolectrictListZip := buildTestSuite(ctx, "robolectric-tests", files["robolectric-tests"]) ctx.Phony("robolectric-tests", robolectricZip, robolectrictListZip) diff --git a/android/variable.go b/android/variable.go index f00dd138b..b5ffa7cf8 100644 --- a/android/variable.go +++ b/android/variable.go @@ -550,6 +550,13 @@ type ProductVariables struct { UseSoongNoticeXML *bool `json:",omitempty"` StripByDefault *bool `json:",omitempty"` + + CompatibilityTestcases map[string]CompatibilityTestcaseJSON +} + +type CompatibilityTestcaseJSON struct { + OutDir string `json:",omitempty"` + IncludeModuleFolder bool `json:",omitempty"` } type PartitionQualifiedVariablesType struct { diff --git a/cc/binary.go b/cc/binary.go index 608251afc..627d5e560 100644 --- a/cc/binary.go +++ b/cc/binary.go @@ -551,10 +551,6 @@ func (binary *binaryDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON binary.baseLinker.moduleInfoJSON(ctx, moduleInfoJSON) } -func (binary *binaryDecorator) testSuiteInfo(ctx ModuleContext) { - // not a test -} - var _ overridable = (*binaryDecorator)(nil) func init() { diff --git a/cc/cc.go b/cc/cc.go index dc9b831f9..c50cb64a0 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -798,8 +798,6 @@ type linker interface { defaultDistFiles() []android.Path moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) - - testSuiteInfo(ctx ModuleContext) } // specifiedDeps is a tuple struct representing dependencies of a linked binary owned by the linker. @@ -2524,8 +2522,6 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { name := v.ImplementationModuleName(ctx.OtherModuleName(c)) ccInfo.LinkerInfo.ImplementationModuleName = &name } - - c.linker.testSuiteInfo(ctx) } if c.library != nil { ccInfo.LibraryInfo = &LibraryInfo{ diff --git a/cc/library.go b/cc/library.go index 5299771ca..b248224bd 100644 --- a/cc/library.go +++ b/cc/library.go @@ -1078,10 +1078,6 @@ func (library *libraryDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSO library.baseLinker.moduleInfoJSON(ctx, moduleInfoJSON) } -func (library *libraryDecorator) testSuiteInfo(ctx ModuleContext) { - // not a test -} - func (library *libraryDecorator) linkStatic(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path { diff --git a/cc/object.go b/cc/object.go index ea3ed6151..95a8beb52 100644 --- a/cc/object.go +++ b/cc/object.go @@ -250,7 +250,3 @@ func (object *objectLinker) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *an object.baseLinker.moduleInfoJSON(ctx, moduleInfoJSON) moduleInfoJSON.Class = []string{"STATIC_LIBRARIES"} } - -func (object *objectLinker) testSuiteInfo(ctx ModuleContext) { - // not a test -} diff --git a/cc/test.go b/cc/test.go index 9c276b81a..fed24671d 100644 --- a/cc/test.go +++ b/cc/test.go @@ -274,12 +274,6 @@ func (test *testDecorator) moduleInfoJSON(ctx android.ModuleContext, moduleInfoJ } } -func (test *testDecorator) testSuiteInfo(ctx ModuleContext) { - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: test.InstallerProperties.Test_suites, - }) -} - func NewTestInstaller() *baseInstaller { return NewBaseInstaller("nativetest", "nativetest64", InstallInData) } @@ -348,10 +342,6 @@ func (test *testBinary) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *androi } -func (test *testBinary) testSuiteInfo(ctx ModuleContext) { - test.testDecorator.testSuiteInfo(ctx) -} - func (test *testBinary) installerProps() []interface{} { return append(test.baseInstaller.installerProps(), test.testDecorator.installerProps()...) } @@ -422,32 +412,24 @@ func (test *testBinary) install(ctx ModuleContext, file android.Path) { test.Properties.Test_options.Unit_test = proptools.BoolPtr(true) } - if !ctx.Config().KatiEnabled() { // TODO(spandandas): Remove the special case for kati - // Install the test config in testcases/ directory for atest. - c, ok := ctx.Module().(*Module) - if !ok { - ctx.ModuleErrorf("Not a cc_test module") - } - // Install configs in the root of $PRODUCT_OUT/testcases/$module - testCases := android.PathForModuleInPartitionInstall(ctx, "testcases", ctx.ModuleName()+c.SubName()) - if ctx.PrimaryArch() { - 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) - } - } - // Install tests and data in arch specific subdir $PRODUCT_OUT/testcases/$module/$arch - testCases = testCases.Join(ctx, ctx.Target().Arch.ArchType.String()) - ctx.InstallTestData(testCases, test.data) - ctx.InstallFile(testCases, file.Base(), file) + // Install the test config in testcases/ directory for atest. + c, ok := ctx.Module().(*Module) + if !ok { + ctx.ModuleErrorf("Not a cc_test module") } + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + NameSuffix: c.SubName(), + TestSuites: test.InstallerProperties.Test_suites, + MainFile: file, + MainFileStem: file.Base(), + ConfigFile: test.testConfig, + ExtraConfigs: test.extraTestConfigs, + Data: test.data, + NeedsArchFolder: true, + PerTestcaseDirectory: Bool(test.Properties.Per_testcase_directory), + }) + test.binaryDecorator.baseInstaller.installTestData(ctx, test.data) test.binaryDecorator.baseInstaller.install(ctx, file) if Bool(test.Properties.Standalone_test) { @@ -588,8 +570,24 @@ func (test *testLibrary) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *andro test.testDecorator.moduleInfoJSON(ctx, moduleInfoJSON) } -func (test *testLibrary) testSuiteInfo(ctx ModuleContext) { - test.testDecorator.testSuiteInfo(ctx) +func (test *testLibrary) install(ctx ModuleContext, file android.Path) { + test.libraryDecorator.install(ctx, file) + + c, ok := ctx.Module().(*Module) + if !ok { + ctx.ModuleErrorf("Expected a cc module") + } + // host tests are not installed to testcases/ as per: + // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/base_rules.mk;l=251;drc=45efec6797cbf812df34dac9d05e43a9fe7217e0 + if test.shared() { + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + NameSuffix: c.SubName(), + TestSuites: test.InstallerProperties.Test_suites, + NeedsArchFolder: true, + MainFile: file, + MainFileStem: file.Base(), + }) + } } func (test *testLibrary) installerProps() []interface{} { @@ -684,6 +682,21 @@ func (benchmark *benchmarkDecorator) install(ctx ModuleContext, file android.Pat benchmark.binaryDecorator.baseInstaller.dir64 = filepath.Join("benchmarktest64", ctx.ModuleName()) benchmark.binaryDecorator.baseInstaller.installTestData(ctx, benchmark.data) benchmark.binaryDecorator.baseInstaller.install(ctx, file) + + c, ok := ctx.Module().(*Module) + if !ok { + ctx.ModuleErrorf("Not a cc module") + } + + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + NameSuffix: c.SubName(), + TestSuites: benchmark.Properties.Test_suites, + MainFile: file, + MainFileStem: file.Base(), + ConfigFile: benchmark.testConfig, + Data: benchmark.data, + NeedsArchFolder: true, + }) } func (benchmark *benchmarkDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) { @@ -709,12 +722,6 @@ func (benchmark *benchmarkDecorator) moduleInfoJSON(ctx ModuleContext, moduleInf } } -func (benchmark *benchmarkDecorator) testSuiteInfo(ctx ModuleContext) { - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: benchmark.Properties.Test_suites, - }) -} - func NewBenchmark(hod android.HostOrDeviceSupported) *Module { module, binary := newBinary(hod) module.multilib = android.MultilibBoth diff --git a/java/app.go b/java/app.go index 3a3253f04..6c1e4f6a5 100644 --- a/java/app.go +++ b/java/app.go @@ -427,8 +427,22 @@ func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleCon moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") } - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: a.appTestHelperAppProperties.Test_suites, + outputFile := a.installedOutputFile + if outputFile == nil { + outputFile = a.outputFile + } + var data []android.DataPath + for _, d := range a.extraOutputFiles { + data = append(data, android.DataPath{SrcPath: d}) + } + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: a.appTestHelperAppProperties.Test_suites, + MainFile: outputFile, + MainFileStem: a.installApkName, + MainFileExt: ".apk", + NeedsArchFolder: true, + NonArchData: data, + PerTestcaseDirectory: proptools.Bool(a.appTestHelperAppProperties.Per_testcase_directory), }) } @@ -980,10 +994,10 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { if ctx.ModuleName() == "framework-res" { // framework-res.apk is installed as system/framework/framework-res.apk a.installDir = android.PathForModuleInstall(ctx, "framework") - } else if a.Privileged() { - a.installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName) } else if ctx.InstallInTestcases() { a.installDir = android.PathForModuleInstall(ctx, a.installApkName, ctx.DeviceConfig().DeviceArch()) + } else if a.Privileged() { + a.installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName) } else { a.installDir = android.PathForModuleInstall(ctx, "app", a.installApkName) } @@ -1130,7 +1144,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { } } } - ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...) + a.installedOutputFile = ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...) } ctx.CheckbuildFile(a.outputFile) @@ -1679,22 +1693,33 @@ func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { 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() { - pathInTestCases := android.PathForModuleInstall(ctx, ctx.Module().Name()) - 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} - ctx.InstallTestData(pathInTestCases, []android.DataPath{dataPath}) - } - } + a.data = android.SortedUniquePaths(a.data) + a.extraTestConfigs = android.SortedUniquePaths(a.extraTestConfigs) + + testOutputFile := a.installedOutputFile + if testOutputFile == nil { + testOutputFile = a.outputFile + } + var testData []android.DataPath + for _, data := range a.data { + dataPath := android.DataPath{SrcPath: data} + testData = append(testData, dataPath) + } + for _, d := range a.extraOutputFiles { + testData = append(testData, android.DataPath{SrcPath: d}) + } + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: a.testProperties.Test_suites, + MainFile: testOutputFile, + MainFileStem: a.installApkName, + MainFileExt: ".apk", + ConfigFile: a.testConfig, + ExtraConfigs: a.extraTestConfigs, + NonArchData: testData, + CompatibilitySupportFiles: a.data, + NeedsArchFolder: true, + PerTestcaseDirectory: proptools.Bool(a.testProperties.Per_testcase_directory), + }) android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{ TestcaseRelDataFiles: testcaseRel(a.data), @@ -1729,10 +1754,6 @@ func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { moduleInfoJSON.AutoTestConfig = []string{"true"} } moduleInfoJSON.TestMainlineModules = append(moduleInfoJSON.TestMainlineModules, a.testProperties.Test_mainline_modules...) - - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: a.testProperties.Test_suites, - }) } func testcaseRel(paths android.Paths) []string { diff --git a/java/app_import.go b/java/app_import.go index 9fb13ba3c..837ab529b 100644 --- a/java/app_import.go +++ b/java/app_import.go @@ -788,8 +788,18 @@ func (a *AndroidTestImport) GenerateAndroidBuildActions(ctx android.ModuleContex a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data) - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: a.testProperties.Test_suites, + var data []android.DataPath + for _, d := range a.data { + data = append(data, android.DataPath{SrcPath: d}) + } + + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: a.testProperties.Test_suites, + MainFile: a.outputFile, + MainFileStem: a.outputFile.Base(), + NeedsArchFolder: true, + Data: data, + CompatibilitySupportFiles: a.data, }) } diff --git a/java/base.go b/java/base.go index a69733866..be7262b81 100644 --- a/java/base.go +++ b/java/base.go @@ -513,8 +513,9 @@ type Module struct { jacocoReportClassesFile android.Path // output file of the module, which may be a classes jar or a dex jar - outputFile android.Path - extraOutputFiles android.Paths + outputFile android.Path + installedOutputFile android.Path + extraOutputFiles android.Paths exportAidlIncludeDirs android.Paths ignoredAidlPermissionList android.Paths diff --git a/java/fuzz.go b/java/fuzz.go index 0e239f0ec..7271b9737 100644 --- a/java/fuzz.go +++ b/java/fuzz.go @@ -131,7 +131,32 @@ func (j *JavaFuzzTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { } - j.Test.GenerateAndroidBuildActions(ctx) + checkMinSdkVersionMts(ctx, j.MinSdkVersion(ctx)) + j.Test.generateAndroidBuildActionsWithConfig(ctx, nil) + + var compatibilitySupportFiles android.Paths + compatibilitySupportFiles = append(compatibilitySupportFiles, j.implementationJarFile) + compatibilitySupportFiles = append(compatibilitySupportFiles, j.jniFilePaths...) + compatibilitySupportFiles = append(compatibilitySupportFiles, j.fuzzPackagedModule.Corpus...) + if j.fuzzPackagedModule.Dictionary != nil { + compatibilitySupportFiles = append(compatibilitySupportFiles, j.fuzzPackagedModule.Dictionary) + } + + outputFile := j.installedOutputFile + if outputFile == nil { + outputFile = j.outputFile + } + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: j.testProperties.Test_suites, + MainFile: outputFile, + MainFileStem: j.Stem(), + MainFileExt: ".jar", + ConfigFile: j.testConfig, + ExtraConfigs: j.extraTestConfigs, + NeedsArchFolder: ctx.Device(), + CompatibilitySupportFiles: compatibilitySupportFiles, + PerTestcaseDirectory: proptools.Bool(j.testProperties.Per_testcase_directory), + }) fuzz.SetFuzzPackagedModuleInfo(ctx, &j.fuzzPackagedModule) } diff --git a/java/java.go b/java/java.go index 5593c9909..10eecafb7 100644 --- a/java/java.go +++ b/java/java.go @@ -1814,6 +1814,7 @@ func (j *TestHost) GenerateAndroidBuildActions(ctx android.ModuleContext) { } j.Test.generateAndroidBuildActionsWithConfig(ctx, configs) + j.Test.javaTestSetTestsuiteInfo(ctx) android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{ TestcaseRelDataFiles: testcaseRel(j.data), OutputFile: j.outputFile, @@ -1836,6 +1837,7 @@ func (j *TestHost) GenerateAndroidBuildActions(ctx android.ModuleContext) { func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) { checkMinSdkVersionMts(ctx, j.MinSdkVersion(ctx)) j.generateAndroidBuildActionsWithConfig(ctx, nil) + j.javaTestSetTestsuiteInfo(ctx) } func (j *Test) generateAndroidBuildActionsWithConfig(ctx android.ModuleContext, configs []tradefed.Config) { @@ -1941,29 +1943,29 @@ func (j *Test) generateAndroidBuildActionsWithConfig(ctx android.ModuleContext, } } moduleInfoJSON.TestMainlineModules = append(moduleInfoJSON.TestMainlineModules, j.testProperties.Test_mainline_modules...) +} +func (j *Test) javaTestSetTestsuiteInfo(ctx android.ModuleContext) { // Install test deps - if !ctx.Config().KatiEnabled() { - pathInTestCases := android.PathForModuleInstall(ctx, "testcases", ctx.ModuleName()) - 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} - ctx.InstallTestData(pathInTestCases, []android.DataPath{dataPath}) - } - if j.outputFile != nil { - ctx.InstallFile(pathInTestCases, ctx.ModuleName()+".jar", j.outputFile) - } + outputFile := j.installedOutputFile + if outputFile == nil { + outputFile = j.outputFile } - - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: j.testProperties.Test_suites, + var testData []android.DataPath + for _, data := range j.data { + dataPath := android.DataPath{SrcPath: data} + testData = append(testData, dataPath) + } + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: j.testProperties.Test_suites, + MainFile: outputFile, + MainFileStem: j.Stem(), + MainFileExt: ".jar", + ConfigFile: j.testConfig, + ExtraConfigs: j.extraTestConfigs, + NeedsArchFolder: ctx.Device(), + NonArchData: testData, + PerTestcaseDirectory: proptools.Bool(j.testProperties.Per_testcase_directory), }) } @@ -1978,12 +1980,24 @@ func (j *TestHelperLibrary) GenerateAndroidBuildActions(ctx android.ModuleContex moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") } optionalConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "AndroidTest.xml") + var config android.Path if optionalConfig.Valid() { + config = optionalConfig.Path() moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, optionalConfig.String()) } - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: j.testHelperLibraryProperties.Test_suites, + outputFile := j.installedOutputFile + if outputFile == nil { + outputFile = j.outputFile + } + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: j.testHelperLibraryProperties.Test_suites, + MainFile: outputFile, + MainFileStem: j.Stem(), + MainFileExt: ".jar", + ConfigFile: config, + NeedsArchFolder: ctx.Device(), + PerTestcaseDirectory: proptools.Bool(j.testHelperLibraryProperties.Per_testcase_directory), }) } diff --git a/python/binary.go b/python/binary.go index f894299f9..abcef73fb 100644 --- a/python/binary.go +++ b/python/binary.go @@ -115,6 +115,12 @@ func (p *PythonBinaryModule) GenerateAndroidBuildActions(ctx android.ModuleConte ctx.SetOutputFiles(android.Paths{p.installSource}, "") + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: p.binaryProperties.Test_suites, + MainFile: p.installSource, + MainFileStem: p.installSource.Base(), + }) + moduleInfoJSON := ctx.ModuleInfoJSON() moduleInfoJSON.Class = []string{"EXECUTABLES"} moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, p.androidMkSharedLibs...) @@ -165,10 +171,6 @@ func (p *PythonBinaryModule) buildBinary(ctx android.ModuleContext) { sharedLibs = append(sharedLibs, ctx.OtherModuleName(dep)) } p.androidMkSharedLibs = sharedLibs - - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: p.binaryProperties.Test_suites, - }) } func (p *PythonBinaryModule) AndroidMkEntries() []android.AndroidMkEntries { diff --git a/python/test.go b/python/test.go index df62ab794..d6670c3c4 100644 --- a/python/test.go +++ b/python/test.go @@ -215,25 +215,21 @@ func (p *PythonTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext installedData := ctx.InstallTestData(installDir, p.data) p.installedDest = ctx.InstallFile(installDir, p.installSource.Base(), p.installSource, installedData...) - // TODO: Remove the special case for kati - if !ctx.Config().KatiEnabled() { - // Install the test config in testcases/ directory for atest. - // Install configs in the root of $PRODUCT_OUT/testcases/$module - testCases := android.PathForModuleInPartitionInstall(ctx, "testcases", ctx.ModuleName()) - if ctx.PrimaryArch() { - 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()) - installedData := ctx.InstallTestData(testCases, p.data) - ctx.InstallFile(testCases, p.installSource.Base(), p.installSource, installedData...) + configFileSuffix := "" + // ATS 2.0 is the test harness for mobly tests and the test config is for ATS 2.0. + // Add "v2" suffix to test config name to distinguish it from the config for TF. + if proptools.String(p.testProperties.Test_options.Runner) == "mobly" { + configFileSuffix = "v2" } + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: p.binaryProperties.Test_suites, + MainFile: p.installSource, + MainFileStem: p.installSource.Base(), + ConfigFile: p.testConfig, + ConfigFileSuffix: configFileSuffix, + Data: p.data, + NeedsArchFolder: true, + }) moduleInfoJSON := ctx.ModuleInfoJSON() moduleInfoJSON.Class = []string{"NATIVE_TESTS"} diff --git a/rust/benchmark.go b/rust/benchmark.go index 3aa2f1779..85aa6a52e 100644 --- a/rust/benchmark.go +++ b/rust/benchmark.go @@ -129,6 +129,15 @@ func (benchmark *benchmarkDecorator) install(ctx ModuleContext) { } benchmark.binaryDecorator.install(ctx) + + mainFile := ctx.RustModule().OutputFile().Path() + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: benchmark.Properties.Test_suites, + MainFile: mainFile, + MainFileExt: mainFile.Ext(), + ConfigFile: benchmark.testConfig, + NeedsArchFolder: true, + }) } func (benchmark *benchmarkDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) { @@ -146,8 +155,4 @@ func (benchmark *benchmarkDecorator) moduleInfoJSON(ctx ModuleContext, moduleInf } else { moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") } - - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: benchmark.Properties.Test_suites, - }) } diff --git a/rust/test.go b/rust/test.go index cedced260..72eaaae81 100644 --- a/rust/test.go +++ b/rust/test.go @@ -204,29 +204,17 @@ func (test *testDecorator) install(ctx ModuleContext) { test.Properties.Test_options.Unit_test = proptools.BoolPtr(true) } - if !ctx.Config().KatiEnabled() { // TODO(spandandas): Remove the special case for kati - // Install the test config in testcases/ directory for atest. - r, ok := ctx.Module().(*Module) - if !ok { - ctx.ModuleErrorf("Not a rust test module") - } - // Install configs in the root of $PRODUCT_OUT/testcases/$module - testCases := android.PathForModuleInPartitionInstall(ctx, "testcases", ctx.ModuleName()+r.SubName()) - if ctx.PrimaryArch() { - 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()) - ctx.InstallTestData(testCases, test.data) - testPath := ctx.RustModule().OutputFile().Path() - ctx.InstallFile(testCases, testPath.Base(), testPath) - } + // Install the test config in testcases/ directory for atest. + mainFile := ctx.RustModule().OutputFile().Path() + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + NameSuffix: ctx.RustModule().SubName(), + TestSuites: test.Properties.Test_suites, + MainFile: mainFile, + MainFileStem: mainFile.Base(), + ConfigFile: test.testConfig, + Data: test.data, + NeedsArchFolder: true, + }) test.binaryDecorator.installTestData(ctx, test.data) test.binaryDecorator.install(ctx) @@ -320,10 +308,6 @@ func (test *testDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *and } else { moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") } - - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: test.Properties.Test_suites, - }) } func rustTestHostMultilib(ctx android.LoadHookContext) { diff --git a/sh/sh_binary.go b/sh/sh_binary.go index 57f5ad1c7..257d60936 100644 --- a/sh/sh_binary.go +++ b/sh/sh_binary.go @@ -540,6 +540,17 @@ func (s *ShTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { installedData := ctx.InstallTestData(s.installDir, s.data) s.installedFile = ctx.InstallExecutable(s.installDir, s.outputFilePath.Base(), s.outputFilePath, installedData...) + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: s.testProperties.Test_suites, + MainFile: s.outputFilePath, + MainFileStem: s.outputFilePath.Base(), + ConfigFile: s.testConfig, + ExtraConfigs: s.extraTestConfigs, + Data: s.data, + NeedsArchFolder: true, + PerTestcaseDirectory: proptools.Bool(s.testProperties.Per_testcase_directory), + }) + mkEntries := s.AndroidMkEntries()[0] android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{ TestcaseRelDataFiles: addArch(ctx.Arch().ArchType.String(), installedData.Paths()), @@ -574,10 +585,6 @@ func (s *ShTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, s.testConfig.String()) } moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, s.extraTestConfigs.Strings()...) - - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: s.testProperties.Test_suites, - }) } func addArch(archType string, paths android.Paths) []string { diff --git a/tradefed_modules/test_module_config.go b/tradefed_modules/test_module_config.go index e833df293..6b30a7a38 100644 --- a/tradefed_modules/test_module_config.go +++ b/tradefed_modules/test_module_config.go @@ -435,9 +435,22 @@ func (m *testModuleConfigModule) generateManifestAndConfig(ctx android.ModuleCon IsUnitTest: m.provider.IsUnitTest, }) - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: m.tradefedProperties.Test_suites, + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: m.tradefedProperties.Test_suites, + MainFile: baseApk, + MainFileExt: ".apk", + ConfigFile: m.testConfig, + NeedsArchFolder: ctx.Device(), }) + + // Install the UNUSED- file to match the UNUSED- stem specified in javaExtraEntries + if m.provider.MkAppClass == "APPS" { + installDir2 := android.PathForModuleInstall(ctx, ctx.ModuleName(), ctx.DeviceConfig().DeviceArch()) + ctx.InstallFile(installDir2, fmt.Sprintf("UNUSED-%s.apk", *m.Base), m.manifest) + } else if m.provider.MkAppClass == "JAVA_LIBRARIES" { + installDir2 := android.PathForModuleInstall(ctx, ctx.ModuleName()) + ctx.InstallFile(installDir2, fmt.Sprintf("UNUSED-%s.jar", *m.Base), m.manifest) + } } var _ android.AndroidMkEntriesProvider = (*testModuleConfigHostModule)(nil) -- cgit v1.2.3 From 24b4b9596f3a422adf7e9569a407944b63cfbed8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kosi=C5=84ski?= Date: Fri, 28 Mar 2025 03:54:15 +0000 Subject: Conditionally enable ARM arch variant features in Rust. To avoid warning spam in the build log, we explicitly list out all features that are mandatory in each variant instead of passing the convenience options "-C target-feature=+vN.Na". Bug: 406874649 Test: local build & flash with flag enabled Flag: build.RELEASE_RUST_USE_ARM_TARGET_ARCH_VARIANT Change-Id: I60858201353cbc8e5d7f0f039be95cb6ea2a0c42 --- android/config.go | 4 +++ rust/config/arm64_device.go | 71 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 65 insertions(+), 10 deletions(-) diff --git a/android/config.go b/android/config.go index 1feda08a3..8d443028b 100644 --- a/android/config.go +++ b/android/config.go @@ -303,6 +303,10 @@ func (c Config) ReleaseAconfigCheckApiLevel() bool { return c.config.productVariables.GetBuildFlagBool("RELEASE_ACONFIG_CHECK_API_LEVEL") } +func (c Config) ReleaseRustUseArmTargetArchVariant() bool { + return c.config.productVariables.GetBuildFlagBool("RELEASE_RUST_USE_ARM_TARGET_ARCH_VARIANT") +} + // A DeviceConfig object represents the configuration for a particular device // being built. For now there will only be one of these, but in the future there // may be multiple devices being built. diff --git a/rust/config/arm64_device.go b/rust/config/arm64_device.go index 533ace773..1f4e6ce9e 100644 --- a/rust/config/arm64_device.go +++ b/rust/config/arm64_device.go @@ -33,17 +33,64 @@ var ( } Arm64LinkFlags = []string{} + // We could simply pass "-C target-feature=+v8.2a" and similar, but "v8.2a" and the other + // architecture version target-features are marked unstable and spam warnings in the build log, + // even though they're just aliases for groups of other features, most of which are stable. + // As a workaround, we'll simply look at this file and enable the constituent features: + // https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_target/target_features.rs.html + + // Mandatory extensions from ARMv8.1-A and ARMv8.2-A + armv82aFeatures = "-C target-feature=+crc,+lse,+rdm,+pan,+lor,+vh,+ras,+dpb" + // Mandatory extensions from ARMv8.3-A, ARMv8.4-A and ARMv8.5-A + armv85aFeatures = "-C target-feature=+rcpc,+paca,+pacg,+jsconv,+dotprod,+dit,+flagm,+ssbs,+sb,+dpb2,+bti" + // Mandatory extensions from ARMv8.6-A and ARMv8.7-A + // "wfxt" is marked unstable, so we don't include it yet. + armv87aFeatures = "-C target-feature=+bf16,+i8mm" + Arm64ArchVariantRustFlags = map[string][]string{ "armv8-a": {}, "armv8-a-branchprot": {}, - "armv8-2a": {}, - "armv8-2a-dotprod": {}, - "armv8-5a": {}, - "armv8-7a": {}, - "armv9-a": {}, - "armv9-2a": {}, - "armv9-3a": {}, - "armv9-4a": {}, + "armv8-2a": { + armv82aFeatures, + }, + "armv8-2a-dotprod": { + armv82aFeatures, + "-C target-feature=+dotprod", + }, + "armv8-5a": { + armv82aFeatures, + armv85aFeatures, + }, + "armv8-7a": { + armv82aFeatures, + armv85aFeatures, + armv87aFeatures, + }, + "armv9-a": { + armv82aFeatures, + armv85aFeatures, + "-C target-feature=+sve2", + }, + "armv9-2a": { + armv82aFeatures, + armv85aFeatures, + armv87aFeatures, + "-C target-feature=+sve2", + }, + // ARMv9.3-A adds +hbc,+mops but they're both unstable + "armv9-3a": { + armv82aFeatures, + armv85aFeatures, + armv87aFeatures, + "-C target-feature=+sve2", + }, + // ARMv9.4-A adds +cssc but it's unstable + "armv9-4a": { + armv82aFeatures, + armv85aFeatures, + armv87aFeatures, + "-C target-feature=+sve2", + }, } ) @@ -54,8 +101,12 @@ func init() { pctx.StaticVariable("Arm64ToolchainLinkFlags", strings.Join(Arm64LinkFlags, " ")) for variant, rustFlags := range Arm64ArchVariantRustFlags { - pctx.StaticVariable("Arm64"+variant+"VariantRustFlags", - strings.Join(rustFlags, " ")) + pctx.VariableFunc("Arm64"+variant+"VariantRustFlags", func(ctx android.PackageVarContext) string { + if ctx.Config().ReleaseRustUseArmTargetArchVariant() { + return strings.Join(rustFlags, " ") + } + return "" + }) } pctx.StaticVariable("DEVICE_ARM64_RUSTC_FLAGS", strings.Join(Arm64RustFlags, " ")) -- cgit v1.2.3 From a933f952666f1282452da43ed5b73ebbdc091b37 Mon Sep 17 00:00:00 2001 From: Szu-An Lu Date: Fri, 28 Mar 2025 04:52:41 -0700 Subject: Revert "Reapply "Always install test files with soong"" Revert submission 32747769-install_test_files_with_soong Reason for revert: Boot test failure b/406661636. Revert for ABTD verification Reverted changes: /q/submissionid:32747769-install_test_files_with_soong Change-Id: I71ed4f5933eaeef6af133c0e0f26baed8e052be8 --- android/arch_module_context.go | 18 +-- android/module.go | 202 ++------------------------------- android/module_context.go | 15 --- android/test_suites.go | 76 ------------- android/variable.go | 7 -- cc/binary.go | 4 + cc/cc.go | 4 + cc/library.go | 4 + cc/object.go | 4 + cc/test.go | 91 +++++++-------- java/app.go | 71 ++++-------- java/app_import.go | 14 +-- java/base.go | 5 +- java/fuzz.go | 27 +---- java/java.go | 58 ++++------ python/binary.go | 10 +- python/test.go | 32 +++--- rust/benchmark.go | 13 +-- rust/test.go | 38 +++++-- sh/sh_binary.go | 15 +-- tradefed_modules/test_module_config.go | 17 +-- 21 files changed, 182 insertions(+), 543 deletions(-) diff --git a/android/arch_module_context.go b/android/arch_module_context.go index 7c440ad00..a3a03af02 100644 --- a/android/arch_module_context.go +++ b/android/arch_module_context.go @@ -30,19 +30,17 @@ type ArchModuleContext interface { Darwin() bool Windows() bool PrimaryArch() bool - PrimaryNativeBridgeArch() bool } type archModuleContext struct { // TODO: these should eventually go through a (possibly cached) provider like any other configuration instead // of being special cased. - ready bool - os OsType - target Target - targetPrimary bool - multiTargets []Target - primaryArch bool - primaryNativeBridgeArch bool + ready bool + os OsType + target Target + targetPrimary bool + multiTargets []Target + primaryArch bool } // ArchReady returns true if the arch mutator has run on the module. Before this returns @@ -91,7 +89,3 @@ func (a *archModuleContext) Windows() bool { func (b *archModuleContext) PrimaryArch() bool { return b.primaryArch } - -func (b *archModuleContext) PrimaryNativeBridgeArch() bool { - return b.primaryNativeBridgeArch -} diff --git a/android/module.go b/android/module.go index da3c8ad70..55f170cfe 100644 --- a/android/module.go +++ b/android/module.go @@ -28,7 +28,6 @@ import ( "github.com/google/blueprint" "github.com/google/blueprint/depset" "github.com/google/blueprint/gobtools" - "github.com/google/blueprint/pathtools" "github.com/google/blueprint/proptools" ) @@ -1837,27 +1836,14 @@ func (m *ModuleBase) archModuleContextFactory(ctx archModuleContextFactoryContex } else { primaryArch = target.Arch.ArchType == config.Targets[target.Os][0].Arch.ArchType } - primaryNativeBridgeArch := false - if target.NativeBridge { - for _, t := range config.Targets[target.Os] { - if t.NativeBridge { - if target.Arch.ArchType == t.Arch.ArchType { - primaryNativeBridgeArch = true - } - // Don't consider further nativebridge targets - break - } - } - } return archModuleContext{ - ready: m.commonProperties.ArchReady, - os: m.commonProperties.CompileOS, - target: m.commonProperties.CompileTarget, - targetPrimary: m.commonProperties.CompilePrimary, - multiTargets: m.commonProperties.CompileMultiTargets, - primaryArch: primaryArch, - primaryNativeBridgeArch: primaryNativeBridgeArch, + ready: m.commonProperties.ArchReady, + os: m.commonProperties.CompileOS, + target: m.commonProperties.CompileTarget, + targetPrimary: m.commonProperties.CompilePrimary, + multiTargets: m.commonProperties.CompileMultiTargets, + primaryArch: primaryArch, } } @@ -2154,10 +2140,6 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) m.generateVariantTarget(ctx) - testData := FirstUniqueFunc(ctx.testData, func(a, b DataPath) bool { - return a == b - }) - installFiles.LicenseMetadataFile = ctx.licenseMetadataFile installFiles.InstallFiles = ctx.installFiles installFiles.CheckbuildFiles = ctx.checkbuildFiles @@ -2166,7 +2148,7 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) installFiles.PackagingSpecs = ctx.packagingSpecs installFiles.KatiInstalls = ctx.katiInstalls installFiles.KatiSymlinks = ctx.katiSymlinks - installFiles.TestData = testData + installFiles.TestData = ctx.testData } else if ctx.Config().AllowMissingDependencies() { // If the module is not enabled it will not create any build rules, nothing will call // ctx.GetMissingDependencies(), and blueprint will consider the missing dependencies to be unhandled @@ -2198,10 +2180,6 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) SetProvider(ctx, InstallFilesProvider, installFiles) buildLicenseMetadata(ctx, ctx.licenseMetadataFile) - if ctx.testSuiteInfoSet { - m.setupTestSuites(ctx, ctx.testSuiteInfo) - } - if len(ctx.moduleInfoJSON) > 0 { for _, moduleInfoJSON := range ctx.moduleInfoJSON { if moduleInfoJSON.Disabled { @@ -2419,172 +2397,6 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) } } -func (m *ModuleBase) CleanupAfterBuildActions() {} - -func (m *ModuleBase) setupTestSuites(ctx ModuleContext, info TestSuiteInfo) { - // We skip test suites when using the ndk or aml abis, as the extra archs (x86_64 + arm64) - // both try to install to the same test file. This could be fixed by always using a per-module - // folder and an arch folder, but as you see later in this function we only conditionally use - // those. - if ctx.Config().NdkAbis() || ctx.Config().AmlAbis() || shouldSkipAndroidMkProcessing(ctx, m) || m.IsSkipInstall() { - return - } - overriddenBy := "" - if b, ok := ctx.Module().(OverridableModule); ok { - overriddenBy = b.GetOverriddenBy() - } - - // M(C)TS supports a full test suite and partial per-module MTS test suites, with naming mts-${MODULE}. - // To reduce repetition, if we find a partial M(C)TS test suite without an full M(C)TS test suite, - // we add the full test suite to our list. - if PrefixInList(info.TestSuites, "mts-") && !InList("mts", info.TestSuites) { - info.TestSuites = append(info.TestSuites, "mts") - } - if PrefixInList(info.TestSuites, "mcts-") && !InList("mcts", info.TestSuites) { - info.TestSuites = append(info.TestSuites, "mcts") - } - - if len(info.TestSuites) == 0 { - info.TestSuites = []string{"null-suite"} - } - info.TestSuites = SortedUniqueStrings(info.TestSuites) - - name := ctx.ModuleName() - if overriddenBy != "" { - name = overriddenBy - } - name += info.NameSuffix - - type testSuiteInfo struct { - name string - dir WritablePath - includeModuleFolder bool - } - - suites := []testSuiteInfo{{ - dir: PathForModuleInPartitionInstall(ctx, "testcases", name), - includeModuleFolder: true, - }} - for _, suite := range info.TestSuites { - if suiteInfo, ok := ctx.Config().productVariables.CompatibilityTestcases[suite]; ok { - rel, err := filepath.Rel(ctx.Config().OutDir(), suiteInfo.OutDir) - if err != nil { - panic(fmt.Sprintf("Could not make COMPATIBILITY_TESTCASES_OUT_%s (%s) relative to the out dir (%s)", suite, suiteInfo.OutDir, ctx.Config().OutDir())) - } - if suiteInfo.IncludeModuleFolder || info.PerTestcaseDirectory { - rel = filepath.Join(rel, name) - } - suites = append(suites, testSuiteInfo{ - name: suite, - dir: PathForArbitraryOutput(ctx, rel), - includeModuleFolder: suiteInfo.IncludeModuleFolder || info.PerTestcaseDirectory, - }) - } - } - - var archDir string - if info.NeedsArchFolder { - archDir = ctx.Arch().ArchType.Name - if archDir == "common" { - archDir = ctx.DeviceConfig().DeviceArch() - } - if ctx.Target().NativeBridge { - archDir = ctx.Target().NativeBridgeHostArchName - } - } - - var installs []filePair - - for _, suite := range suites { - mainFileName := name - if info.MainFileStem != "" { - mainFileName = info.MainFileStem - } - mainFileName += info.MainFileExt - mainFileInstall := joinWriteablePath(ctx, suite.dir, archDir, mainFileName) - if !suite.includeModuleFolder { - mainFileInstall = joinWriteablePath(ctx, suite.dir, mainFileName) - } - if info.MainFile == nil { - panic("mainfile was nil") - } - - installs = append(installs, filePair{ - src: info.MainFile, - dst: mainFileInstall, - }) - - for _, data := range info.Data { - dataOut := joinWriteablePath(ctx, suite.dir, archDir, data.ToRelativeInstallPath()) - if !suite.includeModuleFolder { - dataOut = joinWriteablePath(ctx, suite.dir, data.ToRelativeInstallPath()) - } - installs = append(installs, filePair{ - src: data.SrcPath, - dst: dataOut, - }) - } - for _, data := range info.NonArchData { - dataOut := joinWriteablePath(ctx, suite.dir, data.ToRelativeInstallPath()) - installs = append(installs, filePair{ - src: data.SrcPath, - dst: dataOut, - }) - } - for _, data := range info.CompatibilitySupportFiles { - dataOut := joinWriteablePath(ctx, suite.dir, data.Rel()) - installs = append(installs, filePair{ - src: data, - dst: dataOut, - }) - } - - if ctx.TargetPrimary() || ctx.PrimaryNativeBridgeArch() { - if info.ConfigFile != nil { - installs = append(installs, filePair{ - src: info.ConfigFile, - dst: joinWriteablePath(ctx, suite.dir, name+".config"+info.ConfigFileSuffix), - }) - } else if config := ExistentPathForSource(ctx, ctx.ModuleDir(), "AndroidTest.xml"); config.Valid() { - installs = append(installs, filePair{ - src: config.Path(), - dst: joinWriteablePath(ctx, suite.dir, name+".config"), - }) - } - dynamicConfig := ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml") - if dynamicConfig.Valid() { - installs = append(installs, filePair{ - src: dynamicConfig.Path(), - dst: joinWriteablePath(ctx, suite.dir, name+".dynamic"), - }) - } - for _, extraTestConfig := range info.ExtraConfigs { - if extraTestConfig == nil { - panic("ExtraTestConfig was nil") - } - installs = append(installs, filePair{ - src: extraTestConfig, - dst: joinWriteablePath(ctx, suite.dir, pathtools.ReplaceExtension(extraTestConfig.Base(), "config")), - }) - } - } - } - - SetProvider(ctx, TestSuiteInfoProvider, info) - SetProvider(ctx, testSuiteInstallsInfoProvider, testSuiteInstallsInfo{installs}) -} - -func joinWriteablePath(ctx PathContext, path WritablePath, toJoin ...string) WritablePath { - switch p := path.(type) { - case InstallPath: - return p.Join(ctx, toJoin...) - case OutputPath: - return p.Join(ctx, toJoin...) - default: - panic("unhandled path type") - } -} - func SetJarJarPrefixHandler(handler func(ModuleContext)) { if jarJarPrefixHandler != nil { panic("jarJarPrefixHandler already set") diff --git a/android/module_context.go b/android/module_context.go index 3542671ac..e30afd637 100644 --- a/android/module_context.go +++ b/android/module_context.go @@ -275,10 +275,6 @@ type ModuleContext interface { // directory on the build server with the given filename when any of the // specified goals are built. DistForGoalsWithFilename(goals []string, path Path, filename string) - - // Defines this module as a compatibility suite test and gives all the information needed - // to build the suite. - SetTestSuiteInfo(info TestSuiteInfo) } type moduleContext struct { @@ -338,9 +334,6 @@ type moduleContext struct { complianceMetadataInfo *ComplianceMetadataInfo dists []dist - - testSuiteInfo TestSuiteInfo - testSuiteInfoSet bool } var _ ModuleContext = &moduleContext{} @@ -1048,11 +1041,3 @@ func (c *moduleContext) DistForGoalsWithFilename(goals []string, path Path, file paths: distCopies{{from: path, dest: filename}}, }) } - -func (c *moduleContext) SetTestSuiteInfo(info TestSuiteInfo) { - if c.testSuiteInfoSet { - panic("Cannot call SetTestSuiteInfo twice") - } - c.testSuiteInfo = info - c.testSuiteInfoSet = true -} diff --git a/android/test_suites.go b/android/test_suites.go index 88a410eb1..dbcd48c79 100644 --- a/android/test_suites.go +++ b/android/test_suites.go @@ -16,8 +16,6 @@ package android import ( "path/filepath" - "slices" - "sort" "strings" "github.com/google/blueprint" @@ -39,34 +37,7 @@ type TestSuiteModule interface { } type TestSuiteInfo struct { - // A suffix to append to the name of the test. - // Useful because historically different variants of soong modules became differently-named - // make modules, like "my_test.vendor" for the vendor variant. - NameSuffix string - TestSuites []string - - NeedsArchFolder bool - - MainFile Path - - MainFileStem string - - MainFileExt string - - ConfigFile Path - - ConfigFileSuffix string - - ExtraConfigs Paths - - PerTestcaseDirectory bool - - Data []DataPath - - NonArchData []DataPath - - CompatibilitySupportFiles []Path } var TestSuiteInfoProvider = blueprint.NewProvider[TestSuiteInfo]() @@ -77,20 +48,8 @@ type SupportFilesInfo struct { var SupportFilesInfoProvider = blueprint.NewProvider[SupportFilesInfo]() -type filePair struct { - src Path - dst WritablePath -} - -type testSuiteInstallsInfo struct { - Files []filePair -} - -var testSuiteInstallsInfoProvider = blueprint.NewProvider[testSuiteInstallsInfo]() - func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) { files := make(map[string]map[string]InstallPaths) - var toInstall []filePair ctx.VisitAllModuleProxies(func(m ModuleProxy) { if tsm, ok := OtherModuleProvider(ctx, m, TestSuiteInfoProvider); ok { @@ -103,42 +62,7 @@ func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) { OtherModuleProviderOrDefault(ctx, m, InstallFilesProvider).InstallFiles...) } } - if testSuiteInstalls, ok := OtherModuleProvider(ctx, m, testSuiteInstallsInfoProvider); ok { - installs := OtherModuleProviderOrDefault(ctx, m, InstallFilesProvider).InstallFiles - for _, f := range testSuiteInstalls.Files { - alreadyInstalled := false - for _, install := range installs { - if install.String() == f.dst.String() { - alreadyInstalled = true - break - } - } - if !alreadyInstalled { - toInstall = append(toInstall, f) - } - } - } - }) - - sort.Slice(toInstall, func(i, j int) bool { - c := strings.Compare(toInstall[i].src.String(), toInstall[j].src.String()) - if c < 0 { - return true - } else if c > 0 { - return false - } - return toInstall[i].dst.String() < toInstall[j].dst.String() }) - // Dedup, as multiple tests may install the same test data to the same folder - toInstall = slices.Compact(toInstall) - - for _, install := range toInstall { - ctx.Build(pctx, BuildParams{ - Rule: Cp, - Input: install.src, - Output: install.dst, - }) - } robolectricZip, robolectrictListZip := buildTestSuite(ctx, "robolectric-tests", files["robolectric-tests"]) ctx.Phony("robolectric-tests", robolectricZip, robolectrictListZip) diff --git a/android/variable.go b/android/variable.go index b5ffa7cf8..f00dd138b 100644 --- a/android/variable.go +++ b/android/variable.go @@ -550,13 +550,6 @@ type ProductVariables struct { UseSoongNoticeXML *bool `json:",omitempty"` StripByDefault *bool `json:",omitempty"` - - CompatibilityTestcases map[string]CompatibilityTestcaseJSON -} - -type CompatibilityTestcaseJSON struct { - OutDir string `json:",omitempty"` - IncludeModuleFolder bool `json:",omitempty"` } type PartitionQualifiedVariablesType struct { diff --git a/cc/binary.go b/cc/binary.go index 627d5e560..608251afc 100644 --- a/cc/binary.go +++ b/cc/binary.go @@ -551,6 +551,10 @@ func (binary *binaryDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON binary.baseLinker.moduleInfoJSON(ctx, moduleInfoJSON) } +func (binary *binaryDecorator) testSuiteInfo(ctx ModuleContext) { + // not a test +} + var _ overridable = (*binaryDecorator)(nil) func init() { diff --git a/cc/cc.go b/cc/cc.go index c50cb64a0..dc9b831f9 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -798,6 +798,8 @@ type linker interface { defaultDistFiles() []android.Path moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) + + testSuiteInfo(ctx ModuleContext) } // specifiedDeps is a tuple struct representing dependencies of a linked binary owned by the linker. @@ -2522,6 +2524,8 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { name := v.ImplementationModuleName(ctx.OtherModuleName(c)) ccInfo.LinkerInfo.ImplementationModuleName = &name } + + c.linker.testSuiteInfo(ctx) } if c.library != nil { ccInfo.LibraryInfo = &LibraryInfo{ diff --git a/cc/library.go b/cc/library.go index b248224bd..5299771ca 100644 --- a/cc/library.go +++ b/cc/library.go @@ -1078,6 +1078,10 @@ func (library *libraryDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSO library.baseLinker.moduleInfoJSON(ctx, moduleInfoJSON) } +func (library *libraryDecorator) testSuiteInfo(ctx ModuleContext) { + // not a test +} + func (library *libraryDecorator) linkStatic(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path { diff --git a/cc/object.go b/cc/object.go index 95a8beb52..ea3ed6151 100644 --- a/cc/object.go +++ b/cc/object.go @@ -250,3 +250,7 @@ func (object *objectLinker) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *an object.baseLinker.moduleInfoJSON(ctx, moduleInfoJSON) moduleInfoJSON.Class = []string{"STATIC_LIBRARIES"} } + +func (object *objectLinker) testSuiteInfo(ctx ModuleContext) { + // not a test +} diff --git a/cc/test.go b/cc/test.go index fed24671d..9c276b81a 100644 --- a/cc/test.go +++ b/cc/test.go @@ -274,6 +274,12 @@ func (test *testDecorator) moduleInfoJSON(ctx android.ModuleContext, moduleInfoJ } } +func (test *testDecorator) testSuiteInfo(ctx ModuleContext) { + android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ + TestSuites: test.InstallerProperties.Test_suites, + }) +} + func NewTestInstaller() *baseInstaller { return NewBaseInstaller("nativetest", "nativetest64", InstallInData) } @@ -342,6 +348,10 @@ func (test *testBinary) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *androi } +func (test *testBinary) testSuiteInfo(ctx ModuleContext) { + test.testDecorator.testSuiteInfo(ctx) +} + func (test *testBinary) installerProps() []interface{} { return append(test.baseInstaller.installerProps(), test.testDecorator.installerProps()...) } @@ -412,24 +422,32 @@ func (test *testBinary) install(ctx ModuleContext, file android.Path) { test.Properties.Test_options.Unit_test = proptools.BoolPtr(true) } - // Install the test config in testcases/ directory for atest. - c, ok := ctx.Module().(*Module) - if !ok { - ctx.ModuleErrorf("Not a cc_test module") + if !ctx.Config().KatiEnabled() { // TODO(spandandas): Remove the special case for kati + // Install the test config in testcases/ directory for atest. + c, ok := ctx.Module().(*Module) + if !ok { + ctx.ModuleErrorf("Not a cc_test module") + } + // Install configs in the root of $PRODUCT_OUT/testcases/$module + testCases := android.PathForModuleInPartitionInstall(ctx, "testcases", ctx.ModuleName()+c.SubName()) + if ctx.PrimaryArch() { + 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) + } + } + // Install tests and data in arch specific subdir $PRODUCT_OUT/testcases/$module/$arch + testCases = testCases.Join(ctx, ctx.Target().Arch.ArchType.String()) + ctx.InstallTestData(testCases, test.data) + ctx.InstallFile(testCases, file.Base(), file) } - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - NameSuffix: c.SubName(), - TestSuites: test.InstallerProperties.Test_suites, - MainFile: file, - MainFileStem: file.Base(), - ConfigFile: test.testConfig, - ExtraConfigs: test.extraTestConfigs, - Data: test.data, - NeedsArchFolder: true, - PerTestcaseDirectory: Bool(test.Properties.Per_testcase_directory), - }) - test.binaryDecorator.baseInstaller.installTestData(ctx, test.data) test.binaryDecorator.baseInstaller.install(ctx, file) if Bool(test.Properties.Standalone_test) { @@ -570,24 +588,8 @@ func (test *testLibrary) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *andro test.testDecorator.moduleInfoJSON(ctx, moduleInfoJSON) } -func (test *testLibrary) install(ctx ModuleContext, file android.Path) { - test.libraryDecorator.install(ctx, file) - - c, ok := ctx.Module().(*Module) - if !ok { - ctx.ModuleErrorf("Expected a cc module") - } - // host tests are not installed to testcases/ as per: - // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/base_rules.mk;l=251;drc=45efec6797cbf812df34dac9d05e43a9fe7217e0 - if test.shared() { - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - NameSuffix: c.SubName(), - TestSuites: test.InstallerProperties.Test_suites, - NeedsArchFolder: true, - MainFile: file, - MainFileStem: file.Base(), - }) - } +func (test *testLibrary) testSuiteInfo(ctx ModuleContext) { + test.testDecorator.testSuiteInfo(ctx) } func (test *testLibrary) installerProps() []interface{} { @@ -682,21 +684,6 @@ func (benchmark *benchmarkDecorator) install(ctx ModuleContext, file android.Pat benchmark.binaryDecorator.baseInstaller.dir64 = filepath.Join("benchmarktest64", ctx.ModuleName()) benchmark.binaryDecorator.baseInstaller.installTestData(ctx, benchmark.data) benchmark.binaryDecorator.baseInstaller.install(ctx, file) - - c, ok := ctx.Module().(*Module) - if !ok { - ctx.ModuleErrorf("Not a cc module") - } - - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - NameSuffix: c.SubName(), - TestSuites: benchmark.Properties.Test_suites, - MainFile: file, - MainFileStem: file.Base(), - ConfigFile: benchmark.testConfig, - Data: benchmark.data, - NeedsArchFolder: true, - }) } func (benchmark *benchmarkDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) { @@ -722,6 +709,12 @@ func (benchmark *benchmarkDecorator) moduleInfoJSON(ctx ModuleContext, moduleInf } } +func (benchmark *benchmarkDecorator) testSuiteInfo(ctx ModuleContext) { + android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ + TestSuites: benchmark.Properties.Test_suites, + }) +} + func NewBenchmark(hod android.HostOrDeviceSupported) *Module { module, binary := newBinary(hod) module.multilib = android.MultilibBoth diff --git a/java/app.go b/java/app.go index 6c1e4f6a5..3a3253f04 100644 --- a/java/app.go +++ b/java/app.go @@ -427,22 +427,8 @@ func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleCon moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") } - outputFile := a.installedOutputFile - if outputFile == nil { - outputFile = a.outputFile - } - var data []android.DataPath - for _, d := range a.extraOutputFiles { - data = append(data, android.DataPath{SrcPath: d}) - } - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - TestSuites: a.appTestHelperAppProperties.Test_suites, - MainFile: outputFile, - MainFileStem: a.installApkName, - MainFileExt: ".apk", - NeedsArchFolder: true, - NonArchData: data, - PerTestcaseDirectory: proptools.Bool(a.appTestHelperAppProperties.Per_testcase_directory), + android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ + TestSuites: a.appTestHelperAppProperties.Test_suites, }) } @@ -994,10 +980,10 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { if ctx.ModuleName() == "framework-res" { // framework-res.apk is installed as system/framework/framework-res.apk a.installDir = android.PathForModuleInstall(ctx, "framework") - } else if ctx.InstallInTestcases() { - a.installDir = android.PathForModuleInstall(ctx, a.installApkName, ctx.DeviceConfig().DeviceArch()) } else if a.Privileged() { a.installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName) + } else if ctx.InstallInTestcases() { + a.installDir = android.PathForModuleInstall(ctx, a.installApkName, ctx.DeviceConfig().DeviceArch()) } else { a.installDir = android.PathForModuleInstall(ctx, "app", a.installApkName) } @@ -1144,7 +1130,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { } } } - a.installedOutputFile = ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...) + ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...) } ctx.CheckbuildFile(a.outputFile) @@ -1693,33 +1679,22 @@ func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { 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)...) - a.data = android.SortedUniquePaths(a.data) - a.extraTestConfigs = android.SortedUniquePaths(a.extraTestConfigs) - - testOutputFile := a.installedOutputFile - if testOutputFile == nil { - testOutputFile = a.outputFile - } - var testData []android.DataPath - for _, data := range a.data { - dataPath := android.DataPath{SrcPath: data} - testData = append(testData, dataPath) - } - for _, d := range a.extraOutputFiles { - testData = append(testData, android.DataPath{SrcPath: d}) - } - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - TestSuites: a.testProperties.Test_suites, - MainFile: testOutputFile, - MainFileStem: a.installApkName, - MainFileExt: ".apk", - ConfigFile: a.testConfig, - ExtraConfigs: a.extraTestConfigs, - NonArchData: testData, - CompatibilitySupportFiles: a.data, - NeedsArchFolder: true, - PerTestcaseDirectory: proptools.Bool(a.testProperties.Per_testcase_directory), - }) + // Install test deps + if !ctx.Config().KatiEnabled() { + pathInTestCases := android.PathForModuleInstall(ctx, ctx.Module().Name()) + 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} + ctx.InstallTestData(pathInTestCases, []android.DataPath{dataPath}) + } + } android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{ TestcaseRelDataFiles: testcaseRel(a.data), @@ -1754,6 +1729,10 @@ func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { moduleInfoJSON.AutoTestConfig = []string{"true"} } moduleInfoJSON.TestMainlineModules = append(moduleInfoJSON.TestMainlineModules, a.testProperties.Test_mainline_modules...) + + android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ + TestSuites: a.testProperties.Test_suites, + }) } func testcaseRel(paths android.Paths) []string { diff --git a/java/app_import.go b/java/app_import.go index 837ab529b..9fb13ba3c 100644 --- a/java/app_import.go +++ b/java/app_import.go @@ -788,18 +788,8 @@ func (a *AndroidTestImport) GenerateAndroidBuildActions(ctx android.ModuleContex a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data) - var data []android.DataPath - for _, d := range a.data { - data = append(data, android.DataPath{SrcPath: d}) - } - - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - TestSuites: a.testProperties.Test_suites, - MainFile: a.outputFile, - MainFileStem: a.outputFile.Base(), - NeedsArchFolder: true, - Data: data, - CompatibilitySupportFiles: a.data, + android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ + TestSuites: a.testProperties.Test_suites, }) } diff --git a/java/base.go b/java/base.go index be7262b81..a69733866 100644 --- a/java/base.go +++ b/java/base.go @@ -513,9 +513,8 @@ type Module struct { jacocoReportClassesFile android.Path // output file of the module, which may be a classes jar or a dex jar - outputFile android.Path - installedOutputFile android.Path - extraOutputFiles android.Paths + outputFile android.Path + extraOutputFiles android.Paths exportAidlIncludeDirs android.Paths ignoredAidlPermissionList android.Paths diff --git a/java/fuzz.go b/java/fuzz.go index 7271b9737..0e239f0ec 100644 --- a/java/fuzz.go +++ b/java/fuzz.go @@ -131,32 +131,7 @@ func (j *JavaFuzzTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { } - checkMinSdkVersionMts(ctx, j.MinSdkVersion(ctx)) - j.Test.generateAndroidBuildActionsWithConfig(ctx, nil) - - var compatibilitySupportFiles android.Paths - compatibilitySupportFiles = append(compatibilitySupportFiles, j.implementationJarFile) - compatibilitySupportFiles = append(compatibilitySupportFiles, j.jniFilePaths...) - compatibilitySupportFiles = append(compatibilitySupportFiles, j.fuzzPackagedModule.Corpus...) - if j.fuzzPackagedModule.Dictionary != nil { - compatibilitySupportFiles = append(compatibilitySupportFiles, j.fuzzPackagedModule.Dictionary) - } - - outputFile := j.installedOutputFile - if outputFile == nil { - outputFile = j.outputFile - } - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - TestSuites: j.testProperties.Test_suites, - MainFile: outputFile, - MainFileStem: j.Stem(), - MainFileExt: ".jar", - ConfigFile: j.testConfig, - ExtraConfigs: j.extraTestConfigs, - NeedsArchFolder: ctx.Device(), - CompatibilitySupportFiles: compatibilitySupportFiles, - PerTestcaseDirectory: proptools.Bool(j.testProperties.Per_testcase_directory), - }) + j.Test.GenerateAndroidBuildActions(ctx) fuzz.SetFuzzPackagedModuleInfo(ctx, &j.fuzzPackagedModule) } diff --git a/java/java.go b/java/java.go index 10eecafb7..5593c9909 100644 --- a/java/java.go +++ b/java/java.go @@ -1814,7 +1814,6 @@ func (j *TestHost) GenerateAndroidBuildActions(ctx android.ModuleContext) { } j.Test.generateAndroidBuildActionsWithConfig(ctx, configs) - j.Test.javaTestSetTestsuiteInfo(ctx) android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{ TestcaseRelDataFiles: testcaseRel(j.data), OutputFile: j.outputFile, @@ -1837,7 +1836,6 @@ func (j *TestHost) GenerateAndroidBuildActions(ctx android.ModuleContext) { func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) { checkMinSdkVersionMts(ctx, j.MinSdkVersion(ctx)) j.generateAndroidBuildActionsWithConfig(ctx, nil) - j.javaTestSetTestsuiteInfo(ctx) } func (j *Test) generateAndroidBuildActionsWithConfig(ctx android.ModuleContext, configs []tradefed.Config) { @@ -1943,29 +1941,29 @@ func (j *Test) generateAndroidBuildActionsWithConfig(ctx android.ModuleContext, } } moduleInfoJSON.TestMainlineModules = append(moduleInfoJSON.TestMainlineModules, j.testProperties.Test_mainline_modules...) -} -func (j *Test) javaTestSetTestsuiteInfo(ctx android.ModuleContext) { // Install test deps - outputFile := j.installedOutputFile - if outputFile == nil { - outputFile = j.outputFile - } - var testData []android.DataPath - for _, data := range j.data { - dataPath := android.DataPath{SrcPath: data} - testData = append(testData, dataPath) + if !ctx.Config().KatiEnabled() { + pathInTestCases := android.PathForModuleInstall(ctx, "testcases", ctx.ModuleName()) + 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} + ctx.InstallTestData(pathInTestCases, []android.DataPath{dataPath}) + } + if j.outputFile != nil { + ctx.InstallFile(pathInTestCases, ctx.ModuleName()+".jar", j.outputFile) + } } - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - TestSuites: j.testProperties.Test_suites, - MainFile: outputFile, - MainFileStem: j.Stem(), - MainFileExt: ".jar", - ConfigFile: j.testConfig, - ExtraConfigs: j.extraTestConfigs, - NeedsArchFolder: ctx.Device(), - NonArchData: testData, - PerTestcaseDirectory: proptools.Bool(j.testProperties.Per_testcase_directory), + + android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ + TestSuites: j.testProperties.Test_suites, }) } @@ -1980,24 +1978,12 @@ func (j *TestHelperLibrary) GenerateAndroidBuildActions(ctx android.ModuleContex moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") } optionalConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "AndroidTest.xml") - var config android.Path if optionalConfig.Valid() { - config = optionalConfig.Path() moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, optionalConfig.String()) } - outputFile := j.installedOutputFile - if outputFile == nil { - outputFile = j.outputFile - } - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - TestSuites: j.testHelperLibraryProperties.Test_suites, - MainFile: outputFile, - MainFileStem: j.Stem(), - MainFileExt: ".jar", - ConfigFile: config, - NeedsArchFolder: ctx.Device(), - PerTestcaseDirectory: proptools.Bool(j.testHelperLibraryProperties.Per_testcase_directory), + android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ + TestSuites: j.testHelperLibraryProperties.Test_suites, }) } diff --git a/python/binary.go b/python/binary.go index abcef73fb..f894299f9 100644 --- a/python/binary.go +++ b/python/binary.go @@ -115,12 +115,6 @@ func (p *PythonBinaryModule) GenerateAndroidBuildActions(ctx android.ModuleConte ctx.SetOutputFiles(android.Paths{p.installSource}, "") - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - TestSuites: p.binaryProperties.Test_suites, - MainFile: p.installSource, - MainFileStem: p.installSource.Base(), - }) - moduleInfoJSON := ctx.ModuleInfoJSON() moduleInfoJSON.Class = []string{"EXECUTABLES"} moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, p.androidMkSharedLibs...) @@ -171,6 +165,10 @@ func (p *PythonBinaryModule) buildBinary(ctx android.ModuleContext) { sharedLibs = append(sharedLibs, ctx.OtherModuleName(dep)) } p.androidMkSharedLibs = sharedLibs + + android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ + TestSuites: p.binaryProperties.Test_suites, + }) } func (p *PythonBinaryModule) AndroidMkEntries() []android.AndroidMkEntries { diff --git a/python/test.go b/python/test.go index d6670c3c4..df62ab794 100644 --- a/python/test.go +++ b/python/test.go @@ -215,21 +215,25 @@ func (p *PythonTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext installedData := ctx.InstallTestData(installDir, p.data) p.installedDest = ctx.InstallFile(installDir, p.installSource.Base(), p.installSource, installedData...) - configFileSuffix := "" - // ATS 2.0 is the test harness for mobly tests and the test config is for ATS 2.0. - // Add "v2" suffix to test config name to distinguish it from the config for TF. - if proptools.String(p.testProperties.Test_options.Runner) == "mobly" { - configFileSuffix = "v2" + // TODO: Remove the special case for kati + if !ctx.Config().KatiEnabled() { + // Install the test config in testcases/ directory for atest. + // Install configs in the root of $PRODUCT_OUT/testcases/$module + testCases := android.PathForModuleInPartitionInstall(ctx, "testcases", ctx.ModuleName()) + if ctx.PrimaryArch() { + 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()) + installedData := ctx.InstallTestData(testCases, p.data) + ctx.InstallFile(testCases, p.installSource.Base(), p.installSource, installedData...) } - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - TestSuites: p.binaryProperties.Test_suites, - MainFile: p.installSource, - MainFileStem: p.installSource.Base(), - ConfigFile: p.testConfig, - ConfigFileSuffix: configFileSuffix, - Data: p.data, - NeedsArchFolder: true, - }) moduleInfoJSON := ctx.ModuleInfoJSON() moduleInfoJSON.Class = []string{"NATIVE_TESTS"} diff --git a/rust/benchmark.go b/rust/benchmark.go index 85aa6a52e..3aa2f1779 100644 --- a/rust/benchmark.go +++ b/rust/benchmark.go @@ -129,15 +129,6 @@ func (benchmark *benchmarkDecorator) install(ctx ModuleContext) { } benchmark.binaryDecorator.install(ctx) - - mainFile := ctx.RustModule().OutputFile().Path() - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - TestSuites: benchmark.Properties.Test_suites, - MainFile: mainFile, - MainFileExt: mainFile.Ext(), - ConfigFile: benchmark.testConfig, - NeedsArchFolder: true, - }) } func (benchmark *benchmarkDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) { @@ -155,4 +146,8 @@ func (benchmark *benchmarkDecorator) moduleInfoJSON(ctx ModuleContext, moduleInf } else { moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") } + + android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ + TestSuites: benchmark.Properties.Test_suites, + }) } diff --git a/rust/test.go b/rust/test.go index 72eaaae81..cedced260 100644 --- a/rust/test.go +++ b/rust/test.go @@ -204,17 +204,29 @@ func (test *testDecorator) install(ctx ModuleContext) { test.Properties.Test_options.Unit_test = proptools.BoolPtr(true) } - // Install the test config in testcases/ directory for atest. - mainFile := ctx.RustModule().OutputFile().Path() - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - NameSuffix: ctx.RustModule().SubName(), - TestSuites: test.Properties.Test_suites, - MainFile: mainFile, - MainFileStem: mainFile.Base(), - ConfigFile: test.testConfig, - Data: test.data, - NeedsArchFolder: true, - }) + if !ctx.Config().KatiEnabled() { // TODO(spandandas): Remove the special case for kati + // Install the test config in testcases/ directory for atest. + r, ok := ctx.Module().(*Module) + if !ok { + ctx.ModuleErrorf("Not a rust test module") + } + // Install configs in the root of $PRODUCT_OUT/testcases/$module + testCases := android.PathForModuleInPartitionInstall(ctx, "testcases", ctx.ModuleName()+r.SubName()) + if ctx.PrimaryArch() { + 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()) + ctx.InstallTestData(testCases, test.data) + testPath := ctx.RustModule().OutputFile().Path() + ctx.InstallFile(testCases, testPath.Base(), testPath) + } test.binaryDecorator.installTestData(ctx, test.data) test.binaryDecorator.install(ctx) @@ -308,6 +320,10 @@ func (test *testDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *and } else { moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") } + + android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ + TestSuites: test.Properties.Test_suites, + }) } func rustTestHostMultilib(ctx android.LoadHookContext) { diff --git a/sh/sh_binary.go b/sh/sh_binary.go index 257d60936..57f5ad1c7 100644 --- a/sh/sh_binary.go +++ b/sh/sh_binary.go @@ -540,17 +540,6 @@ func (s *ShTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { installedData := ctx.InstallTestData(s.installDir, s.data) s.installedFile = ctx.InstallExecutable(s.installDir, s.outputFilePath.Base(), s.outputFilePath, installedData...) - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - TestSuites: s.testProperties.Test_suites, - MainFile: s.outputFilePath, - MainFileStem: s.outputFilePath.Base(), - ConfigFile: s.testConfig, - ExtraConfigs: s.extraTestConfigs, - Data: s.data, - NeedsArchFolder: true, - PerTestcaseDirectory: proptools.Bool(s.testProperties.Per_testcase_directory), - }) - mkEntries := s.AndroidMkEntries()[0] android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{ TestcaseRelDataFiles: addArch(ctx.Arch().ArchType.String(), installedData.Paths()), @@ -585,6 +574,10 @@ func (s *ShTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, s.testConfig.String()) } moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, s.extraTestConfigs.Strings()...) + + android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ + TestSuites: s.testProperties.Test_suites, + }) } func addArch(archType string, paths android.Paths) []string { diff --git a/tradefed_modules/test_module_config.go b/tradefed_modules/test_module_config.go index 6b30a7a38..e833df293 100644 --- a/tradefed_modules/test_module_config.go +++ b/tradefed_modules/test_module_config.go @@ -435,22 +435,9 @@ func (m *testModuleConfigModule) generateManifestAndConfig(ctx android.ModuleCon IsUnitTest: m.provider.IsUnitTest, }) - ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - TestSuites: m.tradefedProperties.Test_suites, - MainFile: baseApk, - MainFileExt: ".apk", - ConfigFile: m.testConfig, - NeedsArchFolder: ctx.Device(), + android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ + TestSuites: m.tradefedProperties.Test_suites, }) - - // Install the UNUSED- file to match the UNUSED- stem specified in javaExtraEntries - if m.provider.MkAppClass == "APPS" { - installDir2 := android.PathForModuleInstall(ctx, ctx.ModuleName(), ctx.DeviceConfig().DeviceArch()) - ctx.InstallFile(installDir2, fmt.Sprintf("UNUSED-%s.apk", *m.Base), m.manifest) - } else if m.provider.MkAppClass == "JAVA_LIBRARIES" { - installDir2 := android.PathForModuleInstall(ctx, ctx.ModuleName()) - ctx.InstallFile(installDir2, fmt.Sprintf("UNUSED-%s.jar", *m.Base), m.manifest) - } } var _ android.AndroidMkEntriesProvider = (*testModuleConfigHostModule)(nil) -- cgit v1.2.3 From 711c3acc7c95fe9a43d514e4d9bd09f6848f9e47 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Fri, 28 Mar 2025 07:07:12 -0700 Subject: Improve a doc comment slightly. Change-Id: Ie7d07564805da6aba0aac587e0b243b8ba07addd --- cc/config/x86_windows_host.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cc/config/x86_windows_host.go b/cc/config/x86_windows_host.go index 505ddfab4..c007f454d 100644 --- a/cc/config/x86_windows_host.go +++ b/cc/config/x86_windows_host.go @@ -33,7 +33,8 @@ var ( // Use C99-compliant printf functions (%zd). "-D__USE_MINGW_ANSI_STDIO=1", - // Admit to using >= Windows 7. Both are needed because of <_mingw.h>. + // Admit to using >= Windows 7. + // Both #defines are needed: https://learn.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt "-D_WIN32_WINNT=0x0601", "-DWINVER=0x0601", // Get 64-bit off_t and related functions. -- cgit v1.2.3 From 52872fe1e7052c43be41fbffd9e538eaf1d90610 Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Wed, 19 Mar 2025 21:30:05 +0000 Subject: Migrate the symbols copying rule from make to Soong This change does the followings: - Copy the symbols to $PRODUCT_OUT/symbols based on the symbols infos collected from each modules, which is currently done in make using `copy-unstripped-elf-file-with-mapping` macro. - Generate the elf mapping textproto file based on the copied symbols file. - Set the `SymbolInfosProvider`. The provider is not consumed in this change, but will be done in a follow up change when generating the symbols.zip file. Test: CI Bug: 395989947 Change-Id: I7b462de42618c6a38a8cad658058dd790acd8837 --- apex/apex.go | 2 + cc/builder.go | 9 +++++ cc/cc.go | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++ java/app.go | 8 ++++ rust/builder_test.go | 6 +++ rust/rust.go | 2 + 6 files changed, 139 insertions(+) diff --git a/apex/apex.go b/apex/apex.go index 0db754268..1d41f61dc 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -2941,5 +2941,7 @@ func (a *apexBundle) setSymbolInfosProvider(ctx android.ModuleContext) { } } } + + cc.CopySymbolsAndSetSymbolsInfoProvider(ctx, infos) } } diff --git a/cc/builder.go b/cc/builder.go index f4f85962d..98816e3d6 100644 --- a/cc/builder.go +++ b/cc/builder.go @@ -345,6 +345,13 @@ var ( }, "cFlags") + // Rule to generate the elf mapping textproto file from the symbols file. + elfSymbolsToProto = pctx.AndroidStaticRule("elf_symbols_to_proto", blueprint.RuleParams{ + Command: `${symbols_map} -elf $in -write_if_changed $out`, + Restat: true, + CommandDeps: []string{"${symbols_map}"}, + }) + // Function pointer for producting staticlibs from rlibs. Corresponds to // rust.TransformRlibstoStaticlib(), initialized in soong-rust (rust/builder.go init()) // @@ -370,6 +377,8 @@ func init() { pctx.StaticVariable("relPwd", PwdPrefix()) pctx.HostBinToolVariable("SoongZipCmd", "soong_zip") + + pctx.HostBinToolVariable("symbols_map", "symbols_map") } // builderFlags contains various types of command line flags (and settings) for use in building diff --git a/cc/cc.go b/cc/cc.go index c50cb64a0..b2a2f5e58 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -2180,6 +2180,116 @@ func (c *Module) baseSymbolInfo(ctx android.ModuleContext) *SymbolInfo { } } +type SymbolicOutputInfo struct { + UnstrippedOutputFile android.Path + SymbolicOutputPath android.InstallPath + ElfMappingProtoPath android.InstallPath +} + +type SymbolicOutputInfos []*SymbolicOutputInfo + +// SymbolInfosProvider provides necessary information to generate the symbols.zip +var SymbolInfosProvider = blueprint.NewProvider[SymbolicOutputInfos]() + +func (s *SymbolicOutputInfos) SortedUniqueSymbolicOutputPaths() android.Paths { + ret := make(android.Paths, len(*s)) + for i, info := range *s { + ret[i] = info.SymbolicOutputPath + } + return android.SortedUniquePaths(ret) +} + +func (s *SymbolicOutputInfos) SortedUniqueElfMappingProtoPaths() android.Paths { + ret := make(android.Paths, len(*s)) + for i, info := range *s { + ret[i] = info.ElfMappingProtoPath + } + return android.SortedUniquePaths(ret) +} + +func targetOutUnstripped(ctx android.ModuleContext) android.InstallPath { + return android.PathForModuleInPartitionInstall(ctx, "symbols") +} + +func elfSymbolMappingDir(ctx android.ModuleContext) android.InstallPath { + return android.PathForModuleInPartitionInstall(ctx, "obj", "PACKAGING", "elf_symbol_mapping_intermediates") +} + +// Generates the information to copy the symbols file to $PRODUCT_OUT/symbols directory based on +// the symbols info. The actual copying is done in [CopySymbolsAndSetSymbolsInfoProvider]. +func getSymbolicOutputInfos(ctx android.ModuleContext, info *SymbolInfo) *SymbolicOutputInfo { + + if info.Uninstallable || info.UnstrippedBinaryPath == nil { + return nil + } + + mySymbolPath := info.ModuleDir + + myUnstrippedPath := targetOutUnstripped(ctx).Join(ctx, strings.TrimPrefix(mySymbolPath, android.PathForModuleInPartitionInstall(ctx, "").String()+"/")) + + myInstalledModuleStem := info.InstalledStem + if len(myInstalledModuleStem) == 0 { + myModuleStem := info.Stem + if len(myModuleStem) == 0 { + myModuleStem = info.Name + } + myInstalledModuleStem = myModuleStem + info.Suffix + } + + symbolicOutput := myUnstrippedPath.Join(ctx, myInstalledModuleStem) + + return &SymbolicOutputInfo{ + UnstrippedOutputFile: info.UnstrippedBinaryPath, + SymbolicOutputPath: symbolicOutput, + } +} + +func CopySymbolsAndSetSymbolsInfoProvider(ctx android.ModuleContext, symbolInfos *SymbolInfos) { + if android.ShouldSkipAndroidMkProcessing(ctx, ctx.Module()) { + return + } + var symbolicOutputInfos SymbolicOutputInfos + for _, info := range symbolInfos.Symbols { + if so := getSymbolicOutputInfos(ctx, info); so != nil { + symbolicOutputInfos = append(symbolicOutputInfos, so) + } + } + + // Remove duplicates + symbolicOutputInfos = android.FirstUniqueFunc(symbolicOutputInfos, func(a, b *SymbolicOutputInfo) bool { + return a.UnstrippedOutputFile.String() == b.UnstrippedOutputFile.String() && + a.SymbolicOutputPath.String() == b.SymbolicOutputPath.String() + }) + + // Copy the symbols files to $PRODUCT_OUT/symbols directory + for _, info := range symbolicOutputInfos { + ctx.Build(pctx, android.BuildParams{ + Rule: android.CpNoPreserveSymlink, + Input: info.UnstrippedOutputFile, + Output: info.SymbolicOutputPath, + }) + } + + // Generate the elf mapping textproto file from the copied symbols file + for _, info := range symbolicOutputInfos { + symbolPath := info.SymbolicOutputPath + symbolSubDir := strings.TrimPrefix(filepath.Dir(symbolPath.String()), targetOutUnstripped(ctx).String()+"/") + protoBase := filepath.Base(symbolPath.String()) + ".textproto" + info.ElfMappingProtoPath = elfSymbolMappingDir(ctx).Join(ctx, symbolSubDir, protoBase) + + ctx.Build(pctx, android.BuildParams{ + Rule: elfSymbolsToProto, + Input: symbolPath, + Output: info.ElfMappingProtoPath, + }) + } + + android.SetProvider(ctx, SymbolInfosProvider, symbolicOutputInfos) + + ctx.CheckbuildFile(symbolicOutputInfos.SortedUniqueSymbolicOutputPaths()...) + ctx.CheckbuildFile(symbolicOutputInfos.SortedUniqueElfMappingProtoPaths()...) +} + func (c *Module) collectSymbolsInfo(ctx android.ModuleContext) { if !c.hideApexVariantFromMake && !c.Properties.HideFromMake { infos := &SymbolInfos{} @@ -2192,6 +2302,8 @@ func (c *Module) collectSymbolsInfo(ctx android.ModuleContext) { infos.AppendSymbols(c.getSymbolInfo(ctx, c.sanitize, c.baseSymbolInfo(ctx))) } infos.AppendSymbols(c.getSymbolInfo(ctx, c.installer, c.baseSymbolInfo(ctx))) + + CopySymbolsAndSetSymbolsInfoProvider(ctx, infos) } } diff --git a/java/app.go b/java/app.go index 6c1e4f6a5..a892e8ffd 100644 --- a/java/app.go +++ b/java/app.go @@ -1180,6 +1180,14 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { a.setOutputFiles(ctx) buildComplianceMetadata(ctx) + + if !a.hideApexVariantFromMake && !a.IsHideFromMake() { + if a.embeddedJniLibs { + cc.CopySymbolsAndSetSymbolsInfoProvider(ctx, &cc.SymbolInfos{ + Symbols: a.GetJniSymbolInfos(ctx, a.installPathForJNISymbols), + }) + } + } } func (a *AndroidApp) setOutputFiles(ctx android.ModuleContext) { diff --git a/rust/builder_test.go b/rust/builder_test.go index 7d6b56ac9..95d17b23e 100644 --- a/rust/builder_test.go +++ b/rust/builder_test.go @@ -87,6 +87,8 @@ func TestCompilationOutputFiles(t *testing.T) { "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_dylib/unstripped/libfizz_buzz.dylib.so", "out/target/product/test_device/system/lib64/libfizz_buzz.dylib.so", "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_dylib/meta_lic", + "out/target/product/test_device/obj/PACKAGING/elf_symbol_mapping_intermediates/system/lib64/libfizz_buzz.dylib.so.textproto", + "out/target/product/test_device/symbols/system/lib64/libfizz_buzz.dylib.so", }, }, { @@ -120,6 +122,8 @@ func TestCompilationOutputFiles(t *testing.T) { "out/soong/.intermediates/fizz_buzz/android_arm64_armv8-a/unstripped/fizz_buzz", "out/target/product/test_device/system/bin/fizz_buzz", "out/soong/.intermediates/fizz_buzz/android_arm64_armv8-a/meta_lic", + "out/target/product/test_device/obj/PACKAGING/elf_symbol_mapping_intermediates/system/bin/fizz_buzz.textproto", + "out/target/product/test_device/symbols/system/bin/fizz_buzz", }, }, { @@ -155,6 +159,8 @@ func TestCompilationOutputFiles(t *testing.T) { "out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_shared/meta_lic", "out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_shared/rustdoc.timestamp", "out/target/product/test_device/system/lib64/librust_ffi.so", + "out/target/product/test_device/obj/PACKAGING/elf_symbol_mapping_intermediates/system/lib64/librust_ffi.so.textproto", + "out/target/product/test_device/symbols/system/lib64/librust_ffi.so", }, }, } diff --git a/rust/rust.go b/rust/rust.go index 5941530a6..9643ec90a 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -1295,6 +1295,8 @@ func (mod *Module) setSymbolsInfoProvider(ctx android.ModuleContext) { if mod.sanitize != nil { infos.AppendSymbols(mod.getSymbolInfo(ctx, mod.sanitize, mod.baseSymbolInfo(ctx))) } + + cc.CopySymbolsAndSetSymbolsInfoProvider(ctx, infos) } } -- cgit v1.2.3 From 3eb84a9fe4fe6d158abb745bf6a15e87e6eff114 Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Thu, 13 Feb 2025 02:01:22 +0000 Subject: Define symbols.zip build rules in Soong symbols.zip file consists of all copies of LOCAL_SOONG_UNSTRIPPED_BINARY entires in $PRODUCT_OUT/symbols of modules that are installed. This change utilizes allInstalledModules of android_device module to collect the unstripped binary files of all installed modules. This change generates the build rule of the symbols.zip and the merged elf mapping textproto file, and dists them. Test: m droid dist && diff out/dist/-symbols-.zip with/without this change Bug: 395989947 Change-Id: I5552bc91b1c6a0c4c29a98705867b430125a41b2 --- filesystem/android_device.go | 45 ++++++++++++++++++++++++++++++++++++++++++++ filesystem/filesystem.go | 7 +++++++ 2 files changed, 52 insertions(+) diff --git a/filesystem/android_device.go b/filesystem/android_device.go index dec395060..c33fa962e 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -24,6 +24,7 @@ import ( "sync/atomic" "android/soong/android" + "android/soong/cc" "android/soong/java" "github.com/google/blueprint" @@ -122,6 +123,9 @@ type androidDevice struct { apkCertsInfo android.Path targetFilesZip android.Path updatePackage android.Path + + symbolsZipFile android.ModuleOutPath + symbolsMappingFile android.ModuleOutPath } func AndroidDeviceFactory() android.Module { @@ -201,6 +205,7 @@ func (a *androidDevice) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.miscInfo = a.addMiscInfo(ctx) a.buildTargetFilesZip(ctx, allInstalledModules) a.buildProguardZips(ctx, allInstalledModules) + a.buildSymbolsZip(ctx, allInstalledModules) a.buildUpdatePackage(ctx) var deps []android.Path @@ -376,6 +381,43 @@ func (a *androidDevice) allInstalledModules(ctx android.ModuleContext) []android return ret } +type symbolicOutputInfo struct { + unstrippedOutputFile android.Path + symbolicOutputPath android.InstallPath +} + +func (a *androidDevice) buildSymbolsZip(ctx android.ModuleContext, allInstalledModules []android.Module) { + var allSymbolicOutputPaths, allElfMappingProtoPaths android.Paths + for _, mod := range allInstalledModules { + if commonInfo, _ := android.OtherModuleProvider(ctx, mod, android.CommonModuleInfoProvider); commonInfo.SkipAndroidMkProcessing { + continue + } + if symbolInfos, ok := android.OtherModuleProvider(ctx, mod, cc.SymbolInfosProvider); ok { + allSymbolicOutputPaths = append(allSymbolicOutputPaths, symbolInfos.SortedUniqueSymbolicOutputPaths()...) + allElfMappingProtoPaths = append(allElfMappingProtoPaths, symbolInfos.SortedUniqueElfMappingProtoPaths()...) + } + } + allSymbolicOutputPaths = android.SortedUniquePaths(allSymbolicOutputPaths) + allElfMappingProtoPaths = android.SortedUniquePaths(allElfMappingProtoPaths) + + a.symbolsZipFile = android.PathForModuleOut(ctx, "symbols.zip") + ctx.Build(pctx, android.BuildParams{ + Rule: zipFiles, + Inputs: allSymbolicOutputPaths, + Output: a.symbolsZipFile, + }) + + a.symbolsMappingFile = android.PathForModuleOut(ctx, "symbols-mapping.textproto") + dictMappingBuilder := android.NewRuleBuilder(pctx, ctx) + dictMappingBuilder.Command(). + BuiltTool("symbols_map"). + Flag("-merge"). + Output(a.symbolsMappingFile). + Inputs(allElfMappingProtoPaths) + + dictMappingBuilder.Build("symbols_elf_dict_mapping_proto", "Building symbols mapping proto") +} + func insertBeforeExtension(file, insertion string) string { ext := filepath.Ext(file) return strings.TrimSuffix(file, ext) + insertion + ext @@ -416,6 +458,9 @@ func (a *androidDevice) distFiles(ctx android.ModuleContext) { ctx.DistForGoalWithFilename("droidcore-unbundled", a.proguardDictMapping, namePrefix+insertBeforeExtension(a.proguardDictMapping.Base(), "-FILE_NAME_TAG_PLACEHOLDER")) ctx.DistForGoalWithFilename("droidcore-unbundled", a.proguardUsageZip, namePrefix+insertBeforeExtension(a.proguardUsageZip.Base(), "-FILE_NAME_TAG_PLACEHOLDER")) + ctx.DistForGoalWithFilename("droidcore-unbundled", a.symbolsZipFile, namePrefix+insertBeforeExtension(a.symbolsZipFile.Base(), "-FILE_NAME_TAG_PLACEHOLDER")) + ctx.DistForGoalWithFilename("droidcore-unbundled", a.symbolsMappingFile, namePrefix+insertBeforeExtension(a.symbolsMappingFile.Base(), "-FILE_NAME_TAG_PLACEHOLDER")) + if a.deviceProps.Android_info != nil { ctx.DistForGoal("droidcore-unbundled", android.PathForModuleSrc(ctx, *a.deviceProps.Android_info)) } diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index d2131dc27..95516b89f 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -42,6 +42,7 @@ func init() { pctx.HostBinToolVariable("fileslist", "fileslist") pctx.HostBinToolVariable("fs_config", "fs_config") pctx.HostBinToolVariable("symbols_map", "symbols_map") + pctx.HostBinToolVariable("SoongZipCmd", "soong_zip") } func registerBuildComponents(ctx android.RegistrationContext) { @@ -81,6 +82,12 @@ var ( Command: `(cd ${rootDir}; find . -type d | sed 's,$$,/,'; find . \! -type d) | cut -c 3- | sort | sed 's,^,${prefix},' | ${fs_config} -C -D ${rootDir} -R "${prefix}" > ${out}`, CommandDeps: []string{"${fs_config}"}, }, "rootDir", "prefix") + zipFiles = pctx.AndroidStaticRule("SnapshotZipFiles", blueprint.RuleParams{ + Command: `${SoongZipCmd} -r $out.rsp -o $out`, + CommandDeps: []string{"${SoongZipCmd}"}, + Rspfile: "$out.rsp", + RspfileContent: "$in", + }) ) type filesystem struct { -- cgit v1.2.3 From 4030dfd3485bf829e2bb72319287b4e682210596 Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Fri, 28 Mar 2025 17:46:08 -0700 Subject: Convert BuildSymbolsZip into a Soong api The method was originally used to define the build rules of the symbols.zip and the merged elf mapping proto file in android_device module type. To support generating the symbols.zip in (to be converted) soong test suites, this change converts the `BuildSymbolsZip` method into a soong api. Test: m nothing Bug: 395989947 Change-Id: I9700777916eb2b3c4877deee0c3be567bbf5cf64 --- android/Android.bp | 1 + android/symbols.go | 85 ++++++++++++++++++++++++++++++++++++++++++++ cc/cc.go | 37 +++---------------- filesystem/android_device.go | 29 +-------------- 4 files changed, 92 insertions(+), 60 deletions(-) create mode 100644 android/symbols.go diff --git a/android/Android.bp b/android/Android.bp index 97d634fb5..cefd0a597 100644 --- a/android/Android.bp +++ b/android/Android.bp @@ -113,6 +113,7 @@ bootstrap_go_package { "singleton.go", "singleton_module.go", "soong_config_modules.go", + "symbols.go", "team.go", "test_asserts.go", "test_mapping_zip.go", diff --git a/android/symbols.go b/android/symbols.go new file mode 100644 index 000000000..dea1e81ea --- /dev/null +++ b/android/symbols.go @@ -0,0 +1,85 @@ +// 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 android + +import "github.com/google/blueprint" + +var zipFiles = pctx.AndroidStaticRule("SnapshotZipFiles", blueprint.RuleParams{ + Command: `${SoongZipCmd} -r $out.rsp -o $out`, + CommandDeps: []string{"${SoongZipCmd}"}, + Rspfile: "$out.rsp", + RspfileContent: "$in", +}) + +// Provider for generating symbols.zip +type SymbolicOutputInfo struct { + UnstrippedOutputFile Path + SymbolicOutputPath InstallPath + ElfMappingProtoPath InstallPath +} + +type SymbolicOutputInfos []*SymbolicOutputInfo + +// SymbolInfosProvider provides necessary information to generate the symbols.zip +var SymbolInfosProvider = blueprint.NewProvider[SymbolicOutputInfos]() + +func (s *SymbolicOutputInfos) SortedUniqueSymbolicOutputPaths() Paths { + ret := make(Paths, len(*s)) + for i, info := range *s { + ret[i] = info.SymbolicOutputPath + } + return SortedUniquePaths(ret) +} + +func (s *SymbolicOutputInfos) SortedUniqueElfMappingProtoPaths() Paths { + ret := make(Paths, len(*s)) + for i, info := range *s { + ret[i] = info.ElfMappingProtoPath + } + return SortedUniquePaths(ret) +} + +// Defines the build rules to generate the symbols.zip file and the merged elf mapping textproto +// file. Modules in depModules that provide [SymbolInfosProvider] and are exported to make +// will be listed in the symbols.zip and the merged proto file. +func BuildSymbolsZip(ctx ModuleContext, depModules []Module, symbolsZipFile, mergedMappingProtoFile ModuleOutPath) { + var allSymbolicOutputPaths, allElfMappingProtoPaths Paths + for _, mod := range depModules { + if commonInfo, _ := OtherModuleProvider(ctx, mod, CommonModuleInfoProvider); commonInfo.SkipAndroidMkProcessing { + continue + } + if symbolInfos, ok := OtherModuleProvider(ctx, mod, SymbolInfosProvider); ok { + allSymbolicOutputPaths = append(allSymbolicOutputPaths, symbolInfos.SortedUniqueSymbolicOutputPaths()...) + allElfMappingProtoPaths = append(allElfMappingProtoPaths, symbolInfos.SortedUniqueElfMappingProtoPaths()...) + } + } + allSymbolicOutputPaths = SortedUniquePaths(allSymbolicOutputPaths) + allElfMappingProtoPaths = SortedUniquePaths(allElfMappingProtoPaths) + + ctx.Build(pctx, BuildParams{ + Rule: zipFiles, + Inputs: allSymbolicOutputPaths, + Output: symbolsZipFile, + }) + + dictMappingBuilder := NewRuleBuilder(pctx, ctx) + dictMappingBuilder.Command(). + BuiltTool("symbols_map"). + Flag("-merge"). + Output(mergedMappingProtoFile). + Inputs(allElfMappingProtoPaths) + + dictMappingBuilder.Build("symbols_elf_dict_mapping_proto", "Building symbols mapping proto") +} diff --git a/cc/cc.go b/cc/cc.go index b2a2f5e58..e52955957 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -2180,33 +2180,6 @@ func (c *Module) baseSymbolInfo(ctx android.ModuleContext) *SymbolInfo { } } -type SymbolicOutputInfo struct { - UnstrippedOutputFile android.Path - SymbolicOutputPath android.InstallPath - ElfMappingProtoPath android.InstallPath -} - -type SymbolicOutputInfos []*SymbolicOutputInfo - -// SymbolInfosProvider provides necessary information to generate the symbols.zip -var SymbolInfosProvider = blueprint.NewProvider[SymbolicOutputInfos]() - -func (s *SymbolicOutputInfos) SortedUniqueSymbolicOutputPaths() android.Paths { - ret := make(android.Paths, len(*s)) - for i, info := range *s { - ret[i] = info.SymbolicOutputPath - } - return android.SortedUniquePaths(ret) -} - -func (s *SymbolicOutputInfos) SortedUniqueElfMappingProtoPaths() android.Paths { - ret := make(android.Paths, len(*s)) - for i, info := range *s { - ret[i] = info.ElfMappingProtoPath - } - return android.SortedUniquePaths(ret) -} - func targetOutUnstripped(ctx android.ModuleContext) android.InstallPath { return android.PathForModuleInPartitionInstall(ctx, "symbols") } @@ -2217,7 +2190,7 @@ func elfSymbolMappingDir(ctx android.ModuleContext) android.InstallPath { // Generates the information to copy the symbols file to $PRODUCT_OUT/symbols directory based on // the symbols info. The actual copying is done in [CopySymbolsAndSetSymbolsInfoProvider]. -func getSymbolicOutputInfos(ctx android.ModuleContext, info *SymbolInfo) *SymbolicOutputInfo { +func getSymbolicOutputInfos(ctx android.ModuleContext, info *SymbolInfo) *android.SymbolicOutputInfo { if info.Uninstallable || info.UnstrippedBinaryPath == nil { return nil @@ -2238,7 +2211,7 @@ func getSymbolicOutputInfos(ctx android.ModuleContext, info *SymbolInfo) *Symbol symbolicOutput := myUnstrippedPath.Join(ctx, myInstalledModuleStem) - return &SymbolicOutputInfo{ + return &android.SymbolicOutputInfo{ UnstrippedOutputFile: info.UnstrippedBinaryPath, SymbolicOutputPath: symbolicOutput, } @@ -2248,7 +2221,7 @@ func CopySymbolsAndSetSymbolsInfoProvider(ctx android.ModuleContext, symbolInfos if android.ShouldSkipAndroidMkProcessing(ctx, ctx.Module()) { return } - var symbolicOutputInfos SymbolicOutputInfos + var symbolicOutputInfos android.SymbolicOutputInfos for _, info := range symbolInfos.Symbols { if so := getSymbolicOutputInfos(ctx, info); so != nil { symbolicOutputInfos = append(symbolicOutputInfos, so) @@ -2256,7 +2229,7 @@ func CopySymbolsAndSetSymbolsInfoProvider(ctx android.ModuleContext, symbolInfos } // Remove duplicates - symbolicOutputInfos = android.FirstUniqueFunc(symbolicOutputInfos, func(a, b *SymbolicOutputInfo) bool { + symbolicOutputInfos = android.FirstUniqueFunc(symbolicOutputInfos, func(a, b *android.SymbolicOutputInfo) bool { return a.UnstrippedOutputFile.String() == b.UnstrippedOutputFile.String() && a.SymbolicOutputPath.String() == b.SymbolicOutputPath.String() }) @@ -2284,7 +2257,7 @@ func CopySymbolsAndSetSymbolsInfoProvider(ctx android.ModuleContext, symbolInfos }) } - android.SetProvider(ctx, SymbolInfosProvider, symbolicOutputInfos) + android.SetProvider(ctx, android.SymbolInfosProvider, symbolicOutputInfos) ctx.CheckbuildFile(symbolicOutputInfos.SortedUniqueSymbolicOutputPaths()...) ctx.CheckbuildFile(symbolicOutputInfos.SortedUniqueElfMappingProtoPaths()...) diff --git a/filesystem/android_device.go b/filesystem/android_device.go index c33fa962e..2e84b258f 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -24,7 +24,6 @@ import ( "sync/atomic" "android/soong/android" - "android/soong/cc" "android/soong/java" "github.com/google/blueprint" @@ -387,35 +386,9 @@ type symbolicOutputInfo struct { } func (a *androidDevice) buildSymbolsZip(ctx android.ModuleContext, allInstalledModules []android.Module) { - var allSymbolicOutputPaths, allElfMappingProtoPaths android.Paths - for _, mod := range allInstalledModules { - if commonInfo, _ := android.OtherModuleProvider(ctx, mod, android.CommonModuleInfoProvider); commonInfo.SkipAndroidMkProcessing { - continue - } - if symbolInfos, ok := android.OtherModuleProvider(ctx, mod, cc.SymbolInfosProvider); ok { - allSymbolicOutputPaths = append(allSymbolicOutputPaths, symbolInfos.SortedUniqueSymbolicOutputPaths()...) - allElfMappingProtoPaths = append(allElfMappingProtoPaths, symbolInfos.SortedUniqueElfMappingProtoPaths()...) - } - } - allSymbolicOutputPaths = android.SortedUniquePaths(allSymbolicOutputPaths) - allElfMappingProtoPaths = android.SortedUniquePaths(allElfMappingProtoPaths) - a.symbolsZipFile = android.PathForModuleOut(ctx, "symbols.zip") - ctx.Build(pctx, android.BuildParams{ - Rule: zipFiles, - Inputs: allSymbolicOutputPaths, - Output: a.symbolsZipFile, - }) - a.symbolsMappingFile = android.PathForModuleOut(ctx, "symbols-mapping.textproto") - dictMappingBuilder := android.NewRuleBuilder(pctx, ctx) - dictMappingBuilder.Command(). - BuiltTool("symbols_map"). - Flag("-merge"). - Output(a.symbolsMappingFile). - Inputs(allElfMappingProtoPaths) - - dictMappingBuilder.Build("symbols_elf_dict_mapping_proto", "Building symbols mapping proto") + android.BuildSymbolsZip(ctx, allInstalledModules, a.symbolsZipFile, a.symbolsMappingFile) } func insertBeforeExtension(file, insertion string) string { -- cgit v1.2.3 From 7f59f8a20f1cac73dfce92f43c230f1b604b0801 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Fri, 28 Mar 2025 11:29:36 -0700 Subject: Reapply "Always install test files with soong" This reverts commit a933f952666f1282452da43ed5b73ebbdc091b37. Previously, this commit included a change where I prioritized the fact that it was a test over the fact that the app was priviledged for installation: https://googleplex-android-review.git.corp.google.com/c/platform/build/soong/+/32747769/2/java/app.go#999 I did this because I was worried about modules already installing files that this new testcase installation code would then try to install. I added a check for already installed files in test_suites.go. I thought that I would have to tell test_suites.go about the already installed file via the TestSuiteInfo, but I actually ended up getting that information from the CommonInfo. Using the installed file as the source file is problematic in soong+make builds, because make adds a dependency from the main installed file to the testcase files, and if the testcase files also have a dependency to the main installed file, it's a circular dependency. Swapping the priv-app / testcases priority worked around the circular dependency, but it turns out it causes later issues where some tests are not installed with the privileges they need to run correctly. Bug: 388850000 Test: Presubmits Change-Id: I686c1a7ba4f2367de7a75bf7052cb54d4296265c --- android/arch_module_context.go | 18 ++- android/module.go | 221 +++++++++++++++++++++++++++++++-- android/module_context.go | 15 +++ android/test_suites.go | 95 ++++++++++++++ android/variable.go | 7 ++ cc/binary.go | 4 - cc/cc.go | 4 - cc/library.go | 4 - cc/object.go | 4 - cc/test.go | 91 +++++++------- java/app.go | 59 +++++---- java/app_import.go | 14 ++- java/base.go | 5 +- java/fuzz.go | 23 +++- java/java.go | 50 ++++---- python/binary.go | 10 +- python/test.go | 32 +++-- rust/benchmark.go | 13 +- rust/test.go | 38 ++---- sh/sh_binary.go | 15 ++- tradefed_modules/test_module_config.go | 17 ++- 21 files changed, 553 insertions(+), 186 deletions(-) diff --git a/android/arch_module_context.go b/android/arch_module_context.go index a3a03af02..7c440ad00 100644 --- a/android/arch_module_context.go +++ b/android/arch_module_context.go @@ -30,17 +30,19 @@ type ArchModuleContext interface { Darwin() bool Windows() bool PrimaryArch() bool + PrimaryNativeBridgeArch() bool } type archModuleContext struct { // TODO: these should eventually go through a (possibly cached) provider like any other configuration instead // of being special cased. - ready bool - os OsType - target Target - targetPrimary bool - multiTargets []Target - primaryArch bool + ready bool + os OsType + target Target + targetPrimary bool + multiTargets []Target + primaryArch bool + primaryNativeBridgeArch bool } // ArchReady returns true if the arch mutator has run on the module. Before this returns @@ -89,3 +91,7 @@ func (a *archModuleContext) Windows() bool { func (b *archModuleContext) PrimaryArch() bool { return b.primaryArch } + +func (b *archModuleContext) PrimaryNativeBridgeArch() bool { + return b.primaryNativeBridgeArch +} diff --git a/android/module.go b/android/module.go index 55f170cfe..4211efb63 100644 --- a/android/module.go +++ b/android/module.go @@ -28,6 +28,7 @@ import ( "github.com/google/blueprint" "github.com/google/blueprint/depset" "github.com/google/blueprint/gobtools" + "github.com/google/blueprint/pathtools" "github.com/google/blueprint/proptools" ) @@ -1690,7 +1691,7 @@ func (m *ModuleBase) generateVariantTarget(ctx *moduleContext) { // generateModuleTarget generates phony targets so that you can do `m `. // It will be run on every variant of the module, so it relies on the fact that phony targets // are deduped to merge all the deps from different variants together. -func (m *ModuleBase) generateModuleTarget(ctx *moduleContext) { +func (m *ModuleBase) generateModuleTarget(ctx *moduleContext, testSuiteInstalls []filePair) { var namespacePrefix string nameSpace := ctx.Namespace().Path if nameSpace != "." { @@ -1724,6 +1725,10 @@ func (m *ModuleBase) generateModuleTarget(ctx *moduleContext) { deps = append(deps, outputFiles...) } + for _, p := range testSuiteInstalls { + deps = append(deps, p.dst) + } + if len(deps) > 0 { suffix := "" if ctx.Config().KatiEnabled() { @@ -1836,14 +1841,27 @@ func (m *ModuleBase) archModuleContextFactory(ctx archModuleContextFactoryContex } else { primaryArch = target.Arch.ArchType == config.Targets[target.Os][0].Arch.ArchType } + primaryNativeBridgeArch := false + if target.NativeBridge { + for _, t := range config.Targets[target.Os] { + if t.NativeBridge { + if target.Arch.ArchType == t.Arch.ArchType { + primaryNativeBridgeArch = true + } + // Don't consider further nativebridge targets + break + } + } + } return archModuleContext{ - ready: m.commonProperties.ArchReady, - os: m.commonProperties.CompileOS, - target: m.commonProperties.CompileTarget, - targetPrimary: m.commonProperties.CompilePrimary, - multiTargets: m.commonProperties.CompileMultiTargets, - primaryArch: primaryArch, + ready: m.commonProperties.ArchReady, + os: m.commonProperties.CompileOS, + target: m.commonProperties.CompileTarget, + targetPrimary: m.commonProperties.CompilePrimary, + multiTargets: m.commonProperties.CompileMultiTargets, + primaryArch: primaryArch, + primaryNativeBridgeArch: primaryNativeBridgeArch, } } @@ -2140,6 +2158,10 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) m.generateVariantTarget(ctx) + testData := FirstUniqueFunc(ctx.testData, func(a, b DataPath) bool { + return a == b + }) + installFiles.LicenseMetadataFile = ctx.licenseMetadataFile installFiles.InstallFiles = ctx.installFiles installFiles.CheckbuildFiles = ctx.checkbuildFiles @@ -2148,7 +2170,7 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) installFiles.PackagingSpecs = ctx.packagingSpecs installFiles.KatiInstalls = ctx.katiInstalls installFiles.KatiSymlinks = ctx.katiSymlinks - installFiles.TestData = ctx.testData + installFiles.TestData = testData } else if ctx.Config().AllowMissingDependencies() { // If the module is not enabled it will not create any build rules, nothing will call // ctx.GetMissingDependencies(), and blueprint will consider the missing dependencies to be unhandled @@ -2168,11 +2190,6 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) SetProvider(ctx, SourceFilesInfoProvider, SourceFilesInfo{Srcs: sourceFileProducer.Srcs()}) } - m.generateModuleTarget(ctx) - if ctx.Failed() { - return - } - ctx.TransitiveInstallFiles = depset.New[InstallPath](depset.TOPOLOGICAL, ctx.installFiles, dependencyInstallFiles) installFiles.TransitiveInstallFiles = ctx.TransitiveInstallFiles installFiles.TransitivePackagingSpecs = depset.New[PackagingSpec](depset.TOPOLOGICAL, ctx.packagingSpecs, dependencyPackagingSpecs) @@ -2180,6 +2197,16 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) SetProvider(ctx, InstallFilesProvider, installFiles) buildLicenseMetadata(ctx, ctx.licenseMetadataFile) + var testSuiteInstalls []filePair + if ctx.testSuiteInfoSet { + testSuiteInstalls = m.setupTestSuites(ctx, ctx.testSuiteInfo) + } + + m.generateModuleTarget(ctx, testSuiteInstalls) + if ctx.Failed() { + return + } + if len(ctx.moduleInfoJSON) > 0 { for _, moduleInfoJSON := range ctx.moduleInfoJSON { if moduleInfoJSON.Disabled { @@ -2397,6 +2424,174 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) } } +func (m *ModuleBase) CleanupAfterBuildActions() {} + +func (m *ModuleBase) setupTestSuites(ctx ModuleContext, info TestSuiteInfo) []filePair { + // We skip test suites when using the ndk or aml abis, as the extra archs (x86_64 + arm64) + // both try to install to the same test file. This could be fixed by always using a per-module + // folder and an arch folder, but as you see later in this function we only conditionally use + // those. + if ctx.Config().NdkAbis() || ctx.Config().AmlAbis() || shouldSkipAndroidMkProcessing(ctx, m) || m.IsSkipInstall() { + return nil + } + overriddenBy := "" + if b, ok := ctx.Module().(OverridableModule); ok { + overriddenBy = b.GetOverriddenBy() + } + + // M(C)TS supports a full test suite and partial per-module MTS test suites, with naming mts-${MODULE}. + // To reduce repetition, if we find a partial M(C)TS test suite without an full M(C)TS test suite, + // we add the full test suite to our list. + if PrefixInList(info.TestSuites, "mts-") && !InList("mts", info.TestSuites) { + info.TestSuites = append(info.TestSuites, "mts") + } + if PrefixInList(info.TestSuites, "mcts-") && !InList("mcts", info.TestSuites) { + info.TestSuites = append(info.TestSuites, "mcts") + } + + if len(info.TestSuites) == 0 { + info.TestSuites = []string{"null-suite"} + } + info.TestSuites = SortedUniqueStrings(info.TestSuites) + + name := ctx.ModuleName() + if overriddenBy != "" { + name = overriddenBy + } + name += info.NameSuffix + + type testSuiteInfo struct { + name string + dir WritablePath + includeModuleFolder bool + } + + suites := []testSuiteInfo{{ + dir: PathForModuleInPartitionInstall(ctx, "testcases", name), + includeModuleFolder: true, + }} + for _, suite := range info.TestSuites { + if suiteInfo, ok := ctx.Config().productVariables.CompatibilityTestcases[suite]; ok { + rel, err := filepath.Rel(ctx.Config().OutDir(), suiteInfo.OutDir) + if err != nil { + panic(fmt.Sprintf("Could not make COMPATIBILITY_TESTCASES_OUT_%s (%s) relative to the out dir (%s)", suite, suiteInfo.OutDir, ctx.Config().OutDir())) + } + if suiteInfo.IncludeModuleFolder || info.PerTestcaseDirectory { + rel = filepath.Join(rel, name) + } + suites = append(suites, testSuiteInfo{ + name: suite, + dir: PathForArbitraryOutput(ctx, rel), + includeModuleFolder: suiteInfo.IncludeModuleFolder || info.PerTestcaseDirectory, + }) + } + } + + var archDir string + if info.NeedsArchFolder { + archDir = ctx.Arch().ArchType.Name + if archDir == "common" { + archDir = ctx.DeviceConfig().DeviceArch() + } + if ctx.Target().NativeBridge { + archDir = ctx.Target().NativeBridgeHostArchName + } + } + + var installs []filePair + var oneVariantInstalls []filePair + + for _, suite := range suites { + mainFileName := name + if info.MainFileStem != "" { + mainFileName = info.MainFileStem + } + mainFileName += info.MainFileExt + mainFileInstall := joinWriteablePath(ctx, suite.dir, archDir, mainFileName) + if !suite.includeModuleFolder { + mainFileInstall = joinWriteablePath(ctx, suite.dir, mainFileName) + } + if info.MainFile == nil { + panic("mainfile was nil") + } + + installs = append(installs, filePair{ + src: info.MainFile, + dst: mainFileInstall, + }) + + for _, data := range info.Data { + dataOut := joinWriteablePath(ctx, suite.dir, archDir, data.ToRelativeInstallPath()) + if !suite.includeModuleFolder { + dataOut = joinWriteablePath(ctx, suite.dir, data.ToRelativeInstallPath()) + } + installs = append(installs, filePair{ + src: data.SrcPath, + dst: dataOut, + }) + } + for _, data := range info.NonArchData { + dataOut := joinWriteablePath(ctx, suite.dir, data.ToRelativeInstallPath()) + installs = append(installs, filePair{ + src: data.SrcPath, + dst: dataOut, + }) + } + for _, data := range info.CompatibilitySupportFiles { + dataOut := joinWriteablePath(ctx, suite.dir, data.Rel()) + installs = append(installs, filePair{ + src: data, + dst: dataOut, + }) + } + + if info.ConfigFile != nil { + oneVariantInstalls = append(oneVariantInstalls, filePair{ + src: info.ConfigFile, + dst: joinWriteablePath(ctx, suite.dir, name+".config"+info.ConfigFileSuffix), + }) + } else if config := ExistentPathForSource(ctx, ctx.ModuleDir(), "AndroidTest.xml"); config.Valid() { + oneVariantInstalls = append(oneVariantInstalls, filePair{ + src: config.Path(), + dst: joinWriteablePath(ctx, suite.dir, name+".config"), + }) + } + + dynamicConfig := ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml") + if dynamicConfig.Valid() { + oneVariantInstalls = append(oneVariantInstalls, filePair{ + src: dynamicConfig.Path(), + dst: joinWriteablePath(ctx, suite.dir, name+".dynamic"), + }) + } + for _, extraTestConfig := range info.ExtraConfigs { + if extraTestConfig == nil { + panic("ExtraTestConfig was nil") + } + oneVariantInstalls = append(oneVariantInstalls, filePair{ + src: extraTestConfig, + dst: joinWriteablePath(ctx, suite.dir, pathtools.ReplaceExtension(extraTestConfig.Base(), "config")), + }) + } + } + + SetProvider(ctx, TestSuiteInfoProvider, info) + SetProvider(ctx, testSuiteInstallsInfoProvider, testSuiteInstallsInfo{installs, oneVariantInstalls}) + + return slices.Concat(installs, oneVariantInstalls) +} + +func joinWriteablePath(ctx PathContext, path WritablePath, toJoin ...string) WritablePath { + switch p := path.(type) { + case InstallPath: + return p.Join(ctx, toJoin...) + case OutputPath: + return p.Join(ctx, toJoin...) + default: + panic("unhandled path type") + } +} + func SetJarJarPrefixHandler(handler func(ModuleContext)) { if jarJarPrefixHandler != nil { panic("jarJarPrefixHandler already set") diff --git a/android/module_context.go b/android/module_context.go index e30afd637..3542671ac 100644 --- a/android/module_context.go +++ b/android/module_context.go @@ -275,6 +275,10 @@ type ModuleContext interface { // directory on the build server with the given filename when any of the // specified goals are built. DistForGoalsWithFilename(goals []string, path Path, filename string) + + // Defines this module as a compatibility suite test and gives all the information needed + // to build the suite. + SetTestSuiteInfo(info TestSuiteInfo) } type moduleContext struct { @@ -334,6 +338,9 @@ type moduleContext struct { complianceMetadataInfo *ComplianceMetadataInfo dists []dist + + testSuiteInfo TestSuiteInfo + testSuiteInfoSet bool } var _ ModuleContext = &moduleContext{} @@ -1041,3 +1048,11 @@ func (c *moduleContext) DistForGoalsWithFilename(goals []string, path Path, file paths: distCopies{{from: path, dest: filename}}, }) } + +func (c *moduleContext) SetTestSuiteInfo(info TestSuiteInfo) { + if c.testSuiteInfoSet { + panic("Cannot call SetTestSuiteInfo twice") + } + c.testSuiteInfo = info + c.testSuiteInfoSet = true +} diff --git a/android/test_suites.go b/android/test_suites.go index dbcd48c79..8f40f259b 100644 --- a/android/test_suites.go +++ b/android/test_suites.go @@ -16,6 +16,8 @@ package android import ( "path/filepath" + "slices" + "sort" "strings" "github.com/google/blueprint" @@ -37,7 +39,34 @@ type TestSuiteModule interface { } type TestSuiteInfo struct { + // A suffix to append to the name of the test. + // Useful because historically different variants of soong modules became differently-named + // make modules, like "my_test.vendor" for the vendor variant. + NameSuffix string + TestSuites []string + + NeedsArchFolder bool + + MainFile Path + + MainFileStem string + + MainFileExt string + + ConfigFile Path + + ConfigFileSuffix string + + ExtraConfigs Paths + + PerTestcaseDirectory bool + + Data []DataPath + + NonArchData []DataPath + + CompatibilitySupportFiles []Path } var TestSuiteInfoProvider = blueprint.NewProvider[TestSuiteInfo]() @@ -48,8 +77,22 @@ type SupportFilesInfo struct { var SupportFilesInfoProvider = blueprint.NewProvider[SupportFilesInfo]() +type filePair struct { + src Path + dst WritablePath +} + +type testSuiteInstallsInfo struct { + Files []filePair + OneVariantInstalls []filePair +} + +var testSuiteInstallsInfoProvider = blueprint.NewProvider[testSuiteInstallsInfo]() + func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) { files := make(map[string]map[string]InstallPaths) + var toInstall []filePair + var oneVariantInstalls []filePair ctx.VisitAllModuleProxies(func(m ModuleProxy) { if tsm, ok := OtherModuleProvider(ctx, m, TestSuiteInfoProvider); ok { @@ -62,8 +105,60 @@ func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) { OtherModuleProviderOrDefault(ctx, m, InstallFilesProvider).InstallFiles...) } } + if testSuiteInstalls, ok := OtherModuleProvider(ctx, m, testSuiteInstallsInfoProvider); ok { + installs := OtherModuleProviderOrDefault(ctx, m, InstallFilesProvider).InstallFiles + oneVariantInstalls = append(oneVariantInstalls, testSuiteInstalls.OneVariantInstalls...) + for _, f := range testSuiteInstalls.Files { + alreadyInstalled := false + for _, install := range installs { + if install.String() == f.dst.String() { + alreadyInstalled = true + break + } + } + if !alreadyInstalled { + toInstall = append(toInstall, f) + } + } + } + }) + + filePairSorter := func(arr []filePair) func(i, j int) bool { + return func(i, j int) bool { + c := strings.Compare(arr[i].dst.String(), arr[j].dst.String()) + if c < 0 { + return true + } else if c > 0 { + return false + } + return arr[i].src.String() < arr[j].src.String() + } + } + sort.Slice(toInstall, filePairSorter(toInstall)) + // Dedup, as multiple tests may install the same test data to the same folder + toInstall = slices.Compact(toInstall) + + // Dedup the oneVariant files by only the dst locations, and ignore installs from other variants + sort.Slice(oneVariantInstalls, filePairSorter(oneVariantInstalls)) + oneVariantInstalls = slices.CompactFunc(oneVariantInstalls, func(a, b filePair) bool { + return a.dst.String() == b.dst.String() }) + for _, install := range toInstall { + ctx.Build(pctx, BuildParams{ + Rule: Cp, + Input: install.src, + Output: install.dst, + }) + } + for _, install := range oneVariantInstalls { + ctx.Build(pctx, BuildParams{ + Rule: Cp, + Input: install.src, + Output: install.dst, + }) + } + robolectricZip, robolectrictListZip := buildTestSuite(ctx, "robolectric-tests", files["robolectric-tests"]) ctx.Phony("robolectric-tests", robolectricZip, robolectrictListZip) ctx.DistForGoal("robolectric-tests", robolectricZip, robolectrictListZip) diff --git a/android/variable.go b/android/variable.go index f00dd138b..b5ffa7cf8 100644 --- a/android/variable.go +++ b/android/variable.go @@ -550,6 +550,13 @@ type ProductVariables struct { UseSoongNoticeXML *bool `json:",omitempty"` StripByDefault *bool `json:",omitempty"` + + CompatibilityTestcases map[string]CompatibilityTestcaseJSON +} + +type CompatibilityTestcaseJSON struct { + OutDir string `json:",omitempty"` + IncludeModuleFolder bool `json:",omitempty"` } type PartitionQualifiedVariablesType struct { diff --git a/cc/binary.go b/cc/binary.go index 608251afc..627d5e560 100644 --- a/cc/binary.go +++ b/cc/binary.go @@ -551,10 +551,6 @@ func (binary *binaryDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON binary.baseLinker.moduleInfoJSON(ctx, moduleInfoJSON) } -func (binary *binaryDecorator) testSuiteInfo(ctx ModuleContext) { - // not a test -} - var _ overridable = (*binaryDecorator)(nil) func init() { diff --git a/cc/cc.go b/cc/cc.go index dc9b831f9..c50cb64a0 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -798,8 +798,6 @@ type linker interface { defaultDistFiles() []android.Path moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) - - testSuiteInfo(ctx ModuleContext) } // specifiedDeps is a tuple struct representing dependencies of a linked binary owned by the linker. @@ -2524,8 +2522,6 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { name := v.ImplementationModuleName(ctx.OtherModuleName(c)) ccInfo.LinkerInfo.ImplementationModuleName = &name } - - c.linker.testSuiteInfo(ctx) } if c.library != nil { ccInfo.LibraryInfo = &LibraryInfo{ diff --git a/cc/library.go b/cc/library.go index 5299771ca..b248224bd 100644 --- a/cc/library.go +++ b/cc/library.go @@ -1078,10 +1078,6 @@ func (library *libraryDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSO library.baseLinker.moduleInfoJSON(ctx, moduleInfoJSON) } -func (library *libraryDecorator) testSuiteInfo(ctx ModuleContext) { - // not a test -} - func (library *libraryDecorator) linkStatic(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path { diff --git a/cc/object.go b/cc/object.go index ea3ed6151..95a8beb52 100644 --- a/cc/object.go +++ b/cc/object.go @@ -250,7 +250,3 @@ func (object *objectLinker) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *an object.baseLinker.moduleInfoJSON(ctx, moduleInfoJSON) moduleInfoJSON.Class = []string{"STATIC_LIBRARIES"} } - -func (object *objectLinker) testSuiteInfo(ctx ModuleContext) { - // not a test -} diff --git a/cc/test.go b/cc/test.go index 9c276b81a..fed24671d 100644 --- a/cc/test.go +++ b/cc/test.go @@ -274,12 +274,6 @@ func (test *testDecorator) moduleInfoJSON(ctx android.ModuleContext, moduleInfoJ } } -func (test *testDecorator) testSuiteInfo(ctx ModuleContext) { - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: test.InstallerProperties.Test_suites, - }) -} - func NewTestInstaller() *baseInstaller { return NewBaseInstaller("nativetest", "nativetest64", InstallInData) } @@ -348,10 +342,6 @@ func (test *testBinary) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *androi } -func (test *testBinary) testSuiteInfo(ctx ModuleContext) { - test.testDecorator.testSuiteInfo(ctx) -} - func (test *testBinary) installerProps() []interface{} { return append(test.baseInstaller.installerProps(), test.testDecorator.installerProps()...) } @@ -422,32 +412,24 @@ func (test *testBinary) install(ctx ModuleContext, file android.Path) { test.Properties.Test_options.Unit_test = proptools.BoolPtr(true) } - if !ctx.Config().KatiEnabled() { // TODO(spandandas): Remove the special case for kati - // Install the test config in testcases/ directory for atest. - c, ok := ctx.Module().(*Module) - if !ok { - ctx.ModuleErrorf("Not a cc_test module") - } - // Install configs in the root of $PRODUCT_OUT/testcases/$module - testCases := android.PathForModuleInPartitionInstall(ctx, "testcases", ctx.ModuleName()+c.SubName()) - if ctx.PrimaryArch() { - 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) - } - } - // Install tests and data in arch specific subdir $PRODUCT_OUT/testcases/$module/$arch - testCases = testCases.Join(ctx, ctx.Target().Arch.ArchType.String()) - ctx.InstallTestData(testCases, test.data) - ctx.InstallFile(testCases, file.Base(), file) + // Install the test config in testcases/ directory for atest. + c, ok := ctx.Module().(*Module) + if !ok { + ctx.ModuleErrorf("Not a cc_test module") } + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + NameSuffix: c.SubName(), + TestSuites: test.InstallerProperties.Test_suites, + MainFile: file, + MainFileStem: file.Base(), + ConfigFile: test.testConfig, + ExtraConfigs: test.extraTestConfigs, + Data: test.data, + NeedsArchFolder: true, + PerTestcaseDirectory: Bool(test.Properties.Per_testcase_directory), + }) + test.binaryDecorator.baseInstaller.installTestData(ctx, test.data) test.binaryDecorator.baseInstaller.install(ctx, file) if Bool(test.Properties.Standalone_test) { @@ -588,8 +570,24 @@ func (test *testLibrary) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *andro test.testDecorator.moduleInfoJSON(ctx, moduleInfoJSON) } -func (test *testLibrary) testSuiteInfo(ctx ModuleContext) { - test.testDecorator.testSuiteInfo(ctx) +func (test *testLibrary) install(ctx ModuleContext, file android.Path) { + test.libraryDecorator.install(ctx, file) + + c, ok := ctx.Module().(*Module) + if !ok { + ctx.ModuleErrorf("Expected a cc module") + } + // host tests are not installed to testcases/ as per: + // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/base_rules.mk;l=251;drc=45efec6797cbf812df34dac9d05e43a9fe7217e0 + if test.shared() { + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + NameSuffix: c.SubName(), + TestSuites: test.InstallerProperties.Test_suites, + NeedsArchFolder: true, + MainFile: file, + MainFileStem: file.Base(), + }) + } } func (test *testLibrary) installerProps() []interface{} { @@ -684,6 +682,21 @@ func (benchmark *benchmarkDecorator) install(ctx ModuleContext, file android.Pat benchmark.binaryDecorator.baseInstaller.dir64 = filepath.Join("benchmarktest64", ctx.ModuleName()) benchmark.binaryDecorator.baseInstaller.installTestData(ctx, benchmark.data) benchmark.binaryDecorator.baseInstaller.install(ctx, file) + + c, ok := ctx.Module().(*Module) + if !ok { + ctx.ModuleErrorf("Not a cc module") + } + + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + NameSuffix: c.SubName(), + TestSuites: benchmark.Properties.Test_suites, + MainFile: file, + MainFileStem: file.Base(), + ConfigFile: benchmark.testConfig, + Data: benchmark.data, + NeedsArchFolder: true, + }) } func (benchmark *benchmarkDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) { @@ -709,12 +722,6 @@ func (benchmark *benchmarkDecorator) moduleInfoJSON(ctx ModuleContext, moduleInf } } -func (benchmark *benchmarkDecorator) testSuiteInfo(ctx ModuleContext) { - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: benchmark.Properties.Test_suites, - }) -} - func NewBenchmark(hod android.HostOrDeviceSupported) *Module { module, binary := newBinary(hod) module.multilib = android.MultilibBoth diff --git a/java/app.go b/java/app.go index 3a3253f04..4b0cc56aa 100644 --- a/java/app.go +++ b/java/app.go @@ -427,8 +427,18 @@ func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleCon moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") } - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: a.appTestHelperAppProperties.Test_suites, + var data []android.DataPath + for _, d := range a.extraOutputFiles { + data = append(data, android.DataPath{SrcPath: d}) + } + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: a.appTestHelperAppProperties.Test_suites, + MainFile: a.outputFile, + MainFileStem: a.installApkName, + MainFileExt: ".apk", + NeedsArchFolder: true, + NonArchData: data, + PerTestcaseDirectory: proptools.Bool(a.appTestHelperAppProperties.Per_testcase_directory), }) } @@ -1130,7 +1140,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { } } } - ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...) + a.installedOutputFile = ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...) } ctx.CheckbuildFile(a.outputFile) @@ -1679,22 +1689,29 @@ func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { 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() { - pathInTestCases := android.PathForModuleInstall(ctx, ctx.Module().Name()) - 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} - ctx.InstallTestData(pathInTestCases, []android.DataPath{dataPath}) - } - } + a.data = android.SortedUniquePaths(a.data) + a.extraTestConfigs = android.SortedUniquePaths(a.extraTestConfigs) + + var testData []android.DataPath + for _, data := range a.data { + dataPath := android.DataPath{SrcPath: data} + testData = append(testData, dataPath) + } + for _, d := range a.extraOutputFiles { + testData = append(testData, android.DataPath{SrcPath: d}) + } + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: a.testProperties.Test_suites, + MainFile: a.outputFile, + MainFileStem: a.installApkName, + MainFileExt: ".apk", + ConfigFile: a.testConfig, + ExtraConfigs: a.extraTestConfigs, + NonArchData: testData, + CompatibilitySupportFiles: a.data, + NeedsArchFolder: true, + PerTestcaseDirectory: proptools.Bool(a.testProperties.Per_testcase_directory), + }) android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{ TestcaseRelDataFiles: testcaseRel(a.data), @@ -1729,10 +1746,6 @@ func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { moduleInfoJSON.AutoTestConfig = []string{"true"} } moduleInfoJSON.TestMainlineModules = append(moduleInfoJSON.TestMainlineModules, a.testProperties.Test_mainline_modules...) - - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: a.testProperties.Test_suites, - }) } func testcaseRel(paths android.Paths) []string { diff --git a/java/app_import.go b/java/app_import.go index 9fb13ba3c..837ab529b 100644 --- a/java/app_import.go +++ b/java/app_import.go @@ -788,8 +788,18 @@ func (a *AndroidTestImport) GenerateAndroidBuildActions(ctx android.ModuleContex a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data) - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: a.testProperties.Test_suites, + var data []android.DataPath + for _, d := range a.data { + data = append(data, android.DataPath{SrcPath: d}) + } + + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: a.testProperties.Test_suites, + MainFile: a.outputFile, + MainFileStem: a.outputFile.Base(), + NeedsArchFolder: true, + Data: data, + CompatibilitySupportFiles: a.data, }) } diff --git a/java/base.go b/java/base.go index a69733866..be7262b81 100644 --- a/java/base.go +++ b/java/base.go @@ -513,8 +513,9 @@ type Module struct { jacocoReportClassesFile android.Path // output file of the module, which may be a classes jar or a dex jar - outputFile android.Path - extraOutputFiles android.Paths + outputFile android.Path + installedOutputFile android.Path + extraOutputFiles android.Paths exportAidlIncludeDirs android.Paths ignoredAidlPermissionList android.Paths diff --git a/java/fuzz.go b/java/fuzz.go index 0e239f0ec..2a38d53b6 100644 --- a/java/fuzz.go +++ b/java/fuzz.go @@ -131,7 +131,28 @@ func (j *JavaFuzzTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { } - j.Test.GenerateAndroidBuildActions(ctx) + checkMinSdkVersionMts(ctx, j.MinSdkVersion(ctx)) + j.Test.generateAndroidBuildActionsWithConfig(ctx, nil) + + var compatibilitySupportFiles android.Paths + compatibilitySupportFiles = append(compatibilitySupportFiles, j.implementationJarFile) + compatibilitySupportFiles = append(compatibilitySupportFiles, j.jniFilePaths...) + compatibilitySupportFiles = append(compatibilitySupportFiles, j.fuzzPackagedModule.Corpus...) + if j.fuzzPackagedModule.Dictionary != nil { + compatibilitySupportFiles = append(compatibilitySupportFiles, j.fuzzPackagedModule.Dictionary) + } + + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: j.testProperties.Test_suites, + MainFile: j.outputFile, + MainFileStem: j.Stem(), + MainFileExt: ".jar", + ConfigFile: j.testConfig, + ExtraConfigs: j.extraTestConfigs, + NeedsArchFolder: ctx.Device(), + CompatibilitySupportFiles: compatibilitySupportFiles, + PerTestcaseDirectory: proptools.Bool(j.testProperties.Per_testcase_directory), + }) fuzz.SetFuzzPackagedModuleInfo(ctx, &j.fuzzPackagedModule) } diff --git a/java/java.go b/java/java.go index 5593c9909..a1b18bd30 100644 --- a/java/java.go +++ b/java/java.go @@ -1814,6 +1814,7 @@ func (j *TestHost) GenerateAndroidBuildActions(ctx android.ModuleContext) { } j.Test.generateAndroidBuildActionsWithConfig(ctx, configs) + j.Test.javaTestSetTestsuiteInfo(ctx) android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{ TestcaseRelDataFiles: testcaseRel(j.data), OutputFile: j.outputFile, @@ -1836,6 +1837,7 @@ func (j *TestHost) GenerateAndroidBuildActions(ctx android.ModuleContext) { func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) { checkMinSdkVersionMts(ctx, j.MinSdkVersion(ctx)) j.generateAndroidBuildActionsWithConfig(ctx, nil) + j.javaTestSetTestsuiteInfo(ctx) } func (j *Test) generateAndroidBuildActionsWithConfig(ctx android.ModuleContext, configs []tradefed.Config) { @@ -1941,29 +1943,25 @@ func (j *Test) generateAndroidBuildActionsWithConfig(ctx android.ModuleContext, } } moduleInfoJSON.TestMainlineModules = append(moduleInfoJSON.TestMainlineModules, j.testProperties.Test_mainline_modules...) +} +func (j *Test) javaTestSetTestsuiteInfo(ctx android.ModuleContext) { // Install test deps - if !ctx.Config().KatiEnabled() { - pathInTestCases := android.PathForModuleInstall(ctx, "testcases", ctx.ModuleName()) - 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} - ctx.InstallTestData(pathInTestCases, []android.DataPath{dataPath}) - } - if j.outputFile != nil { - ctx.InstallFile(pathInTestCases, ctx.ModuleName()+".jar", j.outputFile) - } + var testData []android.DataPath + for _, data := range j.data { + dataPath := android.DataPath{SrcPath: data} + testData = append(testData, dataPath) } - - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: j.testProperties.Test_suites, + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: j.testProperties.Test_suites, + MainFile: j.outputFile, + MainFileStem: j.Stem(), + MainFileExt: ".jar", + ConfigFile: j.testConfig, + ExtraConfigs: j.extraTestConfigs, + NeedsArchFolder: ctx.Device(), + NonArchData: testData, + PerTestcaseDirectory: proptools.Bool(j.testProperties.Per_testcase_directory), }) } @@ -1978,12 +1976,20 @@ func (j *TestHelperLibrary) GenerateAndroidBuildActions(ctx android.ModuleContex moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") } optionalConfig := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "AndroidTest.xml") + var config android.Path if optionalConfig.Valid() { + config = optionalConfig.Path() moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, optionalConfig.String()) } - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: j.testHelperLibraryProperties.Test_suites, + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: j.testHelperLibraryProperties.Test_suites, + MainFile: j.outputFile, + MainFileStem: j.Stem(), + MainFileExt: ".jar", + ConfigFile: config, + NeedsArchFolder: ctx.Device(), + PerTestcaseDirectory: proptools.Bool(j.testHelperLibraryProperties.Per_testcase_directory), }) } diff --git a/python/binary.go b/python/binary.go index f894299f9..abcef73fb 100644 --- a/python/binary.go +++ b/python/binary.go @@ -115,6 +115,12 @@ func (p *PythonBinaryModule) GenerateAndroidBuildActions(ctx android.ModuleConte ctx.SetOutputFiles(android.Paths{p.installSource}, "") + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: p.binaryProperties.Test_suites, + MainFile: p.installSource, + MainFileStem: p.installSource.Base(), + }) + moduleInfoJSON := ctx.ModuleInfoJSON() moduleInfoJSON.Class = []string{"EXECUTABLES"} moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, p.androidMkSharedLibs...) @@ -165,10 +171,6 @@ func (p *PythonBinaryModule) buildBinary(ctx android.ModuleContext) { sharedLibs = append(sharedLibs, ctx.OtherModuleName(dep)) } p.androidMkSharedLibs = sharedLibs - - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: p.binaryProperties.Test_suites, - }) } func (p *PythonBinaryModule) AndroidMkEntries() []android.AndroidMkEntries { diff --git a/python/test.go b/python/test.go index df62ab794..d6670c3c4 100644 --- a/python/test.go +++ b/python/test.go @@ -215,25 +215,21 @@ func (p *PythonTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext installedData := ctx.InstallTestData(installDir, p.data) p.installedDest = ctx.InstallFile(installDir, p.installSource.Base(), p.installSource, installedData...) - // TODO: Remove the special case for kati - if !ctx.Config().KatiEnabled() { - // Install the test config in testcases/ directory for atest. - // Install configs in the root of $PRODUCT_OUT/testcases/$module - testCases := android.PathForModuleInPartitionInstall(ctx, "testcases", ctx.ModuleName()) - if ctx.PrimaryArch() { - 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()) - installedData := ctx.InstallTestData(testCases, p.data) - ctx.InstallFile(testCases, p.installSource.Base(), p.installSource, installedData...) + configFileSuffix := "" + // ATS 2.0 is the test harness for mobly tests and the test config is for ATS 2.0. + // Add "v2" suffix to test config name to distinguish it from the config for TF. + if proptools.String(p.testProperties.Test_options.Runner) == "mobly" { + configFileSuffix = "v2" } + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: p.binaryProperties.Test_suites, + MainFile: p.installSource, + MainFileStem: p.installSource.Base(), + ConfigFile: p.testConfig, + ConfigFileSuffix: configFileSuffix, + Data: p.data, + NeedsArchFolder: true, + }) moduleInfoJSON := ctx.ModuleInfoJSON() moduleInfoJSON.Class = []string{"NATIVE_TESTS"} diff --git a/rust/benchmark.go b/rust/benchmark.go index 3aa2f1779..85aa6a52e 100644 --- a/rust/benchmark.go +++ b/rust/benchmark.go @@ -129,6 +129,15 @@ func (benchmark *benchmarkDecorator) install(ctx ModuleContext) { } benchmark.binaryDecorator.install(ctx) + + mainFile := ctx.RustModule().OutputFile().Path() + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: benchmark.Properties.Test_suites, + MainFile: mainFile, + MainFileExt: mainFile.Ext(), + ConfigFile: benchmark.testConfig, + NeedsArchFolder: true, + }) } func (benchmark *benchmarkDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) { @@ -146,8 +155,4 @@ func (benchmark *benchmarkDecorator) moduleInfoJSON(ctx ModuleContext, moduleInf } else { moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") } - - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: benchmark.Properties.Test_suites, - }) } diff --git a/rust/test.go b/rust/test.go index cedced260..72eaaae81 100644 --- a/rust/test.go +++ b/rust/test.go @@ -204,29 +204,17 @@ func (test *testDecorator) install(ctx ModuleContext) { test.Properties.Test_options.Unit_test = proptools.BoolPtr(true) } - if !ctx.Config().KatiEnabled() { // TODO(spandandas): Remove the special case for kati - // Install the test config in testcases/ directory for atest. - r, ok := ctx.Module().(*Module) - if !ok { - ctx.ModuleErrorf("Not a rust test module") - } - // Install configs in the root of $PRODUCT_OUT/testcases/$module - testCases := android.PathForModuleInPartitionInstall(ctx, "testcases", ctx.ModuleName()+r.SubName()) - if ctx.PrimaryArch() { - 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()) - ctx.InstallTestData(testCases, test.data) - testPath := ctx.RustModule().OutputFile().Path() - ctx.InstallFile(testCases, testPath.Base(), testPath) - } + // Install the test config in testcases/ directory for atest. + mainFile := ctx.RustModule().OutputFile().Path() + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + NameSuffix: ctx.RustModule().SubName(), + TestSuites: test.Properties.Test_suites, + MainFile: mainFile, + MainFileStem: mainFile.Base(), + ConfigFile: test.testConfig, + Data: test.data, + NeedsArchFolder: true, + }) test.binaryDecorator.installTestData(ctx, test.data) test.binaryDecorator.install(ctx) @@ -320,10 +308,6 @@ func (test *testDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *and } else { moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") } - - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: test.Properties.Test_suites, - }) } func rustTestHostMultilib(ctx android.LoadHookContext) { diff --git a/sh/sh_binary.go b/sh/sh_binary.go index 57f5ad1c7..257d60936 100644 --- a/sh/sh_binary.go +++ b/sh/sh_binary.go @@ -540,6 +540,17 @@ func (s *ShTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { installedData := ctx.InstallTestData(s.installDir, s.data) s.installedFile = ctx.InstallExecutable(s.installDir, s.outputFilePath.Base(), s.outputFilePath, installedData...) + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: s.testProperties.Test_suites, + MainFile: s.outputFilePath, + MainFileStem: s.outputFilePath.Base(), + ConfigFile: s.testConfig, + ExtraConfigs: s.extraTestConfigs, + Data: s.data, + NeedsArchFolder: true, + PerTestcaseDirectory: proptools.Bool(s.testProperties.Per_testcase_directory), + }) + mkEntries := s.AndroidMkEntries()[0] android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{ TestcaseRelDataFiles: addArch(ctx.Arch().ArchType.String(), installedData.Paths()), @@ -574,10 +585,6 @@ func (s *ShTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, s.testConfig.String()) } moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, s.extraTestConfigs.Strings()...) - - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: s.testProperties.Test_suites, - }) } func addArch(archType string, paths android.Paths) []string { diff --git a/tradefed_modules/test_module_config.go b/tradefed_modules/test_module_config.go index e833df293..6b30a7a38 100644 --- a/tradefed_modules/test_module_config.go +++ b/tradefed_modules/test_module_config.go @@ -435,9 +435,22 @@ func (m *testModuleConfigModule) generateManifestAndConfig(ctx android.ModuleCon IsUnitTest: m.provider.IsUnitTest, }) - android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ - TestSuites: m.tradefedProperties.Test_suites, + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ + TestSuites: m.tradefedProperties.Test_suites, + MainFile: baseApk, + MainFileExt: ".apk", + ConfigFile: m.testConfig, + NeedsArchFolder: ctx.Device(), }) + + // Install the UNUSED- file to match the UNUSED- stem specified in javaExtraEntries + if m.provider.MkAppClass == "APPS" { + installDir2 := android.PathForModuleInstall(ctx, ctx.ModuleName(), ctx.DeviceConfig().DeviceArch()) + ctx.InstallFile(installDir2, fmt.Sprintf("UNUSED-%s.apk", *m.Base), m.manifest) + } else if m.provider.MkAppClass == "JAVA_LIBRARIES" { + installDir2 := android.PathForModuleInstall(ctx, ctx.ModuleName()) + ctx.InstallFile(installDir2, fmt.Sprintf("UNUSED-%s.jar", *m.Base), m.manifest) + } } var _ android.AndroidMkEntriesProvider = (*testModuleConfigHostModule)(nil) -- cgit v1.2.3 From 9f1bef0b17fe251b7d0ba97bc4055f26674d6fd4 Mon Sep 17 00:00:00 2001 From: zhidou Date: Fri, 28 Mar 2025 19:47:12 +0000 Subject: update command to all exported-flag-check exported-flag-check is added new command. This change update the command used to call exported-flag-check. Test: m all_aconfig_declarations Bug:345798636 Change-Id: Ib0600daafe76739ed0484803a7b8dfcfb49d81c6 --- aconfig/init.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/aconfig/init.go b/aconfig/init.go index d8d547022..12bf5d242 100644 --- a/aconfig/init.go +++ b/aconfig/init.go @@ -79,7 +79,10 @@ var ( }, "api_signature_files", "finalized_flags_file", "parsed_flags_file") ExportedFlagCheckRule = pctx.AndroidStaticRule("ExportedFlagCheckRule", blueprint.RuleParams{ - Command: `${exported-flag-check} ${parsed_flags_file} ${finalized_flags_file} ${api_signature_files} > ${out}`, + Command: `${exported-flag-check} validate-exported-flags ` + + ` ${parsed_flags_file} ` + + ` ${finalized_flags_file} ` + + ` ${api_signature_files} > ${out}`, CommandDeps: []string{ "${exported-flag-check}", }, -- cgit v1.2.3 From c93bd1fcd4ce801a0ece2813a846b62345e375ca Mon Sep 17 00:00:00 2001 From: Jooyung Han Date: Fri, 28 Mar 2025 17:27:06 +0900 Subject: Use debugfs instead of debugfs_static debugfs_static is not meant for Android build environment. Bug: 399476012 Test: presubmit Change-Id: Ie0fcfdcb977a25e44dbe5c1ecdf4c54b6496a095 --- apex/builder.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apex/builder.go b/apex/builder.go index 23c2ed8aa..b752dfd98 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -78,7 +78,7 @@ func init() { pctx.HostBinToolVariable("apex_ls", "apex-ls") pctx.HostBinToolVariable("apex_sepolicy_tests", "apex_sepolicy_tests") pctx.HostBinToolVariable("deapexer", "deapexer") - pctx.HostBinToolVariable("debugfs_static", "debugfs_static") + pctx.HostBinToolVariable("debugfs", "debugfs") pctx.HostBinToolVariable("fsck_erofs", "fsck.erofs") pctx.SourcePathVariable("genNdkUsedbyApexPath", "build/soong/scripts/gen_ndk_usedby_apex.sh") pctx.HostBinToolVariable("conv_linker_config", "conv_linker_config") @@ -226,9 +226,9 @@ var ( }, "image_dir") apexHostVerifierRule = pctx.StaticRule("apexHostVerifierRule", blueprint.RuleParams{ - Command: `${host_apex_verifier} --deapexer=${deapexer} --debugfs=${debugfs_static} ` + + Command: `${host_apex_verifier} --deapexer=${deapexer} --debugfs=${debugfs} ` + `--fsckerofs=${fsck_erofs} --apex=${in} --partition_tag=${partition_tag} && touch ${out}`, - CommandDeps: []string{"${host_apex_verifier}", "${deapexer}", "${debugfs_static}", "${fsck_erofs}"}, + CommandDeps: []string{"${host_apex_verifier}", "${deapexer}", "${debugfs}", "${fsck_erofs}"}, Description: "run host_apex_verifier", }, "partition_tag") @@ -240,7 +240,7 @@ var ( apexElfCheckerUnwantedRule = pctx.StaticRule("apexElfCheckerUnwantedRule", blueprint.RuleParams{ Command: `${apex_elf_checker} --tool_path ${tool_path} --unwanted ${unwanted} ${in} && touch ${out}`, - CommandDeps: []string{"${apex_elf_checker}", "${deapexer}", "${debugfs_static}", "${fsck_erofs}", "${config.ClangBin}/llvm-readelf"}, + CommandDeps: []string{"${apex_elf_checker}", "${deapexer}", "${debugfs}", "${fsck_erofs}", "${config.ClangBin}/llvm-readelf"}, Description: "run apex_elf_checker --unwanted", }, "tool_path", "unwanted") ) -- cgit v1.2.3 From c7961acf29fce5507f5ba96aa2b4be199b79655e Mon Sep 17 00:00:00 2001 From: Zhi Dou Date: Sun, 30 Mar 2025 22:43:24 +0000 Subject: Filter flag pb file before generating android_flags.jar This change makes the rule of exported_java_aconfig_library filtering the flag pb files first to remove flags that are exported but not used for any API, and then pass the filtered pb files to aconfig to generate android_flags.jar. After this change, only exported flags used for API will be exposed to android_flags.jar. NO_IFTTT=change the location of the condition line Test: m exported_java_aconfig_library Bug: 345798636 Change-Id: Id0a342ae1643c12d5954f4b86a4604bd653f4c92 --- aconfig/init.go | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/aconfig/init.go b/aconfig/init.go index 12bf5d242..2ff10d79b 100644 --- a/aconfig/init.go +++ b/aconfig/init.go @@ -105,26 +105,29 @@ var ( // exported flags (only). Finally collect all generated code // into the ${out} JAR file. blueprint.RuleParams{ - // LINT.IfChange - Command: `rm -rf ${out}.tmp` + + Command: `rm -rf ${out}.tmp && rm -rf ${out}.pb.tmp ` + `&& for cache in ${cache_files}; do ` + - ` if [ -n "$$(${aconfig} dump-cache --dedup --cache $$cache --filter=is_exported:true --format='{fully_qualified_name}')" ]; then ` + + ` ${exported-flag-check} filter-api-flags --cache $$cache --out ${out}.pb.tmp/$$cache &&` + + ` if [ -n "$$(${aconfig} dump-cache --dedup --cache ${out}.pb.tmp/$$cache --filter=is_exported:true --format='{fully_qualified_name}')" ]; then ` + + // LINT.IfChange ` ${aconfig} create-java-lib` + - ` --cache $$cache` + + ` --cache ${out}.pb.tmp/$$cache` + ` --mode=exported` + ` --allow-instrumentation ${use_new_storage}` + ` --new-exported ${use_new_exported}` + ` --single-exported-file true` + ` --check-api-level ${check_api_level}` + ` --out ${out}.tmp; ` + + // LINT.ThenChange(/aconfig/codegen/init.go) ` fi ` + `done` + `&& $soong_zip -write_if_changed -jar -o ${out} -C ${out}.tmp -D ${out}.tmp` + - `&& rm -rf ${out}.tmp`, - // LINT.ThenChange(/aconfig/codegen/init.go) + `&& rm -rf ${out}.tmp && rm -rf ${out}.pb.tmp `, + CommandDeps: []string{ "$aconfig", "$soong_zip", + "$exported-flag-check", }, }, "cache_files", "use_new_storage", "use_new_exported", "check_api_level") ) -- cgit v1.2.3 From cf25a8c6692967150289e52ab88e32c44d9dfc2b Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Mon, 31 Mar 2025 10:50:53 -0700 Subject: Don't leak variables from wrapper to real script Apparently when using runpy._run_module_as_main(), the newly-run module has access to all the global variables of the wrapper entrypoint script. This was allowing scripts to use our imported modules like sys and os without importing them themselves, making them less likely to work in other enviornments. Create fewer global variables by moving everything into a function. Bug: 406929315 Test: m conv_classpaths_proto && conv_classpaths_proto --help now gives an error about sys not being imported (fixed in ag/32805687) Change-Id: Ifd0d3135bea27a796e9de3829e66a6180788408b --- python/scripts/main.py | 90 ++++++++++++++++++++++++++------------------------ 1 file changed, 47 insertions(+), 43 deletions(-) diff --git a/python/scripts/main.py b/python/scripts/main.py index 35cdfc47e..a3d8f65a2 100644 --- a/python/scripts/main.py +++ b/python/scripts/main.py @@ -1,48 +1,52 @@ +# It's important that we use a function here, as any global variables we make in this script will +# also be available in the real entrypoint run by runpy._run_module_as_main. +def _soong_main(): + import os + import runpy + import shutil + import sys + import tempfile + import zipfile -import os -import runpy -import shutil -import sys -import tempfile -import zipfile + from pathlib import PurePath -from pathlib import PurePath + sys.argv[0] = __loader__.archive + # Set sys.executable to None. The real executable is available as + # sys.argv[0], and too many things assume sys.executable is a regular Python + # binary, which isn't available. By setting it to None we get clear errors + # when people try to use it. + sys.executable = None -sys.argv[0] = __loader__.archive - -# Set sys.executable to None. The real executable is available as -# sys.argv[0], and too many things assume sys.executable is a regular Python -# binary, which isn't available. By setting it to None we get clear errors -# when people try to use it. -sys.executable = None - -# Extract the shared libraries from the zip file into a temporary directory. -# This works around the limitations of dynamic linker. Some Python libraries -# reference the .so files relatively and so extracting only the .so files -# does not work, so we extract the entire parent directory of the .so files to a -# tempdir and then add that to sys.path. -tempdir = None -with zipfile.ZipFile(__loader__.archive) as z: - # any root so files or root directories that contain so files will be - # extracted to the tempdir so the linker load them, this minimizes the - # number of files that need to be extracted to a tempdir - extract_paths = {} - for member in z.infolist(): - if member.filename.endswith('.so'): - extract_paths[PurePath(member.filename).parts[0]] = member.filename - if extract_paths: - tempdir = tempfile.mkdtemp() + # Extract the shared libraries from the zip file into a temporary directory. + # This works around the limitations of dynamic linker. Some Python libraries + # reference the .so files relatively and so extracting only the .so files + # does not work, so we extract the entire parent directory of the .so files to a + # tempdir and then add that to sys.path. + tempdir = None + with zipfile.ZipFile(__loader__.archive) as z: + # any root so files or root directories that contain so files will be + # extracted to the tempdir so the linker load them, this minimizes the + # number of files that need to be extracted to a tempdir + extract_paths = {} for member in z.infolist(): - if not PurePath(member.filename).parts[0] in extract_paths.keys(): - continue - if member.is_dir(): - os.makedirs(os.path.join(tempdir, member.filename)) - else: - z.extract(member, tempdir) - sys.path.insert(0, tempdir) -try: - runpy._run_module_as_main("ENTRY_POINT", alter_argv=False) -finally: - if tempdir is not None: - shutil.rmtree(tempdir) + if member.filename.endswith('.so'): + extract_paths[PurePath(member.filename).parts[0]] = member.filename + if extract_paths: + tempdir = tempfile.mkdtemp() + for member in z.infolist(): + if not PurePath(member.filename).parts[0] in extract_paths.keys(): + continue + if member.is_dir(): + os.makedirs(os.path.join(tempdir, member.filename)) + else: + z.extract(member, tempdir) + sys.path.insert(0, tempdir) + try: + runpy._run_module_as_main("ENTRY_POINT", alter_argv=False) + finally: + if tempdir is not None: + shutil.rmtree(tempdir) + +if __name__ == "__main__": + _soong_main() -- cgit v1.2.3 From 04c5a7954ed8d84a34a84ef4b1653a0ad69612f6 Mon Sep 17 00:00:00 2001 From: Aaron Okano Date: Thu, 20 Mar 2025 15:14:20 +0000 Subject: Enable sparse encoding for AAPT2 in Soong. Leads to smaller APKs, especially after "resource shrinking" (which leaves holes in the resource table). There are multiple paths that apply this optimization: the aapt2 link, convert, and optimize commands. In Soong, there are only rules for link and convert. Apps will normally be linked via the link rule, but in when resource shrinking is enabled, they will additionally go through convert. In the former case, it would be sufficient to add --enable-sparse-encoding to just the link stage, but in the latter case it also needs to be specified in convert, or else the sparse encoding will be undone. I've updated the aapt2convert rule to include --enable-sparse-encoding, and I added --enable-sparse-encoding to the linkFlags that are passed to the aapt2link rule. I tested that ClockworkSetupWizard.apk comes out the end with sparse encoding enabled on seluna-trunk_staging-userdebug. Bug: 374251712 Bug: 123358928 Test: Build with and without flag, verify sparse encoding in APK Flag: build.RELEASE_SOONG_SPARSE_ENCODING Change-Id: Idab84153d537e81e7284ff0415645a1b8d12d6e6 --- android/config.go | 4 ++++ java/aapt2.go | 10 ++++++++-- java/aar.go | 3 +++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/android/config.go b/android/config.go index 8d443028b..37f866cc7 100644 --- a/android/config.go +++ b/android/config.go @@ -307,6 +307,10 @@ func (c Config) ReleaseRustUseArmTargetArchVariant() bool { return c.config.productVariables.GetBuildFlagBool("RELEASE_RUST_USE_ARM_TARGET_ARCH_VARIANT") } +func (c Config) ReleaseUseSparseEncoding() bool { + return c.config.productVariables.GetBuildFlagBool("RELEASE_SOONG_SPARSE_ENCODING") +} + // A DeviceConfig object represents the configuration for a particular device // being built. For now there will only be one of these, but in the future there // may be multiple devices being built. diff --git a/java/aapt2.go b/java/aapt2.go index bae4d1ee3..21087df8f 100644 --- a/java/aapt2.go +++ b/java/aapt2.go @@ -332,15 +332,20 @@ func aapt2ExtractExtraPackages(ctx android.ModuleContext, out android.WritablePa var aapt2ConvertRule = pctx.AndroidStaticRule("aapt2Convert", blueprint.RuleParams{ - Command: `${config.Aapt2Cmd} convert --enable-compact-entries ` + + Command: `${config.Aapt2Cmd} convert $flags ` + `--output-format $format $in -o $out`, CommandDeps: []string{"${config.Aapt2Cmd}"}, - }, "format", + }, "format", "flags", ) // Converts xml files and resource tables (resources.arsc) in the given jar/apk file to a proto // format. The proto definition is available at frameworks/base/tools/aapt2/Resources.proto. func aapt2Convert(ctx android.ModuleContext, out android.WritablePath, in android.Path, format string) { + extraFlags := []string{"--enable-compact-entries"} + if ctx.Config().ReleaseUseSparseEncoding() { + extraFlags = append(extraFlags, "--enable-sparse-encoding") + } + ctx.Build(pctx, android.BuildParams{ Rule: aapt2ConvertRule, Input: in, @@ -348,6 +353,7 @@ func aapt2Convert(ctx android.ModuleContext, out android.WritablePath, in androi Description: "convert to " + format, Args: map[string]string{ "format": format, + "flags": strings.Join(extraFlags, " "), }, }) } diff --git a/java/aar.go b/java/aar.go index ebada655f..f608d4e0f 100644 --- a/java/aar.go +++ b/java/aar.go @@ -263,6 +263,9 @@ func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext android.SdkConte linkFlags = append(linkFlags, a.aaptProperties.Aaptflags...) linkFlags = append(linkFlags, "--enable-compact-entries") + if ctx.Config().ReleaseUseSparseEncoding() { + linkFlags = append(linkFlags, "--enable-sparse-encoding") + } // Find implicit or explicit asset and resource dirs assets := android.PathsRelativeToModuleSourceDir(android.SourceInput{ -- cgit v1.2.3 From 864be1afef818cc28e9249e4d7a2091246c7ac41 Mon Sep 17 00:00:00 2001 From: Yu Liu Date: Mon, 24 Mar 2025 19:11:24 +0000 Subject: Add debug info for incremental build analysis. Bug: 358427516 Test: Manually verified genereated debug file. Change-Id: I1d950da7da6ef8e2a9112eb53587f6495be4a41e --- cmd/soong_build/main.go | 2 ++ ui/build/config.go | 8 +++++++- ui/build/soong.go | 5 +++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go index cd4e9bdc2..b707112fe 100644 --- a/cmd/soong_build/main.go +++ b/cmd/soong_build/main.go @@ -88,6 +88,7 @@ func init() { // the time to remove them yet flag.BoolVar(&cmdlineArgs.RunGoTests, "t", false, "build and run go tests during bootstrap") flag.BoolVar(&cmdlineArgs.IncrementalBuildActions, "incremental-build-actions", false, "generate build actions incrementally") + flag.StringVar(&cmdlineArgs.IncrementalDebugFile, "incremental-debug-file", "", "incremental debug file") // Disable deterministic randomization in the protobuf package, so incremental // builds with unrelated Soong changes don't trigger large rebuilds (since we @@ -356,6 +357,7 @@ func main() { configCache, incremental = incrementalValid(ctx.Config(), configFile) } ctx.SetIncrementalAnalysis(incremental) + ctx.SetIncrementalDebugFile(cmdlineArgs.IncrementalDebugFile) ctx.Register() finalOutputFile, ninjaDeps := runSoongOnlyBuild(ctx) diff --git a/ui/build/config.go b/ui/build/config.go index 94b07811d..e9b32b9fd 100644 --- a/ui/build/config.go +++ b/ui/build/config.go @@ -138,7 +138,8 @@ type configImpl struct { // This file is a detailed dump of all soong-defined modules for debugging purposes. // There's quite a bit of overlap with module-info.json and soong module graph. We // could consider merging them. - moduleDebugFile string + moduleDebugFile string + incrementalDebugFile string // Which builder are we using ninjaCommand ninjaCommandType @@ -325,6 +326,10 @@ func NewConfig(ctx Context, args ...string) Config { ret.moduleDebugFile, _ = filepath.Abs(shared.JoinPath(ret.SoongOutDir(), "soong-debug-info.json")) } + if os.Getenv("GENERATE_INCREMENTAL_DEBUG") == "true" { + ret.incrementalDebugFile, _ = filepath.Abs(shared.JoinPath(ret.SoongOutDir(), "incremental-debug-info.json")) + } + // If SOONG_USE_PARTIAL_COMPILE is set, make it one of "true" or the empty string. // This simplifies the generated Ninja rules, so that they only need to check for the empty string. if value, ok := ret.environ.Get("SOONG_USE_PARTIAL_COMPILE"); ok { @@ -406,6 +411,7 @@ func NewConfig(ctx Context, args ...string) Config { // We read it here already, don't let others share in the fun "GENERATE_SOONG_DEBUG", + "INCREMENTAL_SOONG_DEBUG", // Use config.ninjaCommand instead. "SOONG_NINJA", diff --git a/ui/build/soong.go b/ui/build/soong.go index 58334a907..44b39cd82 100644 --- a/ui/build/soong.go +++ b/ui/build/soong.go @@ -212,6 +212,11 @@ func (pb PrimaryBuilderFactory) primaryBuilderInvocation(config Config) bootstra commonArgs = append(commonArgs, pb.config.moduleDebugFile) } + if pb.config.incrementalDebugFile != "" { + commonArgs = append(commonArgs, "--incremental-debug-file") + commonArgs = append(commonArgs, pb.config.incrementalDebugFile) + } + commonArgs = append(commonArgs, "-l", filepath.Join(pb.config.FileListDir(), "Android.bp.list")) invocationEnv := make(map[string]string) if pb.debugPort != "" { -- cgit v1.2.3 From ca969d1e91210322731616d15cfb27cfd1bf0a8c Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Wed, 26 Mar 2025 15:20:17 -0700 Subject: Build performance-tests with soong For soong-only builds. Bug: 405185546 Test: m performance-tests dist; diffed files before/after this cl Change-Id: Ia1539f4f81422e06d7f0822d08dbc0c881f84ed7 --- android/test_suites.go | 118 +++++++++++++++++++++++++++++++++++++++----- android/test_suites_test.go | 23 ++------- 2 files changed, 110 insertions(+), 31 deletions(-) diff --git a/android/test_suites.go b/android/test_suites.go index 8f40f259b..94b216172 100644 --- a/android/test_suites.go +++ b/android/test_suites.go @@ -91,6 +91,7 @@ var testSuiteInstallsInfoProvider = blueprint.NewProvider[testSuiteInstallsInfo] func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) { files := make(map[string]map[string]InstallPaths) + allTestSuiteInstalls := make(map[string][]Path) var toInstall []filePair var oneVariantInstalls []filePair @@ -104,25 +105,38 @@ func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) { files[testSuite][name] = append(files[testSuite][name], OtherModuleProviderOrDefault(ctx, m, InstallFilesProvider).InstallFiles...) } - } - if testSuiteInstalls, ok := OtherModuleProvider(ctx, m, testSuiteInstallsInfoProvider); ok { - installs := OtherModuleProviderOrDefault(ctx, m, InstallFilesProvider).InstallFiles - oneVariantInstalls = append(oneVariantInstalls, testSuiteInstalls.OneVariantInstalls...) - for _, f := range testSuiteInstalls.Files { - alreadyInstalled := false - for _, install := range installs { - if install.String() == f.dst.String() { - alreadyInstalled = true - break + + if testSuiteInstalls, ok := OtherModuleProvider(ctx, m, testSuiteInstallsInfoProvider); ok { + for _, testSuite := range tsm.TestSuites { + for _, f := range testSuiteInstalls.Files { + allTestSuiteInstalls[testSuite] = append(allTestSuiteInstalls[testSuite], f.dst) + } + for _, f := range testSuiteInstalls.OneVariantInstalls { + allTestSuiteInstalls[testSuite] = append(allTestSuiteInstalls[testSuite], f.dst) } } - if !alreadyInstalled { - toInstall = append(toInstall, f) + installs := OtherModuleProviderOrDefault(ctx, m, InstallFilesProvider).InstallFiles + oneVariantInstalls = append(oneVariantInstalls, testSuiteInstalls.OneVariantInstalls...) + for _, f := range testSuiteInstalls.Files { + alreadyInstalled := false + for _, install := range installs { + if install.String() == f.dst.String() { + alreadyInstalled = true + break + } + } + if !alreadyInstalled { + toInstall = append(toInstall, f) + } } } } }) + for suite, suiteInstalls := range allTestSuiteInstalls { + allTestSuiteInstalls[suite] = SortedUniquePaths(suiteInstalls) + } + filePairSorter := func(arr []filePair) func(i, j int) bool { return func(i, j int) bool { c := strings.Compare(arr[i].dst.String(), arr[j].dst.String()) @@ -134,6 +148,7 @@ func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) { return arr[i].src.String() < arr[j].src.String() } } + sort.Slice(toInstall, filePairSorter(toInstall)) // Dedup, as multiple tests may install the same test data to the same folder toInstall = slices.Compact(toInstall) @@ -166,6 +181,8 @@ func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) { ravenwoodZip, ravenwoodListZip := buildTestSuite(ctx, "ravenwood-tests", files["ravenwood-tests"]) ctx.Phony("ravenwood-tests", ravenwoodZip, ravenwoodListZip) ctx.DistForGoal("ravenwood-tests", ravenwoodZip, ravenwoodListZip) + + buildPerformanceTests(ctx, allTestSuiteInstalls["performance-tests"]) } func buildTestSuite(ctx SingletonContext, suiteName string, files map[string]InstallPaths) (Path, Path) { @@ -232,3 +249,80 @@ func pathForPackaging(ctx PathContext, pathComponents ...string) OutputPath { func pathForTestCases(ctx PathContext) InstallPath { return pathForInstall(ctx, ctx.Config().BuildOS, X86, "testcases") } + +func buildPerformanceTests(ctx SingletonContext, files Paths) { + hostOutTestCases := pathForInstall(ctx, ctx.Config().BuildOSTarget.Os, ctx.Config().BuildOSTarget.Arch.ArchType, "testcases") + targetOutTestCases := pathForInstall(ctx, ctx.Config().AndroidFirstDeviceTarget.Os, ctx.Config().AndroidFirstDeviceTarget.Arch.ArchType, "testcases") + hostOut := filepath.Dir(hostOutTestCases.String()) + targetOut := filepath.Dir(targetOutTestCases.String()) + + testsZip := pathForPackaging(ctx, "performance-tests.zip") + testsListTxt := pathForPackaging(ctx, "performance-tests_list.txt") + testsListZip := pathForPackaging(ctx, "performance-tests_list.zip") + testsConfigsZip := pathForPackaging(ctx, "performance-tests_configs.zip") + var listLines []string + + testsZipBuilder := NewRuleBuilder(pctx, ctx) + testsZipCmd := testsZipBuilder.Command(). + BuiltTool("soong_zip"). + Flag("-sha256"). + Flag("-d"). + FlagWithOutput("-o ", testsZip). + FlagWithArg("-P ", "host"). + FlagWithArg("-C ", hostOut) + + testsConfigsZipBuilder := NewRuleBuilder(pctx, ctx) + testsConfigsZipCmd := testsConfigsZipBuilder.Command(). + BuiltTool("soong_zip"). + Flag("-d"). + FlagWithOutput("-o ", testsConfigsZip). + FlagWithArg("-P ", "host"). + FlagWithArg("-C ", hostOut) + + for _, f := range files { + if strings.HasPrefix(f.String(), hostOutTestCases.String()) { + testsZipCmd.FlagWithInput("-f ", f) + + if strings.HasSuffix(f.String(), ".config") { + testsConfigsZipCmd.FlagWithInput("-f ", f) + listLines = append(listLines, strings.Replace(f.String(), hostOut, "host", 1)) + } + } + } + + testsZipCmd. + FlagWithArg("-P ", "target"). + FlagWithArg("-C ", targetOut) + testsConfigsZipCmd. + FlagWithArg("-P ", "target"). + FlagWithArg("-C ", targetOut) + + for _, f := range files { + if strings.HasPrefix(f.String(), targetOutTestCases.String()) { + testsZipCmd.FlagWithInput("-f ", f) + + if strings.HasSuffix(f.String(), ".config") { + testsConfigsZipCmd.FlagWithInput("-f ", f) + listLines = append(listLines, strings.Replace(f.String(), targetOut, "target", 1)) + } + } + } + + testsZipBuilder.Build("performance_tests_zip", "building performance-tests zip") + testsConfigsZipBuilder.Build("performance_tests_configs_zip", "building performance-tests configs zip") + + WriteFileRule(ctx, testsListTxt, strings.Join(listLines, "\n")) + + testsListZipBuilder := NewRuleBuilder(pctx, ctx) + testsListZipBuilder.Command(). + BuiltTool("soong_zip"). + Flag("-d"). + FlagWithOutput("-o ", testsListZip). + FlagWithArg("-e ", "performance-tests_list"). + FlagWithInput("-f ", testsListTxt) + testsListZipBuilder.Build("performance_tests_list_zip", "building performance-tests list zip") + + ctx.Phony("performance-tests", testsZip) + ctx.DistForGoal("performance-tests", testsZip, testsListZip, testsConfigsZip) + ctx.Phony("tests", PathForPhony(ctx, "performance-tests")) +} diff --git a/android/test_suites_test.go b/android/test_suites_test.go index 03aa42413..955adef9d 100644 --- a/android/test_suites_test.go +++ b/android/test_suites_test.go @@ -15,7 +15,6 @@ package android import ( - "path/filepath" "testing" ) @@ -53,30 +52,16 @@ func TestBuildTestList(t *testing.T) { `) config := ctx.SingletonForTests(t, "testsuites") - allOutputs := config.AllOutputs() wantContents := map[string]string{ - "robolectric-tests.zip": "", - "robolectric-tests_list.zip": "", - "robolectric-tests_list": `host/testcases/Test2/Test21/Test21.config + "out/soong/packaging/robolectric-tests_list": `host/testcases/Test2/Test21/Test21.config `, - "ravenwood-tests.zip": "", - "ravenwood-tests_list.zip": "", - "ravenwood-tests_list": `host/testcases/Test1/Test1.config + "out/soong/packaging/ravenwood-tests_list": `host/testcases/Test1/Test1.config host/testcases/Test2/Test21/Test21.config `, } - for _, output := range allOutputs { - want, ok := wantContents[filepath.Base(output)] - if !ok { - t.Errorf("unexpected output: %q", output) - continue - } - - got := "" - if want != "" { - got = ContentFromFileRuleForTests(t, ctx.TestContext, config.MaybeOutput(output)) - } + for file, want := range wantContents { + got := ContentFromFileRuleForTests(t, ctx.TestContext, config.Output(file)) if want != got { t.Errorf("want %q, got %q", want, got) -- cgit v1.2.3 From ac1a7af2cf6521ae793607d8ca5bead145d68fa8 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 26 Mar 2025 15:22:18 -0700 Subject: Reapply "Clear as much of cc.Module as possible after GenerateBuildActions" This reverts commit effb464e30da10acdeb9c65d3cfd4303a2430dd2. This relands Idc3390ae4506ff2eef3231691e1de7446067961a with a change to skip clearing c.compiler, which is still used by ccdeps.go. Test: out/soong/module_bp_cc_deps.json is not empty Change-Id: Ia0f4e9d8b8c43a80c3575330fbd532d56f890513 --- android/module.go | 9 +++++++++ android/module_proxy.go | 4 ++++ cc/cc.go | 23 +++++++++++++++++++++++ rust/fuzz_test.go | 25 ++++++++++++++++--------- 4 files changed, 52 insertions(+), 9 deletions(-) diff --git a/android/module.go b/android/module.go index 4211efb63..ab7ab77ab 100644 --- a/android/module.go +++ b/android/module.go @@ -46,6 +46,14 @@ type Module interface { // For more information, see Module.GenerateBuildActions within Blueprint's module_ctx.go GenerateAndroidBuildActions(ModuleContext) + // CleanupAfterBuildActions is called after ModuleBase.GenerateBuildActions is finished. + // If all interactions with this module are handled via providers instead of direct access + // to the module then it can free memory attached to the module. + // This is a temporary measure to reduce memory usage, eventually blueprint's reference + // to the Module should be dropped after GenerateAndroidBuildActions once all accesses + // can be done through providers. + CleanupAfterBuildActions() + // Add dependencies to the components of a module, i.e. modules that are created // by the module and which are considered to be part of the creating module. // @@ -2422,6 +2430,7 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) }) } } + m.module.CleanupAfterBuildActions() } func (m *ModuleBase) CleanupAfterBuildActions() {} diff --git a/android/module_proxy.go b/android/module_proxy.go index e2af4a069..b292b5c35 100644 --- a/android/module_proxy.go +++ b/android/module_proxy.go @@ -27,6 +27,10 @@ func (m ModuleProxy) GenerateAndroidBuildActions(context ModuleContext) { panic("method is not implemented on ModuleProxy") } +func (m ModuleProxy) CleanupAfterBuildActions() { + panic("method is not implemented on ModuleProxy") +} + func (m ModuleProxy) ComponentDepsMutator(ctx BottomUpMutatorContext) { panic("method is not implemented on ModuleProxy") } diff --git a/cc/cc.go b/cc/cc.go index e52955957..2c4ed33c6 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -2637,6 +2637,29 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { } } +func (c *Module) CleanupAfterBuildActions() { + // Clear as much of Module as possible to reduce memory usage. + c.generators = nil + c.installer = nil + c.features = nil + c.coverage = nil + c.fuzzer = nil + c.sabi = nil + c.lto = nil + c.afdo = nil + c.orderfile = nil + + // TODO: these can be cleared after nativeBinaryInfoProperties and nativeLibInfoProperties are switched to + // using providers. + // c.linker = nil + // c.stl = nil + // c.sanitize = nil + // c.library = nil + + // TODO: this can be cleared after ccdeps.go is switched to using providers. + // c.compiler = nil +} + func CreateCommonLinkableInfo(ctx android.ModuleContext, mod VersionedLinkableInterface) *LinkableInfo { info := &LinkableInfo{ StaticExecutable: mod.StaticExecutable(), diff --git a/rust/fuzz_test.go b/rust/fuzz_test.go index bdcfbbba1..f462795aa 100644 --- a/rust/fuzz_test.go +++ b/rust/fuzz_test.go @@ -134,17 +134,24 @@ func TestCCFuzzDepBundling(t *testing.T) { } `) - fuzz_shared_libtest := ctx.ModuleForTests(t, "fuzz_shared_libtest", "android_arm64_armv8-a_fuzzer").Module().(cc.LinkableInterface) - fuzz_static_libtest := ctx.ModuleForTests(t, "fuzz_static_libtest", "android_arm64_armv8-a_fuzzer").Module().(cc.LinkableInterface) - fuzz_staticffi_libtest := ctx.ModuleForTests(t, "fuzz_staticffi_libtest", "android_arm64_armv8-a_fuzzer").Module().(cc.LinkableInterface) + fuzz_shared_libtest := ctx.ModuleForTests(t, "fuzz_shared_libtest", "android_arm64_armv8-a_fuzzer").Module() + fuzz_static_libtest := ctx.ModuleForTests(t, "fuzz_static_libtest", "android_arm64_armv8-a_fuzzer").Module() + fuzz_staticffi_libtest := ctx.ModuleForTests(t, "fuzz_staticffi_libtest", "android_arm64_armv8-a_fuzzer").Module() - if !strings.Contains(fuzz_shared_libtest.FuzzSharedLibraries().String(), ":libcc_transitive_dep.so") { - t.Errorf("cc_fuzz does not contain the expected bundled transitive shared libs from rust_ffi_shared ('libcc_transitive_dep'): %#v", fuzz_shared_libtest.FuzzSharedLibraries().String()) + fuzzSharedLibraries := func(module android.Module) string { + if info, ok := android.OtherModuleProvider(ctx, module, cc.LinkableInfoProvider); ok { + return info.FuzzSharedLibraries.String() + } + return "" } - if !strings.Contains(fuzz_static_libtest.FuzzSharedLibraries().String(), ":libcc_transitive_dep.so") { - t.Errorf("cc_fuzz does not contain the expected bundled transitive shared libs from rust_ffi_static ('libcc_transitive_dep'): %#v", fuzz_static_libtest.FuzzSharedLibraries().String()) + + if libs := fuzzSharedLibraries(fuzz_shared_libtest); !strings.Contains(libs, ":libcc_transitive_dep.so") { + t.Errorf("cc_fuzz does not contain the expected bundled transitive shared libs from rust_ffi_shared ('libcc_transitive_dep'): %#v", libs) + } + if libs := fuzzSharedLibraries(fuzz_static_libtest); !strings.Contains(libs, ":libcc_transitive_dep.so") { + t.Errorf("cc_fuzz does not contain the expected bundled transitive shared libs from rust_ffi_static ('libcc_transitive_dep'): %#v", libs) } - if !strings.Contains(fuzz_staticffi_libtest.FuzzSharedLibraries().String(), ":libcc_transitive_dep.so") { - t.Errorf("cc_fuzz does not contain the expected bundled transitive shared libs from rust_ffi_static ('libcc_transitive_dep'): %#v", fuzz_staticffi_libtest.FuzzSharedLibraries().String()) + if libs := fuzzSharedLibraries(fuzz_staticffi_libtest); !strings.Contains(libs, ":libcc_transitive_dep.so") { + t.Errorf("cc_fuzz does not contain the expected bundled transitive shared libs from rust_ffi_static ('libcc_transitive_dep'): %#v", libs) } } -- cgit v1.2.3 From 68212e96b07e28b4fe9aef2f7b9c6e132a6aad25 Mon Sep 17 00:00:00 2001 From: Wei Li Date: Mon, 31 Mar 2025 19:48:21 +0000 Subject: Add compliance metadata for fsverity files Bug: 406021662 Test: presubmits Change-Id: I4f55c89480ee7c7675462754ea6409115d24e36c --- filesystem/filesystem.go | 2 +- filesystem/fsverity_metadata.go | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index d2131dc27..dbe9b3ab0 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -641,7 +641,7 @@ func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) { platformGeneratedFiles := []string{} f.entries = f.copyPackagingSpecs(ctx, builder, specs, rootDir, rebasedDir) f.buildNonDepsFiles(ctx, builder, rootDir, rebasedDir, &fullInstallPaths, &platformGeneratedFiles) - f.buildFsverityMetadataFiles(ctx, builder, specs, rootDir, rebasedDir, &fullInstallPaths) + f.buildFsverityMetadataFiles(ctx, builder, specs, rootDir, rebasedDir, &fullInstallPaths, &platformGeneratedFiles) f.buildEventLogtagsFile(ctx, builder, rebasedDir, &fullInstallPaths, &platformGeneratedFiles) f.buildAconfigFlagsFiles(ctx, builder, specs, rebasedDir, &fullInstallPaths, &platformGeneratedFiles) f.filesystemBuilder.BuildLinkerConfigFile(ctx, builder, rebasedDir, &fullInstallPaths, &platformGeneratedFiles) diff --git a/filesystem/fsverity_metadata.go b/filesystem/fsverity_metadata.go index 89da3182a..465bc6073 100644 --- a/filesystem/fsverity_metadata.go +++ b/filesystem/fsverity_metadata.go @@ -113,6 +113,7 @@ func (f *filesystem) buildFsverityMetadataFiles( rootDir android.OutputPath, rebasedDir android.OutputPath, fullInstallPaths *[]FullInstallPathInfo, + platformGeneratedFiles *[]string, ) { match := func(path string) bool { for _, pattern := range f.properties.Fsverity.Inputs.GetOrDefault(ctx, nil) { @@ -280,17 +281,20 @@ func (f *filesystem) buildFsverityMetadataFiles( builder.Command().Text("cp").Input(apkPath).Text(installedApkPath.String()) builder.Command().Text("cp").Input(idsigPath).Text(installedIdsigPath.String()) + apkFullInstallPath := android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), fmt.Sprintf("etc/security/fsverity/BuildManifest%s.apk", apkNameSuffix)) *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{ SourcePath: apkPath, - FullInstallPath: android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), fmt.Sprintf("etc/security/fsverity/BuildManifest%s.apk", apkNameSuffix)), + FullInstallPath: apkFullInstallPath, }) f.appendToEntry(ctx, installedApkPath) + idsigFullInstallPath := android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), fmt.Sprintf("etc/security/fsverity/BuildManifest%s.apk.idsig", apkNameSuffix)) *fullInstallPaths = append(*fullInstallPaths, FullInstallPathInfo{ SourcePath: idsigPath, - FullInstallPath: android.PathForModuleInPartitionInstall(ctx, f.PartitionType(), fmt.Sprintf("etc/security/fsverity/BuildManifest%s.apk.idsig", apkNameSuffix)), + FullInstallPath: idsigFullInstallPath, }) f.appendToEntry(ctx, installedIdsigPath) + *platformGeneratedFiles = append(*platformGeneratedFiles, apkFullInstallPath.String(), idsigFullInstallPath.String()) } -- cgit v1.2.3 From 682b98b8ec7784f6004686ff8e96f36652c4d31f Mon Sep 17 00:00:00 2001 From: Brett Brotherton Date: Mon, 31 Mar 2025 13:52:42 -0700 Subject: add unit test for python shared_lib code Add some unit tests to cover the new code added to handle python modules with compiled shared libraries Bug: 403060602 Test: go test ./... Change-Id: I815ef40ccc1546a26e5ad5aee46d6b033f647b5f --- python/python.go | 1 - python/python_test.go | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 82 insertions(+), 2 deletions(-) diff --git a/python/python.go b/python/python.go index de21e39bd..f0f25f5ab 100644 --- a/python/python.go +++ b/python/python.go @@ -108,7 +108,6 @@ type BaseProperties struct { // list of the Python libraries compatible both with Python2 and Python3. Libs []string `android:"arch_variant"` - // TODO: b/403060602 - add unit tests for this property and related code // list of shared libraries that should be packaged with the python code for this module. Shared_libs []string `android:"arch_variant"` diff --git a/python/python_test.go b/python/python_test.go index 5f971cdd1..21f6c1274 100644 --- a/python/python_test.go +++ b/python/python_test.go @@ -37,7 +37,7 @@ type pyModule struct { var ( buildNamePrefix = "soong_python_test" - moduleVariantErrTemplate = `%s: module %q variant "[a-zA-Z0-9_]*": ` + moduleVariantErrTemplate = `%s: module %q variant "[a-zA-Z0-9_\-]*": ` pkgPathErrTemplate = moduleVariantErrTemplate + "pkg_path: %q must be a relative path contained in par file." badIdentifierErrTemplate = moduleVariantErrTemplate + @@ -48,6 +48,8 @@ var ( " Second file: in module %s at path %q." badSrcFileExtErr = moduleVariantErrTemplate + `srcs: found non \(.py\|.proto\) file: %q!` badDataFileExtErr = moduleVariantErrTemplate + `data: found \(.py\) file: %q!` + sharedLibErrTemplate = moduleVariantErrTemplate + + "shared_libs: shared_libs is not supported for device builds" bpFile = "Android.bp" data = []struct { @@ -206,6 +208,27 @@ var ( "lib1", "dir/c/file1.py"), }, }, + { + desc: "device module with shared libs", + mockFiles: map[string][]byte{ + filepath.Join("dir", bpFile): []byte( + `python_library { + name: "lib1", + srcs: [ + "file1.py", + ], + shared_libs: [ + "clib1", + ], + }`, + ), + "dir/file1.py": nil, + }, + errors: []string{ + fmt.Sprintf(sharedLibErrTemplate, + "dir/Android.bp:6:18", "lib1"), + }, + }, } ) @@ -312,6 +335,64 @@ func TestInvalidTestOnlyTargets(t *testing.T) { } } +func TestSharedLib(t *testing.T) { + ctx := android.GroupFixturePreparers( + android.PrepareForTestWithDefaults, + android.PrepareForTestWithArchMutator, + android.PrepareForTestWithAllowMissingDependencies, + cc.PrepareForTestWithCcDefaultModules, + PrepareForTestWithPythonBuildComponents, + ).RunTestWithBp( + t, + `python_library_host { + name: "py-lib-host", + srcs: ["py-lib-host.py"], + shared_libs: ["clib-host"], + } + + cc_library_shared { + name: "clib-host", + host_supported: true, + shared_libs: ["clib-host-2"], + } + + cc_library_shared { + name: "clib-host-2", + host_supported: true, + }`, + ) + if len(ctx.Errs) > 0 { + t.Errorf("Expected got: %s, want: 0 errs", ctx.Errs) + } + + mod, modOk := ctx.ModuleForTests(t, "py-lib-host", "linux_glibc_x86_64").Module().(*PythonLibraryModule) + if !modOk { + t.Fatalf("py-lib-host is not Python library!") + } + // ensure the shared lib is included in the data path mappings + dataPathMappings := mod.getDataPathMappings() + if len(dataPathMappings) != 1 { + t.Fatalf("expected 1 data file, got: %d", len(dataPathMappings)) + } + android.AssertStringMatches( + t, + "data path included shared lib", + "clib-host.so", + dataPathMappings[0].dest, + ) + // ensure any dependencies of the shared lib are included in the bundle shared + // libs + android.AssertPathsEndWith( + t, + "shared libs", + []string{ + "clib-host-2.so", + "libc++.so", + }, + mod.getBundleSharedLibs(), + ) +} + func expectModule(t *testing.T, ctx *android.TestContext, name, variant, expectedSrcsZip string, expectedPyRunfiles []string) { module := ctx.ModuleForTests(t, name, variant) -- cgit v1.2.3 From 7777de03acc73db4cd74058d3168c41a83cf1ad0 Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Mon, 31 Mar 2025 11:31:23 -0700 Subject: Introduce Soong api DistForGoalWithFileNameTag(...) The newly introduced api works similar to DistForGoalWithFilename, but appends the file name tag placeholder suffix, which is later converted to the unique host identifer (build id for ci builds, username for local builds). This change also converts the existing dists with the file name tag placeholder suffix to using the new api. Test: m droid dist --soong-only Bug: 407562438 Change-Id: I3e1b80bd1bfe4f89beb6c2ef2004580a909df13d --- android/module_context.go | 14 ++++++++++++++ filesystem/android_device.go | 19 +++++++------------ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/android/module_context.go b/android/module_context.go index 3542671ac..369805eab 100644 --- a/android/module_context.go +++ b/android/module_context.go @@ -267,6 +267,11 @@ type ModuleContext interface { // goal is built. DistForGoalWithFilename(goal string, path Path, filename string) + // DistForGoalWithFilenameTag creates a rule to copy a Path to the artifacts + // directory on the build server with the given filename appended with the + // `-FILE_NAME_TAG_PLACEHOLDER` suffix when the specified goal is built. + DistForGoalWithFilenameTag(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) @@ -1028,6 +1033,15 @@ func (c *moduleContext) DistForGoalWithFilename(goal string, path Path, filename c.DistForGoalsWithFilename([]string{goal}, path, filename) } +func (c *moduleContext) DistForGoalWithFilenameTag(goal string, path Path, filename string) { + insertBeforeExtension := func(file, insertion string) string { + ext := filepath.Ext(file) + return strings.TrimSuffix(file, ext) + insertion + ext + } + + c.DistForGoalWithFilename(goal, path, insertBeforeExtension(filename, "-FILE_NAME_TAG_PLACEHOLDER")) +} + func (c *moduleContext) DistForGoals(goals []string, paths ...Path) { var copies distCopies for _, path := range paths { diff --git a/filesystem/android_device.go b/filesystem/android_device.go index 2e84b258f..217115b06 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -391,11 +391,6 @@ func (a *androidDevice) buildSymbolsZip(ctx android.ModuleContext, allInstalledM android.BuildSymbolsZip(ctx, allInstalledModules, a.symbolsZipFile, a.symbolsMappingFile) } -func insertBeforeExtension(file, insertion string) string { - ext := filepath.Ext(file) - return strings.TrimSuffix(file, ext) + insertion + ext -} - func (a *androidDevice) distInstalledFiles(ctx android.ModuleContext) { distInstalledFilesJsonAndTxt := func(installedFiles InstalledFilesStruct) { if installedFiles.Json != nil { @@ -427,12 +422,12 @@ func (a *androidDevice) distFiles(ctx android.ModuleContext) { if ctx.Config().HasDeviceProduct() { namePrefix = ctx.Config().DeviceProduct() + "-" } - ctx.DistForGoalWithFilename("droidcore-unbundled", a.proguardDictZip, namePrefix+insertBeforeExtension(a.proguardDictZip.Base(), "-FILE_NAME_TAG_PLACEHOLDER")) - ctx.DistForGoalWithFilename("droidcore-unbundled", a.proguardDictMapping, namePrefix+insertBeforeExtension(a.proguardDictMapping.Base(), "-FILE_NAME_TAG_PLACEHOLDER")) - ctx.DistForGoalWithFilename("droidcore-unbundled", a.proguardUsageZip, namePrefix+insertBeforeExtension(a.proguardUsageZip.Base(), "-FILE_NAME_TAG_PLACEHOLDER")) + ctx.DistForGoalWithFilenameTag("droidcore-unbundled", a.proguardDictZip, namePrefix+a.proguardDictZip.Base()) + ctx.DistForGoalWithFilenameTag("droidcore-unbundled", a.proguardDictMapping, namePrefix+a.proguardDictMapping.Base()) + ctx.DistForGoalWithFilenameTag("droidcore-unbundled", a.proguardUsageZip, namePrefix+a.proguardUsageZip.Base()) - ctx.DistForGoalWithFilename("droidcore-unbundled", a.symbolsZipFile, namePrefix+insertBeforeExtension(a.symbolsZipFile.Base(), "-FILE_NAME_TAG_PLACEHOLDER")) - ctx.DistForGoalWithFilename("droidcore-unbundled", a.symbolsMappingFile, namePrefix+insertBeforeExtension(a.symbolsMappingFile.Base(), "-FILE_NAME_TAG_PLACEHOLDER")) + ctx.DistForGoalWithFilenameTag("droidcore-unbundled", a.symbolsZipFile, namePrefix+a.symbolsZipFile.Base()) + ctx.DistForGoalWithFilenameTag("droidcore-unbundled", a.symbolsMappingFile, namePrefix+a.symbolsMappingFile.Base()) if a.deviceProps.Android_info != nil { ctx.DistForGoal("droidcore-unbundled", android.PathForModuleSrc(ctx, *a.deviceProps.Android_info)) @@ -444,10 +439,10 @@ func (a *androidDevice) distFiles(ctx android.ModuleContext) { } } if a.targetFilesZip != nil { - ctx.DistForGoalWithFilename("target-files-package", a.targetFilesZip, namePrefix+insertBeforeExtension(a.targetFilesZip.Base(), "-FILE_NAME_TAG_PLACEHOLDER")) + ctx.DistForGoalWithFilenameTag("target-files-package", a.targetFilesZip, namePrefix+a.targetFilesZip.Base()) } if a.updatePackage != nil { - ctx.DistForGoalWithFilename("updatepackage", a.updatePackage, namePrefix+insertBeforeExtension(a.updatePackage.Base(), "-FILE_NAME_TAG_PLACEHOLDER")) + ctx.DistForGoalWithFilenameTag("updatepackage", a.updatePackage, namePrefix+a.updatePackage.Base()) } } -- cgit v1.2.3 From dd3231113cc392b39176ce85f003cf8cdf87887f Mon Sep 17 00:00:00 2001 From: Joe Onorato Date: Mon, 31 Mar 2025 13:32:45 -0700 Subject: Make the regex for kati parsing status more flexible, so the make side can provide more detail. Bug: 406475346 Test: m, verify output is still pretty printed, and traces have detail Change-Id: I1af7500b67366fb21292cc4dfd25617c8dcff965 --- ui/status/kati.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/status/kati.go b/ui/status/kati.go index dbb0ce3df..9103515ed 100644 --- a/ui/status/kati.go +++ b/ui/status/kati.go @@ -24,7 +24,7 @@ import ( ) var katiError = regexp.MustCompile(`^(\033\[1m)?[^ ]+:[0-9]+: (\033\[31m)?error:`) -var katiIncludeRe = regexp.MustCompile(`^(\[(\d+)/(\d+)] )?((including [^ ]+|initializing (legacy Make module parser|packaging system)|finishing (legacy Make module parsing|packaging rules)|writing (legacy Make module|packaging) rules) ...)$`) +var katiIncludeRe = regexp.MustCompile(`^(\[(\d+)/(\d+)] )?((including|initializing|finishing|writing) .*?)( \.\.\.)?$`) var katiLogRe = regexp.MustCompile(`^\*kati\*: `) var katiNinjaMissing = regexp.MustCompile("^[^ ]+ is missing, regenerating...$") -- cgit v1.2.3 From 84aefff96e7f0f5958543716e151e0019661e673 Mon Sep 17 00:00:00 2001 From: Yu Liu Date: Fri, 28 Mar 2025 23:41:26 +0000 Subject: Convert collectMembers to use ModuleProxy. Bug: 377723687 Test: Unit tests and compare the ninja and mk files generated. Change-Id: I7249451524143f7fc188f0c7ffe4104cd92d5d88 --- android/apex.go | 5 ++ android/license_sdk_member.go | 14 ++-- android/licenses.go | 2 +- android/module.go | 4 + android/sdk.go | 16 ++-- apex/apex.go | 4 +- apex/apex_sdk_member.go | 4 +- cc/binary_sdk_member.go | 64 +++++++++++---- cc/cc.go | 99 +++++++++++++++++----- cc/library_sdk_member.go | 66 ++++++++------- java/base.go | 2 + java/bootclasspath_fragment.go | 45 ++++++---- java/hiddenapi_modular.go | 4 +- java/java.go | 87 ++++++++++++-------- java/platform_compat_config.go | 40 ++++----- java/sdk.go | 2 +- java/sdk_library.go | 141 +++++++++++++++++++++++++------- java/system_modules.go | 29 +++++-- java/systemserver_classpath_fragment.go | 28 +++++-- sdk/member_trait_test.go | 6 +- sdk/update.go | 109 ++++++++++++------------ 21 files changed, 509 insertions(+), 262 deletions(-) diff --git a/android/apex.go b/android/apex.go index 57baff5cf..d01b44259 100644 --- a/android/apex.go +++ b/android/apex.go @@ -653,6 +653,11 @@ type ApexBundleDepsData struct { var ApexBundleDepsDataProvider = blueprint.NewProvider[ApexBundleDepsData]() +// ApexBundleTypeInfo is used to identify the module is a apexBundle module. +type ApexBundleTypeInfo struct{} + +var ApexBundleTypeInfoProvider = blueprint.NewProvider[ApexBundleTypeInfo]() + func (d *ApexBundleDepsInfo) FlatListPath() Path { return d.flatListPath } diff --git a/android/license_sdk_member.go b/android/license_sdk_member.go index b17defea5..ffdcb1375 100644 --- a/android/license_sdk_member.go +++ b/android/license_sdk_member.go @@ -36,9 +36,9 @@ func (l *licenseSdkMemberType) AddDependencies(ctx SdkDependencyContext, depende ctx.AddDependency(ctx.Module(), dependencyTag, names...) } -func (l *licenseSdkMemberType) IsInstance(module Module) bool { +func (l *licenseSdkMemberType) IsInstance(ctx ModuleContext, module ModuleProxy) bool { // Verify that the module being added is compatible with this module type. - _, ok := module.(*licenseModule) + _, ok := OtherModuleProvider(ctx, module, LicenseInfoProvider) return ok } @@ -86,12 +86,12 @@ type licenseSdkMemberProperties struct { License_text Paths } -func (p *licenseSdkMemberProperties) PopulateFromVariant(_ SdkMemberContext, variant Module) { +func (p *licenseSdkMemberProperties) PopulateFromVariant(ctx SdkMemberContext, variant ModuleProxy) { // Populate the properties from the variant. - l := variant.(*licenseModule) - p.License_kinds = l.properties.License_kinds - p.License_text = make(Paths, 0, len(l.base().commonProperties.Effective_license_text)) - for _, np := range l.base().commonProperties.Effective_license_text { + licenseInfo := OtherModuleProviderOrDefault(ctx.SdkModuleContext(), variant, LicenseInfoProvider) + p.License_kinds = licenseInfo.EffectiveLicenseKinds + p.License_text = make(Paths, 0, len(licenseInfo.EffectiveLicenseText)) + for _, np := range licenseInfo.EffectiveLicenseText { p.License_text = append(p.License_text, np.Path) } } diff --git a/android/licenses.go b/android/licenses.go index 387792144..f49b0fc18 100644 --- a/android/licenses.go +++ b/android/licenses.go @@ -36,7 +36,7 @@ type licensesDependencyTag struct { blueprint.BaseDependencyTag } -func (l licensesDependencyTag) SdkMemberType(Module) SdkMemberType { +func (l licensesDependencyTag) SdkMemberType(_ ModuleContext, _ ModuleProxy) SdkMemberType { // Add the supplied module to the sdk as a license module. return LicenseModuleSdkMemberType } diff --git a/android/module.go b/android/module.go index 4211efb63..ef01af0ba 100644 --- a/android/module.go +++ b/android/module.go @@ -1970,6 +1970,8 @@ type CommonModuleInfo struct { IsPrebuilt bool PrebuiltSourceExists bool UsePrebuilt bool + ApexAvailable []string + ImageVariation blueprint.Variation } type ApiLevelOrPlatform struct { @@ -2340,6 +2342,7 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) ExportedToMake: m.ExportedToMake(), Team: m.Team(), PartitionTag: m.PartitionTag(ctx.DeviceConfig()), + ImageVariation: m.module.ImageVariation(), } if mm, ok := m.module.(interface { MinSdkVersion(ctx EarlyModuleContext) ApiLevel @@ -2375,6 +2378,7 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) commonData.MinSdkVersionSupported = am.MinSdkVersionSupported(ctx) commonData.IsInstallableToApex = am.IsInstallableToApex() commonData.IsApexModule = true + commonData.ApexAvailable = am.apexModuleBase().ApexAvailable() } if _, ok := m.module.(ModuleWithMinSdkVersionCheck); ok { diff --git a/android/sdk.go b/android/sdk.go index ab9a91ccb..ea4e9a21e 100644 --- a/android/sdk.go +++ b/android/sdk.go @@ -31,10 +31,10 @@ type minApiLevelForSdkSnapshot interface { // MinApiLevelForSdkSnapshot returns the ApiLevel of the min_sdk_version of the supplied module. // // If the module does not provide a min_sdk_version then it defaults to 1. -func MinApiLevelForSdkSnapshot(ctx EarlyModuleContext, module Module) ApiLevel { +func MinApiLevelForSdkSnapshot(commonInfo *CommonModuleInfo) ApiLevel { minApiLevel := NoneApiLevel - if m, ok := module.(minApiLevelForSdkSnapshot); ok { - minApiLevel = m.MinSdkVersion(ctx) + if commonInfo.MinSdkVersion.ApiLevel != nil { + minApiLevel = *commonInfo.MinSdkVersion.ApiLevel } if minApiLevel == NoneApiLevel { // The default min API level is 1. @@ -410,7 +410,7 @@ type SdkMember interface { Name() string // Variants returns all the variants of this module depended upon by the SDK. - Variants() []Module + Variants() []ModuleProxy } // SdkMemberDependencyTag is the interface that a tag must implement in order to allow the @@ -422,7 +422,7 @@ type SdkMemberDependencyTag interface { // to the sdk. // // Returning nil will prevent the module being added to the sdk. - SdkMemberType(child Module) SdkMemberType + SdkMemberType(ctx ModuleContext, child ModuleProxy) SdkMemberType // ExportMember determines whether a module added to the sdk through this tag will be exported // from the sdk or not. @@ -449,7 +449,7 @@ type sdkMemberDependencyTag struct { export bool } -func (t *sdkMemberDependencyTag) SdkMemberType(_ Module) SdkMemberType { +func (t *sdkMemberDependencyTag) SdkMemberType(_ ModuleContext, _ ModuleProxy) SdkMemberType { return t.memberType } @@ -534,7 +534,7 @@ type SdkMemberType interface { // This is used to check the type of each variant before added to the SdkMember. Returning false // will cause an error to be logged explaining that the module is not allowed in whichever sdk // property it was added. - IsInstance(module Module) bool + IsInstance(ctx ModuleContext, module ModuleProxy) bool // UsesSourceModuleTypeInSnapshot returns true when the AddPrebuiltModule() method returns a // source module type. @@ -800,7 +800,7 @@ type SdkMemberProperties interface { // PopulateFromVariant populates this structure with information from a module variant. // // It will typically be called once for each variant of a member module that the SDK depends upon. - PopulateFromVariant(ctx SdkMemberContext, variant Module) + PopulateFromVariant(ctx SdkMemberContext, variant ModuleProxy) // AddToPropertySet adds the information from this structure to the property set. // diff --git a/apex/apex.go b/apex/apex.go index 1d41f61dc..5df0e2ad1 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -712,7 +712,7 @@ type dependencyTag struct { installable bool } -func (d *dependencyTag) SdkMemberType(_ android.Module) android.SdkMemberType { +func (d *dependencyTag) SdkMemberType(_ android.ModuleContext, _ android.ModuleProxy) android.SdkMemberType { return d.memberType } @@ -2238,6 +2238,8 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { android.SetProvider(ctx, java.AppInfosProvider, a.appInfos) a.setSymbolInfosProvider(ctx) + + android.SetProvider(ctx, android.ApexBundleTypeInfoProvider, android.ApexBundleTypeInfo{}) } // Set prebuiltInfoProvider. This will be used by `apex_prebuiltinfo_singleton` to print out a metadata file diff --git a/apex/apex_sdk_member.go b/apex/apex_sdk_member.go index 284158f07..2a7a5c5b4 100644 --- a/apex/apex_sdk_member.go +++ b/apex/apex_sdk_member.go @@ -44,8 +44,8 @@ func (mt *apexSdkMemberType) AddDependencies(ctx android.SdkDependencyContext, d ctx.AddVariationDependencies(nil, dependencyTag, names...) } -func (mt *apexSdkMemberType) IsInstance(module android.Module) bool { - _, ok := module.(*apexBundle) +func (mt *apexSdkMemberType) IsInstance(ctx android.ModuleContext, module android.ModuleProxy) bool { + _, ok := android.OtherModuleProvider(ctx, module, android.ApexBundleTypeInfoProvider) return ok } diff --git a/cc/binary_sdk_member.go b/cc/binary_sdk_member.go index 4063714ab..e252cf1d8 100644 --- a/cc/binary_sdk_member.go +++ b/cc/binary_sdk_member.go @@ -15,6 +15,7 @@ package cc import ( + "fmt" "path/filepath" "android/soong/android" @@ -52,10 +53,10 @@ func (mt *binarySdkMemberType) AddDependencies(ctx android.SdkDependencyContext, } } -func (mt *binarySdkMemberType) IsInstance(module android.Module) bool { +func (mt *binarySdkMemberType) IsInstance(ctx android.ModuleContext, module android.ModuleProxy) bool { // Check the module to see if it can be used with this module type. - if m, ok := module.(*Module); ok { - for _, allowableMemberType := range m.sdkMemberTypes { + if m, ok := android.OtherModuleProvider(ctx, module, CcInfoProvider); ok { + for _, allowableMemberType := range m.SdkMemberTypes { if allowableMemberType == mt { return true } @@ -68,10 +69,13 @@ func (mt *binarySdkMemberType) IsInstance(module android.Module) bool { func (mt *binarySdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule { pbm := ctx.SnapshotBuilder().AddPrebuiltModule(member, "cc_prebuilt_binary") - ccModule := member.Variants()[0].(*Module) + info, ok := android.OtherModuleProvider(ctx.SdkModuleContext(), member.Variants()[0], CcInfoProvider) + if !ok { + panic(fmt.Errorf("not a cc module: %s", member.Variants()[0])) + } - if stl := ccModule.stl.Properties.Stl; stl != nil { - pbm.AddProperty("stl", proptools.String(stl)) + if info.StlInfo != nil && info.StlInfo.Stl != nil { + pbm.AddProperty("stl", proptools.String(info.StlInfo.Stl)) } return pbm @@ -120,19 +124,49 @@ type nativeBinaryInfoProperties struct { Nocrt bool } -func (p *nativeBinaryInfoProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { - ccModule := variant.(*Module) +func setSharedAndSystemLibs(specifiedDeps *specifiedDeps, sharedLibs []string, systemLibs []string) { + specifiedDeps.sharedLibs = append(specifiedDeps.sharedLibs, sharedLibs...) + // Must distinguish nil and [] in system_shared_libs - ensure that [] in + // either input list doesn't come out as nil. + if specifiedDeps.systemSharedLibs == nil { + specifiedDeps.systemSharedLibs = systemLibs + } else { + specifiedDeps.systemSharedLibs = append(specifiedDeps.systemSharedLibs, systemLibs...) + } +} + +func setLinkerSpecifiedDeps(linker *LinkerInfo, specifiedDeps *specifiedDeps) { + if linker.ObjectLinkerInfo != nil { + setSharedAndSystemLibs(specifiedDeps, linker.ObjectLinkerInfo.SharedLibs, linker.ObjectLinkerInfo.SystemSharedLibs) + return + } + + setSharedAndSystemLibs(specifiedDeps, linker.SharedLibs, linker.SystemSharedLibs) + + if linker.LibraryDecoratorInfo != nil { + setSharedAndSystemLibs(specifiedDeps, linker.LibraryDecoratorInfo.SharedLibs, linker.LibraryDecoratorInfo.SystemSharedLibs) + specifiedDeps.sharedLibs = android.FirstUniqueStrings(specifiedDeps.sharedLibs) + if len(specifiedDeps.systemSharedLibs) > 0 { + // Skip this if systemSharedLibs is either nil or [], to ensure they are + // retained. + specifiedDeps.systemSharedLibs = android.FirstUniqueStrings(specifiedDeps.systemSharedLibs) + } + } +} - p.archType = ccModule.Target().Arch.ArchType.String() - p.outputFile = getRequiredMemberOutputFile(ctx, ccModule) +func (p *nativeBinaryInfoProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.ModuleProxy) { + commonInfo := android.OtherModulePointerProviderOrDefault(ctx.SdkModuleContext(), variant, android.CommonModuleInfoProvider) + ccInfo := android.OtherModulePointerProviderOrDefault(ctx.SdkModuleContext(), variant, CcInfoProvider) + p.archType = commonInfo.Target.Arch.ArchType.String() + p.outputFile = getRequiredMemberOutputFile(ctx, variant) - binaryLinker := ccModule.linker.(*binaryDecorator) - p.StaticExecutable = binaryLinker.static() - p.Nocrt = Bool(binaryLinker.baseLinker.Properties.Nocrt) + if ccInfo.LinkerInfo != nil { + binaryLinker := ccInfo.LinkerInfo.BinaryDecoratorInfo + p.StaticExecutable = binaryLinker.StaticExecutable + p.Nocrt = binaryLinker.Nocrt - if ccModule.linker != nil { specifiedDeps := specifiedDeps{} - specifiedDeps = ccModule.linker.linkerSpecifiedDeps(ctx.SdkModuleContext(), ccModule, specifiedDeps) + setLinkerSpecifiedDeps(ccInfo.LinkerInfo, &specifiedDeps) p.SharedLibs = specifiedDeps.sharedLibs p.SystemSharedLibs = specifiedDeps.systemSharedLibs diff --git a/cc/cc.go b/cc/cc.go index e52955957..757deab15 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -80,6 +80,7 @@ type LinkerInfo struct { SharedLibs []string // list of modules that should only provide headers for this module. HeaderLibs []string + SystemSharedLibs []string ImplementationModuleName *string BinaryDecoratorInfo *BinaryDecoratorInfo @@ -91,7 +92,11 @@ type LinkerInfo struct { PrebuiltLibraryLinkerInfo *PrebuiltLibraryLinkerInfo } -type BinaryDecoratorInfo struct{} +type BinaryDecoratorInfo struct { + StaticExecutable bool + Nocrt bool +} + type LibraryDecoratorInfo struct { ExportIncludeDirs []string InjectBsslHash bool @@ -99,6 +104,11 @@ type LibraryDecoratorInfo struct { // not included in the NDK. NdkSysrootPath android.Path VndkFileName string + // rename host libraries to prevent overlap with system installed libraries + UniqueHostSoname *bool + SharedLibs []string + SystemSharedLibs []string + StubsSymbolFilePath android.Path } type SnapshotInfo struct { @@ -120,7 +130,9 @@ type StubDecoratorInfo struct { type ObjectLinkerInfo struct { // Location of the object in the sysroot. Empty if the object is not // included in the NDK. - NdkSysrootPath android.Path + NdkSysrootPath android.Path + SharedLibs []string + SystemSharedLibs []string } type PrebuiltLibraryLinkerInfo struct { @@ -128,7 +140,8 @@ type PrebuiltLibraryLinkerInfo struct { } type LibraryInfo struct { - BuildStubs bool + BuildStubs bool + AllStubsVersions []string } type InstallerInfo struct { @@ -142,17 +155,33 @@ type LocalOrGlobalFlagsInfo struct { CppFlags []string // Flags that apply to C++ source files } +type SanitizeInfo struct { + IsUnsanitizedVariant bool + Sanitize SanitizeUserProps +} + +type StlInfo struct { + Stl *string +} + // Common info about the cc module. type CcInfo struct { IsPrebuilt bool CmakeSnapshotSupported bool HasLlndkStubs bool DataPaths []android.DataPath - CompilerInfo *CompilerInfo - LinkerInfo *LinkerInfo - SnapshotInfo *SnapshotInfo - LibraryInfo *LibraryInfo - InstallerInfo *InstallerInfo + VendorAvailable bool + OdmAvailable bool + ProductAvailable bool + // Allowable SdkMemberTypes of this module type. + SdkMemberTypes []android.SdkMemberType + CompilerInfo *CompilerInfo + LinkerInfo *LinkerInfo + SnapshotInfo *SnapshotInfo + LibraryInfo *LibraryInfo + InstallerInfo *InstallerInfo + StlInfo *StlInfo + SanitizeInfo *SanitizeInfo } var CcInfoProvider = blueprint.NewProvider[*CcInfo]() @@ -2541,6 +2570,10 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { CmakeSnapshotSupported: proptools.Bool(c.Properties.Cmake_snapshot_supported), HasLlndkStubs: c.HasLlndkStubs(), DataPaths: c.DataPaths(), + VendorAvailable: c.VendorAvailable(), + OdmAvailable: c.OdmAvailable(), + ProductAvailable: c.ProductAvailable(), + SdkMemberTypes: c.sdkMemberTypes, } if c.compiler != nil { cflags := c.compiler.baseCompilerProps().Cflags @@ -2564,21 +2597,34 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { if c.linker != nil { baseLinkerProps := c.linker.baseLinkerProps() ccInfo.LinkerInfo = &LinkerInfo{ - WholeStaticLibs: baseLinkerProps.Whole_static_libs.GetOrDefault(ctx, nil), - StaticLibs: baseLinkerProps.Static_libs.GetOrDefault(ctx, nil), - SharedLibs: baseLinkerProps.Shared_libs.GetOrDefault(ctx, nil), - HeaderLibs: baseLinkerProps.Header_libs.GetOrDefault(ctx, nil), + WholeStaticLibs: baseLinkerProps.Whole_static_libs.GetOrDefault(ctx, nil), + StaticLibs: baseLinkerProps.Static_libs.GetOrDefault(ctx, nil), + SharedLibs: baseLinkerProps.Shared_libs.GetOrDefault(ctx, nil), + HeaderLibs: baseLinkerProps.Header_libs.GetOrDefault(ctx, nil), + SystemSharedLibs: baseLinkerProps.System_shared_libs, } switch decorator := c.linker.(type) { case *binaryDecorator: - ccInfo.LinkerInfo.BinaryDecoratorInfo = &BinaryDecoratorInfo{} + ccInfo.LinkerInfo.BinaryDecoratorInfo = &BinaryDecoratorInfo{ + StaticExecutable: decorator.static(), + Nocrt: Bool(decorator.baseLinker.Properties.Nocrt), + } case *libraryDecorator: - lk := c.linker.(*libraryDecorator) ccInfo.LinkerInfo.LibraryDecoratorInfo = &LibraryDecoratorInfo{ - InjectBsslHash: Bool(lk.Properties.Inject_bssl_hash), - NdkSysrootPath: lk.ndkSysrootPath, - VndkFileName: lk.getLibNameHelper(c.BaseModuleName(), true, false) + ".so", + InjectBsslHash: Bool(decorator.Properties.Inject_bssl_hash), + NdkSysrootPath: decorator.ndkSysrootPath, + VndkFileName: decorator.getLibNameHelper(c.BaseModuleName(), true, false) + ".so", + UniqueHostSoname: decorator.Properties.Unique_host_soname, + StubsSymbolFilePath: decorator.stubsSymbolFilePath, + } + var properties StaticOrSharedProperties + if decorator.static() { + properties = decorator.StaticProperties.Static + } else if decorator.shared() { + properties = decorator.SharedProperties.Shared } + ccInfo.LinkerInfo.LibraryDecoratorInfo.SharedLibs = properties.Shared_libs.GetOrDefault(ctx, nil) + ccInfo.LinkerInfo.LibraryDecoratorInfo.SystemSharedLibs = properties.System_shared_libs case *testBinary: ccInfo.LinkerInfo.TestBinaryInfo = &TestBinaryInfo{ Gtest: decorator.testDecorator.gtest(), @@ -2587,7 +2633,9 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { ccInfo.LinkerInfo.BenchmarkDecoratorInfo = &BenchmarkDecoratorInfo{} case *objectLinker: ccInfo.LinkerInfo.ObjectLinkerInfo = &ObjectLinkerInfo{ - NdkSysrootPath: c.linker.(*objectLinker).ndkSysrootPath, + NdkSysrootPath: c.linker.(*objectLinker).ndkSysrootPath, + SharedLibs: decorator.Properties.Shared_libs.GetOrDefault(ctx, nil), + SystemSharedLibs: decorator.Properties.System_shared_libs, } case *stubDecorator: ccInfo.LinkerInfo.StubDecoratorInfo = &StubDecoratorInfo{} @@ -2610,7 +2658,8 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { } if c.library != nil { ccInfo.LibraryInfo = &LibraryInfo{ - BuildStubs: c.library.BuildStubs(), + BuildStubs: c.library.BuildStubs(), + AllStubsVersions: c.library.AllStubsVersions(), } } if c.installer != nil { @@ -2624,6 +2673,17 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { } } } + if c.stl != nil { + ccInfo.StlInfo = &StlInfo{ + Stl: c.stl.Properties.Stl, + } + } + if c.sanitize != nil { + ccInfo.SanitizeInfo = &SanitizeInfo{ + IsUnsanitizedVariant: c.sanitize.isUnsanitizedVariant(), + Sanitize: c.sanitize.Properties.Sanitize, + } + } android.SetProvider(ctx, CcInfoProvider, &ccInfo) c.setOutputFiles(ctx) @@ -2680,6 +2740,7 @@ func CreateCommonLinkableInfo(ctx android.ModuleContext, mod VersionedLinkableIn info.HasLLNDKStubs = vi.HasLLNDKStubs() info.IsLLNDKMovedToApex = vi.IsLLNDKMovedToApex() info.ImplementationModuleName = vi.ImplementationModuleName(mod.BaseModuleName()) + vi.AllStubsVersions() } if !mod.PreventInstall() && fuzz.IsValid(ctx, mod.FuzzModuleStruct()) && mod.IsFuzzModule() { diff --git a/cc/library_sdk_member.go b/cc/library_sdk_member.go index 46290300c..1db60e5df 100644 --- a/cc/library_sdk_member.go +++ b/cc/library_sdk_member.go @@ -15,6 +15,7 @@ package cc import ( + "fmt" "path/filepath" "android/soong/android" @@ -186,10 +187,10 @@ func (mt *librarySdkMemberType) AddDependencies(ctx android.SdkDependencyContext } } -func (mt *librarySdkMemberType) IsInstance(module android.Module) bool { +func (mt *librarySdkMemberType) IsInstance(ctx android.ModuleContext, module android.ModuleProxy) bool { // Check the module to see if it can be used with this module type. - if m, ok := module.(*Module); ok { - for _, allowableMemberType := range m.sdkMemberTypes { + if m, ok := android.OtherModuleProvider(ctx, module, CcInfoProvider); ok { + for _, allowableMemberType := range m.SdkMemberTypes { if allowableMemberType == mt { return true } @@ -202,7 +203,11 @@ func (mt *librarySdkMemberType) IsInstance(module android.Module) bool { func (mt *librarySdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule { pbm := ctx.SnapshotBuilder().AddPrebuiltModule(member, mt.prebuiltModuleType) - ccModule := member.Variants()[0].(*Module) + ccModule := member.Variants()[0] + info, ok := android.OtherModuleProvider(ctx.SdkModuleContext(), ccModule, CcInfoProvider) + if !ok { + panic(fmt.Errorf("not a cc module: %s", member.Variants()[0])) + } if ctx.RequiresTrait(nativeBridgeSdkTrait) { pbm.AddProperty("native_bridge_supported", true) @@ -216,30 +221,30 @@ func (mt *librarySdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, pbm.AddProperty("recovery_available", true) } - if proptools.Bool(ccModule.VendorProperties.Vendor_available) { + if info.VendorAvailable { pbm.AddProperty("vendor_available", true) } - if proptools.Bool(ccModule.VendorProperties.Odm_available) { + if info.OdmAvailable { pbm.AddProperty("odm_available", true) } - if proptools.Bool(ccModule.VendorProperties.Product_available) { + if info.ProductAvailable { pbm.AddProperty("product_available", true) } - sdkVersion := ccModule.SdkVersion() + sdkVersion := android.OtherModulePointerProviderOrDefault(ctx.SdkModuleContext(), + ccModule, android.CommonModuleInfoProvider).SdkVersion if sdkVersion != "" { pbm.AddProperty("sdk_version", sdkVersion) } - stl := ccModule.stl.Properties.Stl - if stl != nil { - pbm.AddProperty("stl", proptools.String(stl)) + if info.StlInfo != nil && info.StlInfo.Stl != nil { + pbm.AddProperty("stl", proptools.String(info.StlInfo.Stl)) } - if lib, ok := ccModule.linker.(*libraryDecorator); ok { - uhs := lib.Properties.Unique_host_soname + if info.LinkerInfo != nil && info.LinkerInfo.LibraryDecoratorInfo != nil { + uhs := info.LinkerInfo.LibraryDecoratorInfo.UniqueHostSoname if uhs != nil { pbm.AddProperty("unique_host_soname", proptools.Bool(uhs)) } @@ -496,21 +501,21 @@ type nativeLibInfoProperties struct { outputFile android.Path } -func (p *nativeLibInfoProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { +func (p *nativeLibInfoProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.ModuleProxy) { addOutputFile := true - ccModule := variant.(*Module) + ccInfo := android.OtherModulePointerProviderOrDefault(ctx.SdkModuleContext(), variant, CcInfoProvider) - if s := ccModule.sanitize; s != nil { + if s := ccInfo.SanitizeInfo; s != nil { // We currently do not capture sanitizer flags for libs with sanitizers // enabled, because they may vary among variants that cannot be represented // in the input blueprint files. In particular, sanitizerDepsMutator enables // various sanitizers on dependencies, but in many cases only on static // ones, and we cannot specify sanitizer flags at the link type level (i.e. // in StaticOrSharedProperties). - if s.isUnsanitizedVariant() { + if s.IsUnsanitizedVariant { // This still captures explicitly disabled sanitizers, which may be // necessary to avoid cyclic dependencies. - p.Sanitize = s.Properties.Sanitize + p.Sanitize = s.Sanitize } else { // Do not add the output file to the snapshot if we don't represent it // properly. @@ -525,7 +530,7 @@ func (p *nativeLibInfoProperties) PopulateFromVariant(ctx android.SdkMemberConte exportedIncludeDirs, exportedGeneratedIncludeDirs := android.FilterPathListPredicate( exportedInfo.IncludeDirs, isGeneratedHeaderDirectory) - target := ccModule.Target() + target := android.OtherModulePointerProviderOrDefault(ctx.SdkModuleContext(), variant, android.CommonModuleInfoProvider).Target p.archSubDir = target.Arch.ArchType.String() if target.NativeBridge == android.NativeBridgeEnabled { p.archSubDir += "_native_bridge" @@ -541,12 +546,13 @@ func (p *nativeLibInfoProperties) PopulateFromVariant(ctx android.SdkMemberConte p.ExportedSystemIncludeDirs = android.FirstUniquePaths(dirs) p.ExportedFlags = exportedInfo.Flags - if ccModule.linker != nil { + if linker := ccInfo.LinkerInfo; linker != nil { specifiedDeps := specifiedDeps{} - specifiedDeps = ccModule.linker.linkerSpecifiedDeps(ctx.SdkModuleContext(), ccModule, specifiedDeps) + setLinkerSpecifiedDeps(linker, &specifiedDeps) - if lib := ccModule.library; lib != nil { - if !lib.HasStubsVariants() { + if lib := ccInfo.LibraryInfo; lib != nil { + linkableInfo := android.OtherModulePointerProviderOrDefault(ctx.SdkModuleContext(), variant, LinkableInfoProvider) + if !linkableInfo.HasStubsVariants { // Propagate dynamic dependencies for implementation libs, but not stubs. p.SharedLibs = specifiedDeps.sharedLibs } else { @@ -554,11 +560,11 @@ func (p *nativeLibInfoProperties) PopulateFromVariant(ctx android.SdkMemberConte // ccModule.StubsVersion()) if the module is versioned. 2. Ensure that all // the versioned stub libs are retained in the prebuilt tree; currently only // the stub corresponding to ccModule.StubsVersion() is. - p.StubsVersions = lib.AllStubsVersions() - if lib.BuildStubs() && ccModule.stubsSymbolFilePath() == nil { + p.StubsVersions = lib.AllStubsVersions + if lib.BuildStubs && linker.LibraryDecoratorInfo.StubsSymbolFilePath == nil { ctx.ModuleErrorf("Could not determine symbol_file") } else { - p.StubsSymbolFilePath = ccModule.stubsSymbolFilePath() + p.StubsSymbolFilePath = linker.LibraryDecoratorInfo.StubsSymbolFilePath } } } @@ -567,16 +573,16 @@ func (p *nativeLibInfoProperties) PopulateFromVariant(ctx android.SdkMemberConte p.ExportedGeneratedHeaders = exportedInfo.GeneratedHeaders if !p.memberType.noOutputFiles && addOutputFile { - p.outputFile = getRequiredMemberOutputFile(ctx, ccModule) + p.outputFile = getRequiredMemberOutputFile(ctx, variant) } } -func getRequiredMemberOutputFile(ctx android.SdkMemberContext, ccModule *Module) android.Path { +func getRequiredMemberOutputFile(ctx android.SdkMemberContext, module android.Module) android.Path { var path android.Path - if info, ok := android.OtherModuleProvider(ctx.SdkModuleContext(), ccModule, LinkableInfoProvider); ok && info.OutputFile.Valid() { + if info, ok := android.OtherModuleProvider(ctx.SdkModuleContext(), module, LinkableInfoProvider); ok && info.OutputFile.Valid() { path = info.OutputFile.Path() } else { - ctx.SdkModuleContext().ModuleErrorf("member variant %s does not have a valid output file", ccModule) + ctx.SdkModuleContext().ModuleErrorf("member variant %s does not have a valid output file", module) } return path } diff --git a/java/base.go b/java/base.go index be7262b81..0f0a50524 100644 --- a/java/base.go +++ b/java/base.go @@ -1332,6 +1332,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath StubsLinkType: j.stubsLinkType, AconfigIntermediateCacheOutputPaths: deps.aconfigProtoFiles, SdkVersion: j.SdkVersion(ctx), + OverrideMinSdkVersion: j.overridableProperties.Min_sdk_version, } } @@ -1963,6 +1964,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath AconfigIntermediateCacheOutputPaths: j.aconfigCacheFiles, SdkVersion: j.SdkVersion(ctx), OutputFile: j.outputFile, + OverrideMinSdkVersion: j.overridableProperties.Min_sdk_version, } } diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go index a09416dc4..8ee37ab9f 100644 --- a/java/bootclasspath_fragment.go +++ b/java/bootclasspath_fragment.go @@ -41,7 +41,13 @@ func registerBootclasspathFragmentBuildComponents(ctx android.RegistrationContex ctx.RegisterModuleType("prebuilt_bootclasspath_fragment", prebuiltBootclasspathFragmentFactory) } -type BootclasspathFragmentInfo struct{} +type BootclasspathFragmentInfo struct { + ImageName *string + Contents []string + ApiStubLibs []string + CorePlatformApiStubLibs []string + Fragments []ApexVariantReference +} var BootclasspathFragmentInfoProvider = blueprint.NewProvider[BootclasspathFragmentInfo]() @@ -73,10 +79,10 @@ func (b bootclasspathFragmentContentDependencyTag) ReplaceSourceWithPrebuilt() b // SdkMemberType causes dependencies added with this tag to be automatically added to the sdk as if // they were specified using java_boot_libs or java_sdk_libs. -func (b bootclasspathFragmentContentDependencyTag) SdkMemberType(child android.Module) android.SdkMemberType { +func (b bootclasspathFragmentContentDependencyTag) SdkMemberType(ctx android.ModuleContext, child android.ModuleProxy) android.SdkMemberType { // If the module is a java_sdk_library then treat it as if it was specified in the java_sdk_libs // property, otherwise treat if it was specified in the java_boot_libs property. - if javaSdkLibrarySdkMemberType.IsInstance(child) { + if javaSdkLibrarySdkMemberType.IsInstance(ctx, child) { return javaSdkLibrarySdkMemberType } @@ -562,7 +568,13 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo b.HideFromMake() } - android.SetProvider(ctx, BootclasspathFragmentInfoProvider, BootclasspathFragmentInfo{}) + android.SetProvider(ctx, BootclasspathFragmentInfoProvider, BootclasspathFragmentInfo{ + ImageName: b.properties.Image_name, + Contents: b.properties.Contents.GetOrDefault(ctx, nil), + ApiStubLibs: b.properties.Api.Stub_libs.GetOrDefault(ctx, nil), + CorePlatformApiStubLibs: b.properties.Core_platform_api.Stub_libs.GetOrDefault(ctx, nil), + Fragments: b.properties.Fragments, + }) } // getProfileProviderApex returns the name of the apex that provides a boot image profile, or an @@ -809,7 +821,8 @@ func (b *BootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleC for _, module := range contents { // If the module has a min_sdk_version that is higher than the target build release then it will // not work on the target build release and so must not be included in the sdk snapshot. - minApiLevel := android.MinApiLevelForSdkSnapshot(ctx, module) + commonInfo := android.OtherModulePointerProviderOrDefault(ctx, module, android.CommonModuleInfoProvider) + minApiLevel := android.MinApiLevelForSdkSnapshot(commonInfo) if minApiLevel.GreaterThan(targetApiLevel) { continue } @@ -897,8 +910,8 @@ func (b *bootclasspathFragmentMemberType) AddDependencies(ctx android.SdkDepende ctx.AddVariationDependencies(nil, dependencyTag, names...) } -func (b *bootclasspathFragmentMemberType) IsInstance(module android.Module) bool { - _, ok := module.(*BootclasspathFragmentModule) +func (b *bootclasspathFragmentMemberType) IsInstance(ctx android.ModuleContext, module android.ModuleProxy) bool { + _, ok := android.OtherModuleProvider(ctx, module, BootclasspathFragmentInfoProvider) return ok } @@ -958,15 +971,15 @@ type bootclasspathFragmentSdkMemberProperties struct { Filtered_flags_path android.OptionalPath `supported_build_releases:"Tiramisu+"` } -func (b *bootclasspathFragmentSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { - module := variant.(*BootclasspathFragmentModule) +func (b *bootclasspathFragmentSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.ModuleProxy) { + mctx := ctx.SdkModuleContext() + module, _ := android.OtherModuleProvider(mctx, variant, BootclasspathFragmentInfoProvider) - b.Image_name = module.properties.Image_name - b.Contents = module.properties.Contents.GetOrDefault(ctx.SdkModuleContext(), nil) + b.Image_name = module.ImageName + b.Contents = module.Contents // Get the hidden API information from the module. - mctx := ctx.SdkModuleContext() - hiddenAPIInfo, _ := android.OtherModuleProvider(mctx, module, HiddenAPIInfoForSdkProvider) + hiddenAPIInfo, _ := android.OtherModuleProvider(mctx, variant, HiddenAPIInfoForSdkProvider) b.Flag_files_by_category = hiddenAPIInfo.FlagFilesByCategory // Copy all the generated file paths. @@ -982,11 +995,11 @@ func (b *bootclasspathFragmentSdkMemberProperties) PopulateFromVariant(ctx andro b.Filtered_flags_path = android.OptionalPathForPath(hiddenAPIInfo.FilteredFlagsPath) // Copy stub_libs properties. - b.Stub_libs = module.properties.Api.Stub_libs.GetOrDefault(mctx, nil) - b.Core_platform_stub_libs = module.properties.Core_platform_api.Stub_libs.GetOrDefault(mctx, nil) + b.Stub_libs = module.ApiStubLibs + b.Core_platform_stub_libs = module.CorePlatformApiStubLibs // Copy fragment properties. - b.Fragments = module.properties.Fragments + b.Fragments = module.Fragments } func (b *bootclasspathFragmentSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go index 365005835..7c502a95c 100644 --- a/java/hiddenapi_modular.go +++ b/java/hiddenapi_modular.go @@ -197,7 +197,7 @@ func (b hiddenAPIStubsDependencyTag) ReplaceSourceWithPrebuilt() bool { return false } -func (b hiddenAPIStubsDependencyTag) SdkMemberType(child android.Module) android.SdkMemberType { +func (b hiddenAPIStubsDependencyTag) SdkMemberType(ctx android.ModuleContext, child android.ModuleProxy) android.SdkMemberType { // Do not add additional dependencies to the sdk. if b.fromAdditionalDependency { return nil @@ -205,7 +205,7 @@ func (b hiddenAPIStubsDependencyTag) SdkMemberType(child android.Module) android // If the module is a java_sdk_library then treat it as if it was specific in the java_sdk_libs // property, otherwise treat if it was specified in the java_header_libs property. - if javaSdkLibrarySdkMemberType.IsInstance(child) { + if javaSdkLibrarySdkMemberType.IsInstance(ctx, child) { return javaSdkLibrarySdkMemberType } diff --git a/java/java.go b/java/java.go index a1b18bd30..18920aa11 100644 --- a/java/java.go +++ b/java/java.go @@ -103,8 +103,8 @@ var ( PropertyName: "java_header_libs", SupportsSdk: true, }, - func(_ android.SdkMemberContext, j *Library) android.Path { - headerJars := j.HeaderJars() + func(_ android.SdkMemberContext, j android.Module, javaInfo *JavaInfo) android.Path { + headerJars := javaInfo.HeaderJars if len(headerJars) != 1 { panic(fmt.Errorf("there must be only one header jar from %q", j.Name())) } @@ -116,8 +116,8 @@ var ( } // Export implementation classes jar as part of the sdk. - exportImplementationClassesJar = func(_ android.SdkMemberContext, j *Library) android.Path { - implementationJars := j.ImplementationAndResourcesJars() + exportImplementationClassesJar = func(_ android.SdkMemberContext, j android.Module, javaInfo *JavaInfo) android.Path { + implementationJars := javaInfo.ImplementationAndResourcesJars if len(implementationJars) != 1 { panic(fmt.Errorf("there must be only one implementation jar from %q", j.Name())) } @@ -160,9 +160,9 @@ var ( PropertyName: "java_boot_libs", SupportsSdk: true, }, - func(ctx android.SdkMemberContext, j *Library) android.Path { + func(ctx android.SdkMemberContext, j android.Module, javaInfo *JavaInfo) android.Path { if snapshotRequiresImplementationJar(ctx) { - return exportImplementationClassesJar(ctx, j) + return exportImplementationClassesJar(ctx, j, javaInfo) } // Java boot libs are only provided in the SDK to provide access to their dex implementation @@ -202,7 +202,7 @@ var ( // This was only added in Tiramisu. SupportedBuildReleaseSpecification: "Tiramisu+", }, - func(ctx android.SdkMemberContext, j *Library) android.Path { + func(ctx android.SdkMemberContext, _ android.Module, _ *JavaInfo) android.Path { // Java systemserver libs are only provided in the SDK to provide access to their dex // implementation jar for use by dexpreopting. They do not need to provide an actual // implementation jar but the java_import will need a file that exists so just copy an empty @@ -433,8 +433,11 @@ type JavaInfo struct { DexpreopterInfo *DexpreopterInfo - XrefJavaFiles android.Paths - XrefKotlinFiles android.Paths + XrefJavaFiles android.Paths + XrefKotlinFiles android.Paths + OverrideMinSdkVersion *string + CompileDex *bool + SystemModules string } var JavaInfoProvider = blueprint.NewProvider[*JavaInfo]() @@ -453,7 +456,8 @@ type DexpreopterInfo struct { } type JavaLibraryInfo struct { - Prebuilt bool + Prebuilt bool + PermittedPackages []string } var JavaLibraryInfoProvider = blueprint.NewProvider[JavaLibraryInfo]() @@ -1148,7 +1152,8 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { }) android.SetProvider(ctx, JavaLibraryInfoProvider, JavaLibraryInfo{ - Prebuilt: false, + Prebuilt: false, + PermittedPackages: j.properties.Permitted_packages, }) if javaInfo != nil { @@ -1339,7 +1344,7 @@ type librarySdkMemberType struct { // Function to retrieve the appropriate output jar (implementation or header) from // the library. - jarToExportGetter func(ctx android.SdkMemberContext, j *Library) android.Path + jarToExportGetter func(ctx android.SdkMemberContext, j android.Module, javaInfo *JavaInfo) android.Path // Function to compute the snapshot relative path to which the named library's // jar should be copied. @@ -1359,9 +1364,9 @@ func (mt *librarySdkMemberType) AddDependencies(ctx android.SdkDependencyContext ctx.AddVariationDependencies(nil, dependencyTag, names...) } -func (mt *librarySdkMemberType) IsInstance(module android.Module) bool { - _, ok := module.(*Library) - return ok +func (mt *librarySdkMemberType) IsInstance(ctx android.ModuleContext, module android.ModuleProxy) bool { + info, ok := android.OtherModuleProvider(ctx, module, JavaLibraryInfoProvider) + return ok && !info.Prebuilt } func (mt *librarySdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule { @@ -1388,26 +1393,30 @@ type librarySdkMemberProperties struct { DexPreoptProfileGuided *bool `supported_build_releases:"UpsideDownCake+"` } -func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { - j := variant.(*Library) +func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.ModuleProxy) { + //j := variant.(*Library) + mctx := ctx.SdkModuleContext() + commonInfo := android.OtherModulePointerProviderOrDefault(mctx, variant, android.CommonModuleInfoProvider) + javaInfo := android.OtherModulePointerProviderOrDefault(mctx, variant, JavaInfoProvider) + libraryInfo := android.OtherModuleProviderOrDefault(mctx, variant, JavaLibraryInfoProvider) - p.JarToExport = ctx.MemberType().(*librarySdkMemberType).jarToExportGetter(ctx, j) + p.JarToExport = ctx.MemberType().(*librarySdkMemberType).jarToExportGetter(ctx, variant, javaInfo) - p.AidlIncludeDirs = j.AidlIncludeDirs() + p.AidlIncludeDirs = javaInfo.AidlIncludeDirs - p.PermittedPackages = j.PermittedPackagesForUpdatableBootJars() + p.PermittedPackages = libraryInfo.PermittedPackages // If the min_sdk_version was set then add the canonical representation of the API level to the // snapshot. - if j.overridableProperties.Min_sdk_version != nil { - canonical, err := android.ReplaceFinalizedCodenames(ctx.SdkModuleContext().Config(), j.minSdkVersion.String()) + if javaInfo.OverrideMinSdkVersion != nil { + canonical, err := android.ReplaceFinalizedCodenames(mctx.Config(), commonInfo.MinSdkVersion.ApiLevel.String()) if err != nil { ctx.ModuleErrorf("%s", err) } p.MinSdkVersion = proptools.StringPtr(canonical) } - if j.dexpreopter.dexpreoptProperties.Dex_preopt_result.Profile_guided { + if javaInfo.ProfileGuided { p.DexPreoptProfileGuided = proptools.BoolPtr(true) } } @@ -1659,6 +1668,12 @@ type JavaTestImport struct { dexJarFile android.Path } +type JavaTestInfo struct { + TestConfig android.Path +} + +var JavaTestInfoProvider = blueprint.NewProvider[JavaTestInfo]() + func (j *Test) InstallInTestcases() bool { // Host java tests install into $(HOST_OUT_JAVA_LIBRARIES), and then are copied into // testcases by base_rules.mk. @@ -1963,6 +1978,10 @@ func (j *Test) javaTestSetTestsuiteInfo(ctx android.ModuleContext) { NonArchData: testData, PerTestcaseDirectory: proptools.Bool(j.testProperties.Per_testcase_directory), }) + + android.SetProvider(ctx, JavaTestInfoProvider, JavaTestInfo{ + TestConfig: j.testConfig, + }) } func (j *TestHelperLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { @@ -2013,8 +2032,8 @@ func (mt *testSdkMemberType) AddDependencies(ctx android.SdkDependencyContext, d ctx.AddVariationDependencies(nil, dependencyTag, names...) } -func (mt *testSdkMemberType) IsInstance(module android.Module) bool { - _, ok := module.(*Test) +func (mt *testSdkMemberType) IsInstance(ctx android.ModuleContext, module android.ModuleProxy) bool { + _, ok := android.OtherModuleProvider(ctx, module, JavaTestInfoProvider) return ok } @@ -2033,16 +2052,14 @@ type testSdkMemberProperties struct { TestConfig android.Path } -func (p *testSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { - test := variant.(*Test) - - implementationJars := test.ImplementationJars() +func (p *testSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.ModuleProxy) { + implementationJars := android.OtherModulePointerProviderOrDefault(ctx.SdkModuleContext(), variant, JavaInfoProvider).ImplementationJars if len(implementationJars) != 1 { - panic(fmt.Errorf("there must be only one implementation jar from %q", test.Name())) + panic(fmt.Errorf("there must be only one implementation jar from %q", variant.Name())) } p.JarToExport = implementationJars[0] - p.TestConfig = test.testConfig + p.TestConfig = android.OtherModuleProviderOrDefault(ctx.SdkModuleContext(), variant, JavaTestInfoProvider).TestConfig } func (p *testSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { @@ -3273,7 +3290,8 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { android.SetProvider(ctx, JavaInfoProvider, javaInfo) android.SetProvider(ctx, JavaLibraryInfoProvider, JavaLibraryInfo{ - Prebuilt: true, + Prebuilt: true, + PermittedPackages: j.properties.Permitted_packages, }) ctx.SetOutputFiles(android.Paths{j.combinedImplementationFile}, "") @@ -3874,4 +3892,9 @@ func setExtraJavaInfo(ctx android.ModuleContext, module android.Module, javaInfo javaInfo.XrefJavaFiles = xr.XrefJavaFiles() javaInfo.XrefKotlinFiles = xr.XrefKotlinFiles() } + + if sdk, ok := module.(android.SdkContext); ok { + javaInfo.SystemModules = sdk.SystemModules() + javaInfo.SdkVersion = sdk.SdkVersion(ctx) + } } diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go index d2ec8bd4f..4d43ba9a6 100644 --- a/java/platform_compat_config.go +++ b/java/platform_compat_config.go @@ -44,8 +44,12 @@ func registerPlatformCompatConfigBuildComponents(ctx android.RegistrationContext } type PlatformCompatConfigInfo struct { - CompatConfig android.OutputPath - SubDir string + CompatConfig android.OutputPath + SubDir string + CompatConfigMetadata android.Path + // Whether to include it in the "merged" XML (merged_compat_config.xml) or not. + IncludeInMergedXml bool + Prebuilt bool } var PlatformCompatConfigInfoProvider = blueprint.NewProvider[PlatformCompatConfigInfo]() @@ -99,14 +103,6 @@ type platformCompatConfigMetadataProvider interface { includeInMergedXml() bool } -type PlatformCompatConfigMetadataInfo struct { - CompatConfigMetadata android.Path - // Whether to include it in the "merged" XML (merged_compat_config.xml) or not. - IncludeInMergedXml bool -} - -var PlatformCompatConfigMetadataInfoProvider = blueprint.NewProvider[PlatformCompatConfigMetadataInfo]() - type PlatformCompatConfigIntf interface { android.Module @@ -141,13 +137,11 @@ func (p *platformCompatConfig) GenerateAndroidBuildActions(ctx android.ModuleCon ctx.SetOutputFiles(android.Paths{p.configFile}, "") android.SetProvider(ctx, PlatformCompatConfigInfoProvider, PlatformCompatConfigInfo{ - CompatConfig: p.CompatConfig(), - SubDir: p.SubDir(), - }) - - android.SetProvider(ctx, PlatformCompatConfigMetadataInfoProvider, PlatformCompatConfigMetadataInfo{ + CompatConfig: p.CompatConfig(), + SubDir: p.SubDir(), CompatConfigMetadata: p.compatConfigMetadata(), IncludeInMergedXml: p.includeInMergedXml(), + Prebuilt: false, }) } @@ -173,9 +167,9 @@ func (b *compatConfigMemberType) AddDependencies(ctx android.SdkDependencyContex ctx.AddVariationDependencies(nil, dependencyTag, names...) } -func (b *compatConfigMemberType) IsInstance(module android.Module) bool { - _, ok := module.(*platformCompatConfig) - return ok +func (b *compatConfigMemberType) IsInstance(ctx android.ModuleContext, module android.ModuleProxy) bool { + info, ok := android.OtherModuleProvider(ctx, module, PlatformCompatConfigInfoProvider) + return ok && !info.Prebuilt } func (b *compatConfigMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule { @@ -192,9 +186,8 @@ type compatConfigSdkMemberProperties struct { Metadata android.Path } -func (b *compatConfigSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { - module := variant.(*platformCompatConfig) - b.Metadata = module.metadataFile +func (b *compatConfigSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.ModuleProxy) { + b.Metadata = android.OtherModuleProviderOrDefault(ctx.SdkModuleContext(), variant, PlatformCompatConfigInfoProvider).CompatConfigMetadata } func (b *compatConfigSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { @@ -252,9 +245,10 @@ var _ platformCompatConfigMetadataProvider = (*prebuiltCompatConfigModule)(nil) func (module *prebuiltCompatConfigModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { module.metadataFile = module.prebuilt.SingleSourcePath(ctx) - android.SetProvider(ctx, PlatformCompatConfigMetadataInfoProvider, PlatformCompatConfigMetadataInfo{ + android.SetProvider(ctx, PlatformCompatConfigInfoProvider, PlatformCompatConfigInfo{ CompatConfigMetadata: module.compatConfigMetadata(), IncludeInMergedXml: module.includeInMergedXml(), + Prebuilt: true, }) } @@ -280,7 +274,7 @@ func (p *platformCompatConfigSingleton) GenerateBuildActions(ctx android.Singlet if !android.OtherModulePointerProviderOrDefault(ctx, module, android.CommonModuleInfoProvider).Enabled { return } - if c, ok := android.OtherModuleProvider(ctx, module, PlatformCompatConfigMetadataInfoProvider); ok { + if c, ok := android.OtherModuleProvider(ctx, module, PlatformCompatConfigInfoProvider); ok { if !android.IsModulePreferredProxy(ctx, module) { return } diff --git a/java/sdk.go b/java/sdk.go index 73262dab3..187c36ec4 100644 --- a/java/sdk.go +++ b/java/sdk.go @@ -99,7 +99,7 @@ func systemModuleKind(sdkKind android.SdkKind, apiLevel android.ApiLevel) androi return systemModuleKind } -func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext android.SdkContext) sdkDep { +func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext SdkVersionContext) sdkDep { sdkVersion := sdkContext.SdkVersion(ctx) if !sdkVersion.Valid() { ctx.PropertyErrorf("sdk_version", "invalid version %q", sdkVersion.Raw) diff --git a/java/sdk_library.go b/java/sdk_library.go index 00ba8b2fb..10647d027 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -1022,6 +1022,12 @@ func (c *commonToSdkLibraryAndImport) generateCommonBuildActions(ctx android.Mod ExportableStubDexJarPaths: exportableStubPaths, RemovedTxtFiles: removedApiFilePaths, SharedLibrary: c.sharedLibrary(), + DoctagPaths: c.doctagPaths, + OnBootclasspathSince: c.commonSdkLibraryProperties.On_bootclasspath_since, + OnBootclasspathBefore: c.commonSdkLibraryProperties.On_bootclasspath_before, + MinDeviceSdk: c.commonSdkLibraryProperties.Min_device_sdk, + MaxDeviceSdk: c.commonSdkLibraryProperties.Max_device_sdk, + ImplLibProfileGuided: c.implLibraryInfo != nil && c.implLibraryInfo.ProfileGuided, } } @@ -1204,6 +1210,18 @@ var _ SdkLibraryComponentDependency = (*Import)(nil) var _ SdkLibraryComponentDependency = (*SdkLibrary)(nil) var _ SdkLibraryComponentDependency = (*SdkLibraryImport)(nil) +type ApiScopePathsInfo struct { + StubsImplPath android.Paths + CurrentApiFilePath android.OptionalPath + RemovedApiFilePath android.OptionalPath + StubsSrcJar android.OptionalPath + AnnotationsZip android.OptionalPath +} + +type ApiScopePropsInfo struct { + SdkVersion *string +} + type SdkLibraryInfo struct { // GeneratingLibs is the names of the library modules that this sdk library // generates. Note that this only includes the name of the modules that other modules can @@ -1224,7 +1242,16 @@ type SdkLibraryInfo struct { // Whether if this can be used as a shared library. SharedLibrary bool - Prebuilt bool + Prebuilt bool + DistStem string + DoctagPaths android.Paths + OnBootclasspathSince *string + OnBootclasspathBefore *string + MinDeviceSdk *string + MaxDeviceSdk *string + ImplLibProfileGuided bool + ApiScopePaths map[string]ApiScopePathsInfo + ApiScopeProps map[string]ApiScopePropsInfo } var SdkLibraryInfoProvider = blueprint.NewProvider[SdkLibraryInfo]() @@ -1582,13 +1609,39 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) javaInfo := &JavaInfo{ JacocoReportClassesFile: module.jacocoReportClassesFile, + CompileDex: module.dexProperties.Compile_dex, } setExtraJavaInfo(ctx, ctx.Module(), javaInfo) android.SetProvider(ctx, JavaInfoProvider, javaInfo) sdkLibInfo.GeneratingLibs = generatingLibs sdkLibInfo.Prebuilt = false + sdkLibInfo.DistStem = module.distStem() + if module.scopePaths != nil { + sdkLibInfo.ApiScopePaths = make(map[string]ApiScopePathsInfo) + for k, v := range module.scopePaths { + sdkLibInfo.ApiScopePaths[k.name] = ApiScopePathsInfo{ + StubsImplPath: v.stubsImplPath, + CurrentApiFilePath: v.currentApiFilePath, + RemovedApiFilePath: v.removedApiFilePath, + StubsSrcJar: v.stubsSrcJar, + AnnotationsZip: v.annotationsZip, + } + } + } + if module.scopeToProperties != nil { + sdkLibInfo.ApiScopeProps = make(map[string]ApiScopePropsInfo) + for k, v := range module.scopeToProperties { + sdkLibInfo.ApiScopeProps[k.name] = ApiScopePropsInfo{ + SdkVersion: v.Sdk_version, + } + } + } android.SetProvider(ctx, SdkLibraryInfoProvider, sdkLibInfo) + + android.SetProvider(ctx, JavaLibraryInfoProvider, JavaLibraryInfo{ + PermittedPackages: module.PermittedPackagesForUpdatableBootJars(), + }) } func setOutputFilesFromJavaInfo(ctx android.ModuleContext, info *JavaInfo) { @@ -1630,12 +1683,17 @@ func (module *SdkLibrary) apiDistPath(apiScope *apiScope) string { // Get the sdk version for use when compiling the stubs library. func (module *SdkLibrary) sdkVersionForStubsLibrary(mctx android.EarlyModuleContext, apiScope *apiScope) string { - scopeProperties := module.scopeToProperties[apiScope] - if scopeProperties.Sdk_version != nil { - return proptools.String(scopeProperties.Sdk_version) + return getSdkVersionForStubsLibrary(mctx, apiScope, module.scopeToProperties[apiScope].Sdk_version, + android.SdkContext(&module.Library)) +} + +func getSdkVersionForStubsLibrary(mctx android.EarlyModuleContext, apiScope *apiScope, + sdkVersion *string, sdkContext SdkVersionContext) string { + if sdkVersion != nil { + return proptools.String(sdkVersion) } - sdkDep := decodeSdkDep(mctx, android.SdkContext(&module.Library)) + sdkDep := decodeSdkDep(mctx, sdkContext) if sdkDep.hasStandardLibs() { // If building against a standard sdk then use the sdk version appropriate for the scope. return apiScope.sdkVersion @@ -2341,9 +2399,9 @@ func (s *sdkLibrarySdkMemberType) AddDependencies(ctx android.SdkDependencyConte ctx.AddVariationDependencies(nil, dependencyTag, names...) } -func (s *sdkLibrarySdkMemberType) IsInstance(module android.Module) bool { - _, ok := module.(*SdkLibrary) - return ok +func (s *sdkLibrarySdkMemberType) IsInstance(ctx android.ModuleContext, module android.ModuleProxy) bool { + info, ok := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider) + return ok && !info.Prebuilt } func (s *sdkLibrarySdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule { @@ -2436,49 +2494,70 @@ type scopeProperties struct { SdkVersion string } -func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { - sdk := variant.(*SdkLibrary) +type SdkVersionContext interface { + SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec + SystemModules() string +} + +type SdkVersionContextProviderImpl struct { + javaInfo *JavaInfo +} + +func (s *SdkVersionContextProviderImpl) SdkVersion(_ android.EarlyModuleContext) android.SdkSpec { + return s.javaInfo.SdkVersion +} +func (s *SdkVersionContextProviderImpl) SystemModules() string { + return s.javaInfo.SystemModules +} + +func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.ModuleProxy) { + mctx := ctx.SdkModuleContext() + javaInfo := android.OtherModulePointerProviderOrDefault(mctx, variant, JavaInfoProvider) + libraryInfo := android.OtherModuleProviderOrDefault(mctx, variant, JavaLibraryInfoProvider) + sdkInfo := android.OtherModuleProviderOrDefault(mctx, variant, SdkLibraryInfoProvider) // Copy the stem name for files in the sdk snapshot. - s.Stem = sdk.distStem() + s.Stem = sdkInfo.DistStem s.Scopes = make(map[*apiScope]*scopeProperties) for _, apiScope := range AllApiScopes { - paths := sdk.findScopePaths(apiScope) - if paths == nil { + paths, ok := sdkInfo.ApiScopePaths[apiScope.name] + if !ok { continue } - jars := paths.stubsImplPath + jars := paths.StubsImplPath if len(jars) > 0 { properties := scopeProperties{} properties.Jars = jars - properties.SdkVersion = sdk.sdkVersionForStubsLibrary(ctx.SdkModuleContext(), apiScope) - properties.StubsSrcJar = paths.stubsSrcJar.Path() - if paths.currentApiFilePath.Valid() { - properties.CurrentApiFile = paths.currentApiFilePath.Path() + properties.SdkVersion = getSdkVersionForStubsLibrary(mctx, apiScope, sdkInfo.ApiScopeProps[apiScope.name].SdkVersion, + &SdkVersionContextProviderImpl{javaInfo}) + + properties.StubsSrcJar = paths.StubsSrcJar.Path() + if paths.CurrentApiFilePath.Valid() { + properties.CurrentApiFile = paths.CurrentApiFilePath.Path() } - if paths.removedApiFilePath.Valid() { - properties.RemovedApiFile = paths.removedApiFilePath.Path() + if paths.RemovedApiFilePath.Valid() { + properties.RemovedApiFile = paths.RemovedApiFilePath.Path() } // The annotations zip is only available for modules that set annotations_enabled: true. - if paths.annotationsZip.Valid() { - properties.AnnotationsZip = paths.annotationsZip.Path() + if paths.AnnotationsZip.Valid() { + properties.AnnotationsZip = paths.AnnotationsZip.Path() } s.Scopes[apiScope] = &properties } } - s.Shared_library = proptools.BoolPtr(sdk.sharedLibrary()) - s.Compile_dex = sdk.dexProperties.Compile_dex - s.Doctag_paths = sdk.doctagPaths - s.Permitted_packages = sdk.PermittedPackagesForUpdatableBootJars() - s.On_bootclasspath_since = sdk.commonSdkLibraryProperties.On_bootclasspath_since - s.On_bootclasspath_before = sdk.commonSdkLibraryProperties.On_bootclasspath_before - s.Min_device_sdk = sdk.commonSdkLibraryProperties.Min_device_sdk - s.Max_device_sdk = sdk.commonSdkLibraryProperties.Max_device_sdk + s.Shared_library = proptools.BoolPtr(sdkInfo.SharedLibrary) + s.Compile_dex = javaInfo.CompileDex + s.Doctag_paths = sdkInfo.DoctagPaths + s.Permitted_packages = libraryInfo.PermittedPackages + s.On_bootclasspath_since = sdkInfo.OnBootclasspathSince + s.On_bootclasspath_before = sdkInfo.OnBootclasspathBefore + s.Min_device_sdk = sdkInfo.MinDeviceSdk + s.Max_device_sdk = sdkInfo.MaxDeviceSdk - if sdk.implLibraryInfo != nil && sdk.implLibraryInfo.ProfileGuided { + if sdkInfo.ImplLibProfileGuided { s.DexPreoptProfileGuided = proptools.BoolPtr(true) } } diff --git a/java/system_modules.go b/java/system_modules.go index e955aec15..0d64f37ac 100644 --- a/java/system_modules.go +++ b/java/system_modules.go @@ -131,6 +131,8 @@ type SystemModulesProviderInfo struct { // depset of header jars for this module and all transitive static dependencies TransitiveStaticLibsHeaderJars depset.DepSet[android.Path] + Prebuilt bool + Libs []string } var SystemModulesProvider = blueprint.NewProvider[*SystemModulesProviderInfo]() @@ -150,7 +152,17 @@ type SystemModulesProperties struct { Libs []string } +func (system *systemModulesImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { + info := system.commonBuildActions(ctx) + info.Prebuilt = true + android.SetProvider(ctx, SystemModulesProvider, info) +} + func (system *SystemModules) GenerateAndroidBuildActions(ctx android.ModuleContext) { + android.SetProvider(ctx, SystemModulesProvider, system.commonBuildActions(ctx)) +} + +func (system *SystemModules) commonBuildActions(ctx android.ModuleContext) *SystemModulesProviderInfo { var jars android.Paths var transitiveStaticLibsHeaderJars []depset.DepSet[android.Path] @@ -163,12 +175,13 @@ func (system *SystemModules) GenerateAndroidBuildActions(ctx android.ModuleConte system.outputDir, system.outputDeps = TransformJarsToSystemModules(ctx, jars) - android.SetProvider(ctx, SystemModulesProvider, &SystemModulesProviderInfo{ + return &SystemModulesProviderInfo{ HeaderJars: jars, OutputDir: system.outputDir, OutputDirDeps: system.outputDeps, TransitiveStaticLibsHeaderJars: depset.New(depset.PREORDER, nil, transitiveStaticLibsHeaderJars), - }) + Libs: system.properties.Libs, + } } // ComponentDepsMutator is called before prebuilt modules without a corresponding source module are @@ -275,12 +288,11 @@ func (mt *systemModulesSdkMemberType) AddDependencies(ctx android.SdkDependencyC ctx.AddVariationDependencies(nil, dependencyTag, names...) } -func (mt *systemModulesSdkMemberType) IsInstance(module android.Module) bool { - if _, ok := module.(*SystemModules); ok { +func (mt *systemModulesSdkMemberType) IsInstance(ctx android.ModuleContext, module android.ModuleProxy) bool { + if info, ok := android.OtherModuleProvider(ctx, module, SystemModulesProvider); ok { // A prebuilt system module cannot be added as a member of an sdk because the source and // snapshot instances would conflict. - _, ok := module.(*systemModulesImport) - return !ok + return !info.Prebuilt } return false } @@ -299,9 +311,8 @@ func (mt *systemModulesSdkMemberType) CreateVariantPropertiesStruct() android.Sd return &systemModulesInfoProperties{} } -func (p *systemModulesInfoProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { - systemModule := variant.(*SystemModules) - p.Libs = systemModule.properties.Libs +func (p *systemModulesInfoProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.ModuleProxy) { + p.Libs = android.OtherModulePointerProviderOrDefault(ctx.SdkModuleContext(), variant, SystemModulesProvider).Libs } func (p *systemModulesInfoProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { diff --git a/java/systemserver_classpath_fragment.go b/java/systemserver_classpath_fragment.go index a60f6b82c..d745afc79 100644 --- a/java/systemserver_classpath_fragment.go +++ b/java/systemserver_classpath_fragment.go @@ -97,6 +97,13 @@ type SystemServerClasspathModule struct { var _ android.ApexModule = (*SystemServerClasspathModule)(nil) +type SystemServerClasspathInfo struct { + Contents []string + StandaloneContents []string +} + +var SystemServerClasspathInfoProvider = blueprint.NewProvider[SystemServerClasspathInfo]() + func (m *SystemServerClasspathModule) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel { return android.MinApiLevel } @@ -139,6 +146,11 @@ func (s *SystemServerClasspathModule) GenerateAndroidBuildActions(ctx android.Mo classpathJars = append(classpathJars, standaloneClasspathJars...) s.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, configuredJars, classpathJars) s.setPartitionInfoOfLibraries(ctx) + + android.SetProvider(ctx, SystemServerClasspathInfoProvider, SystemServerClasspathInfo{ + Contents: s.properties.Contents.GetOrDefault(ctx, nil), + StandaloneContents: s.properties.Standalone_contents.GetOrDefault(ctx, nil), + }) } // Map of java library name to their install partition. @@ -214,10 +226,10 @@ func (systemServerClasspathFragmentContentDependencyTag) ReplaceSourceWithPrebui // SdkMemberType causes dependencies added with this tag to be automatically added to the sdk as if // they were specified using java_systemserver_libs or java_sdk_libs. -func (b systemServerClasspathFragmentContentDependencyTag) SdkMemberType(child android.Module) android.SdkMemberType { +func (b systemServerClasspathFragmentContentDependencyTag) SdkMemberType(ctx android.ModuleContext, child android.ModuleProxy) android.SdkMemberType { // If the module is a java_sdk_library then treat it as if it was specified in the java_sdk_libs // property, otherwise treat if it was specified in the java_systemserver_libs property. - if javaSdkLibrarySdkMemberType.IsInstance(child) { + if javaSdkLibrarySdkMemberType.IsInstance(ctx, child) { return javaSdkLibrarySdkMemberType } @@ -278,8 +290,8 @@ func (s *systemServerClasspathFragmentMemberType) AddDependencies(ctx android.Sd ctx.AddVariationDependencies(nil, dependencyTag, names...) } -func (s *systemServerClasspathFragmentMemberType) IsInstance(module android.Module) bool { - _, ok := module.(*SystemServerClasspathModule) +func (s *systemServerClasspathFragmentMemberType) IsInstance(ctx android.ModuleContext, module android.ModuleProxy) bool { + _, ok := android.OtherModuleProvider(ctx, module, SystemServerClasspathInfoProvider) return ok } @@ -305,11 +317,11 @@ type systemServerClasspathFragmentSdkMemberProperties struct { Standalone_contents []string } -func (s *systemServerClasspathFragmentSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { - module := variant.(*SystemServerClasspathModule) +func (s *systemServerClasspathFragmentSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.ModuleProxy) { + module := android.OtherModuleProviderOrDefault(ctx.SdkModuleContext(), variant, SystemServerClasspathInfoProvider) - s.Contents = module.properties.Contents.GetOrDefault(ctx.SdkModuleContext(), nil) - s.Standalone_contents = module.properties.Standalone_contents.GetOrDefault(ctx.SdkModuleContext(), nil) + s.Contents = module.Contents + s.Standalone_contents = module.StandaloneContents } func (s *systemServerClasspathFragmentSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { diff --git a/sdk/member_trait_test.go b/sdk/member_trait_test.go index 9b41e9b7a..6bcc5b110 100644 --- a/sdk/member_trait_test.go +++ b/sdk/member_trait_test.go @@ -45,7 +45,7 @@ func (t *fakeMemberType) AddDependencies(ctx android.SdkDependencyContext, depen } } -func (t *fakeMemberType) IsInstance(module android.Module) bool { +func (t *fakeMemberType) IsInstance(_ android.ModuleContext, _ android.ModuleProxy) bool { return true } @@ -67,8 +67,8 @@ type fakeMemberTypeProperties struct { path android.Path } -func (t *fakeMemberTypeProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { - headerJars := variant.(java.ApexDependency).HeaderJars() +func (t *fakeMemberTypeProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.ModuleProxy) { + headerJars := android.OtherModulePointerProviderOrDefault(ctx.SdkModuleContext(), variant, java.JavaInfoProvider).HeaderJars if len(headerJars) != 1 { panic(fmt.Errorf("there must be only one header jar from %q", variant.Name())) } diff --git a/sdk/update.go b/sdk/update.go index 00352cb1d..684598270 100644 --- a/sdk/update.go +++ b/sdk/update.go @@ -115,10 +115,10 @@ func (gc *generatedContents) UnindentedPrintf(format string, args ...interface{} // multilibs (32/64/both) are used by this sdk variant. func (s *sdk) collectMembers(ctx android.ModuleContext) { s.multilibUsages = multilibNone - ctx.WalkDeps(func(child android.Module, parent android.Module) bool { + ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool { tag := ctx.OtherModuleDependencyTag(child) if memberTag, ok := tag.(android.SdkMemberDependencyTag); ok { - memberType := memberTag.SdkMemberType(child) + memberType := memberTag.SdkMemberType(ctx, child) // If a nil SdkMemberType was returned then this module should not be added to the sdk. if memberType == nil { @@ -126,32 +126,31 @@ func (s *sdk) collectMembers(ctx android.ModuleContext) { } // Make sure that the resolved module is allowed in the member list property. - if !memberType.IsInstance(child) { + if !memberType.IsInstance(ctx, child) { ctx.ModuleErrorf("module %q is not valid in property %s", ctx.OtherModuleName(child), memberType.SdkPropertyName()) } // Keep track of which multilib variants are used by the sdk. - s.multilibUsages = s.multilibUsages.addArchType(child.Target().Arch.ArchType) + commonInfo := android.OtherModulePointerProviderOrDefault(ctx, child, android.CommonModuleInfoProvider) + s.multilibUsages = s.multilibUsages.addArchType(commonInfo.Target.Arch.ArchType) exportedComponentsInfo, _ := android.OtherModuleProvider(ctx, child, android.ExportedComponentsInfoProvider) - var container android.Module - if parent != ctx.Module() { - container = parent - } - - minApiLevel := android.MinApiLevelForSdkSnapshot(ctx, child) - + minApiLevel := android.MinApiLevelForSdkSnapshot(commonInfo) export := memberTag.ExportMember() - s.memberVariantDeps = append(s.memberVariantDeps, sdkMemberVariantDep{ + vd := sdkMemberVariantDep{ sdkVariant: s, memberType: memberType, variant: child, minApiLevel: minApiLevel, - container: container, export: export, exportedComponentsInfo: exportedComponentsInfo, - }) + } + if !android.EqualModules(parent, ctx.Module()) { + container := parent + vd.container = &container + } + s.memberVariantDeps = append(s.memberVariantDeps, vd) // Recurse down into the member's dependencies as it may have dependencies that need to be // automatically added to the sdk. @@ -198,7 +197,7 @@ func (s *sdk) groupMemberVariantsByMemberThenType(ctx android.ModuleContext, tar if err != nil { targetApiLevel = android.FutureApiLevel } - if lastApiLevel, exists := ignoreHostModuleVariantsAboveDessert[name]; exists && targetApiLevel.GreaterThan(lastApiLevel) && memberVariantDep.Host() { + if lastApiLevel, exists := ignoreHostModuleVariantsAboveDessert[name]; exists && targetApiLevel.GreaterThan(lastApiLevel) && memberVariantDep.Host(ctx) { // ignore host variant of this module if the targetApiLevel is V and above. continue } @@ -255,7 +254,7 @@ func isMemberTypeSupportedByTargetBuildRelease(memberType android.SdkMemberType, return supportedByTargetBuildRelease } -func appendUniqueVariants(variants []android.Module, newVariant android.Module) []android.Module { +func appendUniqueVariants(variants []android.ModuleProxy, newVariant android.ModuleProxy) []android.ModuleProxy { for _, v := range variants { if v == newVariant { return variants @@ -346,7 +345,7 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext, sdkVariants []*sdk) { // Always include host variants (e.g. host tools) in the snapshot. // Host variants should not be guarded by a min_sdk_version check. In fact, host variants // do not have a `min_sdk_version`. - if memberVariantDep.Host() { + if memberVariantDep.Host(ctx) { exclude = false } @@ -623,7 +622,7 @@ func (s *sdk) generateInfoData(ctx android.ModuleContext, memberVariantDeps []sd modules = append(modules, &sdkInfo) name2Info := map[string]*moduleInfo{} - getModuleInfo := func(module android.Module) *moduleInfo { + getModuleInfo := func(module android.ModuleProxy) *moduleInfo { name := module.Name() info := name2Info[name] if info == nil { @@ -655,7 +654,7 @@ func (s *sdk) generateInfoData(ctx android.ModuleContext, memberVariantDeps []sd sdkInfo.memberSpecific[propertyName] = android.SortedUniqueStrings(list) if memberVariantDep.container != nil { - containerInfo := getModuleInfo(memberVariantDep.container) + containerInfo := getModuleInfo(*memberVariantDep.container) containerInfo.deps = android.SortedUniqueStrings(append(containerInfo.deps, memberName)) } @@ -1129,8 +1128,8 @@ func (s *snapshotBuilder) AddPrebuiltModule(member android.SdkMember, moduleType } // Where available copy apex_available properties from the member. - if apexAware, ok := variant.(interface{ ApexAvailable() []string }); ok { - apexAvailable := apexAware.ApexAvailable() + if info, ok := android.OtherModuleProvider(s.ctx, variant, android.CommonModuleInfoProvider); ok && info.IsApexModule { + apexAvailable := info.ApexAvailable if len(apexAvailable) == 0 { // //apex_available:platform is the default. apexAvailable = []string{android.AvailableToPlatform} @@ -1154,7 +1153,7 @@ func (s *snapshotBuilder) AddPrebuiltModule(member android.SdkMember, moduleType hostSupported := false for _, variant := range member.Variants() { - osClass := variant.Target().Os.Class + osClass := android.OtherModulePointerProviderOrDefault(mctx, variant, android.CommonModuleInfoProvider).Target.Os.Class if osClass == android.Host { hostSupported = true } else if osClass == android.Device { @@ -1250,12 +1249,12 @@ type sdkMemberVariantDep struct { memberType android.SdkMemberType // The variant that is added to the sdk. - variant android.Module + variant android.ModuleProxy // The optional container of this member, i.e. the module that is depended upon by the sdk // (possibly transitively) and whose dependency on this module is why it was added to the sdk. // Is nil if this a direct dependency of the sdk. - container android.Module + container *android.ModuleProxy // True if the member should be exported, i.e. accessible, from outside the sdk. export bool @@ -1268,8 +1267,8 @@ type sdkMemberVariantDep struct { } // Host returns true if the sdk member is a host variant (e.g. host tool) -func (s *sdkMemberVariantDep) Host() bool { - return s.variant.Target().Os.Class == android.Host +func (s *sdkMemberVariantDep) Host(ctx android.ModuleContext) bool { + return android.OtherModulePointerProviderOrDefault(ctx, s.variant, android.CommonModuleInfoProvider).Host } var _ android.SdkMember = (*sdkMember)(nil) @@ -1279,14 +1278,14 @@ var _ android.SdkMember = (*sdkMember)(nil) type sdkMember struct { memberType android.SdkMemberType name string - variants []android.Module + variants []android.ModuleProxy } func (m *sdkMember) Name() string { return m.name } -func (m *sdkMember) Variants() []android.Module { +func (m *sdkMember) Variants() []android.ModuleProxy { return m.variants } @@ -1344,15 +1343,16 @@ type variantCoordinate struct { linkType string } -func getVariantCoordinate(ctx *memberContext, variant android.Module) variantCoordinate { +func getVariantCoordinate(ctx *memberContext, variant android.ModuleProxy) variantCoordinate { linkType := "" if len(ctx.MemberType().SupportedLinkages()) > 0 { - linkType = getLinkType(variant) + linkType = getLinkType(ctx.sdkMemberContext, variant) } + info := android.OtherModulePointerProviderOrDefault(ctx.SdkModuleContext(), variant, android.CommonModuleInfoProvider) return variantCoordinate{ - osType: variant.Target().Os, - archId: archIdFromTarget(variant.Target()), - image: variant.ImageVariation().Variation, + osType: info.Target.Os, + archId: archIdFromTarget(info.Target), + image: info.ImageVariation.Variation, linkType: linkType, } } @@ -1371,24 +1371,24 @@ func getVariantCoordinate(ctx *memberContext, variant android.Module) variantCoo // by apex variant, where one is the default/platform variant and one is the APEX variant. In that // case it picks the APEX variant. It picks the APEX variant because that is the behavior that would // be expected -func selectApexVariantsWhereAvailable(ctx *memberContext, variants []android.Module) []android.Module { +func selectApexVariantsWhereAvailable(ctx *memberContext, variants []android.ModuleProxy) []android.ModuleProxy { moduleCtx := ctx.sdkMemberContext // Group the variants by coordinates. - variantsByCoord := make(map[variantCoordinate][]android.Module) + variantsByCoord := make(map[variantCoordinate][]android.ModuleProxy) for _, variant := range variants { coord := getVariantCoordinate(ctx, variant) variantsByCoord[coord] = append(variantsByCoord[coord], variant) } - toDiscard := make(map[android.Module]struct{}) + toDiscard := make(map[android.ModuleProxy]struct{}) for coord, list := range variantsByCoord { count := len(list) if count == 1 { continue } - variantsByApex := make(map[string]android.Module) + variantsByApex := make(map[string]android.ModuleProxy) conflictDetected := false for _, variant := range list { apexInfo, _ := android.OtherModuleProvider(moduleCtx, variant, android.ApexInfoProvider) @@ -1430,7 +1430,7 @@ func selectApexVariantsWhereAvailable(ctx *memberContext, variants []android.Mod // If there are any variants to discard then remove them from the list of variants, while // preserving the order. if len(toDiscard) > 0 { - filtered := []android.Module{} + filtered := []android.ModuleProxy{} for _, variant := range variants { if _, ok := toDiscard[variant]; !ok { filtered = append(filtered, variant) @@ -1469,7 +1469,7 @@ type variantPropertiesFactoryFunc func() android.SdkMemberProperties // Create a new osTypeSpecificInfo for the specified os type and its properties // structures populated with information from the variants. -func newOsTypeSpecificInfo(ctx android.SdkMemberContext, osType android.OsType, variantPropertiesFactory variantPropertiesFactoryFunc, osTypeVariants []android.Module) *osTypeSpecificInfo { +func newOsTypeSpecificInfo(ctx android.SdkMemberContext, osType android.OsType, variantPropertiesFactory variantPropertiesFactoryFunc, osTypeVariants []android.ModuleProxy) *osTypeSpecificInfo { osInfo := &osTypeSpecificInfo{ osType: osType, } @@ -1485,10 +1485,10 @@ func newOsTypeSpecificInfo(ctx android.SdkMemberContext, osType android.OsType, osInfo.Properties = osSpecificVariantPropertiesFactory() // Group the variants by arch type. - var variantsByArchId = make(map[archId][]android.Module) + var variantsByArchId = make(map[archId][]android.ModuleProxy) var archIds []archId for _, variant := range osTypeVariants { - target := variant.Target() + target := android.OtherModulePointerProviderOrDefault(ctx.SdkModuleContext(), variant, android.CommonModuleInfoProvider).Target id := archIdFromTarget(target) if _, ok := variantsByArchId[id]; !ok { archIds = append(archIds, id) @@ -1695,7 +1695,7 @@ var _ propertiesContainer = (*archTypeSpecificInfo)(nil) // Create a new archTypeSpecificInfo for the specified arch type and its properties // structures populated with information from the variants. -func newArchSpecificInfo(ctx android.SdkMemberContext, archId archId, osType android.OsType, variantPropertiesFactory variantPropertiesFactoryFunc, archVariants []android.Module) *archTypeSpecificInfo { +func newArchSpecificInfo(ctx android.SdkMemberContext, archId archId, osType android.OsType, variantPropertiesFactory variantPropertiesFactoryFunc, archVariants []android.ModuleProxy) *archTypeSpecificInfo { // Create an arch specific info into which the variant properties can be copied. archInfo := &archTypeSpecificInfo{archId: archId, osType: osType} @@ -1710,9 +1710,9 @@ func newArchSpecificInfo(ctx android.SdkMemberContext, archId archId, osType and archInfo.Properties.PopulateFromVariant(ctx, archVariants[0]) } else { // Group the variants by image type. - variantsByImage := make(map[string][]android.Module) + variantsByImage := make(map[string][]android.ModuleProxy) for _, variant := range archVariants { - image := variant.ImageVariation().Variation + image := android.OtherModulePointerProviderOrDefault(ctx.SdkModuleContext(), variant, android.CommonModuleInfoProvider).ImageVariation.Variation variantsByImage[image] = append(variantsByImage[image], variant) } @@ -1730,14 +1730,14 @@ func newArchSpecificInfo(ctx android.SdkMemberContext, archId archId, osType and // // If the variant is not differentiated by link type then it returns "", // otherwise it returns one of "static" or "shared". -func getLinkType(variant android.Module) string { +func getLinkType(ctx android.ModuleContext, variant android.ModuleProxy) string { linkType := "" - if linkable, ok := variant.(cc.LinkableInterface); ok { - if linkable.Shared() && linkable.Static() { + if linkable, ok := android.OtherModuleProvider(ctx, variant, cc.LinkableInfoProvider); ok { + if linkable.Shared && linkable.Static { panic(fmt.Errorf("expected variant %q to be either static or shared but was both", variant.String())) - } else if linkable.Shared() { + } else if linkable.Shared { linkType = "shared" - } else if linkable.Static() { + } else if linkable.Static { linkType = "static" } else { panic(fmt.Errorf("expected variant %q to be either static or shared but was neither", variant.String())) @@ -1825,7 +1825,7 @@ type imageVariantSpecificInfo struct { linkInfos []*linkTypeSpecificInfo } -func newImageVariantSpecificInfo(ctx android.SdkMemberContext, imageVariant string, variantPropertiesFactory variantPropertiesFactoryFunc, imageVariants []android.Module) *imageVariantSpecificInfo { +func newImageVariantSpecificInfo(ctx android.SdkMemberContext, imageVariant string, variantPropertiesFactory variantPropertiesFactoryFunc, imageVariants []android.ModuleProxy) *imageVariantSpecificInfo { // Create an image variant specific info into which the variant properties can be copied. imageInfo := &imageVariantSpecificInfo{imageVariant: imageVariant} @@ -1841,7 +1841,7 @@ func newImageVariantSpecificInfo(ctx android.SdkMemberContext, imageVariant stri // There is more than one variant for this image variant which must be differentiated by link // type. Or there are multiple supported linkages and we need to nest based on link type. for _, linkVariant := range imageVariants { - linkType := getLinkType(linkVariant) + linkType := getLinkType(ctx.SdkModuleContext(), linkVariant) if linkType == "" { panic(fmt.Errorf("expected one arch specific variant as it is not identified by link type but found %d", len(imageVariants))) } else { @@ -1925,7 +1925,7 @@ var _ propertiesContainer = (*linkTypeSpecificInfo)(nil) // Create a new linkTypeSpecificInfo for the specified link type and its properties // structures populated with information from the variant. -func newLinkSpecificInfo(ctx android.SdkMemberContext, linkType string, variantPropertiesFactory variantPropertiesFactoryFunc, linkVariant android.Module) *linkTypeSpecificInfo { +func newLinkSpecificInfo(ctx android.SdkMemberContext, linkType string, variantPropertiesFactory variantPropertiesFactoryFunc, linkVariant android.ModuleProxy) *linkTypeSpecificInfo { linkInfo := &linkTypeSpecificInfo{ baseInfo: baseInfo{ // Create the properties into which the link type specific properties will be @@ -2008,9 +2008,10 @@ func (s *sdk) createMemberSnapshot(ctx *memberContext, member *sdkMember, bpModu variants := selectApexVariantsWhereAvailable(ctx, member.variants) // Group the variants by os type. - variantsByOsType := make(map[android.OsType][]android.Module) + variantsByOsType := make(map[android.OsType][]android.ModuleProxy) for _, variant := range variants { - osType := variant.Target().Os + osType := android.OtherModulePointerProviderOrDefault( + ctx.SdkModuleContext(), variant, android.CommonModuleInfoProvider).Target.Os variantsByOsType[osType] = append(variantsByOsType[osType], variant) } -- cgit v1.2.3 From f52ba6e6fcc191df99427e163ea20e17fa8c4bf2 Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Mon, 31 Mar 2025 11:07:49 -0700 Subject: Dist symbols.zip file in test_package module type This change collects the test modules that are built when building test_package module and utilizes the `android.BuildSymbolsZip` api introduced in ag/32774321 to generate the per test suite symbols.zip file and the merged elf mapping proto file. Test: m continuous_native_tests_soong dist Test: CI Bug: 407562438 Change-Id: I68975b6582b2a3006465102d65696231ea75a47f --- ci_tests/ci_test_package_zip.go | 53 +++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/ci_tests/ci_test_package_zip.go b/ci_tests/ci_test_package_zip.go index bee8e9d2f..5ec1012d2 100644 --- a/ci_tests/ci_test_package_zip.go +++ b/ci_tests/ci_test_package_zip.go @@ -15,8 +15,10 @@ package ci_tests import ( + "cmp" "fmt" "path/filepath" + "slices" "strings" "android/soong/android" @@ -159,33 +161,49 @@ func (p *testPackageZip) GenerateAndroidBuildActions(ctx android.ModuleContext) ctx.SetOutputFiles(android.Paths{p.output}, "") } -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) +func getAllTestModules(ctx android.ModuleContext) []android.Module { + var ret []android.Module ctx.WalkDeps(func(child, parent android.Module) bool { if !child.Enabled(ctx) { return false } if android.EqualModules(parent, ctx.Module()) && ctx.OtherModuleDependencyTag(child) == testPackageZipDepTag { // handle direct deps - extendBuilderCommand(ctx, child, builder, stagingDir, productOut, arch, secondArch) + ret = append(ret, child) return true } else if !android.EqualModules(parent, ctx.Module()) && ctx.OtherModuleDependencyTag(child) == android.RequiredDepTag { // handle the "required" from deps - extendBuilderCommand(ctx, child, builder, stagingDir, productOut, arch, secondArch) + ret = append(ret, child) return true } else { return false } }) + ret = android.FirstUniqueInPlace(ret) + slices.SortFunc(ret, func(a, b android.Module) int { + return cmp.Compare(a.String(), b.String()) + }) + return ret +} + +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) + + allTestModules := getAllTestModules(ctx) + for _, dep := range allTestModules { + extendBuilderCommand(ctx, dep, builder, stagingDir, productOut, arch, secondArch) + } + + createSymbolsZip(ctx, allTestModules) output := android.PathForModuleOut(ctx, ctx.ModuleName()+".zip") builder.Command(). @@ -198,6 +216,15 @@ func createOutput(ctx android.ModuleContext, pctx android.PackageContext) androi return output } +func createSymbolsZip(ctx android.ModuleContext, allModules []android.Module) { + symbolsZipFile := android.PathForModuleOut(ctx, "symbols.zip") + symbolsMappingFile := android.PathForModuleOut(ctx, "symbols-mapping.textproto") + android.BuildSymbolsZip(ctx, allModules, symbolsZipFile, symbolsMappingFile) + + ctx.SetOutputFiles(android.Paths{symbolsZipFile}, ".symbols") + ctx.SetOutputFiles(android.Paths{symbolsMappingFile}, ".elf_mapping") +} + func extendBuilderCommand(ctx android.ModuleContext, m android.Module, builder *android.RuleBuilder, stagingDir android.ModuleOutPath, productOut, arch, secondArch string) { info, ok := android.OtherModuleProvider(ctx, m, android.ModuleInfoJSONProvider) if !ok { -- cgit v1.2.3 From e1263aece70f00c5d6f3826bab647dc8745e39ea Mon Sep 17 00:00:00 2001 From: Bill Yang Date: Tue, 1 Apr 2025 03:32:47 +0000 Subject: Introduce tests_if_exist_host attribute for test_packages Introdue a new attribute for test_packages to add tests for the host variant if exist. Bug: 399246722 Test: m dist continuous_instrumentation_tests Change-Id: Id5d8896437ec3ac6362ceae437bb14b9b8115b61 --- ci_tests/ci_test_package_zip.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ci_tests/ci_test_package_zip.go b/ci_tests/ci_test_package_zip.go index bee8e9d2f..e481bbac7 100644 --- a/ci_tests/ci_test_package_zip.go +++ b/ci_tests/ci_test_package_zip.go @@ -58,6 +58,8 @@ type CITestPackageProperties struct { Tests_if_exist_device_both proptools.Configurable[[]string] `android:"arch_variant"` // git-main only test modules. Will only be added as dependencies based on the first supported arch variant and the device os variant if exists. Tests_if_exist_device_first proptools.Configurable[[]string] `android:"arch_variant"` + // git-main only test modules. Will only be added as dependencies based on host if exists. + Tests_if_exist_host proptools.Configurable[[]string] `android:"arch_variant"` } type testPackageZipDepTagType struct { @@ -91,6 +93,12 @@ func (p *testPackageZip) DepsMutator(ctx android.BottomUpMutatorContext) { for _, t := range p.properties.Host_tests.GetOrDefault(ctx, nil) { ctx.AddVariationDependencies(ctx.Config().BuildOSTarget.Variations(), testPackageZipDepTag, t) } + // adding Tests_if_exist_host property deps + for _, t := range p.properties.Tests_if_exist_host.GetOrDefault(ctx, nil) { + if ctx.OtherModuleExists(t) { + 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) { -- cgit v1.2.3 From 99f38199f6ec45824c5dfb66047dca56c41dfe73 Mon Sep 17 00:00:00 2001 From: Wei Li Date: Mon, 31 Mar 2025 23:59:38 -0700 Subject: Use InstallFile instead PackageFile so the installed files could be reported properly Bug: 398039178 Test: presubmits Change-Id: Ib5ae3b6aab88b79ac1015dac285a6e8246ed80b3 --- bpf/bpf.go | 10 ++++++---- bpf/libbpf/libbpf_prog.go | 9 ++++++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/bpf/bpf.go b/bpf/bpf.go index deb465dd6..f57dff0f1 100644 --- a/bpf/bpf.go +++ b/bpf/bpf.go @@ -110,7 +110,8 @@ type bpf struct { android.DefaultableModuleBase properties BpfProperties - objs android.Paths + objs android.Paths + installDir android.InstallPath } var _ android.ImageInterface = (*bpf)(nil) @@ -228,12 +229,12 @@ func (bpf *bpf) GenerateAndroidBuildActions(ctx android.ModuleContext) { } - installDir := android.PathForModuleInstall(ctx, "etc", "bpf") + bpf.installDir = android.PathForModuleInstall(ctx, "etc", "bpf") if len(bpf.properties.Sub_dir) > 0 { - installDir = installDir.Join(ctx, bpf.properties.Sub_dir) + bpf.installDir = bpf.installDir.Join(ctx, bpf.properties.Sub_dir) } for _, obj := range bpf.objs { - ctx.PackageFile(installDir, obj.Base(), obj) + ctx.InstallFile(bpf.installDir, obj.Base(), obj) } android.SetProvider(ctx, BpfInfoProvider, BpfInfo{ @@ -267,6 +268,7 @@ func (bpf *bpf) AndroidMk() android.AndroidMkData { fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", obj.String()) fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", obj.Base()) fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC") + fmt.Fprintln(w, "LOCAL_SOONG_INSTALLED_MODULE := ", filepath.Join(bpf.installDir.String(), obj.Base())) fmt.Fprintln(w, localModulePath) // AconfigUpdateAndroidMkData may have added elements to Extra. Process them here. for _, extra := range data.Extra { diff --git a/bpf/libbpf/libbpf_prog.go b/bpf/libbpf/libbpf_prog.go index 44013e5e3..f68bf3d34 100644 --- a/bpf/libbpf/libbpf_prog.go +++ b/bpf/libbpf/libbpf_prog.go @@ -17,6 +17,7 @@ package libbpf_prog import ( "fmt" "io" + "path/filepath" "runtime" "strings" @@ -100,6 +101,7 @@ type libbpfProg struct { android.DefaultableModuleBase properties LibbpfProgProperties objs android.Paths + installDir android.InstallPath } var _ android.ImageInterface = (*libbpfProg)(nil) @@ -231,12 +233,12 @@ func (libbpf *libbpfProg) GenerateAndroidBuildActions(ctx android.ModuleContext) libbpf.objs = append(libbpf.objs, objStripped.WithoutRel()) } - installDir := android.PathForModuleInstall(ctx, "etc", "bpf") + libbpf.installDir = android.PathForModuleInstall(ctx, "etc", "bpf") if len(libbpf.properties.Relative_install_path) > 0 { - installDir = installDir.Join(ctx, libbpf.properties.Relative_install_path) + libbpf.installDir = libbpf.installDir.Join(ctx, libbpf.properties.Relative_install_path) } for _, obj := range libbpf.objs { - ctx.PackageFile(installDir, obj.Base(), obj) + ctx.InstallFile(libbpf.installDir, obj.Base(), obj) } ctx.SetOutputFiles(libbpf.objs, "") @@ -262,6 +264,7 @@ func (libbpf *libbpfProg) AndroidMk() android.AndroidMkData { fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", obj.String()) fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", obj.Base()) fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC") + fmt.Fprintln(w, "LOCAL_SOONG_INSTALLED_MODULE := ", filepath.Join(libbpf.installDir.String(), obj.Base())) fmt.Fprintln(w, localModulePath) // AconfigUpdateAndroidMkData may have added elements to Extra. Process them here. for _, extra := range data.Extra { -- cgit v1.2.3 From e6a0c71e0097e86d1ace7f32c1eaf457e0491ed2 Mon Sep 17 00:00:00 2001 From: Jooyung Han Date: Tue, 1 Apr 2025 16:03:19 +0900 Subject: apex.compressible should be used with system/updatable It doesn't make sense to compress non-updatable apexes. It will use more storage and processing time. Bug: 407670345 Flag: EXEMPT build-time checks Test: m --no-skip-soong-tests Change-Id: If12875239ee3fc8932d6112c6fc27966d0230336 --- apex/apex.go | 9 +++++++++ apex/apex_test.go | 43 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/apex/apex.go b/apex/apex.go index 1d41f61dc..2ca1ba3c5 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -1640,6 +1640,15 @@ func (f fsType) string() string { } func (a *apexBundle) setCompression(ctx android.ModuleContext) { + if a.isCompressable() { + if !a.Updatable() { + ctx.PropertyErrorf("compressible", "do not compress non-updatable APEX") + } + if a.PartitionTag(ctx.DeviceConfig()) != "system" { + ctx.PropertyErrorf("compressible", "do not compress non-system APEX") + } + } + if a.testOnlyShouldForceCompression() { a.isCompressed = true } else { diff --git a/apex/apex_test.go b/apex/apex_test.go index 327e018f4..dd17d7794 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -9260,7 +9260,8 @@ func TestCompressedApex(t *testing.T) { name: "myapex", key: "myapex.key", compressible: true, - updatable: false, + updatable: true, + min_sdk_version: "29", } apex_key { name: "myapex.key", @@ -9291,6 +9292,40 @@ func TestCompressedApex(t *testing.T) { ensureContains(t, androidMk, "LOCAL_MODULE_STEM := myapex.capex\n") } +func TestCompressedApex_NonUpdatable(t *testing.T) { + t.Parallel() + + testApexError(t, `do not compress non-updatable`, ` + apex { + name: "myapex", + key: "myapex.key", + compressible: true, + updatable: false, + } + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + `) + + testApexError(t, `do not compress non-system`, ` + apex { + name: "myapex", + key: "myapex.key", + compressible: true, + updatable: true, + min_sdk_version: "29", + vendor: true, + } + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + `) +} + func TestCompressedApexIsDisabledWhenUsingErofs(t *testing.T) { t.Parallel() ctx := testApex(t, ` @@ -9298,7 +9333,8 @@ func TestCompressedApexIsDisabledWhenUsingErofs(t *testing.T) { name: "myapex", key: "myapex.key", compressible: true, - updatable: false, + updatable: true, + min_sdk_version: "29", payload_fs_type: "erofs", } apex_key { @@ -9879,7 +9915,8 @@ func TestApexOutputFileProducer(t *testing.T) { name: "myapex", key: "myapex.key", compressible: true, - updatable: false, + updatable: true, + min_sdk_version: "29", } apex_key { -- cgit v1.2.3 From 6826ffb60a17663b6207ed3a3cfb68dea9f84a1a Mon Sep 17 00:00:00 2001 From: "Naresh Kumar Podishetty (xWF)" Date: Tue, 1 Apr 2025 01:25:49 -0700 Subject: Revert "add unit test for python shared_lib code" This reverts commit 682b98b8ec7784f6004686ff8e96f36652c4d31f. Reason for revert: Change-Id: Ic2336e652c6a9f11545c0568cf157c552d683ff6 --- python/python.go | 1 + python/python_test.go | 83 +-------------------------------------------------- 2 files changed, 2 insertions(+), 82 deletions(-) diff --git a/python/python.go b/python/python.go index f0f25f5ab..de21e39bd 100644 --- a/python/python.go +++ b/python/python.go @@ -108,6 +108,7 @@ type BaseProperties struct { // list of the Python libraries compatible both with Python2 and Python3. Libs []string `android:"arch_variant"` + // TODO: b/403060602 - add unit tests for this property and related code // list of shared libraries that should be packaged with the python code for this module. Shared_libs []string `android:"arch_variant"` diff --git a/python/python_test.go b/python/python_test.go index 21f6c1274..5f971cdd1 100644 --- a/python/python_test.go +++ b/python/python_test.go @@ -37,7 +37,7 @@ type pyModule struct { var ( buildNamePrefix = "soong_python_test" - moduleVariantErrTemplate = `%s: module %q variant "[a-zA-Z0-9_\-]*": ` + moduleVariantErrTemplate = `%s: module %q variant "[a-zA-Z0-9_]*": ` pkgPathErrTemplate = moduleVariantErrTemplate + "pkg_path: %q must be a relative path contained in par file." badIdentifierErrTemplate = moduleVariantErrTemplate + @@ -48,8 +48,6 @@ var ( " Second file: in module %s at path %q." badSrcFileExtErr = moduleVariantErrTemplate + `srcs: found non \(.py\|.proto\) file: %q!` badDataFileExtErr = moduleVariantErrTemplate + `data: found \(.py\) file: %q!` - sharedLibErrTemplate = moduleVariantErrTemplate + - "shared_libs: shared_libs is not supported for device builds" bpFile = "Android.bp" data = []struct { @@ -208,27 +206,6 @@ var ( "lib1", "dir/c/file1.py"), }, }, - { - desc: "device module with shared libs", - mockFiles: map[string][]byte{ - filepath.Join("dir", bpFile): []byte( - `python_library { - name: "lib1", - srcs: [ - "file1.py", - ], - shared_libs: [ - "clib1", - ], - }`, - ), - "dir/file1.py": nil, - }, - errors: []string{ - fmt.Sprintf(sharedLibErrTemplate, - "dir/Android.bp:6:18", "lib1"), - }, - }, } ) @@ -335,64 +312,6 @@ func TestInvalidTestOnlyTargets(t *testing.T) { } } -func TestSharedLib(t *testing.T) { - ctx := android.GroupFixturePreparers( - android.PrepareForTestWithDefaults, - android.PrepareForTestWithArchMutator, - android.PrepareForTestWithAllowMissingDependencies, - cc.PrepareForTestWithCcDefaultModules, - PrepareForTestWithPythonBuildComponents, - ).RunTestWithBp( - t, - `python_library_host { - name: "py-lib-host", - srcs: ["py-lib-host.py"], - shared_libs: ["clib-host"], - } - - cc_library_shared { - name: "clib-host", - host_supported: true, - shared_libs: ["clib-host-2"], - } - - cc_library_shared { - name: "clib-host-2", - host_supported: true, - }`, - ) - if len(ctx.Errs) > 0 { - t.Errorf("Expected got: %s, want: 0 errs", ctx.Errs) - } - - mod, modOk := ctx.ModuleForTests(t, "py-lib-host", "linux_glibc_x86_64").Module().(*PythonLibraryModule) - if !modOk { - t.Fatalf("py-lib-host is not Python library!") - } - // ensure the shared lib is included in the data path mappings - dataPathMappings := mod.getDataPathMappings() - if len(dataPathMappings) != 1 { - t.Fatalf("expected 1 data file, got: %d", len(dataPathMappings)) - } - android.AssertStringMatches( - t, - "data path included shared lib", - "clib-host.so", - dataPathMappings[0].dest, - ) - // ensure any dependencies of the shared lib are included in the bundle shared - // libs - android.AssertPathsEndWith( - t, - "shared libs", - []string{ - "clib-host-2.so", - "libc++.so", - }, - mod.getBundleSharedLibs(), - ) -} - func expectModule(t *testing.T, ctx *android.TestContext, name, variant, expectedSrcsZip string, expectedPyRunfiles []string) { module := ctx.ModuleForTests(t, name, variant) -- cgit v1.2.3 From 090b2538f66b4c8707c0f344d875a1bb41502c25 Mon Sep 17 00:00:00 2001 From: LaMont Jones Date: Fri, 28 Mar 2025 18:30:04 -0700 Subject: release_config: better validation of protobuf fields Improperly formed protobuf files should generate helpful errors instead of panicking. Bug: b/407736539 Test: Manual, TH Change-Id: I26a71861ef8f450613a4a8137059e9bc547f8215 --- cmd/release_config/build_flag_declarations/main.go | 5 +- .../release_config_lib/flag_artifact.go | 12 ++- .../release_config_lib/flag_declaration.go | 30 +++++- .../release_config_lib/flag_value.go | 22 +++- .../release_config_lib/flag_value_test.go | 24 ++++- .../release_config_lib/release_configs.go | 116 +++++++++++---------- 6 files changed, 137 insertions(+), 72 deletions(-) diff --git a/cmd/release_config/build_flag_declarations/main.go b/cmd/release_config/build_flag_declarations/main.go index cc286b6a9..f1716bb7e 100644 --- a/cmd/release_config/build_flag_declarations/main.go +++ b/cmd/release_config/build_flag_declarations/main.go @@ -69,7 +69,10 @@ func main() { intermediates = append(intermediates, fda) } for _, decl := range flags.decls { - fa := rc_lib.FlagArtifactFactory(decl) + fa, err := rc_lib.FlagArtifactFactory(decl) + if err != nil { + errorExit(err) + } (*flagArtifacts)[*fa.FlagDeclaration.Name] = fa } diff --git a/cmd/release_config/release_config_lib/flag_artifact.go b/cmd/release_config/release_config_lib/flag_artifact.go index f493e1e06..6e278eb95 100644 --- a/cmd/release_config/release_config_lib/flag_artifact.go +++ b/cmd/release_config/release_config_lib/flag_artifact.go @@ -47,19 +47,21 @@ type FlagArtifact struct { // Key is flag name. type FlagArtifacts map[string]*FlagArtifact -func FlagArtifactFactory(declPath string) *FlagArtifact { - fd := &rc_proto.FlagDeclaration{} - fa := &FlagArtifact{ +func FlagArtifactFactory(declPath string) (fa *FlagArtifact, err error) { + fd, err := FlagDeclarationFactory(declPath) + if err != nil { + return nil, err + } + fa = &FlagArtifact{ FlagDeclaration: fd, DeclarationIndex: -1, Traces: []*rc_proto.Tracepoint{}, } if declPath != "" { - LoadMessage(declPath, fd) fa.Value = fd.GetValue() fa.Traces = append(fa.Traces, &rc_proto.Tracepoint{Source: proto.String(declPath), Value: fa.Value}) } - return fa + return fa, nil } func FlagArtifactsFactory(artifactsPath string) *FlagArtifacts { diff --git a/cmd/release_config/release_config_lib/flag_declaration.go b/cmd/release_config/release_config_lib/flag_declaration.go index 22001bf09..d06d7efb9 100644 --- a/cmd/release_config/release_config_lib/flag_declaration.go +++ b/cmd/release_config/release_config_lib/flag_declaration.go @@ -15,6 +15,9 @@ package release_config_lib import ( + "fmt" + "path/filepath" + rc_proto "android/soong/cmd/release_config/release_config_proto" ) @@ -25,14 +28,33 @@ var ( DuplicateDeclarationAllowlist = map[string]bool{} ) -func FlagDeclarationFactory(protoPath string) (fd *rc_proto.FlagDeclaration) { +func FlagDeclarationFactory(protoPath string) (fd *rc_proto.FlagDeclaration, err error) { fd = &rc_proto.FlagDeclaration{} - if protoPath != "" { - LoadMessage(protoPath, fd) + if protoPath == "" { + return fd, nil + } + LoadMessage(protoPath, fd) + + switch { + case fd.Name == nil: + return nil, fmt.Errorf("Flag declaration %s does not specify name", protoPath) + case *fd.Name == "RELEASE_ACONFIG_VALUE_SETS": + return nil, fmt.Errorf("%s: %s is a reserved build flag", protoPath, *fd.Name) + case fmt.Sprintf("%s.textproto", *fd.Name) != filepath.Base(protoPath): + return nil, fmt.Errorf("%s incorrectly declares flag %s", protoPath, *fd.Name) + case fd.Namespace == nil: + return nil, fmt.Errorf("Flag declaration %s has no namespace.", protoPath) + case fd.Containers != nil: + for _, container := range fd.Containers { + if !validContainer(container) { + return nil, fmt.Errorf("Flag declaration %s has invalid container %s", protoPath, container) + } + } } + // If the input didn't specify a value, create one (== UnspecifiedValue). if fd.Value == nil { fd.Value = &rc_proto.Value{Val: &rc_proto.Value_UnspecifiedValue{false}} } - return fd + return fd, nil } diff --git a/cmd/release_config/release_config_lib/flag_value.go b/cmd/release_config/release_config_lib/flag_value.go index 76363cec4..f55fa3eda 100644 --- a/cmd/release_config/release_config_lib/flag_value.go +++ b/cmd/release_config/release_config_lib/flag_value.go @@ -15,6 +15,8 @@ package release_config_lib import ( + "fmt" + "path/filepath" "strings" rc_proto "android/soong/cmd/release_config/release_config_proto" @@ -28,12 +30,24 @@ type FlagValue struct { proto rc_proto.FlagValue } -func FlagValueFactory(protoPath string) (fv *FlagValue) { +func FlagValueFactory(protoPath string) (fv *FlagValue, err error) { fv = &FlagValue{path: protoPath} - if protoPath != "" { - LoadMessage(protoPath, &fv.proto) + if protoPath == "" { + return fv, nil } - return fv + LoadMessage(protoPath, &fv.proto) + + if fv.proto.Name == nil { + return nil, fmt.Errorf("%s does not set name", protoPath) + } + name := *fv.proto.Name + switch { + case name == "RELEASE_ACONFIG_VALUE_SETS": + return nil, fmt.Errorf("%s: %s is a reserved build flag", protoPath, name) + case fmt.Sprintf("%s.textproto", name) != filepath.Base(protoPath): + return nil, fmt.Errorf("%s incorrectly sets value for flag %s", protoPath, name) + } + return fv, nil } func UnmarshalValue(str string) *rc_proto.Value { diff --git a/cmd/release_config/release_config_lib/flag_value_test.go b/cmd/release_config/release_config_lib/flag_value_test.go index 8a98baf6a..5bd2d7eb3 100644 --- a/cmd/release_config/release_config_lib/flag_value_test.go +++ b/cmd/release_config/release_config_lib/flag_value_test.go @@ -15,11 +15,15 @@ package release_config_lib import ( + "fmt" "os" "path/filepath" + "strings" "testing" rc_proto "android/soong/cmd/release_config/release_config_proto" + // For Assert*. + "android/soong/android" "google.golang.org/protobuf/proto" ) @@ -50,6 +54,15 @@ func TestFlagValueFactory(t *testing.T) { }, err: nil, }, + { + name: "missingName", + protoPath: "build/release/flag_values/test/RELEASE_FOO.textproto", + data: []byte(`value {string_value: "BAR"}`), + expected: rc_proto.FlagValue{ + Value: &rc_proto.Value{Val: &rc_proto.Value_StringValue{"BAR"}}, + }, + err: fmt.Errorf("does not set name"), + }, } for _, tc := range testCases { var err error @@ -61,8 +74,15 @@ func TestFlagValueFactory(t *testing.T) { if err = os.WriteFile(path, tc.data, 0644); err != nil { t.Fatal(err) } - actual := FlagValueFactory(path) - tc.assertProtoEqual(t, &tc.expected, &actual.proto) + actual, err := FlagValueFactory(path) + if tc.err == nil { + android.AssertSame(t, "Expected %v got %v", tc.err, err) + tc.assertProtoEqual(t, &tc.expected, &actual.proto) + } else if err == nil { + t.Errorf("Expected error containing '%q' got nil", tc.err.Error()) + } else if !strings.Contains(err.Error(), tc.err.Error()) { + t.Errorf("Error %v does not include %v", err.Error(), tc.err.Error()) + } } } diff --git a/cmd/release_config/release_config_lib/release_configs.go b/cmd/release_config/release_config_lib/release_configs.go index dd98bca0b..a32ea98f9 100644 --- a/cmd/release_config/release_config_lib/release_configs.go +++ b/cmd/release_config/release_config_lib/release_configs.go @@ -211,15 +211,49 @@ func (configs *ReleaseConfigs) GetSortedReleaseConfigs() (ret []*ReleaseConfig) return ret } -func ReleaseConfigMapFactory(protoPath string) (m *ReleaseConfigMap) { +func ReleaseConfigMapFactory(protoPath string) (m *ReleaseConfigMap, err error) { m = &ReleaseConfigMap{ path: protoPath, ReleaseConfigContributions: make(map[string]*ReleaseConfigContribution), } - if protoPath != "" { - LoadMessage(protoPath, &m.proto) + if protoPath == "" { + return m, nil } - return m + LoadMessage(protoPath, &m.proto) + if m.proto.DefaultContainers == nil { + return nil, fmt.Errorf("Release config map %s lacks default_containers", protoPath) + } + for _, container := range m.proto.DefaultContainers { + if !validContainer(container) { + return nil, fmt.Errorf("Release config map %s has invalid container %s", protoPath, container) + } + } + return m, nil +} + +func ReleaseConfigContributionFactory(protoPath string, dirIndex int) (rcc *ReleaseConfigContribution, err error) { + rcc = &ReleaseConfigContribution{path: protoPath, DeclarationIndex: dirIndex} + if protoPath == "" { + return rcc, nil + } + LoadMessage(protoPath, &rcc.proto) + + switch { + case rcc.proto.Name == nil: + return nil, fmt.Errorf("%s does not specify name", protoPath) + case fmt.Sprintf("%s.textproto", *rcc.proto.Name) != filepath.Base(protoPath): + return nil, fmt.Errorf("%s incorrectly declares release config %s", protoPath, *rcc.proto.Name) + } + + // Provide a default value for ReleaseConfigType if not specified. + if rcc.proto.ReleaseConfigType == nil { + if *rcc.proto.Name == "root" { + rcc.proto.ReleaseConfigType = rc_proto.ReleaseConfigType_EXPLICIT_INHERITANCE_CONFIG.Enum() + } else { + rcc.proto.ReleaseConfigType = rc_proto.ReleaseConfigType_RELEASE_CONFIG.Enum() + } + } + return rcc, nil } // Find the top of the release config contribution directory. @@ -264,15 +298,7 @@ func (configs *ReleaseConfigs) LoadReleaseConfigMap(path string, ConfigDirIndex if _, err := os.Stat(path); err != nil { return fmt.Errorf("%s does not exist\n", path) } - m := ReleaseConfigMapFactory(path) - if m.proto.DefaultContainers == nil { - return fmt.Errorf("Release config map %s lacks default_containers", path) - } - for _, container := range m.proto.DefaultContainers { - if !validContainer(container) { - return fmt.Errorf("Release config map %s has invalid container %s", path, container) - } - } + m, err := ReleaseConfigMapFactory(path) configs.FilesUsedMap[path] = true dir := filepath.Dir(path) // Record any aliases, checking for duplicates. @@ -287,7 +313,6 @@ func (configs *ReleaseConfigs) LoadReleaseConfigMap(path string, ConfigDirIndex } configs.Aliases[name] = alias.Target } - var err error // Temporarily allowlist duplicate flag declaration files to prevent // more from entering the tree while we work to clean up the duplicates // that already exist. @@ -303,26 +328,17 @@ func (configs *ReleaseConfigs) LoadReleaseConfigMap(path string, ConfigDirIndex } } err = WalkTextprotoFiles(dir, "flag_declarations", func(path string, d fs.DirEntry, err error) error { - flagDeclaration := FlagDeclarationFactory(path) - // Container must be specified. + flagDeclaration, err := FlagDeclarationFactory(path) + if err != nil { + return err + } + // If not given, set Containers to the default for this directory. if flagDeclaration.Containers == nil { flagDeclaration.Containers = m.proto.DefaultContainers - } else { - for _, container := range flagDeclaration.Containers { - if !validContainer(container) { - return fmt.Errorf("Flag declaration %s has invalid container %s", path, container) - } - } - } - if flagDeclaration.Namespace == nil { - return fmt.Errorf("Flag declaration %s has no namespace.", path) } m.FlagDeclarations = append(m.FlagDeclarations, *flagDeclaration) name := *flagDeclaration.Name - if name == "RELEASE_ACONFIG_VALUE_SETS" { - return fmt.Errorf("%s: %s is a reserved build flag", path, name) - } if def, ok := configs.FlagArtifacts[name]; !ok { configs.FlagArtifacts[name] = &FlagArtifact{FlagDeclaration: flagDeclaration, DeclarationIndex: ConfigDirIndex} } else if !proto.Equal(def.FlagDeclaration, flagDeclaration) || !DuplicateDeclarationAllowlist[name] { @@ -358,36 +374,27 @@ func (configs *ReleaseConfigs) LoadReleaseConfigMap(path string, ConfigDirIndex } err = WalkTextprotoFiles(dir, "release_configs", func(path string, d fs.DirEntry, err error) error { - releaseConfigContribution := &ReleaseConfigContribution{path: path, DeclarationIndex: ConfigDirIndex} - LoadMessage(path, &releaseConfigContribution.proto) - name := *releaseConfigContribution.proto.Name - if fmt.Sprintf("%s.textproto", name) != filepath.Base(path) { - return fmt.Errorf("%s incorrectly declares release config %s", path, name) - } - releaseConfigType := releaseConfigContribution.proto.ReleaseConfigType - if releaseConfigType == nil { - if name == "root" { - releaseConfigType = rc_proto.ReleaseConfigType_EXPLICIT_INHERITANCE_CONFIG.Enum() - } else { - releaseConfigType = rc_proto.ReleaseConfigType_RELEASE_CONFIG.Enum() - } + rcc, err := ReleaseConfigContributionFactory(path, ConfigDirIndex) + if err != nil { + return err } + name := *rcc.proto.Name if _, ok := configs.ReleaseConfigs[name]; !ok { configs.ReleaseConfigs[name] = ReleaseConfigFactory(name, ConfigDirIndex) - configs.ReleaseConfigs[name].ReleaseConfigType = *releaseConfigType + configs.ReleaseConfigs[name].ReleaseConfigType = *rcc.proto.ReleaseConfigType } config := configs.ReleaseConfigs[name] - if config.ReleaseConfigType != *releaseConfigType { - return fmt.Errorf("%s mismatching ReleaseConfigType value %s", path, *releaseConfigType) + if config.ReleaseConfigType != *rcc.proto.ReleaseConfigType { + return fmt.Errorf("%s mismatching ReleaseConfigType value %s", path, *rcc.proto.ReleaseConfigType) } config.FilesUsedMap[path] = true - config.DisallowLunchUse = config.DisallowLunchUse || releaseConfigContribution.proto.GetDisallowLunchUse() + config.DisallowLunchUse = config.DisallowLunchUse || rcc.proto.GetDisallowLunchUse() inheritNames := make(map[string]bool) for _, inh := range config.InheritNames { inheritNames[inh] = true } // If this contribution says to inherit something we already inherited, we do not want the duplicate. - for _, cInh := range releaseConfigContribution.proto.Inherits { + for _, cInh := range rcc.proto.Inherits { if !inheritNames[cInh] { config.InheritNames = append(config.InheritNames, cInh) inheritNames[cInh] = true @@ -396,25 +403,22 @@ func (configs *ReleaseConfigs) LoadReleaseConfigMap(path string, ConfigDirIndex // Only walk flag_values/{RELEASE} for defined releases. err2 := WalkTextprotoFiles(dir, filepath.Join("flag_values", name), func(path string, d fs.DirEntry, err error) error { - flagValue := FlagValueFactory(path) - if fmt.Sprintf("%s.textproto", *flagValue.proto.Name) != filepath.Base(path) { - return fmt.Errorf("%s incorrectly sets value for flag %s", path, *flagValue.proto.Name) - } - if *flagValue.proto.Name == "RELEASE_ACONFIG_VALUE_SETS" { - return fmt.Errorf("%s: %s is a reserved build flag", path, *flagValue.proto.Name) + flagValue, err := FlagValueFactory(path) + if err != nil { + return err } config.FilesUsedMap[path] = true - releaseConfigContribution.FlagValues = append(releaseConfigContribution.FlagValues, flagValue) + rcc.FlagValues = append(rcc.FlagValues, flagValue) return nil }) if err2 != nil { return err2 } - if releaseConfigContribution.proto.GetAconfigFlagsOnly() { + if rcc.proto.GetAconfigFlagsOnly() { config.AconfigFlagsOnly = true } - m.ReleaseConfigContributions[name] = releaseConfigContribution - config.Contributions = append(config.Contributions, releaseConfigContribution) + m.ReleaseConfigContributions[name] = rcc + config.Contributions = append(config.Contributions, rcc) return nil }) if err != nil { -- cgit v1.2.3 From 657f124b20e72c5643aa7cfab76aba2917b7c1f9 Mon Sep 17 00:00:00 2001 From: Makoto Onuki Date: Thu, 27 Mar 2025 12:15:13 -0700 Subject: Copy "all aconfig flag" storage files to ravenwood-runtime Bug: 396458006 Test m nothing --no-skip-soong-tests Test: $ANDROID_BUILD_TOP/frameworks/base/ravenwood/scripts/run-ravenwood-tests.sh -s Flag: EXEMPT only adding new files to ravenwood-runtime Test: m ravenwood-runtime make sure the following files exist: $ find out/host/linux-x86/testcases/ravenwood-runtime/aconfig/ out/host/linux-x86/testcases/ravenwood-runtime/aconfig/ out/host/linux-x86/testcases/ravenwood-runtime/aconfig/maps out/host/linux-x86/testcases/ravenwood-runtime/aconfig/maps/all_aconfig_declarations.package.map out/host/linux-x86/testcases/ravenwood-runtime/aconfig/maps/all_aconfig_declarations.flag.map out/host/linux-x86/testcases/ravenwood-runtime/aconfig/all_aconfig_declarations.pb out/host/linux-x86/testcases/ravenwood-runtime/aconfig/all_aconfig_declarations.textproto out/host/linux-x86/testcases/ravenwood-runtime/aconfig/boot out/host/linux-x86/testcases/ravenwood-runtime/aconfig/boot/all_aconfig_declarations.flag.info out/host/linux-x86/testcases/ravenwood-runtime/aconfig/boot/all_aconfig_declarations.val Change-Id: Iadfa0abb5004ca6f689571a27fc8877ca7af7079 --- aconfig/Android.bp | 1 + aconfig/all_aconfig_declarations.go | 109 ++++++++++++++++++++++++-- aconfig/all_aconfig_declarations_extension.go | 6 +- aconfig/init.go | 30 +++++++ java/ravenwood.go | 44 ++++++++++- java/ravenwood_test.go | 14 ++++ 6 files changed, 193 insertions(+), 11 deletions(-) diff --git a/aconfig/Android.bp b/aconfig/Android.bp index a15fe866b..47a999987 100644 --- a/aconfig/Android.bp +++ b/aconfig/Android.bp @@ -35,6 +35,7 @@ all_aconfig_declarations { name: "all_aconfig_declarations", visibility: [ "//vendor:__subpackages__", // for vendor extensions + "//frameworks/base/ravenwood", ], api_signature_files: [ ":frameworks-base-api-current.txt", diff --git a/aconfig/all_aconfig_declarations.go b/aconfig/all_aconfig_declarations.go index 5a5262485..174aea186 100644 --- a/aconfig/all_aconfig_declarations.go +++ b/aconfig/all_aconfig_declarations.go @@ -17,6 +17,7 @@ package aconfig import ( "fmt" "slices" + "strconv" "android/soong/android" @@ -24,6 +25,10 @@ import ( "github.com/google/blueprint/proptools" ) +const allAconfigDeclarationsStorage = "all_aconfig_declarations_storage" + +const AllAconfigModule = "all_aconfig_declarations" + // A singleton module that collects all of the aconfig flags declared in the // tree into a single combined file for export to the external flag setting // server (inside Google it's Gantry). @@ -38,15 +43,40 @@ func AllAconfigDeclarationsFactory() android.SingletonModule { return module } -type allAconfigDeclarationsInfo struct { - parsedFlagsFile android.Path +// AllAconfigDeclarationsInfo contains flag storage files containing all flags from all the modules +// across the whole Android source tree. None of these files may be installed on the device. +// They should only be used or consumed as artifacts from the build servers, +// or used by host side tools/tests. +type AllAconfigDeclarationsInfo struct { + // ParsedFlagsFile contains all flags in a binary proto format. + ParsedFlagsFile android.Path + + // TextProtoFlagsFile contains all flags in a text proto format. + TextProtoFlagsFile android.Path + + // StorageFlagVal is a "flag_val" storage file for all flags. + StorageFlagVal android.Path + + // StorageFlagMap is a "flag_map" storage file for all flags. + StorageFlagMap android.Path + + // StorageFlagInfo is a "flag_info" storage file for all flags. + StorageFlagInfo android.Path + + // StoragePackageMap is a "package_map" storage file for all flags. + StoragePackageMap android.Path } -var allAconfigDeclarationsInfoProvider = blueprint.NewProvider[allAconfigDeclarationsInfo]() +var AllAconfigDeclarationsInfoProvider = blueprint.NewProvider[AllAconfigDeclarationsInfo]() type allAconfigReleaseDeclarationsSingleton struct { intermediateBinaryProtoPath android.OutputPath intermediateTextProtoPath android.OutputPath + + intermediateStorageFlagVal android.OutputPath + intermediateStorageFlagMap android.OutputPath + intermediateStorageFlagInfo android.OutputPath + intermediateStoragePackageMap android.OutputPath } type ApiSurfaceContributorProperties struct { @@ -135,8 +165,14 @@ func (this *allAconfigDeclarationsSingleton) GenerateAndroidBuildActions(ctx and ctx.Phony("all_aconfig_declarations", depsFiles...) - android.SetProvider(ctx, allAconfigDeclarationsInfoProvider, allAconfigDeclarationsInfo{ - parsedFlagsFile: parsedFlagsFile, + android.SetProvider(ctx, AllAconfigDeclarationsInfoProvider, AllAconfigDeclarationsInfo{ + ParsedFlagsFile: parsedFlagsFile, + TextProtoFlagsFile: android.PathForIntermediates(ctx, "all_aconfig_declarations.textproto"), + + StoragePackageMap: android.PathForIntermediates(ctx, "all_aconfig_declarations.package.map"), + StorageFlagMap: android.PathForIntermediates(ctx, "all_aconfig_declarations.flag.map"), + StorageFlagInfo: android.PathForIntermediates(ctx, "all_aconfig_declarations.flag.info"), + StorageFlagVal: android.PathForIntermediates(ctx, "all_aconfig_declarations.val"), }) } @@ -171,6 +207,11 @@ func (this *allAconfigDeclarationsSingleton) GenerateSingletonBuildActions(ctx a paths := allAconfigReleaseDeclarationsSingleton{ intermediateBinaryProtoPath: android.PathForIntermediates(ctx, assembleFileName(rcName, "all_aconfig_declarations.pb")), intermediateTextProtoPath: android.PathForIntermediates(ctx, assembleFileName(rcName, "all_aconfig_declarations.textproto")), + + intermediateStoragePackageMap: android.PathForIntermediates(ctx, assembleFileName(rcName, "all_aconfig_declarations.package.map")), + intermediateStorageFlagMap: android.PathForIntermediates(ctx, assembleFileName(rcName, "all_aconfig_declarations.flag.map")), + intermediateStorageFlagInfo: android.PathForIntermediates(ctx, assembleFileName(rcName, "all_aconfig_declarations.flag.info")), + intermediateStorageFlagVal: android.PathForIntermediates(ctx, assembleFileName(rcName, "all_aconfig_declarations.val")), } this.releaseMap[rcName] = paths ctx.Build(pctx, android.BuildParams{ @@ -195,6 +236,64 @@ func (this *allAconfigDeclarationsSingleton) GenerateSingletonBuildActions(ctx a }, }) ctx.Phony("all_aconfig_declarations_textproto", this.releaseMap[rcName].intermediateTextProtoPath) + + storageFilesVersion := 1 + if ctx.Config().ReleaseFingerprintAconfigPackages() { + storageFilesVersion = 2 + } + const container = "all_aconfig_declarations" + + ctx.Build(pctx, android.BuildParams{ + Rule: allDeclarationsRuleStoragePackageMap, + Inputs: cacheFiles, + Output: this.releaseMap[rcName].intermediateStoragePackageMap, + Description: "all_aconfig_declarations_storage_package_map", + Args: map[string]string{ + "container": container, + "cache_files": android.JoinPathsWithPrefix(cacheFiles, "--cache "), + "version": strconv.Itoa(storageFilesVersion), + }, + }) + ctx.Phony(allAconfigDeclarationsStorage, this.releaseMap[rcName].intermediateStoragePackageMap) + + ctx.Build(pctx, android.BuildParams{ + Rule: allDeclarationsRuleStorageFlagMap, + Inputs: cacheFiles, + Output: this.releaseMap[rcName].intermediateStorageFlagMap, + Description: "all_aconfig_declarations_storage_flag_map", + Args: map[string]string{ + "container": container, + "cache_files": android.JoinPathsWithPrefix(cacheFiles, "--cache "), + "version": strconv.Itoa(storageFilesVersion), + }, + }) + ctx.Phony(allAconfigDeclarationsStorage, this.releaseMap[rcName].intermediateStorageFlagMap) + + ctx.Build(pctx, android.BuildParams{ + Rule: allDeclarationsRuleStorageFlagInfo, + Inputs: cacheFiles, + Output: this.releaseMap[rcName].intermediateStorageFlagInfo, + Description: "all_aconfig_declarations_storage_flag_info", + Args: map[string]string{ + "container": container, + "cache_files": android.JoinPathsWithPrefix(cacheFiles, "--cache "), + "version": strconv.Itoa(storageFilesVersion), + }, + }) + ctx.Phony(allAconfigDeclarationsStorage, this.releaseMap[rcName].intermediateStorageFlagInfo) + + ctx.Build(pctx, android.BuildParams{ + Rule: allDeclarationsRuleStorageFlagVal, + Inputs: cacheFiles, + Output: this.releaseMap[rcName].intermediateStorageFlagVal, + Description: "all_aconfig_declarations_storage_flag_val", + Args: map[string]string{ + "container": container, + "cache_files": android.JoinPathsWithPrefix(cacheFiles, "--cache "), + "version": strconv.Itoa(storageFilesVersion), + }, + }) + ctx.Phony(allAconfigDeclarationsStorage, this.releaseMap[rcName].intermediateStorageFlagVal) } for _, rcName := range this.sortedConfigNames() { diff --git a/aconfig/all_aconfig_declarations_extension.go b/aconfig/all_aconfig_declarations_extension.go index d5a458811..83540526c 100644 --- a/aconfig/all_aconfig_declarations_extension.go +++ b/aconfig/all_aconfig_declarations_extension.go @@ -62,10 +62,10 @@ func (ext *allAconfigDeclarationsExtension) GenerateAndroidBuildActions(ctx andr var parsedFlagsFile android.Path ctx.VisitDirectDepsProxyWithTag(allAconfigDeclarationsDependencyTag, func(proxy android.ModuleProxy) { - if info, ok := android.OtherModuleProvider(ctx, proxy, allAconfigDeclarationsInfoProvider); ok { - parsedFlagsFile = info.parsedFlagsFile + if info, ok := android.OtherModuleProvider(ctx, proxy, AllAconfigDeclarationsInfoProvider); ok { + parsedFlagsFile = info.ParsedFlagsFile } else { - ctx.PropertyErrorf("base", "base must provide allAconfigDeclarationsInfo") + ctx.PropertyErrorf("base", "base must provide AllAconfigDeclarationsInfo") } }) diff --git a/aconfig/init.go b/aconfig/init.go index d8d547022..61dbb1637 100644 --- a/aconfig/init.go +++ b/aconfig/init.go @@ -70,6 +70,36 @@ var ( "${aconfig}", }, }, "cache_files") + + allDeclarationsRuleStoragePackageMap = pctx.AndroidStaticRule("all_aconfig_declarations_storage_package_map", + blueprint.RuleParams{ + Command: `${aconfig} create-storage --container ${container} --file package_map --out ${out} ${cache_files} --version ${version}`, + CommandDeps: []string{ + "${aconfig}", + }, + }, "container", "cache_files", "version") + allDeclarationsRuleStorageFlagMap = pctx.AndroidStaticRule("all_aconfig_declarations_storage_flag_map", + blueprint.RuleParams{ + Command: `${aconfig} create-storage --container ${container} --file flag_map --out ${out} ${cache_files} --version ${version}`, + CommandDeps: []string{ + "${aconfig}", + }, + }, "container", "cache_files", "version") + allDeclarationsRuleStorageFlagInfo = pctx.AndroidStaticRule("all_aconfig_declarations_storage_flag_info", + blueprint.RuleParams{ + Command: `${aconfig} create-storage --container ${container} --file flag_info --out ${out} ${cache_files} --version ${version}`, + CommandDeps: []string{ + "${aconfig}", + }, + }, "container", "cache_files", "version") + allDeclarationsRuleStorageFlagVal = pctx.AndroidStaticRule("all_aconfig_declarations_storage_flag_val", + blueprint.RuleParams{ + Command: `${aconfig} create-storage --container ${container} --file flag_val --out ${out} ${cache_files} --version ${version}`, + CommandDeps: []string{ + "${aconfig}", + }, + }, "container", "cache_files", "version") + RecordFinalizedFlagsRule = pctx.AndroidStaticRule("RecordFinalizedFlagsRule", blueprint.RuleParams{ Command: `${record-finalized-flags} ${parsed_flags_file} ${finalized_flags_file} ${api_signature_files} > ${out}`, diff --git a/java/ravenwood.go b/java/ravenwood.go index a942dc653..a71195d79 100644 --- a/java/ravenwood.go +++ b/java/ravenwood.go @@ -14,6 +14,7 @@ package java import ( + "android/soong/aconfig" "strconv" "android/soong/android" @@ -37,6 +38,7 @@ var ravenwoodUtilsTag = dependencyTag{name: "ravenwoodutils"} var ravenwoodRuntimeTag = dependencyTag{name: "ravenwoodruntime"} var ravenwoodTestResourceApkTag = dependencyTag{name: "ravenwoodtestresapk"} var ravenwoodTestInstResourceApkTag = dependencyTag{name: "ravenwoodtest-inst-res-apk"} +var allAconfigModuleTag = dependencyTag{name: "all_aconfig"} var genManifestProperties = pctx.AndroidStaticRule("genManifestProperties", blueprint.RuleParams{ @@ -338,6 +340,10 @@ func (r *ravenwoodLibgroup) DepsMutator(ctx android.BottomUpMutatorContext) { for _, lib := range r.ravenwoodLibgroupProperties.Jni_libs.GetOrDefault(ctx, nil) { ctx.AddVariationDependencies(ctx.Config().BuildOSTarget.Variations(), jniLibTag, lib) } + + if r.Name() == ravenwoodRuntimeName { + ctx.AddVariationDependencies(nil, allAconfigModuleTag, aconfig.AllAconfigModule) + } } func (r *ravenwoodLibgroup) GenerateAndroidBuildActions(ctx android.ModuleContext) { @@ -355,6 +361,12 @@ func (r *ravenwoodLibgroup) GenerateAndroidBuildActions(ctx android.ModuleContex names: jniDepNames, }) + install := func(to android.InstallPath, srcs ...android.Path) { + for _, s := range srcs { + ctx.InstallFile(to, s.Base(), s) + } + } + // Install our runtime into expected location for packaging installPath := android.PathForModuleInstall(ctx, r.BaseModuleName()) for _, lib := range r.ravenwoodLibgroupProperties.Libs { @@ -373,19 +385,45 @@ func (r *ravenwoodLibgroup) GenerateAndroidBuildActions(ctx android.ModuleContex soInstallPath := android.PathForModuleInstall(ctx, r.BaseModuleName()).Join(ctx, getLibPath(r.forceArchType)) for _, jniLib := range jniLibs { - ctx.InstallFile(soInstallPath, jniLib.path.Base(), jniLib.path) + install(soInstallPath, jniLib.path) } dataInstallPath := installPath.Join(ctx, "ravenwood-data") data := android.PathsForModuleSrc(ctx, r.ravenwoodLibgroupProperties.Data) for _, file := range data { - ctx.InstallFile(dataInstallPath, file.Base(), file) + install(dataInstallPath, file) } fontsInstallPath := installPath.Join(ctx, "fonts") fonts := android.PathsForModuleSrc(ctx, r.ravenwoodLibgroupProperties.Fonts) for _, file := range fonts { - ctx.InstallFile(fontsInstallPath, file.Base(), file) + install(fontsInstallPath, file) + } + + // Copy aconfig flag storage files. + if r.Name() == ravenwoodRuntimeName { + allAconfigFound := false + if allAconfig := ctx.GetDirectDepProxyWithTag(aconfig.AllAconfigModule, allAconfigModuleTag); allAconfig != nil { + aadi, ok := android.OtherModuleProvider(ctx, allAconfig, aconfig.AllAconfigDeclarationsInfoProvider) + if ok { + // Binary proto file and the text proto. + // We don't really use the text proto file, but having this would make debugging easier. + install(installPath.Join(ctx, "aconfig/metadata/aconfig/etc"), aadi.ParsedFlagsFile, aadi.TextProtoFlagsFile) + + // The "new" storage files. + install(installPath.Join(ctx, "aconfig/metadata/aconfig/maps"), aadi.StoragePackageMap, aadi.StorageFlagMap) + install(installPath.Join(ctx, "aconfig/metadata/aconfig/boot"), aadi.StorageFlagVal, aadi.StorageFlagInfo) + + allAconfigFound = true + } + } + if !allAconfigFound { + if ctx.Config().AllowMissingDependencies() { + ctx.AddMissingDependencies([]string{aconfig.AllAconfigModule}) + } else { + ctx.ModuleErrorf("missing dependency %q", aconfig.AllAconfigModule) + } + } } // Normal build should perform install steps diff --git a/java/ravenwood_test.go b/java/ravenwood_test.go index d6493bcfa..79a22e74e 100644 --- a/java/ravenwood_test.go +++ b/java/ravenwood_test.go @@ -15,6 +15,7 @@ package java import ( + "android/soong/aconfig" "runtime" "testing" @@ -27,6 +28,9 @@ var prepareRavenwoodRuntime = android.GroupFixturePreparers( RegisterRavenwoodBuildComponents(ctx) }), android.FixtureAddTextFile("ravenwood/Android.bp", ` + all_aconfig_declarations { + name: "all_aconfig_declarations", + } cc_library_shared { name: "ravenwood-runtime-jni1", host_supported: true, @@ -111,6 +115,7 @@ func TestRavenwoodRuntime(t *testing.T) { ctx := android.GroupFixturePreparers( PrepareForIntegrationTestWithJava, etc.PrepareForTestWithPrebuiltEtc, + aconfig.PrepareForTestWithAconfigBuildComponents, prepareRavenwoodRuntime, ).RunTest(t) @@ -129,6 +134,14 @@ func TestRavenwoodRuntime(t *testing.T) { runtime.Output(installPathPrefix + "/ravenwood-runtime/lib64/ravenwood-runtime-jni3.so") runtime.Output(installPathPrefix + "/ravenwood-runtime/ravenwood-data/app1.apk") runtime.Output(installPathPrefix + "/ravenwood-runtime/fonts/Font.ttf") + + runtime.Output(installPathPrefix + "/ravenwood-runtime/aconfig/metadata/aconfig/etc/all_aconfig_declarations.pb") + runtime.Output(installPathPrefix + "/ravenwood-runtime/aconfig/metadata/aconfig/etc/all_aconfig_declarations.textproto") + runtime.Output(installPathPrefix + "/ravenwood-runtime/aconfig/metadata/aconfig/maps/all_aconfig_declarations.package.map") + runtime.Output(installPathPrefix + "/ravenwood-runtime/aconfig/metadata/aconfig/maps/all_aconfig_declarations.flag.map") + runtime.Output(installPathPrefix + "/ravenwood-runtime/aconfig/metadata/aconfig/boot/all_aconfig_declarations.flag.info") + runtime.Output(installPathPrefix + "/ravenwood-runtime/aconfig/metadata/aconfig/boot/all_aconfig_declarations.val") + utils := ctx.ModuleForTests(t, "ravenwood-utils", "android_common") utils.Output(installPathPrefix + "/ravenwood-utils/framework-rules.ravenwood.jar") } @@ -142,6 +155,7 @@ func TestRavenwoodTest(t *testing.T) { ctx := android.GroupFixturePreparers( PrepareForIntegrationTestWithJava, etc.PrepareForTestWithPrebuiltEtc, + aconfig.PrepareForTestWithAconfigBuildComponents, prepareRavenwoodRuntime, ).RunTestWithBp(t, ` cc_library_shared { -- cgit v1.2.3 From 9520235434a5c62b887f66d6d2d538fb55506a5c Mon Sep 17 00:00:00 2001 From: Ivan Lozano Date: Tue, 1 Apr 2025 16:12:01 +0000 Subject: rust: Ensure rustdoc implicits are available The variant that builds rustdocs may vary based on which mutators are applied to a module. Prior to stub support being added, all variants called `rustc` initially so dependencies of rustdoc were being built in that step. With stub support added, stub variants do not call `rustc`. If the rustdoc producing variant is a stub variant, this leads to rustdoc failing because implicit deps haven't been built. We can resolve this by explicitly listing rustdoc dependencies as implicit in its build rule. Bug: 403635935 Test: m rustdoc Change-Id: I950644b6743a9f45c5bd53e89fdbf24c8dbecad3 --- rust/builder.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rust/builder.go b/rust/builder.go index 1b6a6c117..4e19bf79d 100644 --- a/rust/builder.go +++ b/rust/builder.go @@ -559,12 +559,18 @@ func Rustdoc(ctx ModuleContext, main android.Path, deps PathDeps, // https://github.com/rust-lang/rust/blob/master/src/librustdoc/html/render/write_shared.rs#L144-L146 docDir := android.PathForOutput(ctx, "rustdoc") + var implicits android.Paths + implicits = append(implicits, rustLibsToPaths(deps.RLibs)...) + implicits = append(implicits, rustLibsToPaths(deps.DyLibs)...) + implicits = append(implicits, rustLibsToPaths(deps.ProcMacros)...) + ctx.Build(pctx, android.BuildParams{ Rule: rustdoc, Description: "rustdoc " + main.Rel(), Output: docTimestampFile, Input: main, Implicit: ctx.RustModule().UnstrippedOutputFile(), + Implicits: implicits, Args: map[string]string{ "rustdocFlags": strings.Join(rustdocFlags, " "), "outDir": docDir.String(), -- cgit v1.2.3 From 6953b14ef69bfe93b13778fca2e7115fc55f9708 Mon Sep 17 00:00:00 2001 From: "Liana Kazanova (xWF)" Date: Tue, 1 Apr 2025 09:56:49 -0700 Subject: Revert "Don't leak variables from wrapper to real script" This reverts commit cf25a8c6692967150289e52ab88e32c44d9dfc2b. Reason for revert: Droidmonitor created revert due to http://b/407690689 Change-Id: If82d5d9da64cc07e080c3d0db55d5c5447723637 --- python/scripts/main.py | 90 ++++++++++++++++++++++++-------------------------- 1 file changed, 43 insertions(+), 47 deletions(-) diff --git a/python/scripts/main.py b/python/scripts/main.py index a3d8f65a2..35cdfc47e 100644 --- a/python/scripts/main.py +++ b/python/scripts/main.py @@ -1,52 +1,48 @@ -# It's important that we use a function here, as any global variables we make in this script will -# also be available in the real entrypoint run by runpy._run_module_as_main. -def _soong_main(): - import os - import runpy - import shutil - import sys - import tempfile - import zipfile - from pathlib import PurePath +import os +import runpy +import shutil +import sys +import tempfile +import zipfile - sys.argv[0] = __loader__.archive +from pathlib import PurePath - # Set sys.executable to None. The real executable is available as - # sys.argv[0], and too many things assume sys.executable is a regular Python - # binary, which isn't available. By setting it to None we get clear errors - # when people try to use it. - sys.executable = None - # Extract the shared libraries from the zip file into a temporary directory. - # This works around the limitations of dynamic linker. Some Python libraries - # reference the .so files relatively and so extracting only the .so files - # does not work, so we extract the entire parent directory of the .so files to a - # tempdir and then add that to sys.path. - tempdir = None - with zipfile.ZipFile(__loader__.archive) as z: - # any root so files or root directories that contain so files will be - # extracted to the tempdir so the linker load them, this minimizes the - # number of files that need to be extracted to a tempdir - extract_paths = {} - for member in z.infolist(): - if member.filename.endswith('.so'): - extract_paths[PurePath(member.filename).parts[0]] = member.filename - if extract_paths: - tempdir = tempfile.mkdtemp() - for member in z.infolist(): - if not PurePath(member.filename).parts[0] in extract_paths.keys(): - continue - if member.is_dir(): - os.makedirs(os.path.join(tempdir, member.filename)) - else: - z.extract(member, tempdir) - sys.path.insert(0, tempdir) - try: - runpy._run_module_as_main("ENTRY_POINT", alter_argv=False) - finally: - if tempdir is not None: - shutil.rmtree(tempdir) +sys.argv[0] = __loader__.archive + +# Set sys.executable to None. The real executable is available as +# sys.argv[0], and too many things assume sys.executable is a regular Python +# binary, which isn't available. By setting it to None we get clear errors +# when people try to use it. +sys.executable = None -if __name__ == "__main__": - _soong_main() +# Extract the shared libraries from the zip file into a temporary directory. +# This works around the limitations of dynamic linker. Some Python libraries +# reference the .so files relatively and so extracting only the .so files +# does not work, so we extract the entire parent directory of the .so files to a +# tempdir and then add that to sys.path. +tempdir = None +with zipfile.ZipFile(__loader__.archive) as z: + # any root so files or root directories that contain so files will be + # extracted to the tempdir so the linker load them, this minimizes the + # number of files that need to be extracted to a tempdir + extract_paths = {} + for member in z.infolist(): + if member.filename.endswith('.so'): + extract_paths[PurePath(member.filename).parts[0]] = member.filename + if extract_paths: + tempdir = tempfile.mkdtemp() + for member in z.infolist(): + if not PurePath(member.filename).parts[0] in extract_paths.keys(): + continue + if member.is_dir(): + os.makedirs(os.path.join(tempdir, member.filename)) + else: + z.extract(member, tempdir) + sys.path.insert(0, tempdir) +try: + runpy._run_module_as_main("ENTRY_POINT", alter_argv=False) +finally: + if tempdir is not None: + shutil.rmtree(tempdir) -- cgit v1.2.3 From c96e0eb436de5b3f73831e1e9782bac3215060f7 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Tue, 1 Apr 2025 10:22:28 -0700 Subject: Revert^2 "Don't leak variables from wrapper to real script" This reverts commit 6953b14ef69bfe93b13778fca2e7115fc55f9708. Reason for revert: issue fixed in ag/32824539 Change-Id: I5bb1dd15a001b2a17f38cd88f92f0bda1493a4dd --- python/scripts/main.py | 90 ++++++++++++++++++++++++++------------------------ 1 file changed, 47 insertions(+), 43 deletions(-) diff --git a/python/scripts/main.py b/python/scripts/main.py index 35cdfc47e..a3d8f65a2 100644 --- a/python/scripts/main.py +++ b/python/scripts/main.py @@ -1,48 +1,52 @@ +# It's important that we use a function here, as any global variables we make in this script will +# also be available in the real entrypoint run by runpy._run_module_as_main. +def _soong_main(): + import os + import runpy + import shutil + import sys + import tempfile + import zipfile -import os -import runpy -import shutil -import sys -import tempfile -import zipfile + from pathlib import PurePath -from pathlib import PurePath + sys.argv[0] = __loader__.archive + # Set sys.executable to None. The real executable is available as + # sys.argv[0], and too many things assume sys.executable is a regular Python + # binary, which isn't available. By setting it to None we get clear errors + # when people try to use it. + sys.executable = None -sys.argv[0] = __loader__.archive - -# Set sys.executable to None. The real executable is available as -# sys.argv[0], and too many things assume sys.executable is a regular Python -# binary, which isn't available. By setting it to None we get clear errors -# when people try to use it. -sys.executable = None - -# Extract the shared libraries from the zip file into a temporary directory. -# This works around the limitations of dynamic linker. Some Python libraries -# reference the .so files relatively and so extracting only the .so files -# does not work, so we extract the entire parent directory of the .so files to a -# tempdir and then add that to sys.path. -tempdir = None -with zipfile.ZipFile(__loader__.archive) as z: - # any root so files or root directories that contain so files will be - # extracted to the tempdir so the linker load them, this minimizes the - # number of files that need to be extracted to a tempdir - extract_paths = {} - for member in z.infolist(): - if member.filename.endswith('.so'): - extract_paths[PurePath(member.filename).parts[0]] = member.filename - if extract_paths: - tempdir = tempfile.mkdtemp() + # Extract the shared libraries from the zip file into a temporary directory. + # This works around the limitations of dynamic linker. Some Python libraries + # reference the .so files relatively and so extracting only the .so files + # does not work, so we extract the entire parent directory of the .so files to a + # tempdir and then add that to sys.path. + tempdir = None + with zipfile.ZipFile(__loader__.archive) as z: + # any root so files or root directories that contain so files will be + # extracted to the tempdir so the linker load them, this minimizes the + # number of files that need to be extracted to a tempdir + extract_paths = {} for member in z.infolist(): - if not PurePath(member.filename).parts[0] in extract_paths.keys(): - continue - if member.is_dir(): - os.makedirs(os.path.join(tempdir, member.filename)) - else: - z.extract(member, tempdir) - sys.path.insert(0, tempdir) -try: - runpy._run_module_as_main("ENTRY_POINT", alter_argv=False) -finally: - if tempdir is not None: - shutil.rmtree(tempdir) + if member.filename.endswith('.so'): + extract_paths[PurePath(member.filename).parts[0]] = member.filename + if extract_paths: + tempdir = tempfile.mkdtemp() + for member in z.infolist(): + if not PurePath(member.filename).parts[0] in extract_paths.keys(): + continue + if member.is_dir(): + os.makedirs(os.path.join(tempdir, member.filename)) + else: + z.extract(member, tempdir) + sys.path.insert(0, tempdir) + try: + runpy._run_module_as_main("ENTRY_POINT", alter_argv=False) + finally: + if tempdir is not None: + shutil.rmtree(tempdir) + +if __name__ == "__main__": + _soong_main() -- cgit v1.2.3 From 0ccb50417fd3894bce9b05f64cd985b16dcd2e18 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Tue, 1 Apr 2025 10:32:32 -0700 Subject: Add printflags command This is moved from build/bazel/bin/printflags, which is being removed. Bug: 315353489 Test: printflags Change-Id: I92f1a0ce126373f6e4e4a179e460884a7b969266 --- bin/printflags | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100755 bin/printflags diff --git a/bin/printflags b/bin/printflags new file mode 100755 index 000000000..feea76aba --- /dev/null +++ b/bin/printflags @@ -0,0 +1,25 @@ +#!/bin/bash -e + +# Copyright (C) 2023 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. +source $(cd $(dirname $BASH_SOURCE) &> /dev/null && pwd)/../../make/shell_utils.sh +require_top + +aconfig="$ANDROID_SOONG_HOST_OUT"/bin/aconfig +flags_file="$(getoutdir)"/soong/.intermediates/all_aconfig_declarations.pb +if [[ ! -f "$aconfig" || ! -f "$flags_file" ]]; then + echo "Missing dependencies: please run 'm all_aconfig_declarations' and try again." + exit 1 +fi +$aconfig dump-cache --cache "$flags_file" "$@" -- cgit v1.2.3 From c39065110bb5207200f686d0edac3c030e24e194 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Mon, 31 Mar 2025 20:32:35 +0000 Subject: Fix test_config_module pacakging diffs When packaging test_module_config in *-tests.zip (e.g. device-platinum-tests.zip), we should package the bogus m.manifestFile and not baseApk. This CL restores the behavior prior to ag/32769639 Bug: 405183828 Test: m out/soong/packaging/device-platinum-tests.zip (top of CL stack) Test: verified that it is bit identical to $ANDROID_PRODUCT_OUT/device-platinum-tests.zip prior to ag/32769639 Test: RUN_BUILD_TESTS=true m nothing Change-Id: Ie7109276adb66a3a9120b8a69ef525bd55cd092f --- tradefed_modules/test_module_config.go | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/tradefed_modules/test_module_config.go b/tradefed_modules/test_module_config.go index 6b30a7a38..62d1bcead 100644 --- a/tradefed_modules/test_module_config.go +++ b/tradefed_modules/test_module_config.go @@ -435,22 +435,19 @@ func (m *testModuleConfigModule) generateManifestAndConfig(ctx android.ModuleCon IsUnitTest: m.provider.IsUnitTest, }) + mainFileExt := ".apk" + if m.provider.MkAppClass == "JAVA_LIBRARIES" { + mainFileExt = ".jar" + } + ctx.SetTestSuiteInfo(android.TestSuiteInfo{ TestSuites: m.tradefedProperties.Test_suites, - MainFile: baseApk, - MainFileExt: ".apk", + MainFile: m.manifest, + MainFileStem: fmt.Sprintf("UNUSED-%s", *m.Base), + MainFileExt: mainFileExt, ConfigFile: m.testConfig, NeedsArchFolder: ctx.Device(), }) - - // Install the UNUSED- file to match the UNUSED- stem specified in javaExtraEntries - if m.provider.MkAppClass == "APPS" { - installDir2 := android.PathForModuleInstall(ctx, ctx.ModuleName(), ctx.DeviceConfig().DeviceArch()) - ctx.InstallFile(installDir2, fmt.Sprintf("UNUSED-%s.apk", *m.Base), m.manifest) - } else if m.provider.MkAppClass == "JAVA_LIBRARIES" { - installDir2 := android.PathForModuleInstall(ctx, ctx.ModuleName()) - ctx.InstallFile(installDir2, fmt.Sprintf("UNUSED-%s.jar", *m.Base), m.manifest) - } } var _ android.AndroidMkEntriesProvider = (*testModuleConfigHostModule)(nil) -- cgit v1.2.3 From 83f77dc1b8572f8676dacffc126217aa02248167 Mon Sep 17 00:00:00 2001 From: "Liana Kazanova (xWF)" Date: Tue, 1 Apr 2025 11:57:31 -0700 Subject: Revert "Use InstallFile instead PackageFile so the installed files could be reported properly" This reverts commit 99f38199f6ec45824c5dfb66047dca56c41dfe73. Reason for revert: DroidMonitor: Potential culprit for http://b/407785030 - verifying through ABTD before revert submission. This is part of the standard investigation process, and does not mean your CL will be reverted. Change-Id: Ic1152fdae5b6a4e49032cc46a2aeffd0661a7b9b --- bpf/bpf.go | 10 ++++------ bpf/libbpf/libbpf_prog.go | 9 +++------ 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/bpf/bpf.go b/bpf/bpf.go index f57dff0f1..deb465dd6 100644 --- a/bpf/bpf.go +++ b/bpf/bpf.go @@ -110,8 +110,7 @@ type bpf struct { android.DefaultableModuleBase properties BpfProperties - objs android.Paths - installDir android.InstallPath + objs android.Paths } var _ android.ImageInterface = (*bpf)(nil) @@ -229,12 +228,12 @@ func (bpf *bpf) GenerateAndroidBuildActions(ctx android.ModuleContext) { } - bpf.installDir = android.PathForModuleInstall(ctx, "etc", "bpf") + installDir := android.PathForModuleInstall(ctx, "etc", "bpf") if len(bpf.properties.Sub_dir) > 0 { - bpf.installDir = bpf.installDir.Join(ctx, bpf.properties.Sub_dir) + installDir = installDir.Join(ctx, bpf.properties.Sub_dir) } for _, obj := range bpf.objs { - ctx.InstallFile(bpf.installDir, obj.Base(), obj) + ctx.PackageFile(installDir, obj.Base(), obj) } android.SetProvider(ctx, BpfInfoProvider, BpfInfo{ @@ -268,7 +267,6 @@ func (bpf *bpf) AndroidMk() android.AndroidMkData { fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", obj.String()) fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", obj.Base()) fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC") - fmt.Fprintln(w, "LOCAL_SOONG_INSTALLED_MODULE := ", filepath.Join(bpf.installDir.String(), obj.Base())) fmt.Fprintln(w, localModulePath) // AconfigUpdateAndroidMkData may have added elements to Extra. Process them here. for _, extra := range data.Extra { diff --git a/bpf/libbpf/libbpf_prog.go b/bpf/libbpf/libbpf_prog.go index f68bf3d34..44013e5e3 100644 --- a/bpf/libbpf/libbpf_prog.go +++ b/bpf/libbpf/libbpf_prog.go @@ -17,7 +17,6 @@ package libbpf_prog import ( "fmt" "io" - "path/filepath" "runtime" "strings" @@ -101,7 +100,6 @@ type libbpfProg struct { android.DefaultableModuleBase properties LibbpfProgProperties objs android.Paths - installDir android.InstallPath } var _ android.ImageInterface = (*libbpfProg)(nil) @@ -233,12 +231,12 @@ func (libbpf *libbpfProg) GenerateAndroidBuildActions(ctx android.ModuleContext) libbpf.objs = append(libbpf.objs, objStripped.WithoutRel()) } - libbpf.installDir = android.PathForModuleInstall(ctx, "etc", "bpf") + installDir := android.PathForModuleInstall(ctx, "etc", "bpf") if len(libbpf.properties.Relative_install_path) > 0 { - libbpf.installDir = libbpf.installDir.Join(ctx, libbpf.properties.Relative_install_path) + installDir = installDir.Join(ctx, libbpf.properties.Relative_install_path) } for _, obj := range libbpf.objs { - ctx.InstallFile(libbpf.installDir, obj.Base(), obj) + ctx.PackageFile(installDir, obj.Base(), obj) } ctx.SetOutputFiles(libbpf.objs, "") @@ -264,7 +262,6 @@ func (libbpf *libbpfProg) AndroidMk() android.AndroidMkData { fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", obj.String()) fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", obj.Base()) fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC") - fmt.Fprintln(w, "LOCAL_SOONG_INSTALLED_MODULE := ", filepath.Join(libbpf.installDir.String(), obj.Base())) fmt.Fprintln(w, localModulePath) // AconfigUpdateAndroidMkData may have added elements to Extra. Process them here. for _, extra := range data.Extra { -- cgit v1.2.3 From 01b18240ac0e34fbc404b4c87d1029015bf47136 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Mon, 31 Mar 2025 21:17:28 +0000 Subject: Build device-platinum-tests.zip using Soong The packaging rules are similar to performance-tests.zip, which was added to Soong in ag/32749281. `buildPerformanceTests` has been renamed to `packageTestSuite`, and an enum has been added to distinguish performance-tests and device-platinum-tests. device-platinum-tests also dists a zip containing host .so files, and a new rule has been added to build that. Bug: 405183828 Test: Soong built device-platinum-tests.zip is bit-identical to Make built device-platinum-tests.zip Change-Id: I2c15b064f77d2ed1876f6e84820d8d6a360c635b --- android/test_suites.go | 79 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 13 deletions(-) diff --git a/android/test_suites.go b/android/test_suites.go index 94b216172..e28033b1f 100644 --- a/android/test_suites.go +++ b/android/test_suites.go @@ -15,6 +15,7 @@ package android import ( + "fmt" "path/filepath" "slices" "sort" @@ -182,7 +183,37 @@ func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) { ctx.Phony("ravenwood-tests", ravenwoodZip, ravenwoodListZip) ctx.DistForGoal("ravenwood-tests", ravenwoodZip, ravenwoodListZip) - buildPerformanceTests(ctx, allTestSuiteInstalls["performance-tests"]) + packageTestSuite(ctx, allTestSuiteInstalls["performance-tests"], performanceTests) + packageTestSuite(ctx, allTestSuiteInstalls["device-platinum-tests"], devicePlatinumTests) +} + +type suiteKind int + +const ( + performanceTests suiteKind = iota + devicePlatinumTests +) + +func (sk suiteKind) String() string { + switch sk { + case performanceTests: + return "performance-tests" + case devicePlatinumTests: + return "device-platinum-tests" + default: + panic(fmt.Sprintf("Unrecognized suite kind %d for use in packageTestSuite", sk)) + } + return "" +} + +func (sk suiteKind) buildHostSharedLibsZip() bool { + switch sk { + case performanceTests: + return false + case devicePlatinumTests: + return true + } + return false } func buildTestSuite(ctx SingletonContext, suiteName string, files map[string]InstallPaths) (Path, Path) { @@ -250,16 +281,17 @@ func pathForTestCases(ctx PathContext) InstallPath { return pathForInstall(ctx, ctx.Config().BuildOS, X86, "testcases") } -func buildPerformanceTests(ctx SingletonContext, files Paths) { +func packageTestSuite(ctx SingletonContext, files Paths, sk suiteKind) { hostOutTestCases := pathForInstall(ctx, ctx.Config().BuildOSTarget.Os, ctx.Config().BuildOSTarget.Arch.ArchType, "testcases") targetOutTestCases := pathForInstall(ctx, ctx.Config().AndroidFirstDeviceTarget.Os, ctx.Config().AndroidFirstDeviceTarget.Arch.ArchType, "testcases") hostOut := filepath.Dir(hostOutTestCases.String()) targetOut := filepath.Dir(targetOutTestCases.String()) - testsZip := pathForPackaging(ctx, "performance-tests.zip") - testsListTxt := pathForPackaging(ctx, "performance-tests_list.txt") - testsListZip := pathForPackaging(ctx, "performance-tests_list.zip") - testsConfigsZip := pathForPackaging(ctx, "performance-tests_configs.zip") + testsZip := pathForPackaging(ctx, sk.String()+".zip") + testsListTxt := pathForPackaging(ctx, sk.String()+"_list.txt") + testsListZip := pathForPackaging(ctx, sk.String()+"_list.zip") + testsConfigsZip := pathForPackaging(ctx, sk.String()+"_configs.zip") + testsHostSharedLibsZip := pathForPackaging(ctx, sk.String()+"_host-shared-libs.zip") var listLines []string testsZipBuilder := NewRuleBuilder(pctx, ctx) @@ -308,8 +340,26 @@ func buildPerformanceTests(ctx SingletonContext, files Paths) { } } - testsZipBuilder.Build("performance_tests_zip", "building performance-tests zip") - testsConfigsZipBuilder.Build("performance_tests_configs_zip", "building performance-tests configs zip") + testsZipBuilder.Build(sk.String(), "building "+sk.String()+" zip") + testsConfigsZipBuilder.Build(sk.String()+"-configs", "building "+sk.String()+" configs zip") + + if sk.buildHostSharedLibsZip() { + testsHostSharedLibsZipBuilder := NewRuleBuilder(pctx, ctx) + testsHostSharedLibsZipCmd := testsHostSharedLibsZipBuilder.Command(). + BuiltTool("soong_zip"). + Flag("-d"). + FlagWithOutput("-o ", testsHostSharedLibsZip). + FlagWithArg("-P ", "host"). + FlagWithArg("-C ", hostOut) + + for _, f := range files { + if strings.HasPrefix(f.String(), hostOutTestCases.String()) && strings.HasSuffix(f.String(), ".so") { + testsHostSharedLibsZipCmd.FlagWithInput("-f ", f) + } + } + + testsHostSharedLibsZipBuilder.Build(sk.String()+"-host-shared-libs", "building "+sk.String()+"host shared libs") + } WriteFileRule(ctx, testsListTxt, strings.Join(listLines, "\n")) @@ -318,11 +368,14 @@ func buildPerformanceTests(ctx SingletonContext, files Paths) { BuiltTool("soong_zip"). Flag("-d"). FlagWithOutput("-o ", testsListZip). - FlagWithArg("-e ", "performance-tests_list"). + FlagWithArg("-e ", sk.String()+"_list"). FlagWithInput("-f ", testsListTxt) - testsListZipBuilder.Build("performance_tests_list_zip", "building performance-tests list zip") + testsListZipBuilder.Build(sk.String()+"_list_zip", "building "+sk.String()+" list zip") - ctx.Phony("performance-tests", testsZip) - ctx.DistForGoal("performance-tests", testsZip, testsListZip, testsConfigsZip) - ctx.Phony("tests", PathForPhony(ctx, "performance-tests")) + ctx.Phony(sk.String(), testsZip) + ctx.DistForGoal(sk.String(), testsZip, testsListZip, testsConfigsZip) + if sk.buildHostSharedLibsZip() { + ctx.DistForGoal(sk.String(), testsHostSharedLibsZip) + } + ctx.Phony("tests", PathForPhony(ctx, sk.String())) } -- cgit v1.2.3 From 44fccd1aef010a386c8be9da68cf3f50190917f5 Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Tue, 1 Apr 2025 13:26:22 -0700 Subject: Support DistForGoalWithFilenameTag in singleton context similar to http://ag/32805863, but for singletons. Test: m nothing Bug: 407562438 Change-Id: I03838b3af62b88fc1ff4f5dffaa872d1f342af45 --- android/singleton.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/android/singleton.go b/android/singleton.go index e5f26842a..64bafa31f 100644 --- a/android/singleton.go +++ b/android/singleton.go @@ -15,7 +15,9 @@ package android import ( + "path/filepath" "slices" + "strings" "sync" "github.com/google/blueprint" @@ -113,6 +115,11 @@ type SingletonContext interface { // goal is built. DistForGoalWithFilename(goal string, path Path, filename string) + // DistForGoalWithFilenameTag creates a rule to copy a Path to the artifacts + // directory on the build server with the given filename appended with the + // `-FILE_NAME_TAG_PLACEHOLDER` suffix when the specified goal is built. + DistForGoalWithFilenameTag(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) @@ -390,6 +397,15 @@ func (s *singletonContextAdaptor) DistForGoalWithFilename(goal string, path Path s.DistForGoalsWithFilename([]string{goal}, path, filename) } +func (s *singletonContextAdaptor) DistForGoalWithFilenameTag(goal string, path Path, filename string) { + insertBeforeExtension := func(file, insertion string) string { + ext := filepath.Ext(file) + return strings.TrimSuffix(file, ext) + insertion + ext + } + + s.DistForGoalWithFilename(goal, path, insertBeforeExtension(filename, "-FILE_NAME_TAG_PLACEHOLDER")) +} + func (s *singletonContextAdaptor) DistForGoals(goals []string, paths ...Path) { var copies distCopies for _, path := range paths { -- cgit v1.2.3 From d5d316e81d59a7ecb0b1ff002c316c62fb987b82 Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Mon, 31 Mar 2025 16:44:11 -0700 Subject: Dist test suites' symbols.zip in soong only build This change generates the build rules for the symbols.zip and the merged elf mapping proto file for the test suites that are listed in `test_suites` property of the modules. To prevent build rule collision with make, this is only enalbed on soong only build. Test: m cts dist --soong-only Bug: 407562438 Change-Id: I93bf64ffb089f7767e44a212b5063dfc8519e763 --- android/symbols.go | 16 ++++++++++++--- android/test_suites.go | 44 +++++++++++++++++++++++++++++++---------- ci_tests/ci_test_package_zip.go | 2 +- filesystem/android_device.go | 2 +- 4 files changed, 49 insertions(+), 15 deletions(-) diff --git a/android/symbols.go b/android/symbols.go index dea1e81ea..f6cabcf19 100644 --- a/android/symbols.go +++ b/android/symbols.go @@ -14,7 +14,11 @@ package android -import "github.com/google/blueprint" +import ( + "fmt" + + "github.com/google/blueprint" +) var zipFiles = pctx.AndroidStaticRule("SnapshotZipFiles", blueprint.RuleParams{ Command: `${SoongZipCmd} -r $out.rsp -o $out`, @@ -51,10 +55,16 @@ func (s *SymbolicOutputInfos) SortedUniqueElfMappingProtoPaths() Paths { return SortedUniquePaths(ret) } +// symbolsContext allows calling [BuildSymbolsZip] in both modules and singletons +type symbolsContext interface { + OtherModuleProviderContext + BuilderContext +} + // Defines the build rules to generate the symbols.zip file and the merged elf mapping textproto // file. Modules in depModules that provide [SymbolInfosProvider] and are exported to make // will be listed in the symbols.zip and the merged proto file. -func BuildSymbolsZip(ctx ModuleContext, depModules []Module, symbolsZipFile, mergedMappingProtoFile ModuleOutPath) { +func BuildSymbolsZip(ctx symbolsContext, depModules []Module, iden string, symbolsZipFile, mergedMappingProtoFile WritablePath) { var allSymbolicOutputPaths, allElfMappingProtoPaths Paths for _, mod := range depModules { if commonInfo, _ := OtherModuleProvider(ctx, mod, CommonModuleInfoProvider); commonInfo.SkipAndroidMkProcessing { @@ -81,5 +91,5 @@ func BuildSymbolsZip(ctx ModuleContext, depModules []Module, symbolsZipFile, mer Output(mergedMappingProtoFile). Inputs(allElfMappingProtoPaths) - dictMappingBuilder.Build("symbols_elf_dict_mapping_proto", "Building symbols mapping proto") + dictMappingBuilder.Build(fmt.Sprintf("%s_symbols_elf_dict_mapping_proto", iden), fmt.Sprintf("Building symbols mapping proto for %s", iden)) } diff --git a/android/test_suites.go b/android/test_suites.go index e28033b1f..1ddc52522 100644 --- a/android/test_suites.go +++ b/android/test_suites.go @@ -16,6 +16,7 @@ package android import ( "fmt" + "maps" "path/filepath" "slices" "sort" @@ -90,8 +91,14 @@ type testSuiteInstallsInfo struct { var testSuiteInstallsInfoProvider = blueprint.NewProvider[testSuiteInstallsInfo]() +type testModulesInstallsMap map[Module]InstallPaths + +func (t testModulesInstallsMap) testModules() []Module { + return slices.Collect(maps.Keys(t)) +} + func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) { - files := make(map[string]map[string]InstallPaths) + files := make(map[string]testModulesInstallsMap) allTestSuiteInstalls := make(map[string][]Path) var toInstall []filePair var oneVariantInstalls []filePair @@ -100,10 +107,9 @@ func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) { if tsm, ok := OtherModuleProvider(ctx, m, TestSuiteInfoProvider); ok { for _, testSuite := range tsm.TestSuites { if files[testSuite] == nil { - files[testSuite] = make(map[string]InstallPaths) + files[testSuite] = make(testModulesInstallsMap) } - name := ctx.ModuleName(m) - files[testSuite][name] = append(files[testSuite][name], + files[testSuite][m] = append(files[testSuite][m], OtherModuleProviderOrDefault(ctx, m, InstallFilesProvider).InstallFiles...) } @@ -134,6 +140,18 @@ func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) { } }) + if !ctx.Config().KatiEnabled() { + for _, testSuite := range SortedKeys(files) { + testSuiteSymbolsZipFile := pathForTestSymbols(ctx, fmt.Sprintf("%s-symbols.zip", testSuite)) + testSuiteMergedMappingProtoFile := pathForTestSymbols(ctx, fmt.Sprintf("%s-symbols-mapping.textproto", testSuite)) + allTestModules := files[testSuite].testModules() + BuildSymbolsZip(ctx, allTestModules, testSuite, testSuiteSymbolsZipFile, testSuiteMergedMappingProtoFile) + + ctx.DistForGoalWithFilenameTag(testSuite, testSuiteSymbolsZipFile, testSuiteSymbolsZipFile.Base()) + ctx.DistForGoalWithFilenameTag(testSuite, testSuiteMergedMappingProtoFile, testSuiteMergedMappingProtoFile.Base()) + } + } + for suite, suiteInstalls := range allTestSuiteInstalls { allTestSuiteInstalls[suite] = SortedUniquePaths(suiteInstalls) } @@ -216,19 +234,21 @@ func (sk suiteKind) buildHostSharedLibsZip() bool { return false } -func buildTestSuite(ctx SingletonContext, suiteName string, files map[string]InstallPaths) (Path, Path) { - var installedPaths InstallPaths - for _, module := range SortedKeys(files) { - installedPaths = append(installedPaths, files[module]...) +func buildTestSuite(ctx SingletonContext, suiteName string, files testModulesInstallsMap) (Path, Path) { + var installedPaths Paths + for _, module := range files.testModules() { + installedPaths = append(installedPaths, files[module].Paths()...) } + installedPaths = SortedUniquePaths(installedPaths) + outputFile := pathForPackaging(ctx, suiteName+".zip") rule := NewRuleBuilder(pctx, ctx) rule.Command().BuiltTool("soong_zip"). FlagWithOutput("-o ", outputFile). FlagWithArg("-P ", "host/testcases"). FlagWithArg("-C ", pathForTestCases(ctx).String()). - FlagWithRspFileInputList("-r ", outputFile.ReplaceExtension(ctx, "rsp"), installedPaths.Paths()). + FlagWithRspFileInputList("-r ", outputFile.ReplaceExtension(ctx, "rsp"), installedPaths). Flag("-sha256") // necessary to save cas_uploader's time testList := buildTestList(ctx, suiteName+"_list", installedPaths) @@ -245,7 +265,7 @@ func buildTestSuite(ctx SingletonContext, suiteName string, files map[string]Ins return outputFile, testListZipOutputFile } -func buildTestList(ctx SingletonContext, listFile string, installedPaths InstallPaths) Path { +func buildTestList(ctx SingletonContext, listFile string, installedPaths Paths) Path { buf := &strings.Builder{} for _, p := range installedPaths { if p.Ext() != ".config" { @@ -281,6 +301,10 @@ func pathForTestCases(ctx PathContext) InstallPath { return pathForInstall(ctx, ctx.Config().BuildOS, X86, "testcases") } +func pathForTestSymbols(ctx PathContext, pathComponents ...string) InstallPath { + return pathForInstall(ctx, ctx.Config().BuildOS, ctx.Config().BuildArch, "", pathComponents...) +} + func packageTestSuite(ctx SingletonContext, files Paths, sk suiteKind) { hostOutTestCases := pathForInstall(ctx, ctx.Config().BuildOSTarget.Os, ctx.Config().BuildOSTarget.Arch.ArchType, "testcases") targetOutTestCases := pathForInstall(ctx, ctx.Config().AndroidFirstDeviceTarget.Os, ctx.Config().AndroidFirstDeviceTarget.Arch.ArchType, "testcases") diff --git a/ci_tests/ci_test_package_zip.go b/ci_tests/ci_test_package_zip.go index 5ec1012d2..50ef0e0c7 100644 --- a/ci_tests/ci_test_package_zip.go +++ b/ci_tests/ci_test_package_zip.go @@ -219,7 +219,7 @@ func createOutput(ctx android.ModuleContext, pctx android.PackageContext) androi func createSymbolsZip(ctx android.ModuleContext, allModules []android.Module) { symbolsZipFile := android.PathForModuleOut(ctx, "symbols.zip") symbolsMappingFile := android.PathForModuleOut(ctx, "symbols-mapping.textproto") - android.BuildSymbolsZip(ctx, allModules, symbolsZipFile, symbolsMappingFile) + android.BuildSymbolsZip(ctx, allModules, ctx.ModuleName(), symbolsZipFile, symbolsMappingFile) ctx.SetOutputFiles(android.Paths{symbolsZipFile}, ".symbols") ctx.SetOutputFiles(android.Paths{symbolsMappingFile}, ".elf_mapping") diff --git a/filesystem/android_device.go b/filesystem/android_device.go index 217115b06..88a09dbd2 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -388,7 +388,7 @@ type symbolicOutputInfo struct { func (a *androidDevice) buildSymbolsZip(ctx android.ModuleContext, allInstalledModules []android.Module) { a.symbolsZipFile = android.PathForModuleOut(ctx, "symbols.zip") a.symbolsMappingFile = android.PathForModuleOut(ctx, "symbols-mapping.textproto") - android.BuildSymbolsZip(ctx, allInstalledModules, a.symbolsZipFile, a.symbolsMappingFile) + android.BuildSymbolsZip(ctx, allInstalledModules, ctx.ModuleName(), a.symbolsZipFile, a.symbolsMappingFile) } func (a *androidDevice) distInstalledFiles(ctx android.ModuleContext) { -- cgit v1.2.3 From cfb1be864769e9363cac22dba84b0080ed5158d2 Mon Sep 17 00:00:00 2001 From: Yu Liu Date: Tue, 1 Apr 2025 20:11:57 +0000 Subject: Convert ccdeps to use ModuleProxy. Bug: 377723687 Test: Unit tests and compare the ninja json and mk files generated. Change-Id: I2ce3dd67d86baa56e89880c5fb9d7dfdb643ae39 --- cc/cc.go | 32 ++++++++++++++++++++++++-------- cc/ccdeps.go | 41 +++++++++++++++++++++-------------------- 2 files changed, 45 insertions(+), 28 deletions(-) diff --git a/cc/cc.go b/cc/cc.go index ec594d075..887557d1c 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -174,14 +174,17 @@ type CcInfo struct { OdmAvailable bool ProductAvailable bool // Allowable SdkMemberTypes of this module type. - SdkMemberTypes []android.SdkMemberType - CompilerInfo *CompilerInfo - LinkerInfo *LinkerInfo - SnapshotInfo *SnapshotInfo - LibraryInfo *LibraryInfo - InstallerInfo *InstallerInfo - StlInfo *StlInfo - SanitizeInfo *SanitizeInfo + SdkMemberTypes []android.SdkMemberType + LocalFlags LocalOrGlobalFlagsInfo + GlobalFlags LocalOrGlobalFlagsInfo + SystemIncludeFlags []string + CompilerInfo *CompilerInfo + LinkerInfo *LinkerInfo + SnapshotInfo *SnapshotInfo + LibraryInfo *LibraryInfo + InstallerInfo *InstallerInfo + StlInfo *StlInfo + SanitizeInfo *SanitizeInfo } var CcInfoProvider = blueprint.NewProvider[*CcInfo]() @@ -2574,6 +2577,19 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { OdmAvailable: c.OdmAvailable(), ProductAvailable: c.ProductAvailable(), SdkMemberTypes: c.sdkMemberTypes, + LocalFlags: LocalOrGlobalFlagsInfo{ + CommonFlags: c.flags.Local.CommonFlags, + CFlags: c.flags.Local.CFlags, + ConlyFlags: c.flags.Local.ConlyFlags, + CppFlags: c.flags.Local.CppFlags, + }, + GlobalFlags: LocalOrGlobalFlagsInfo{ + CommonFlags: c.flags.Global.CommonFlags, + CFlags: c.flags.Global.CFlags, + ConlyFlags: c.flags.Global.ConlyFlags, + CppFlags: c.flags.Global.CppFlags, + }, + SystemIncludeFlags: c.flags.SystemIncludeFlags, } if c.compiler != nil { cflags := c.compiler.baseCompilerProps().Cflags diff --git a/cc/ccdeps.go b/cc/ccdeps.go index 4247778e8..fefd57f91 100644 --- a/cc/ccdeps.go +++ b/cc/ccdeps.go @@ -90,10 +90,10 @@ func (c *ccdepsGeneratorSingleton) GenerateBuildActions(ctx android.SingletonCon moduleDeps.C_clang = fmt.Sprintf("%s%s", buildCMakePath(pathToCC), cClang) moduleDeps.Cpp_clang = fmt.Sprintf("%s%s", buildCMakePath(pathToCC), cppClang) - ctx.VisitAllModules(func(module android.Module) { - if ccModule, ok := module.(*Module); ok { - if compiledModule, ok := ccModule.compiler.(CompiledInterface); ok { - generateCLionProjectData(ctx, compiledModule, ccModule, bestVariantFound, moduleInfos) + ctx.VisitAllModuleProxies(func(module android.ModuleProxy) { + if ccModule, ok := android.OtherModuleProvider(ctx, module, CcInfoProvider); ok { + if ccModule.CompilerInfo != nil { + generateCLionProjectData(ctx, module, ccModule, bestVariantFound, moduleInfos) } } }) @@ -169,11 +169,12 @@ func parseCompilerCCParameters(ctx android.SingletonContext, params []string) cc return compilerParams } -func generateCLionProjectData(ctx android.SingletonContext, compiledModule CompiledInterface, - ccModule *Module, bestVariantFound map[string]bool, moduleInfos map[string]ccIdeInfo) { - moduleName := ccModule.ModuleBase.Name() - srcs := compiledModule.Srcs() - +func generateCLionProjectData(ctx android.SingletonContext, module android.ModuleProxy, + ccModule *CcInfo, bestVariantFound map[string]bool, moduleInfos map[string]ccIdeInfo) { + commonInfo := android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoProvider) + moduleName := commonInfo.BaseModuleName + srcs := ccModule.CompilerInfo.Srcs + target := commonInfo.Target // Skip if best variant has already been found. if bestVariantFound[moduleName] { return @@ -185,7 +186,7 @@ func generateCLionProjectData(ctx android.SingletonContext, compiledModule Compi } // Check if device arch matches, in which case this is the best variant and takes precedence. - if ccModule.Device() && ccModule.ModuleBase.Arch().ArchType.Name == ctx.DeviceConfig().DeviceArch() { + if target.Os.Class == android.Device && target.Arch.ArchType.Name == ctx.DeviceConfig().DeviceArch() { bestVariantFound[moduleName] = true } else if _, ok := moduleInfos[moduleName]; ok { // Skip because this isn't the best variant and a previous one has already been added. @@ -195,20 +196,20 @@ func generateCLionProjectData(ctx android.SingletonContext, compiledModule Compi dpInfo := ccIdeInfo{} - dpInfo.Path = append(dpInfo.Path, path.Dir(ctx.BlueprintFile(ccModule))) + dpInfo.Path = append(dpInfo.Path, path.Dir(ctx.BlueprintFile(module))) dpInfo.Srcs = append(dpInfo.Srcs, srcs.Strings()...) dpInfo.Path = android.FirstUniqueStrings(dpInfo.Path) dpInfo.Srcs = android.FirstUniqueStrings(dpInfo.Srcs) - dpInfo.Global_Common_Flags = parseCompilerCCParameters(ctx, ccModule.flags.Global.CommonFlags) - dpInfo.Local_Common_Flags = parseCompilerCCParameters(ctx, ccModule.flags.Local.CommonFlags) - dpInfo.Global_C_flags = parseCompilerCCParameters(ctx, ccModule.flags.Global.CFlags) - dpInfo.Local_C_flags = parseCompilerCCParameters(ctx, ccModule.flags.Local.CFlags) - dpInfo.Global_C_only_flags = parseCompilerCCParameters(ctx, ccModule.flags.Global.ConlyFlags) - dpInfo.Local_C_only_flags = parseCompilerCCParameters(ctx, ccModule.flags.Local.ConlyFlags) - dpInfo.Global_Cpp_flags = parseCompilerCCParameters(ctx, ccModule.flags.Global.CppFlags) - dpInfo.Local_Cpp_flags = parseCompilerCCParameters(ctx, ccModule.flags.Local.CppFlags) - dpInfo.System_include_flags = parseCompilerCCParameters(ctx, ccModule.flags.SystemIncludeFlags) + dpInfo.Global_Common_Flags = parseCompilerCCParameters(ctx, ccModule.GlobalFlags.CommonFlags) + dpInfo.Local_Common_Flags = parseCompilerCCParameters(ctx, ccModule.LocalFlags.CommonFlags) + dpInfo.Global_C_flags = parseCompilerCCParameters(ctx, ccModule.GlobalFlags.CFlags) + dpInfo.Local_C_flags = parseCompilerCCParameters(ctx, ccModule.LocalFlags.CFlags) + dpInfo.Global_C_only_flags = parseCompilerCCParameters(ctx, ccModule.GlobalFlags.ConlyFlags) + dpInfo.Local_C_only_flags = parseCompilerCCParameters(ctx, ccModule.LocalFlags.ConlyFlags) + dpInfo.Global_Cpp_flags = parseCompilerCCParameters(ctx, ccModule.GlobalFlags.CppFlags) + dpInfo.Local_Cpp_flags = parseCompilerCCParameters(ctx, ccModule.LocalFlags.CppFlags) + dpInfo.System_include_flags = parseCompilerCCParameters(ctx, ccModule.SystemIncludeFlags) dpInfo.Module_name = moduleName -- cgit v1.2.3 From 1da6abbcccf2578e74a4dc1b675b2cc3ed5fc802 Mon Sep 17 00:00:00 2001 From: Brett Brotherton Date: Tue, 1 Apr 2025 15:36:25 -0600 Subject: add unit test for python shared_lib code Add some unit tests to cover the new code added to handle python modules with compiled shared libraries reland of ag/32805012 with gofmt + fix for host build target to be OS agnostic Bug: 403060602 Test: go test ./... Change-Id: I469450b3990f439869f5638d1620f17d3f38282d --- python/python.go | 1 - python/python_test.go | 89 ++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 85 insertions(+), 5 deletions(-) diff --git a/python/python.go b/python/python.go index de21e39bd..f0f25f5ab 100644 --- a/python/python.go +++ b/python/python.go @@ -108,7 +108,6 @@ type BaseProperties struct { // list of the Python libraries compatible both with Python2 and Python3. Libs []string `android:"arch_variant"` - // TODO: b/403060602 - add unit tests for this property and related code // list of shared libraries that should be packaged with the python code for this module. Shared_libs []string `android:"arch_variant"` diff --git a/python/python_test.go b/python/python_test.go index 5f971cdd1..a46b05a8f 100644 --- a/python/python_test.go +++ b/python/python_test.go @@ -37,7 +37,7 @@ type pyModule struct { var ( buildNamePrefix = "soong_python_test" - moduleVariantErrTemplate = `%s: module %q variant "[a-zA-Z0-9_]*": ` + moduleVariantErrTemplate = `%s: module %q variant "[a-zA-Z0-9_\-]*": ` pkgPathErrTemplate = moduleVariantErrTemplate + "pkg_path: %q must be a relative path contained in par file." badIdentifierErrTemplate = moduleVariantErrTemplate + @@ -46,9 +46,11 @@ var ( "found two files to be placed at the same location within zip %q." + " First file: in module %s at path %q." + " Second file: in module %s at path %q." - badSrcFileExtErr = moduleVariantErrTemplate + `srcs: found non \(.py\|.proto\) file: %q!` - badDataFileExtErr = moduleVariantErrTemplate + `data: found \(.py\) file: %q!` - bpFile = "Android.bp" + badSrcFileExtErr = moduleVariantErrTemplate + `srcs: found non \(.py\|.proto\) file: %q!` + badDataFileExtErr = moduleVariantErrTemplate + `data: found \(.py\) file: %q!` + sharedLibErrTemplate = moduleVariantErrTemplate + + "shared_libs: shared_libs is not supported for device builds" + bpFile = "Android.bp" data = []struct { desc string @@ -206,6 +208,27 @@ var ( "lib1", "dir/c/file1.py"), }, }, + { + desc: "device module with shared libs", + mockFiles: map[string][]byte{ + filepath.Join("dir", bpFile): []byte( + `python_library { + name: "lib1", + srcs: [ + "file1.py", + ], + shared_libs: [ + "clib1", + ], + }`, + ), + "dir/file1.py": nil, + }, + errors: []string{ + fmt.Sprintf(sharedLibErrTemplate, + "dir/Android.bp:6:18", "lib1"), + }, + }, } ) @@ -312,6 +335,64 @@ func TestInvalidTestOnlyTargets(t *testing.T) { } } +func TestSharedLib(t *testing.T) { + ctx := android.GroupFixturePreparers( + android.PrepareForTestWithDefaults, + android.PrepareForTestWithArchMutator, + android.PrepareForTestWithAllowMissingDependencies, + cc.PrepareForTestWithCcDefaultModules, + PrepareForTestWithPythonBuildComponents, + ).RunTestWithBp( + t, + `python_library_host { + name: "py-lib-host", + srcs: ["py-lib-host.py"], + shared_libs: ["clib-host"], + } + + cc_library_shared { + name: "clib-host", + host_supported: true, + shared_libs: ["clib-host-2"], + } + + cc_library_shared { + name: "clib-host-2", + host_supported: true, + }`, + ) + if len(ctx.Errs) > 0 { + t.Errorf("Expected got: %s, want: 0 errs", ctx.Errs) + } + + mod, modOk := ctx.ModuleForTests(t, "py-lib-host", ctx.Config.BuildOSTarget.String()).Module().(*PythonLibraryModule) + if !modOk { + t.Fatalf("py-lib-host is not Python library!") + } + // ensure the shared lib is included in the data path mappings + dataPathMappings := mod.getDataPathMappings() + if len(dataPathMappings) != 1 { + t.Fatalf("expected 1 data file, got: %d", len(dataPathMappings)) + } + android.AssertStringMatches( + t, + "data path included shared lib", + "clib-host.so", + dataPathMappings[0].dest, + ) + // ensure any dependencies of the shared lib are included in the bundle shared + // libs + android.AssertPathsEndWith( + t, + "shared libs", + []string{ + "clib-host-2.so", + "libc++.so", + }, + mod.getBundleSharedLibs(), + ) +} + func expectModule(t *testing.T, ctx *android.TestContext, name, variant, expectedSrcsZip string, expectedPyRunfiles []string) { module := ctx.ModuleForTests(t, name, variant) -- cgit v1.2.3 From fe10de51d3173ac8edce8a4de4dce3827e136346 Mon Sep 17 00:00:00 2001 From: mrziwang Date: Tue, 1 Apr 2025 15:59:45 -0700 Subject: Remove SupportFilesInfo Provider TestSuiteInfoProvider has support files info already Test: CI Change-Id: I0085917ce48995f7f73ca24c1ed40b5e6d0eb380 --- android/test_suites.go | 6 ------ tradefed_modules/test_module_config.go | 7 ------- 2 files changed, 13 deletions(-) diff --git a/android/test_suites.go b/android/test_suites.go index e28033b1f..74293ca21 100644 --- a/android/test_suites.go +++ b/android/test_suites.go @@ -72,12 +72,6 @@ type TestSuiteInfo struct { var TestSuiteInfoProvider = blueprint.NewProvider[TestSuiteInfo]() -type SupportFilesInfo struct { - SupportFiles InstallPaths -} - -var SupportFilesInfoProvider = blueprint.NewProvider[SupportFilesInfo]() - type filePair struct { src Path dst WritablePath diff --git a/tradefed_modules/test_module_config.go b/tradefed_modules/test_module_config.go index 62d1bcead..10f7c8f33 100644 --- a/tradefed_modules/test_module_config.go +++ b/tradefed_modules/test_module_config.go @@ -179,10 +179,6 @@ func (m *testModuleConfigModule) GenerateAndroidBuildActions(ctx android.ModuleC moduleInfoJSON.TestConfig = []string{m.testConfig.String()} moduleInfoJSON.AutoTestConfig = []string{"true"} moduleInfoJSON.TestModuleConfigBase = proptools.String(m.Base) - - android.SetProvider(ctx, android.SupportFilesInfoProvider, android.SupportFilesInfo{ - SupportFiles: m.supportFiles, - }) } // Ensure at least one test_suite is listed. Ideally it should be general-tests @@ -332,9 +328,6 @@ func (m *testModuleConfigHostModule) DepsMutator(ctx android.BottomUpMutatorCont func (m *testModuleConfigHostModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { m.validateBase(ctx, &testModuleConfigHostTag, "java_test_host", true) m.generateManifestAndConfig(ctx) - android.SetProvider(ctx, android.SupportFilesInfoProvider, android.SupportFilesInfo{ - SupportFiles: m.supportFiles, - }) } // Ensure the base listed is the right type by checking that we get the expected provider data. -- cgit v1.2.3 From fcdb829ce6acb7c197ad8e060f6028c9016cce39 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Tue, 1 Apr 2025 20:54:43 +0000 Subject: Import PRODUCT_HOST_PACKAGES in Soong Unlike PRODUCT_PACKAGES which has been added to `PartitionVarsForSoongMigrationOnlyDoNotUse`, this will be part of the ProductVariables API Bug: 407560033 Test: presubmits Change-Id: I797a4c8dd34c17b73a488bdd1298338a0ab2a041 --- android/variable.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/android/variable.go b/android/variable.go index b5ffa7cf8..e1f667cf5 100644 --- a/android/variable.go +++ b/android/variable.go @@ -552,6 +552,9 @@ type ProductVariables struct { StripByDefault *bool `json:",omitempty"` CompatibilityTestcases map[string]CompatibilityTestcaseJSON + + // Will be used to install host tools in soong only builds + ProductHostPackages []string `json:",omitempty"` } type CompatibilityTestcaseJSON struct { -- cgit v1.2.3 From 9f29ac1033c72ac0acb60d6e7c5a74e2576b3f9f Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Tue, 1 Apr 2025 22:37:21 +0000 Subject: Install PRODUCT_HOST_PACKAGES in soong-only builds Bug: 407560033 Test: lunch aosp_cf_x86_64_phone-trunk_staging-userdebug && m nothing Test: aninja -t path droid out/host/linux-x86/bin/adevice # path exists Change-Id: I7951a4aa90a5492ecd69e9e432e8f02a5035a993 --- filesystem/android_device.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/filesystem/android_device.go b/filesystem/android_device.go index 217115b06..b42446fea 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -302,6 +302,13 @@ func (a *androidDevice) GenerateAndroidBuildActions(ctx android.ModuleContext) { } else { buildComplianceMetadata(ctx, filesystemDepTag) } + + // Add the host tools as deps + if !ctx.Config().KatiEnabled() && proptools.Bool(a.deviceProps.Main_device) { + for _, hostTool := range ctx.Config().ProductVariables().ProductHostPackages { + ctx.Phony("droid", android.PathForPhony(ctx, hostTool+"-host")) + } + } } func buildComplianceMetadata(ctx android.ModuleContext, tags ...blueprint.DependencyTag) { -- cgit v1.2.3 From bff263273a9e08db7e4ad42cfd443d4c57c1c078 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Tue, 1 Apr 2025 14:36:42 -0700 Subject: Disable memory profiling when it is not in use Go enables memory profile collection automatically if any references are linked in to the binary. Since soong_build conditionally saves memory profiles based on the -memprofile argument (which propagates from the SOONG_PROFILE_MEM environment variable) the runtime always has memory profile collection enabled, which involves collecting a stack trace and other allocation metadata approximately every 512kB of allocattions. Set runtime.MemProfileRate to 0 when the -memprofile argument is not provided to disable the tracing, reducing analysis time by 5%. Test: manual Change-Id: I59670013a1710e537744677d192328ee46940b74 --- cmd/soong_build/main.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go index b707112fe..c01ae6294 100644 --- a/cmd/soong_build/main.go +++ b/cmd/soong_build/main.go @@ -21,6 +21,7 @@ import ( "fmt" "os" "path/filepath" + "runtime" "strings" "time" @@ -28,13 +29,14 @@ import ( "android/soong/android/allowlists" "android/soong/shared" + androidProtobuf "google.golang.org/protobuf/android" + "github.com/google/blueprint" "github.com/google/blueprint/bootstrap" "github.com/google/blueprint/deptools" "github.com/google/blueprint/metrics" "github.com/google/blueprint/pathtools" "github.com/google/blueprint/proptools" - androidProtobuf "google.golang.org/protobuf/android" ) var ( @@ -330,6 +332,12 @@ func parseAvailableEnv() map[string]string { func main() { flag.Parse() + if cmdlineArgs.Memprofile == "" { + // Go enables memory profile collection automatically if any references + // are linked in to the binary. + // Disable collection of memory profiles if we won't save one to disk. + runtime.MemProfileRate = 0 + } soongStartTime := time.Now() shared.ReexecWithDelveMaybe(delveListen, delvePath) -- cgit v1.2.3 From 990f3d3ff9d080ae545001331ef9b5064ba5c3be Mon Sep 17 00:00:00 2001 From: LaMont Jones Date: Tue, 1 Apr 2025 13:22:25 -0700 Subject: Disable stub validation for partial compile Disable stub validation when SOONG_PARTIAL_COMPILE=true. If there would have been stub validation, it is now available as the ninja target `{MODULE_NAME}-stub-validation`. Drop disable_api_lint from Partial Compile. It would only have effect on userdebug builds or during `m checkapi`. Bug: b/396345437 Test: manual, TH Change-Id: Id02d2fdf4e59b2a744f45ae7a8f095622e3173d4 --- android/config.go | 40 +++++++++++++++++----------------------- android/config_test.go | 15 +-------------- java/droiddoc.go | 3 --- java/droidstubs.go | 5 +---- java/java.go | 11 +++++++++-- 5 files changed, 28 insertions(+), 46 deletions(-) diff --git a/android/config.go b/android/config.go index 8d443028b..bf952d71e 100644 --- a/android/config.go +++ b/android/config.go @@ -408,14 +408,12 @@ type partialCompileFlags struct { // Whether to use d8 instead of r8 Use_d8 bool - // Whether to disable stub validation. This is slightly more surgical - // than DISABLE_STUB_VALIDATION, in that it only applies to partial - // compile builds. + // Whether to disable stub validation for partial compile builds. + // This is similar to setting `DISABLE_STUB_VALIDATION=true`: the + // validation checks are still created, but are not run by default. + // To run the validation checks, use `m {MODULE_NAME}-stub-validation`. Disable_stub_validation bool - // Whether to disable api lint. - Disable_api_lint bool - // Add others as needed. } @@ -425,8 +423,13 @@ var defaultPartialCompileFlags = partialCompileFlags{} // These are the flags when `SOONG_PARTIAL_COMPILE=true`. var enabledPartialCompileFlags = partialCompileFlags{ Use_d8: true, - Disable_stub_validation: false, - Disable_api_lint: false, + Disable_stub_validation: true, +} + +// These are the flags when `SOONG_PARTIAL_COMPILE=all`. +var allPartialCompileFlags = partialCompileFlags{ + Use_d8: true, + Disable_stub_validation: true, } type deviceConfig struct { @@ -501,24 +504,15 @@ func (c *config) parsePartialCompileFlags(isEngBuild bool) (partialCompileFlags, state = "+" } switch tok { - case "all": - // Turn on **all** of the flags. - ret = partialCompileFlags{ - Use_d8: true, - Disable_stub_validation: true, - Disable_api_lint: true, - } - case "true": - ret = enabledPartialCompileFlags + // Big toggle switches. case "false": - // Set everything to false. ret = partialCompileFlags{} + case "true": + ret = enabledPartialCompileFlags + case "all": + ret = allPartialCompileFlags - case "api_lint", "enable_api_lint": - ret.Disable_api_lint = !makeVal(state, !defaultPartialCompileFlags.Disable_api_lint) - case "disable_api_lint": - ret.Disable_api_lint = makeVal(state, defaultPartialCompileFlags.Disable_api_lint) - + // Individual flags. case "stub_validation", "enable_stub_validation": ret.Disable_stub_validation = !makeVal(state, !defaultPartialCompileFlags.Disable_stub_validation) case "disable_stub_validation": diff --git a/android/config_test.go b/android/config_test.go index 81b7c3eb5..22827f58e 100644 --- a/android/config_test.go +++ b/android/config_test.go @@ -218,11 +218,6 @@ func (p partialCompileFlags) updateUseD8(value bool) partialCompileFlags { return p } -func (p partialCompileFlags) updateDisableApiLint(value bool) partialCompileFlags { - p.Disable_api_lint = value - return p -} - func (p partialCompileFlags) updateDisableStubValidation(value bool) partialCompileFlags { p.Disable_stub_validation = value return p @@ -246,7 +241,7 @@ func TestPartialCompile(t *testing.T) { {"false", true, partialCompileFlags{}}, {"true", true, enabledPartialCompileFlags}, {"true", false, partialCompileFlags{}}, - {"all", true, partialCompileFlags{}.updateUseD8(true).updateDisableApiLint(true).updateDisableStubValidation(true)}, + {"all", true, partialCompileFlags{}.updateUseD8(true).updateDisableStubValidation(true)}, // This verifies both use_d8 and the processing order. {"true,use_d8", true, enabledPartialCompileFlags.updateUseD8(true)}, @@ -254,14 +249,6 @@ func TestPartialCompile(t *testing.T) { {"use_d8,false", true, partialCompileFlags{}}, {"false,+use_d8", true, partialCompileFlags{}.updateUseD8(true)}, - // disable_api_lint can be specified with any of 3 options. - {"false,-api_lint", true, partialCompileFlags{}.updateDisableApiLint(true)}, - {"false,-enable_api_lint", true, partialCompileFlags{}.updateDisableApiLint(true)}, - {"false,+disable_api_lint", true, partialCompileFlags{}.updateDisableApiLint(true)}, - {"false,+api_lint", true, partialCompileFlags{}.updateDisableApiLint(false)}, - {"false,+enable_api_lint", true, partialCompileFlags{}.updateDisableApiLint(false)}, - {"false,-disable_api_lint", true, partialCompileFlags{}.updateDisableApiLint(false)}, - // disable_stub_validation can be specified with any of 3 options. {"false,-stub_validation", true, partialCompileFlags{}.updateDisableStubValidation(true)}, {"false,-enable_stub_validation", true, partialCompileFlags{}.updateDisableStubValidation(true)}, diff --git a/java/droiddoc.go b/java/droiddoc.go index 3faf294de..225f201a9 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -195,9 +195,6 @@ func apiCheckEnabled(ctx android.ModuleContext, apiToCheck ApiToCheck, apiVersio "them instead.") } return false - } else if ctx.Config().PartialCompileFlags().Disable_stub_validation && - !ctx.Config().BuildFromTextStub() { - return false } else if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" { return true } else if String(apiToCheck.Api_file) != "" { diff --git a/java/droidstubs.go b/java/droidstubs.go index b30c8448a..3498f30ff 100644 --- a/java/droidstubs.go +++ b/java/droidstubs.go @@ -1251,7 +1251,7 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Add options for the other optional tasks: API-lint and check-released. // We generate separate timestamp files for them. - doApiLint := BoolDefault(d.properties.Check_api.Api_lint.Enabled, false) && !ctx.Config().PartialCompileFlags().Disable_api_lint + doApiLint := BoolDefault(d.properties.Check_api.Api_lint.Enabled, false) doCheckReleased := apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") writeSdkValues := Bool(d.properties.Write_sdk_values) @@ -1380,15 +1380,12 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { if d.apiLintTimestamp != nil { cmd.Validation(d.apiLintTimestamp) } - if d.checkLastReleasedApiTimestamp != nil { cmd.Validation(d.checkLastReleasedApiTimestamp) } - if d.checkNullabilityWarningsTimestamp != nil { cmd.Validation(d.checkNullabilityWarningsTimestamp) } - rule.Build("metalavaCurrentApiCheck", "check current API") d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "update_current_api.timestamp") diff --git a/java/java.go b/java/java.go index 18920aa11..34e76181e 100644 --- a/java/java.go +++ b/java/java.go @@ -2568,7 +2568,6 @@ func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { apiContributions := al.properties.Api_contributions addValidations := !ctx.Config().IsEnvTrue("DISABLE_STUB_VALIDATION") && !ctx.Config().IsEnvTrue("WITHOUT_CHECK_API") && - !ctx.Config().PartialCompileFlags().Disable_stub_validation && proptools.BoolDefault(al.properties.Enable_validation, true) for _, apiContributionName := range apiContributions { ctx.AddDependency(ctx.Module(), javaApiContributionTag, apiContributionName) @@ -2744,7 +2743,15 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { cmd.FlagForEachInput("--migrate-nullness ", previousApiFiles) } - al.addValidation(ctx, cmd, al.validationPaths) + // While we could use SOONG_USE_PARTIAL_COMPILE in the validation's rule, that would unduly + // complicate the code for minimal benefit. Instead, add a phony + // target to let the developer manually run the validation if they so + // desire. + ctx.Phony("stub-validation", al.validationPaths...) + ctx.Phony(ctx.ModuleName()+"-stub-validation", al.validationPaths...) + if !ctx.Config().PartialCompileFlags().Disable_stub_validation { + al.addValidation(ctx, cmd, al.validationPaths) + } generateRevertAnnotationArgs(ctx, cmd, al.stubsType, al.aconfigProtoFiles) -- cgit v1.2.3 From bb79e3f9a52419e7dca593215cc9d96371f62041 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Wed, 2 Apr 2025 17:18:48 +0000 Subject: Handle phony target generation for override modules in Soong-only The build actions of override modules happens in an "override variant" of the overriden app. ctx.ModuleName() of this variant is always com.android.foo due to which `m com.$company.android.foo` in soong only builds does not build anything. Replace ctx.ModuleName() with BaseModuleName to match the behavior in Make+soong builds Test: lunch aosp_cf_x86_64_phone-trunk_staging-userbug && m nothing Test: aninja -t query com.android.heathfitness-install Before and after diff https://diff.googleplex.com/#key=lu5yN9IQEZIg Test: aninja -t query com.google.android.healthfitness-install # no longer empty Bug: 406510107 Change-Id: Ia1227f5a516cdd5aca80b1088d80a83750c53adb --- android/module.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/android/module.go b/android/module.go index 42b4ef198..b61b5941a 100644 --- a/android/module.go +++ b/android/module.go @@ -1688,8 +1688,8 @@ func (m *ModuleBase) generateVariantTarget(ctx *moduleContext) { namespacePrefix = namespacePrefix + "-" } - if !ctx.uncheckedModule { - name := namespacePrefix + ctx.ModuleName() + "-" + ctx.ModuleSubDir() + "-checkbuild" + if !ctx.uncheckedModule && !shouldSkipAndroidMkProcessing(ctx, m) { + name := namespacePrefix + ctx.module.base().BaseModuleName() + "-" + ctx.ModuleSubDir() + "-checkbuild" ctx.Phony(name, ctx.checkbuildFiles...) ctx.checkbuildTarget = PathForPhony(ctx, name) } @@ -1710,7 +1710,7 @@ func (m *ModuleBase) generateModuleTarget(ctx *moduleContext, testSuiteInstalls var info ModuleBuildTargetsInfo if len(ctx.installFiles) > 0 { - name := namespacePrefix + ctx.ModuleName() + "-install" + name := namespacePrefix + ctx.module.base().BaseModuleName() + "-install" installFiles := ctx.installFiles.Paths() ctx.Phony(name, installFiles...) info.InstallTarget = PathForPhony(ctx, name) @@ -1722,13 +1722,13 @@ func (m *ModuleBase) generateModuleTarget(ctx *moduleContext, testSuiteInstalls // Those could depend on the build target and fail to compile // for the current build target. if (!ctx.Config().KatiEnabled() || !shouldSkipAndroidMkProcessing(ctx, m)) && !ctx.uncheckedModule && ctx.checkbuildTarget != nil { - name := namespacePrefix + ctx.ModuleName() + "-checkbuild" + name := namespacePrefix + ctx.module.base().BaseModuleName() + "-checkbuild" ctx.Phony(name, ctx.checkbuildTarget) deps = append(deps, ctx.checkbuildTarget) } if outputFiles, err := outputFilesForModule(ctx, ctx.Module(), ""); err == nil && len(outputFiles) > 0 { - name := namespacePrefix + ctx.ModuleName() + "-outputs" + name := namespacePrefix + ctx.module.base().BaseModuleName() + "-outputs" ctx.Phony(name, outputFiles...) deps = append(deps, outputFiles...) } @@ -1743,16 +1743,16 @@ func (m *ModuleBase) generateModuleTarget(ctx *moduleContext, testSuiteInstalls suffix = "-soong" } - ctx.Phony(namespacePrefix+ctx.ModuleName()+suffix, deps...) + ctx.Phony(namespacePrefix+ctx.module.base().BaseModuleName()+suffix, deps...) if ctx.Device() { // Generate a target suffix for use in atest etc. - ctx.Phony(namespacePrefix+ctx.ModuleName()+"-target"+suffix, deps...) + ctx.Phony(namespacePrefix+ctx.module.base().BaseModuleName()+"-target"+suffix, deps...) } else { // Generate a host suffix for use in atest etc. - ctx.Phony(namespacePrefix+ctx.ModuleName()+"-host"+suffix, deps...) + ctx.Phony(namespacePrefix+ctx.module.base().BaseModuleName()+"-host"+suffix, deps...) if ctx.Target().HostCross { // Generate a host-cross suffix for use in atest etc. - ctx.Phony(namespacePrefix+ctx.ModuleName()+"-host-cross"+suffix, deps...) + ctx.Phony(namespacePrefix+ctx.module.base().BaseModuleName()+"-host-cross"+suffix, deps...) } } -- cgit v1.2.3 From a2215262f3263e8d965a20ac5c24803f24e7e110 Mon Sep 17 00:00:00 2001 From: Wei Li Date: Wed, 2 Apr 2025 17:09:21 -0700 Subject: Add property "licenses" on auto-generated module for system_other.avbpubkey Bug: 406019430 Test: presubmits Change-Id: I3aaf75e9ea8c1d6353c12b7bdf3000520337ba66 --- fsgen/prebuilt_etc_modules_gen.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fsgen/prebuilt_etc_modules_gen.go b/fsgen/prebuilt_etc_modules_gen.go index c0f114caf..b675b0dc0 100644 --- a/fsgen/prebuilt_etc_modules_gen.go +++ b/fsgen/prebuilt_etc_modules_gen.go @@ -423,12 +423,14 @@ func createAvbpubkeyModule(ctx android.LoadHookContext) bool { Private_key *string No_full_install *bool Visibility []string + Licenses []string }{ Name: proptools.StringPtr("system_other_avbpubkey"), Product_specific: proptools.BoolPtr(true), Private_key: proptools.StringPtr(avbKeyPath), No_full_install: proptools.BoolPtr(true), Visibility: []string{"//visibility:public"}, + Licenses: []string{"Android-Apache-2.0"}, }, ) return true -- cgit v1.2.3 From 0485a8080ea23bd4c9c809b916787dfad774ceaa Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Thu, 3 Apr 2025 16:50:01 +0000 Subject: Fix path extension for mac compatibility Shared libs have .dylib extension on macs Test: go test ./python (on my linux) Test: will use go/abtd for mac Change-Id: Ic0bdbcebe7a3322e332b49630a2cd6e668108a16 --- python/python_test.go | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/python/python_test.go b/python/python_test.go index a46b05a8f..ef8ae25c5 100644 --- a/python/python_test.go +++ b/python/python_test.go @@ -377,20 +377,24 @@ func TestSharedLib(t *testing.T) { android.AssertStringMatches( t, "data path included shared lib", - "clib-host.so", dataPathMappings[0].dest, + "clib-host(.so|.dylib)", ) // ensure any dependencies of the shared lib are included in the bundle shared // libs - android.AssertPathsEndWith( + android.AssertStringMatches( t, "shared libs", - []string{ - "clib-host-2.so", - "libc++.so", - }, - mod.getBundleSharedLibs(), + mod.getBundleSharedLibs()[0].String(), + "clib-host-2(.so|.dylib)$", ) + android.AssertStringMatches( + t, + "shared libs", + mod.getBundleSharedLibs()[1].String(), + "libc\\+\\+(.so|.dylib)$", + ) + } func expectModule(t *testing.T, ctx *android.TestContext, name, variant, expectedSrcsZip string, expectedPyRunfiles []string) { -- cgit v1.2.3 From 81bc22663340229da6c89e0679e8fa16e4d0e8ea Mon Sep 17 00:00:00 2001 From: Yu Liu Date: Wed, 2 Apr 2025 21:06:41 +0000 Subject: Change WalkDeps in apex.go to WalkDepsProxy. Bug: 377723687 Test: Unit tests and compare the ninja json and mk files generated. Change-Id: I31f3327112b8fa5e45cd9edd3a5397c8d1b7a64e --- android/module.go | 6 ++- apex/androidmk.go | 60 ++++++++++++----------- apex/apex.go | 140 +++++++++++++++++++++++++++++++++++------------------- apex/builder.go | 8 ++-- cc/androidmk.go | 8 ---- cc/cc.go | 11 +---- cc/library.go | 4 -- java/androidmk.go | 2 +- java/app.go | 17 +++++-- java/app_set.go | 9 ++-- java/base.go | 2 + java/java.go | 17 +++++++ 12 files changed, 171 insertions(+), 113 deletions(-) diff --git a/android/module.go b/android/module.go index 42b4ef198..3f3d5b401 100644 --- a/android/module.go +++ b/android/module.go @@ -1979,7 +1979,10 @@ type CommonModuleInfo struct { PrebuiltSourceExists bool UsePrebuilt bool ApexAvailable []string - ImageVariation blueprint.Variation + // This field is different from the above one as it can have different values + // for cc, java library and sdkLibraryXml. + ApexAvailableFor []string + ImageVariation blueprint.Variation } type ApiLevelOrPlatform struct { @@ -2387,6 +2390,7 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) commonData.IsInstallableToApex = am.IsInstallableToApex() commonData.IsApexModule = true commonData.ApexAvailable = am.apexModuleBase().ApexAvailable() + commonData.ApexAvailableFor = am.ApexAvailableFor() } if _, ok := m.module.(ModuleWithMinSdkVersionCheck); ok { diff --git a/apex/androidmk.go b/apex/androidmk.go index 0a5644ae3..f1097275e 100644 --- a/apex/androidmk.go +++ b/apex/androidmk.go @@ -21,9 +21,7 @@ import ( "strings" "android/soong/android" - "android/soong/cc" "android/soong/java" - "android/soong/rust" ) func (a *apexBundle) AndroidMk() android.AndroidMkData { @@ -118,8 +116,8 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, apexBundleName, moduleDir st } fmt.Fprintln(w, "LOCAL_MODULE :=", moduleName) - if fi.module != nil && fi.module.Owner() != "" { - fmt.Fprintln(w, "LOCAL_MODULE_OWNER :=", fi.module.Owner()) + if fi.providers != nil && fi.providers.commonInfo.Owner != "" { + fmt.Fprintln(w, "LOCAL_MODULE_OWNER :=", fi.providers.commonInfo.Owner) } // /apex//{lib|framework|...} pathForSymbol := filepath.Join("$(PRODUCT_OUT)", "apex", apexBundleName, fi.installDir) @@ -143,10 +141,10 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, apexBundleName, moduleDir st fmt.Fprintln(w, "LOCAL_CHECKED_MODULE :=", fi.builtFile.String()) } fmt.Fprintln(w, "LOCAL_MODULE_CLASS :=", fi.class.nameInMake()) - if fi.module != nil { + if fi.providers != nil { // This apexFile's module comes from Soong - if fi.module.Target().Arch.ArchType != android.Common { - archStr := fi.module.Target().Arch.ArchType.String() + if fi.providers.commonInfo.Target.Arch.ArchType != android.Common { + archStr := fi.providers.commonInfo.Target.Arch.ArchType.String() fmt.Fprintln(w, "LOCAL_MODULE_TARGET_ARCH :=", archStr) } } @@ -159,9 +157,10 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, apexBundleName, moduleDir st // we need to remove the suffix from LOCAL_MODULE_STEM, otherwise // we will have foo.jar.jar fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", strings.TrimSuffix(fi.stem(), ".jar")) - if javaModule, ok := fi.module.(java.ApexDependency); ok { - fmt.Fprintln(w, "LOCAL_SOONG_CLASSES_JAR :=", javaModule.ImplementationAndResourcesJars()[0].String()) - fmt.Fprintln(w, "LOCAL_SOONG_HEADER_JAR :=", javaModule.HeaderJars()[0].String()) + if fi.providers != nil && fi.providers.javaInfo != nil && fi.providers.javaInfo.ApexDependencyInfo != nil { + apexInfo := fi.providers.javaInfo.ApexDependencyInfo + fmt.Fprintln(w, "LOCAL_SOONG_CLASSES_JAR :=", apexInfo.ImplementationAndResourcesJars[0].String()) + fmt.Fprintln(w, "LOCAL_SOONG_HEADER_JAR :=", apexInfo.HeaderJars[0].String()) } else { fmt.Fprintln(w, "LOCAL_SOONG_CLASSES_JAR :=", fi.builtFile.String()) fmt.Fprintln(w, "LOCAL_SOONG_HEADER_JAR :=", fi.builtFile.String()) @@ -175,34 +174,39 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, apexBundleName, moduleDir st // we need to remove the suffix from LOCAL_MODULE_STEM, otherwise // we will have foo.apk.apk fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", strings.TrimSuffix(fi.stem(), ".apk")) - if app, ok := fi.module.(*java.AndroidApp); ok { - android.AndroidMkEmitAssignList(w, "LOCAL_PREBUILT_COVERAGE_ARCHIVE", app.JniCoverageOutputs().Strings()) - if jniLibSymbols := app.JNISymbolsInstalls(modulePath); len(jniLibSymbols) > 0 { + if fi.providers != nil && fi.providers.appInfo != nil { + appInfo := fi.providers.appInfo + android.AndroidMkEmitAssignList(w, "LOCAL_PREBUILT_COVERAGE_ARCHIVE", appInfo.JniCoverageOutputs.Strings()) + if jniLibSymbols := java.JNISymbolsInstalls(appInfo.JniLibs, modulePath); len(jniLibSymbols) > 0 { fmt.Fprintln(w, "LOCAL_SOONG_JNI_LIBS_SYMBOLS :=", jniLibSymbols.String()) } } fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_app_prebuilt.mk") case appSet: - as, ok := fi.module.(*java.AndroidAppSet) - if !ok { + if fi.providers == nil || fi.providers.appInfo == nil { panic(fmt.Sprintf("Expected %s to be AndroidAppSet", fi.module)) } - fmt.Fprintln(w, "LOCAL_APK_SET_INSTALL_FILE :=", as.PackedAdditionalOutputs().String()) - fmt.Fprintln(w, "LOCAL_APKCERTS_FILE :=", as.APKCertsFile().String()) + appInfo := fi.providers.appInfo + fmt.Fprintln(w, "LOCAL_APK_SET_INSTALL_FILE :=", appInfo.PackedAdditionalOutputs.String()) + fmt.Fprintln(w, "LOCAL_APKCERTS_FILE :=", appInfo.ApkCertsFile.String()) fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_android_app_set.mk") case nativeSharedLib, nativeExecutable, nativeTest: fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", fi.stem()) - if ccMod, ok := fi.module.(*cc.Module); ok { - if ccMod.UnstrippedOutputFile() != nil { - fmt.Fprintln(w, "LOCAL_SOONG_UNSTRIPPED_BINARY :=", ccMod.UnstrippedOutputFile().String()) - } - ccMod.AndroidMkWriteAdditionalDependenciesForSourceAbiDiff(w) - if ccMod.CoverageOutputFile().Valid() { - fmt.Fprintln(w, "LOCAL_PREBUILT_COVERAGE_ARCHIVE :=", ccMod.CoverageOutputFile().String()) - } - } else if rustMod, ok := fi.module.(*rust.Module); ok { - if rustMod.UnstrippedOutputFile() != nil { - fmt.Fprintln(w, "LOCAL_SOONG_UNSTRIPPED_BINARY :=", rustMod.UnstrippedOutputFile().String()) + if fi.providers != nil && fi.providers.linkableInfo != nil { + linkableInfo := fi.providers.linkableInfo + if fi.providers.ccInfo != nil { + if linkableInfo.UnstrippedOutputFile != nil { + fmt.Fprintln(w, "LOCAL_SOONG_UNSTRIPPED_BINARY :=", linkableInfo.UnstrippedOutputFile.String()) + } + if fi.providers.ccInfo.LinkerInfo != nil && fi.providers.ccInfo.LinkerInfo.LibraryDecoratorInfo != nil && !linkableInfo.Static { + fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES +=", strings.Join( + fi.providers.ccInfo.LinkerInfo.LibraryDecoratorInfo.SAbiDiff.Strings(), " ")) + } + if linkableInfo.CoverageOutputFile.Valid() { + fmt.Fprintln(w, "LOCAL_PREBUILT_COVERAGE_ARCHIVE :=", linkableInfo.CoverageOutputFile.String()) + } + } else if fi.providers.rustInfo != nil && linkableInfo.UnstrippedOutputFile != nil { + fmt.Fprintln(w, "LOCAL_SOONG_UNSTRIPPED_BINARY :=", linkableInfo.UnstrippedOutputFile.String()) } } fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_cc_rust_prebuilt.mk") diff --git a/apex/apex.go b/apex/apex.go index 5df0e2ad1..e865125e0 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -607,12 +607,23 @@ type apexFile struct { multilib string // TODO(jiyong): remove this - module android.Module + module *android.ModuleProxy + providers *providerInfoForApexFile +} + +type providerInfoForApexFile struct { + commonInfo *android.CommonModuleInfo + javaInfo *java.JavaInfo + appInfo *java.AppInfo + ccInfo *cc.CcInfo + rustInfo *rust.RustInfo + linkableInfo *cc.LinkableInfo + vintfFragmentInfo *android.VintfFragmentInfo } // 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 { + installDir string, class apexFileClass, module *android.ModuleProxy) apexFile { ret := apexFile{ builtFile: builtFile, installDir: installDir, @@ -621,12 +632,35 @@ func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidM module: module, } if module != nil { - if installFilesInfo, ok := android.OtherModuleProvider(ctx, module, android.InstallFilesProvider); ok { + if installFilesInfo, ok := android.OtherModuleProvider(ctx, *module, android.InstallFilesProvider); ok { ret.checkbuildTarget = installFilesInfo.CheckbuildTarget } ret.moduleDir = ctx.OtherModuleDir(module) - ret.partition = module.PartitionTag(ctx.DeviceConfig()) - ret.multilib = module.Target().Arch.ArchType.Multilib + commonInfo := android.OtherModulePointerProviderOrDefault(ctx, module, android.CommonModuleInfoProvider) + ret.partition = commonInfo.PartitionTag + ret.multilib = commonInfo.Target.Arch.ArchType.Multilib + ret.providers = &providerInfoForApexFile{} + if commonInfo, ok := android.OtherModuleProvider(ctx, module, android.CommonModuleInfoProvider); ok { + ret.providers.commonInfo = commonInfo + } + if javaInfo, ok := android.OtherModuleProvider(ctx, module, java.JavaInfoProvider); ok { + ret.providers.javaInfo = javaInfo + } + if appInfo, ok := android.OtherModuleProvider(ctx, module, java.AppInfoProvider); ok { + ret.providers.appInfo = appInfo + } + if ccInfo, ok := android.OtherModuleProvider(ctx, module, cc.CcInfoProvider); ok { + ret.providers.ccInfo = ccInfo + } + if linkableInfo, ok := android.OtherModuleProvider(ctx, module, cc.LinkableInfoProvider); ok { + ret.providers.linkableInfo = linkableInfo + } + if rustInfo, ok := android.OtherModuleProvider(ctx, module, rust.RustInfoProvider); ok { + ret.providers.rustInfo = rustInfo + } + if vintfInfo, ok := android.OtherModuleProvider(ctx, module, android.VintfFragmentInfoProvider); ok { + ret.providers.vintfFragmentInfo = &vintfInfo + } } return ret } @@ -667,11 +701,11 @@ func (af *apexFile) symlinkPaths() []string { // availableToPlatform tests whether this apexFile is from a module that can be installed to the // platform. func (af *apexFile) availableToPlatform() bool { - if af.module == nil { + if af.providers == nil || af.providers.commonInfo == nil { return false } - if am, ok := af.module.(android.ApexModule); ok { - return am.AvailableFor(android.AvailableToPlatform) + if af.providers.commonInfo.IsApexModule { + return android.CheckAvailableForApex(android.AvailableToPlatform, af.providers.commonInfo.ApexAvailableFor) } return false } @@ -1372,7 +1406,7 @@ func setDirInApexForNativeBridge(commonInfo *android.CommonModuleInfo, dir *stri // apexFileFor 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, module android.Module, +func apexFileForNativeLibrary(ctx android.BaseModuleContext, module android.ModuleProxy, 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. @@ -1404,10 +1438,10 @@ func apexFileForNativeLibrary(ctx android.BaseModuleContext, module android.Modu fileToCopy := android.OutputFileForModule(ctx, module, "") androidMkModuleName := commonInfo.BaseModuleName + ccMod.SubName - return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, module) + return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, &module) } -func apexFileForExecutable(ctx android.BaseModuleContext, module android.Module, +func apexFileForExecutable(ctx android.BaseModuleContext, module android.ModuleProxy, commonInfo *android.CommonModuleInfo, ccInfo *cc.CcInfo) apexFile { linkableInfo := android.OtherModuleProviderOrDefault(ctx, module, cc.LinkableInfoProvider) dirInApex := "bin" @@ -1415,13 +1449,13 @@ func apexFileForExecutable(ctx android.BaseModuleContext, module android.Module, 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 := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, &module) af.symlinks = linkableInfo.Symlinks af.dataPaths = ccInfo.DataPaths return af } -func apexFileForRustExecutable(ctx android.BaseModuleContext, module android.Module, +func apexFileForRustExecutable(ctx android.BaseModuleContext, module android.ModuleProxy, commonInfo *android.CommonModuleInfo) apexFile { linkableInfo := android.OtherModuleProviderOrDefault(ctx, module, cc.LinkableInfoProvider) dirInApex := "bin" @@ -1429,39 +1463,39 @@ func apexFileForRustExecutable(ctx android.BaseModuleContext, module android.Mod 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 := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, &module) return af } -func apexFileForShBinary(ctx android.BaseModuleContext, module android.Module, +func apexFileForShBinary(ctx android.BaseModuleContext, module android.ModuleProxy, 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 := newApexFile(ctx, fileToCopy, commonInfo.BaseModuleName, dirInApex, shBinary, &module) af.symlinks = sh.Symlinks return af } -func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, module android.Module, +func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, module android.ModuleProxy, 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, module) + return newApexFile(ctx, outputFile, makeModuleName, dirInApex, etc, &module) } -func apexFileForCompatConfig(ctx android.BaseModuleContext, module android.Module, +func apexFileForCompatConfig(ctx android.BaseModuleContext, module android.ModuleProxy, config *java.PlatformCompatConfigInfo, depName string) apexFile { dirInApex := filepath.Join("etc", config.SubDir) fileToCopy := config.CompatConfig - return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, module) + return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, &module) } -func apexFileForVintfFragment(ctx android.BaseModuleContext, module android.Module, +func apexFileForVintfFragment(ctx android.BaseModuleContext, module android.ModuleProxy, commonInfo *android.CommonModuleInfo, vf *android.VintfFragmentInfo) apexFile { dirInApex := filepath.Join("etc", "vintf") - return newApexFile(ctx, vf.OutputFile, commonInfo.BaseModuleName, dirInApex, etc, module) + 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 @@ -1481,16 +1515,16 @@ 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 android.Module, javaInfo *java.JavaInfo) apexFile { +func apexFileForJavaModule(ctx android.ModuleContext, module android.ModuleProxy, 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 android.Module, +func apexFileForJavaModuleWithFile(ctx android.ModuleContext, module android.ModuleProxy, javaInfo *java.JavaInfo, dexImplementationJar android.Path) apexFile { dirInApex := "javalib" commonInfo := android.OtherModulePointerProviderOrDefault(ctx, module, android.CommonModuleInfoProvider) - af := newApexFile(ctx, dexImplementationJar, commonInfo.BaseModuleName, dirInApex, javaSharedLib, module) + 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 @@ -1532,7 +1566,7 @@ func sanitizedBuildIdForPath(ctx android.BaseModuleContext) string { return buildId } -func apexFilesForAndroidApp(ctx android.BaseModuleContext, module android.Module, +func apexFilesForAndroidApp(ctx android.BaseModuleContext, module android.ModuleProxy, commonInfo *android.CommonModuleInfo, aapp *java.AppInfo) []apexFile { appDir := "app" if aapp.Privileged { @@ -1545,7 +1579,7 @@ func apexFilesForAndroidApp(ctx android.BaseModuleContext, module android.Module dirInApex := filepath.Join(appDir, aapp.InstallApkName+"@"+sanitizedBuildIdForPath(ctx)) fileToCopy := aapp.OutputFile - af := newApexFile(ctx, fileToCopy, commonInfo.BaseModuleName, dirInApex, app, module) + 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 @@ -1560,7 +1594,7 @@ func apexFilesForAndroidApp(ctx android.BaseModuleContext, module android.Module if allowlist := aapp.PrivAppAllowlist; allowlist.Valid() { dirInApex := filepath.Join("etc", "permissions") - privAppAllowlist := newApexFile(ctx, allowlist.Path(), commonInfo.BaseModuleName+"_privapp", dirInApex, etc, module) + privAppAllowlist := newApexFile(ctx, allowlist.Path(), commonInfo.BaseModuleName+"_privapp", dirInApex, etc, &module) apexFiles = append(apexFiles, privAppAllowlist) } @@ -1569,24 +1603,24 @@ func apexFilesForAndroidApp(ctx android.BaseModuleContext, module android.Module return apexFiles } -func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, module android.Module, rro java.RuntimeResourceOverlayInfo) apexFile { +func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, module android.ModuleProxy, rro java.RuntimeResourceOverlayInfo) apexFile { rroDir := "overlay" dirInApex := filepath.Join(rroDir, rro.Theme) fileToCopy := rro.OutputFile - af := newApexFile(ctx, fileToCopy, module.Name(), dirInApex, app, module) + af := newApexFile(ctx, fileToCopy, module.Name(), dirInApex, app, &module) af.certificate = rro.Certificate return af } -func apexFileForBpfProgram(ctx android.BaseModuleContext, builtFile android.Path, apex_sub_dir string, bpfProgram android.Module) apexFile { +func apexFileForBpfProgram(ctx android.BaseModuleContext, builtFile android.Path, apex_sub_dir string, bpfProgram android.ModuleProxy) apexFile { dirInApex := filepath.Join("etc", "bpf", apex_sub_dir) - return newApexFile(ctx, builtFile, builtFile.Base(), dirInApex, etc, bpfProgram) + return newApexFile(ctx, builtFile, builtFile.Base(), dirInApex, etc, &bpfProgram) } -func apexFileForFilesystem(ctx android.BaseModuleContext, buildFile android.Path, module android.Module) apexFile { +func apexFileForFilesystem(ctx android.BaseModuleContext, buildFile android.Path, module android.ModuleProxy) apexFile { dirInApex := filepath.Join("etc", "fs") - return newApexFile(ctx, buildFile, buildFile.Base(), dirInApex, etc, module) + return newApexFile(ctx, buildFile, buildFile.Base(), dirInApex, etc, &module) } // WalkPayloadDeps visits dependencies that contributes to the payload of this APEX. For each of the @@ -1803,7 +1837,7 @@ func (a *apexBundle) enforcePartitionTagOnApexSystemServerJar(ctx android.Module }) } -func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, child, parent android.Module) bool { +func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, child, parent android.ModuleProxy) bool { depTag := ctx.OtherModuleDependencyTag(child) if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok { return false @@ -1905,7 +1939,7 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, // 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 := newApexFile(ctx, appInfo.OutputFile, commonInfo.BaseModuleName, appDirName, appSet, &child) af.certificate = java.PresignedCertificate vctx.filesInfo = append(vctx.filesInfo, af) } else { @@ -2148,7 +2182,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { checkDuplicate: a.shouldCheckDuplicate(ctx), unwantedTransitiveDeps: a.properties.Unwanted_transitive_deps, } - ctx.WalkDeps(func(child, parent android.Module) bool { return a.depVisitor(&vctx, ctx, child, parent) }) + ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool { return a.depVisitor(&vctx, ctx, child, parent) }) vctx.normalizeFileInfo(ctx) if a.privateKeyFile == nil { if ctx.Config().AllowMissingDependencies() { @@ -2300,7 +2334,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 android.Module) []apexFile { +func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module android.ModuleProxy) []apexFile { bootclasspathFragmentInfo, _ := android.OtherModuleProvider(ctx, module, java.BootclasspathFragmentApexContentInfoProvider) var filesToAdd []apexFile @@ -2349,7 +2383,7 @@ func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module android.Mo // 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 android.Module) *apexFile { +func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module android.ModuleProxy) *apexFile { info, _ := android.OtherModuleProvider(ctx, module, java.ClasspathFragmentProtoContentInfoProvider) if !info.ClasspathFragmentProtoGenerated { return nil @@ -2361,7 +2395,7 @@ func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module android.Mo // 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, javaModule android.Module) apexFile { +func apexFileForBootclasspathFragmentContentModule(ctx android.ModuleContext, fragmentModule, javaModule android.ModuleProxy) apexFile { bootclasspathFragmentInfo, _ := android.OtherModuleProvider(ctx, fragmentModule, java.BootclasspathFragmentApexContentInfoProvider) // Get the dexBootJar from the bootclasspath_fragment as that is responsible for performing the @@ -2925,21 +2959,29 @@ func (a *apexBundle) setSymbolInfosProvider(ctx android.ModuleContext) { switch fi.class { case nativeSharedLib, nativeExecutable, nativeTest: info.Stem = fi.stem() - if ccMod, ok := fi.module.(*cc.Module); ok { - if ccMod.UnstrippedOutputFile() != nil { - info.UnstrippedBinaryPath = ccMod.UnstrippedOutputFile() - } - } else if rustMod, ok := fi.module.(*rust.Module); ok { - if rustMod.UnstrippedOutputFile() != nil { - info.UnstrippedBinaryPath = rustMod.UnstrippedOutputFile() + if fi.providers != nil && fi.providers.linkableInfo != nil { + linkableInfo := fi.providers.linkableInfo + if linkableInfo.UnstrippedOutputFile != nil { + info.UnstrippedBinaryPath = linkableInfo.UnstrippedOutputFile } } if info.UnstrippedBinaryPath != nil { infos.AppendSymbols(info) } case app: - if app, ok := fi.module.(*java.AndroidApp); ok { - infos.AppendSymbols(app.GetJniSymbolInfos(ctx, moduleDir)...) + if fi.providers != nil && fi.providers.appInfo != nil { + appInfo := fi.providers.appInfo + // The following logic comes from java.GetJniSymbolInfos + for _, install := range java.JNISymbolsInstalls(appInfo.JniLibs, moduleDir.String()) { + info := &cc.SymbolInfo{ + Name: fi.providers.commonInfo.BaseModuleName, + ModuleDir: filepath.Dir(install.To), + Uninstallable: fi.providers.commonInfo.SkipInstall || !fi.providers.javaInfo.Installable || fi.providers.commonInfo.NoFullInstall, + UnstrippedBinaryPath: install.From, + InstalledStem: filepath.Base(install.To), + } + infos.AppendSymbols(info) + } } } } diff --git a/apex/builder.go b/apex/builder.go index b752dfd98..becda2ba9 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -526,7 +526,7 @@ func markManifestTestOnly(ctx android.ModuleContext, androidManifestFile android func shouldApplyAssembleVintf(fi apexFile) bool { isVintfFragment, _ := path.Match("etc/vintf/*", fi.path()) - _, fromVintfFragmentModule := fi.module.(*android.VintfFragmentModule) + fromVintfFragmentModule := fi.providers != nil && fi.providers.vintfFragmentInfo != nil return isVintfFragment && !fromVintfFragmentModule } @@ -653,10 +653,10 @@ func (a *apexBundle) buildApex(ctx android.ModuleContext) { // are zipped. So we need to unzip them. copyCommands = append(copyCommands, fmt.Sprintf("unzip -qDD -d %s %s", destPathDir, - fi.module.(*java.AndroidAppSet).PackedAdditionalOutputs().String())) + fi.providers.appInfo.PackedAdditionalOutputs.String())) if installSymbolFiles { installedPath = ctx.InstallFileWithExtraFilesZip(apexDir.Join(ctx, fi.installDir), - fi.stem(), fi.builtFile, fi.module.(*java.AndroidAppSet).PackedAdditionalOutputs()) + fi.stem(), fi.builtFile, fi.providers.appInfo.PackedAdditionalOutputs) } } else { if installSymbolFiles { @@ -1200,7 +1200,7 @@ func (a *apexBundle) buildCannedFsConfig(ctx android.ModuleContext) android.Path readOnlyPaths = append(readOnlyPaths, pathInApex) // Additional APKs appSetDirs = append(appSetDirs, f.installDir) - appSetFiles[f.installDir] = f.module.(*java.AndroidAppSet).PackedAdditionalOutputs() + appSetFiles[f.installDir] = f.providers.appInfo.PackedAdditionalOutputs } else { readOnlyPaths = append(readOnlyPaths, pathInApex) } diff --git a/cc/androidmk.go b/cc/androidmk.go index b016788ee..1e407f401 100644 --- a/cc/androidmk.go +++ b/cc/androidmk.go @@ -16,7 +16,6 @@ package cc import ( "fmt" - "io" "path/filepath" "strings" @@ -218,13 +217,6 @@ func (library *libraryDecorator) androidMkEntriesWriteAdditionalDependenciesForS } } -// TODO(ccross): remove this once apex/androidmk.go is converted to AndroidMkEntries -func (library *libraryDecorator) androidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer) { - if !library.static() { - fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES +=", strings.Join(library.sAbiDiff.Strings(), " ")) - } -} - func (library *libraryDecorator) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { if library.static() { entries.Class = "STATIC_LIBRARIES" diff --git a/cc/cc.go b/cc/cc.go index 887557d1c..ea9d76598 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -21,7 +21,6 @@ package cc import ( "errors" "fmt" - "io" "path/filepath" "slices" "strconv" @@ -109,6 +108,7 @@ type LibraryDecoratorInfo struct { SharedLibs []string SystemSharedLibs []string StubsSymbolFilePath android.Path + SAbiDiff android.Paths } type SnapshotInfo struct { @@ -2632,6 +2632,7 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { VndkFileName: decorator.getLibNameHelper(c.BaseModuleName(), true, false) + ".so", UniqueHostSoname: decorator.Properties.Unique_host_soname, StubsSymbolFilePath: decorator.stubsSymbolFilePath, + SAbiDiff: decorator.sAbiDiff, } var properties StaticOrSharedProperties if decorator.static() { @@ -4430,14 +4431,6 @@ func installable(c LinkableInterface, apexInfo android.ApexInfo) bool { return false } -func (c *Module) AndroidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer) { - if c.linker != nil { - if library, ok := c.linker.(*libraryDecorator); ok { - library.androidMkWriteAdditionalDependenciesForSourceAbiDiff(w) - } - } -} - var _ android.ApexModule = (*Module)(nil) // Implements android.ApexModule diff --git a/cc/library.go b/cc/library.go index b248224bd..2f98807cf 100644 --- a/cc/library.go +++ b/cc/library.go @@ -16,7 +16,6 @@ package cc import ( "fmt" - "io" "path/filepath" "regexp" "slices" @@ -798,9 +797,6 @@ type libraryInterface interface { // Gets the ABI properties for vendor, product, or platform variant getHeaderAbiCheckerProperties(m *Module) headerAbiCheckerProperties - // Write LOCAL_ADDITIONAL_DEPENDENCIES for ABI diff - androidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer) - apexAvailable() []string setAPIListCoverageXMLPath(out android.ModuleOutPath) diff --git a/java/androidmk.go b/java/androidmk.go index c9de7e6d2..22973f187 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -359,7 +359,7 @@ func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries { entries.AddStrings("LOCAL_OVERRIDES_PACKAGES", app.getOverriddenPackages()...) if app.embeddedJniLibs { - jniSymbols := app.JNISymbolsInstalls(app.installPathForJNISymbols.String()) + jniSymbols := JNISymbolsInstalls(app.jniLibs, app.installPathForJNISymbols.String()) entries.SetString("LOCAL_SOONG_JNI_LIBS_SYMBOLS", jniSymbols.String()) } else { var names []string diff --git a/java/app.go b/java/app.go index f6f9fed96..2840c7f3f 100644 --- a/java/app.go +++ b/java/app.go @@ -83,6 +83,9 @@ type AppInfo struct { PrivAppAllowlist android.OptionalPath OverriddenManifestPackageName *string ApkCertsFile android.Path + JniLibs []jniLib + JniCoverageOutputs android.Paths + PackedAdditionalOutputs android.Path } var AppInfoProvider = blueprint.NewProvider[*AppInfo]() @@ -413,8 +416,10 @@ func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleCon TestOnly: true, }) appInfo := &AppInfo{ - Updatable: Bool(a.appProperties.Updatable), - TestHelperApp: true, + Updatable: Bool(a.appProperties.Updatable), + TestHelperApp: true, + JniLibs: a.jniLibs, + JniCoverageOutputs: a.jniCoverageOutputs, } setCommonAppInfo(appInfo, a) android.SetProvider(ctx, AppInfoProvider, appInfo) @@ -452,7 +457,7 @@ func (a *AndroidApp) baseSymbolInfo(ctx android.ModuleContext) *cc.SymbolInfo { func (a *AndroidApp) GetJniSymbolInfos(ctx android.ModuleContext, JniSymbolInstallPath android.Path) []*cc.SymbolInfo { infos := []*cc.SymbolInfo{} - for _, install := range a.JNISymbolsInstalls(JniSymbolInstallPath.String()) { + for _, install := range JNISymbolsInstalls(a.jniLibs, JniSymbolInstallPath.String()) { info := a.baseSymbolInfo(ctx) info.UnstrippedBinaryPath = install.From info.ModuleDir = filepath.Dir(install.To) @@ -483,6 +488,8 @@ func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) { EmbeddedJNILibs: embeddedJniLibs, MergedManifestFile: a.mergedManifest, OverriddenManifestPackageName: &overriddenName, + JniLibs: a.jniLibs, + JniCoverageOutputs: a.jniCoverageOutputs, } setCommonAppInfo(appInfo, a) android.SetProvider(ctx, AppInfoProvider, appInfo) @@ -864,9 +871,9 @@ func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, prebuiltJniPackages andro return jniJarFile } -func (a *AndroidApp) JNISymbolsInstalls(installPath string) android.RuleBuilderInstalls { +func JNISymbolsInstalls(jniLibs []jniLib, installPath string) android.RuleBuilderInstalls { var jniSymbols android.RuleBuilderInstalls - for _, jniLib := range a.jniLibs { + for _, jniLib := range jniLibs { if jniLib.unstrippedFile != nil { jniSymbols = append(jniSymbols, android.RuleBuilderInstall{ From: jniLib.unstrippedFile, diff --git a/java/app_set.go b/java/app_set.go index 6a2c678a8..6e61b9802 100644 --- a/java/app_set.go +++ b/java/app_set.go @@ -193,10 +193,11 @@ func (as *AndroidAppSet) GenerateAndroidBuildActions(ctx android.ModuleContext) ) android.SetProvider(ctx, AppInfoProvider, &AppInfo{ - AppSet: true, - Privileged: as.Privileged(), - OutputFile: as.OutputFile(), - ApkCertsFile: as.apkcertsFile, + AppSet: true, + Privileged: as.Privileged(), + OutputFile: as.OutputFile(), + ApkCertsFile: as.apkcertsFile, + PackedAdditionalOutputs: as.packedOutput, }) } diff --git a/java/base.go b/java/base.go index 0f0a50524..7a465d4eb 100644 --- a/java/base.go +++ b/java/base.go @@ -1333,6 +1333,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath AconfigIntermediateCacheOutputPaths: deps.aconfigProtoFiles, SdkVersion: j.SdkVersion(ctx), OverrideMinSdkVersion: j.overridableProperties.Min_sdk_version, + Installable: BoolDefault(j.properties.Installable, true), } } @@ -1965,6 +1966,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath SdkVersion: j.SdkVersion(ctx), OutputFile: j.outputFile, OverrideMinSdkVersion: j.overridableProperties.Min_sdk_version, + Installable: BoolDefault(j.properties.Installable, true), } } diff --git a/java/java.go b/java/java.go index 18920aa11..ffcaa92c8 100644 --- a/java/java.go +++ b/java/java.go @@ -281,6 +281,14 @@ type ModuleWithSdkDepInfo struct { Stubs bool } +type ApexDependencyInfo struct { + // These fields can be different from the ones in JavaInfo, for example, for sdk_library + // the following fields are set since sdk_library inherits the implementations of + // ApexDependency from base, but the same-named fields are not set in JavaInfo. + HeaderJars android.Paths + ImplementationAndResourcesJars android.Paths +} + // JavaInfo contains information about a java module for use by modules that depend on it. type JavaInfo struct { // HeaderJars is a list of jars that can be passed as the javac classpath in order to link @@ -438,6 +446,8 @@ type JavaInfo struct { OverrideMinSdkVersion *string CompileDex *bool SystemModules string + Installable bool + ApexDependencyInfo *ApexDependencyInfo } var JavaInfoProvider = blueprint.NewProvider[*JavaInfo]() @@ -3897,4 +3907,11 @@ func setExtraJavaInfo(ctx android.ModuleContext, module android.Module, javaInfo javaInfo.SystemModules = sdk.SystemModules() javaInfo.SdkVersion = sdk.SdkVersion(ctx) } + + if ap, ok := module.(ApexDependency); ok { + javaInfo.ApexDependencyInfo = &ApexDependencyInfo{ + HeaderJars: ap.HeaderJars(), + ImplementationAndResourcesJars: ap.ImplementationAndResourcesJars(), + } + } } -- cgit v1.2.3 From c45044cdc5940eb89924264b358d43c36c339b7c Mon Sep 17 00:00:00 2001 From: William Escande Date: Thu, 3 Apr 2025 11:56:05 -0700 Subject: Revert "Merge "bt available hack" into main am: 85289cfc21 am: 1493ed2731" This reverts commit ba2b56ea7409b7cc98c87613424b57e285e1f40d. Reason for revert: Time to cleanup Remove "bt available hack" We deleted com.android.btservices apex. This hack is no longer needed. The last suppression cl is http://ag/32874862 that remove the reference to the btservices apex Bug: 383863941 Test: m . Flag: EXEMPT - build time cleanup Change-Id: I518d424b5c1c6ed97eedef242c47b5ce18bef13b --- android/apex.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/android/apex.go b/android/apex.go index bbd687574..db955b59c 100644 --- a/android/apex.go +++ b/android/apex.go @@ -452,10 +452,6 @@ func CheckAvailableForApex(what string, apex_available []string) bool { if strings.HasSuffix(apex_name, ".*") && strings.HasPrefix(what, strings.TrimSuffix(apex_name, "*")) { return true } - // TODO b/383863941: Remove once legacy name is no longer used - if (apex_name == "com.android.btservices" && what == "com.android.bt") || (apex_name == "com.android.bt" && what == "com.android.btservices") { - return true - } } return false } -- cgit v1.2.3 From 0df22c120c22e237d43737c0794a83c88ffafeda Mon Sep 17 00:00:00 2001 From: mrziwang Date: Thu, 3 Apr 2025 19:49:03 +0000 Subject: Use intermediate file to hold file inputs in packageTestSuite to prevent the soong_zip argument list from being too long Test: CI Bug: 388850000 Bug: 405184090 Change-Id: I3fd1dd43e044a9b2252de9074886c84687205813 --- android/test_suites.go | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/android/test_suites.go b/android/test_suites.go index 1ddc52522..9b95349b0 100644 --- a/android/test_suites.go +++ b/android/test_suites.go @@ -318,6 +318,11 @@ func packageTestSuite(ctx SingletonContext, files Paths, sk suiteKind) { testsHostSharedLibsZip := pathForPackaging(ctx, sk.String()+"_host-shared-libs.zip") var listLines []string + // use intermediate files to hold the file inputs, to prevent argument list from being too long + testsZipCmdHostFileInput := PathForIntermediates(ctx, sk.String()+"_host_list.txt") + testsZipCmdTargetFileInput := PathForIntermediates(ctx, sk.String()+"_target_list.txt") + var testsZipCmdHostFileInputContent, testsZipCmdTargetFileInputContent []string + testsZipBuilder := NewRuleBuilder(pctx, ctx) testsZipCmd := testsZipBuilder.Command(). BuiltTool("soong_zip"). @@ -337,7 +342,8 @@ func packageTestSuite(ctx SingletonContext, files Paths, sk suiteKind) { for _, f := range files { if strings.HasPrefix(f.String(), hostOutTestCases.String()) { - testsZipCmd.FlagWithInput("-f ", f) + testsZipCmdHostFileInputContent = append(testsZipCmdHostFileInputContent, f.String()) + testsZipCmd.Implicit(f) if strings.HasSuffix(f.String(), ".config") { testsConfigsZipCmd.FlagWithInput("-f ", f) @@ -345,8 +351,10 @@ func packageTestSuite(ctx SingletonContext, files Paths, sk suiteKind) { } } } + WriteFileRule(ctx, testsZipCmdHostFileInput, strings.Join(testsZipCmdHostFileInputContent, " ")) testsZipCmd. + FlagWithInput("-l ", testsZipCmdHostFileInput). FlagWithArg("-P ", "target"). FlagWithArg("-C ", targetOut) testsConfigsZipCmd. @@ -355,7 +363,8 @@ func packageTestSuite(ctx SingletonContext, files Paths, sk suiteKind) { for _, f := range files { if strings.HasPrefix(f.String(), targetOutTestCases.String()) { - testsZipCmd.FlagWithInput("-f ", f) + testsZipCmdTargetFileInputContent = append(testsZipCmdTargetFileInputContent, f.String()) + testsZipCmd.Implicit(f) if strings.HasSuffix(f.String(), ".config") { testsConfigsZipCmd.FlagWithInput("-f ", f) @@ -363,6 +372,8 @@ func packageTestSuite(ctx SingletonContext, files Paths, sk suiteKind) { } } } + WriteFileRule(ctx, testsZipCmdTargetFileInput, strings.Join(testsZipCmdTargetFileInputContent, " ")) + testsZipCmd.FlagWithInput("-l ", testsZipCmdTargetFileInput) testsZipBuilder.Build(sk.String(), "building "+sk.String()+" zip") testsConfigsZipBuilder.Build(sk.String()+"-configs", "building "+sk.String()+" configs zip") -- cgit v1.2.3 From 8a1e6c3d02a818e98408adc9be6b1d84b5546c37 Mon Sep 17 00:00:00 2001 From: Etienne Dechamps Date: Fri, 4 Apr 2025 12:47:41 +0000 Subject: Add the blessing license type https://spdx.org/licenses/blessing.html As found in: https://cs.android.com/android/platform/superproject/main/+/main:external/perfetto/LICENSE;l=229-235;drc=fcae37623e3eeaefe7ecbfa192f87f8c44b56ecc Bug: 346770535 Test: N/A Change-Id: I16532271d0e7f25f830aee860dcd4c21dfb86f42 --- licenses/Android.bp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/licenses/Android.bp b/licenses/Android.bp index f420110dd..68a9d027b 100644 --- a/licenses/Android.bp +++ b/licenses/Android.bp @@ -218,6 +218,12 @@ license_kind { url: "https://spdx.org/licenses/Artistic-2.0.html", } +license_kind { + name: "SPDX-license-identifier-blessing", + conditions: ["unencumbered"], + url: "https://spdx.org/licenses/blessing.html", +} + license_kind { name: "SPDX-license-identifier-BSD", conditions: ["notice"], -- cgit v1.2.3 From ad74c81106079fa76b615589346b106c495b9e2e Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Thu, 3 Apr 2025 16:32:32 -0700 Subject: Add support for .flat files with flags in the directory This change is a follow up from https://r.android.com/3314715, based on the requirement that flag path can be present as a subdirectory of resource type subdirectory. i.e. previously the support was only done to `flag(fully.qualified.flag_name)/values`, but with this change `values/flag(fully.qualified.flag_name)`-like path is also supported. Test: m nothing --no-skip-soong-tests Bug: 374827548 Change-Id: Ie58159cdcd152b66d3c816d3f5a9b5a5971e25a5 --- java/aapt2.go | 13 +++++++------ java/app_test.go | 7 +++++++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/java/aapt2.go b/java/aapt2.go index bae4d1ee3..86cce5b63 100644 --- a/java/aapt2.go +++ b/java/aapt2.go @@ -52,14 +52,15 @@ func pathToAapt2Path(ctx android.ModuleContext, res android.Path) android.Writab } subDir := filepath.Dir(res.String()) subDir, lastDir := filepath.Split(subDir) - if isFlagsPath(subDir) { - var flag string + var flag string + if isFlagsPath(lastDir) { + flag = "." + strings.TrimPrefix(lastDir, "flag") + subDir, lastDir = filepath.Split(subDir) + } else if isFlagsPath(subDir) { subDir, flag = filepath.Split(filepath.Dir(subDir)) - flag = strings.TrimPrefix(flag, "flag") - name = fmt.Sprintf("%s_%s.%s%s.flat", lastDir, name, flag, extension) - } else { - name = fmt.Sprintf("%s_%s%s.flat", lastDir, name, extension) + flag = "." + strings.TrimPrefix(flag, "flag") } + name = fmt.Sprintf("%s_%s%s%s.flat", lastDir, name, flag, extension) out := android.PathForModuleOut(ctx, "aapt2", subDir, name) return out } diff --git a/java/app_test.go b/java/app_test.go index 5f5f04d78..7abde7839 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -4899,6 +4899,7 @@ func TestResourcesWithFlagDirectories(t *testing.T) { "res/flag(!test.package.flag2)/values/bools.xml": nil, "res/flag(test.package.flag1)/values-config/strings_google_services.xml": nil, "res/flags(test.package.flag1)/values/strings.xml": nil, + "res/drawable/flag(test.package.flag1)/qs_flashlight_icon_off.xml": nil, }), ).RunTestWithBp(t, ` android_library { @@ -4937,6 +4938,12 @@ func TestResourcesWithFlagDirectories(t *testing.T) { compileOutputPaths, "out/soong/.intermediates/foo/android_common/aapt2/res/values_strings.(test.package.flag1).arsc.flat", ) + android.AssertStringListContains( + t, + "Expected to generate flag path when it is a subdirectory of resource type subdirectory", + compileOutputPaths, + "out/soong/.intermediates/foo/android_common/aapt2/res/drawable/_qs_flashlight_icon_off.(test.package.flag1).xml.flat", + ) } func TestAutogeneratedStaticRro(t *testing.T) { -- cgit v1.2.3 From 3262c2b07b8ec9c883cdf4627f01359e9d03e58e Mon Sep 17 00:00:00 2001 From: Jiakai Zhang Date: Fri, 4 Apr 2025 10:30:41 -0700 Subject: Get rid of the hardcoded default profile paths. They are probably never used. They can only cause confusion. Also, some comments were wrong. This CL updates the comments to reflect how things actually work. Change-Id: I87dc6e49908fe9939e842304531a3fef1e5a6c5c --- dexpreopt/testing.go | 2 +- java/dexpreopt_bootjars.go | 32 +++++++++++++++++--------------- sdk/bootclasspath_fragment_sdk_test.go | 3 +++ 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/dexpreopt/testing.go b/dexpreopt/testing.go index b1fbef566..f72061b16 100644 --- a/dexpreopt/testing.go +++ b/dexpreopt/testing.go @@ -180,7 +180,7 @@ func FixtureSetPreoptWithUpdatableBcp(value bool) android.FixturePreparer { // FixtureSetBootImageProfiles sets the BootImageProfiles property in the global config. func FixtureSetBootImageProfiles(profiles ...string) android.FixturePreparer { return FixtureModifyGlobalConfig(func(ctx android.PathContext, dexpreoptConfig *GlobalConfig) { - dexpreoptConfig.BootImageProfiles = android.PathsForSource(ctx, profiles) + dexpreoptConfig.BootImageProfiles = android.PathsForTesting(profiles...) }) } diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index 228704355..30e208d0a 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -1381,6 +1381,10 @@ const failureMessage = `ERROR: Dex2oat failed to compile a boot image. It is likely that the boot classpath is inconsistent. Rebuild with ART_BOOT_IMAGE_EXTRA_ARGS="--runtime-arg -verbose:verifier" to see verification errors.` +// bootImageProfileRuleCommon contains the common logic for generating boot image profiles for both +// the platform and the ART module when building from source. +// Building from prebuilts is not handled here. Instead, the profile is extracted from the prebuilt +// ART module. func bootImageProfileRuleCommon(ctx android.ModuleContext, name string, dexFiles android.Paths, dexLocations []string) android.WritablePath { globalSoong := dexpreopt.GetGlobalSoongConfig(ctx) global := dexpreopt.GetGlobalConfig(ctx) @@ -1389,33 +1393,31 @@ func bootImageProfileRuleCommon(ctx android.ModuleContext, name string, dexFiles return nil } - defaultProfile := "frameworks/base/boot/boot-image-profile.txt" - // If ART is prebuilt, primarily in next release configs, this will still use - // the profile from source which represent the latest code, so it may not - // correspond to the BCP jars in the prebuilt APEX, but this is the profile we - // have access to. - artProfile := "art/build/boot/boot-image-profile.txt" - extraProfile := "frameworks/base/boot/boot-image-profile-extra.txt" - rule := android.NewRuleBuilder(pctx, ctx) var profiles android.Paths if len(global.BootImageProfiles) > 0 { + // The most common case. The profiles are specified by + // `PRODUCT_DEX_PREOPT_BOOT_IMAGE_PROFILE_LOCATION`. + // - On a bundled build, this list contains both the ART profile and the frameworks profile. + // - On an unbundled build with ART source code being present, this list only contains the ART + // profile. profiles = append(profiles, global.BootImageProfiles...) - } else if path := android.ExistentPathForSource(ctx, defaultProfile); path.Valid() { - profiles = append(profiles, path.Path()) } else { - // No profile (not even a default one, which is the case on some branches - // like master-art-host that don't have frameworks/base). + // No profile specified. This means we are building an unbundled build with ART source code + // being absent, meaning we are not building the platform or the ART module, so we don't need + // a profile. // Return nil and continue without profile. return nil } - if path := android.ExistentPathForSource(ctx, artProfile); path.Valid() { - profiles = append(profiles, path.Path()) - } + extraProfile := "frameworks/base/boot/boot-image-profile-extra.txt" if path := android.ExistentPathForSource(ctx, extraProfile); path.Valid() { profiles = append(profiles, path.Path()) } + // We concatenate the profiles into a single file. Later, `profman` filters the entries based on + // `dexFiles` to only keep the relevant ones. For example, when this function is called for + // generating the profile for the ART module, `profman` only keeps the entries for the ART module + // and not the platform. bootImageProfile := android.PathForModuleOut(ctx, name, "boot-image-profile.txt") rule.Command().Text("cat").Inputs(profiles).Text(">").Output(bootImageProfile) diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go index 80ced00bf..8986efd48 100644 --- a/sdk/bootclasspath_fragment_sdk_test.go +++ b/sdk/bootclasspath_fragment_sdk_test.go @@ -21,6 +21,7 @@ import ( "testing" "android/soong/android" + "android/soong/dexpreopt" "android/soong/java" ) @@ -91,6 +92,8 @@ func TestSnapshotWithBootclasspathFragment_ImageName(t *testing.T) { fixtureAddPlatformBootclasspathForBootclasspathFragmentWithExtra( "com.android.art", "art-bootclasspath-fragment", java.ApexBootJarFragmentsForPlatformBootclasspath), + dexpreopt.FixtureSetBootImageProfiles("art/build/boot/boot-image-profile.txt"), + java.PrepareForBootImageConfigTest, java.PrepareApexBootJarConfigsAndModules, android.FixtureWithRootAndroidBp(` -- cgit v1.2.3 From b7d04d26bf3fa1b82019a54e569b0063bf7956fc Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 3 Apr 2025 19:48:37 -0700 Subject: Consitently use ModuleProxy instead of *ModuleProxy ModuleProxy has an IsNil method, convert the methods that return a possibly nil *ModuleProxy to return a ModuleProxy{} instead, and make the callers check IsNil() instead of == nil. Test: all soong tests pass Change-Id: Ic632015f25fbf0ef78744542212081a80d4ace3d --- android/base_module_context.go | 28 +++++++++++++------------- android/module_context.go | 6 +++--- android/module_proxy.go | 2 +- android/path_properties_test.go | 2 +- android/paths.go | 16 +++++++-------- apex/apex.go | 44 ++++++++++++++++++++--------------------- apex/builder.go | 10 +++++----- cc/ndk_library.go | 8 ++++---- java/droiddoc.go | 4 ++-- java/ravenwood.go | 6 +++--- java/robolectric.go | 2 +- 11 files changed, 64 insertions(+), 64 deletions(-) diff --git a/android/base_module_context.go b/android/base_module_context.go index 5cb9e71cf..86c6b4491 100644 --- a/android/base_module_context.go +++ b/android/base_module_context.go @@ -123,7 +123,7 @@ type BaseModuleContext interface { // dependencies that are not an android.Module. GetDirectDepWithTag(name string, tag blueprint.DependencyTag) Module - GetDirectDepProxyWithTag(name string, tag blueprint.DependencyTag) *ModuleProxy + GetDirectDepProxyWithTag(name string, tag blueprint.DependencyTag) ModuleProxy // VisitDirectDeps calls visit for each direct dependency. If there are multiple // direct dependencies on the same module visit will be called multiple times on that module @@ -329,11 +329,11 @@ func (b *baseModuleContext) GetDirectDepWithTag(name string, tag blueprint.Depen return nil } -func (b *baseModuleContext) GetDirectDepProxyWithTag(name string, tag blueprint.DependencyTag) *ModuleProxy { - if module := b.bp.GetDirectDepProxyWithTag(name, tag); module != nil { - return &ModuleProxy{*module} +func (b *baseModuleContext) GetDirectDepProxyWithTag(name string, tag blueprint.DependencyTag) ModuleProxy { + if module := b.bp.GetDirectDepProxyWithTag(name, tag); !module.IsNil() { + return ModuleProxy{module} } - return nil + return ModuleProxy{} } func (b *baseModuleContext) blueprintBaseModuleContext() blueprint.BaseModuleContext { @@ -403,11 +403,11 @@ func (b *baseModuleContext) validateAndroidModule(module blueprint.Module, tag b } func (b *baseModuleContext) validateAndroidModuleProxy( - module blueprint.ModuleProxy, tag blueprint.DependencyTag, strict bool) *ModuleProxy { - aModule := ModuleProxy{module: module} + module blueprint.ModuleProxy, tag blueprint.DependencyTag, strict bool) ModuleProxy { + aModule := ModuleProxy{module} if !strict { - return &aModule + return aModule } if !OtherModulePointerProviderOrDefault(b, module, CommonModuleInfoProvider).Enabled { @@ -418,10 +418,10 @@ func (b *baseModuleContext) validateAndroidModuleProxy( b.ModuleErrorf("depends on disabled module %q", b.OtherModuleName(aModule)) } } - return nil + return ModuleProxy{} } - return &aModule + return aModule } func (b *baseModuleContext) getDirectDepsInternal(name string, tag blueprint.DependencyTag) []Module { @@ -480,8 +480,8 @@ func (b *baseModuleContext) VisitDirectDeps(visit func(Module)) { func (b *baseModuleContext) VisitDirectDepsProxy(visit func(ModuleProxy)) { b.bp.VisitDirectDepsProxy(func(module blueprint.ModuleProxy) { - if aModule := b.validateAndroidModuleProxy(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil { - visit(*aModule) + if aModule := b.validateAndroidModuleProxy(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); !aModule.IsNil() { + visit(aModule) } }) } @@ -503,8 +503,8 @@ func (b *baseModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, func (b *baseModuleContext) VisitDirectDepsProxyWithTag(tag blueprint.DependencyTag, visit func(proxy ModuleProxy)) { b.bp.VisitDirectDepsProxy(func(module blueprint.ModuleProxy) { if b.bp.OtherModuleDependencyTag(module) == tag { - if aModule := b.validateAndroidModuleProxy(module, tag, b.strictVisitDeps); aModule != nil { - visit(*aModule) + if aModule := b.validateAndroidModuleProxy(module, tag, b.strictVisitDeps); !aModule.IsNil() { + visit(aModule) } } }) diff --git a/android/module_context.go b/android/module_context.go index 369805eab..6e562bb24 100644 --- a/android/module_context.go +++ b/android/module_context.go @@ -496,15 +496,15 @@ func (m *moduleContext) GetDirectDepWithTag(name string, tag blueprint.Dependenc } } -func (m *moduleContext) GetDirectDepProxyWithTag(name string, tag blueprint.DependencyTag) *ModuleProxy { +func (m *moduleContext) GetDirectDepProxyWithTag(name string, tag blueprint.DependencyTag) ModuleProxy { deps := m.getDirectDepsProxyInternal(name, tag) if len(deps) == 1 { - return &deps[0] + return deps[0] } else if len(deps) >= 2 { panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q", name, m.ModuleName())) } else { - return nil + return ModuleProxy{} } } diff --git a/android/module_proxy.go b/android/module_proxy.go index b292b5c35..cb374bf1d 100644 --- a/android/module_proxy.go +++ b/android/module_proxy.go @@ -9,7 +9,7 @@ type ModuleProxy struct { module blueprint.ModuleProxy } -var _ Module = (*ModuleProxy)(nil) +var _ Module = ModuleProxy{} func (m ModuleProxy) IsNil() bool { return m.module.IsNil() diff --git a/android/path_properties_test.go b/android/path_properties_test.go index 6f44f2872..f2adf7e64 100644 --- a/android/path_properties_test.go +++ b/android/path_properties_test.go @@ -64,7 +64,7 @@ func (p *pathDepsMutatorTestModule) GenerateAndroidBuildActions(ctx ModuleContex if p.props.Foo != "" { // Make sure there is only one dependency on a module listed in a property present in multiple property structs m := SrcIsModule(p.props.Foo) - if GetModuleProxyFromPathDep(ctx, m, "") == nil { + if GetModuleProxyFromPathDep(ctx, m, "").IsNil() { ctx.ModuleErrorf("GetDirectDepWithTag failed") } } diff --git a/android/paths.go b/android/paths.go index 6612d37d3..2d740b1e7 100644 --- a/android/paths.go +++ b/android/paths.go @@ -609,7 +609,7 @@ func DirectoryPathsForModuleSrc(ctx ModuleMissingDepsPathContext, paths []string for _, path := range paths { if m, t := SrcIsModuleWithTag(path); m != "" { module := GetModuleProxyFromPathDep(ctx, m, t) - if module == nil { + if module.IsNil() { ctx.ModuleErrorf(`missing dependency on %q, is the property annotated with android:"path"?`, m) continue } @@ -621,7 +621,7 @@ func DirectoryPathsForModuleSrc(ctx ModuleMissingDepsPathContext, paths []string if !ok { panic(fmt.Errorf("%s is not an OtherModuleProviderContext", ctx)) } - if dirProvider, ok := OtherModuleProvider(mctx, *module, DirProvider); ok { + if dirProvider, ok := OtherModuleProvider(mctx, module, DirProvider); ok { ret = append(ret, dirProvider.Dirs...) } else { ReportPathErrorf(ctx, "module %q does not implement DirProvider", module) @@ -680,14 +680,14 @@ func (p OutputPaths) Strings() []string { // If the module dependency is not a SourceFileProducer or OutputFileProducer, appropriate errors will be returned. func getPathsFromModuleDep(ctx ModuleWithDepsPathContext, path, moduleName, tag string) (Paths, error) { module := GetModuleProxyFromPathDep(ctx, moduleName, tag) - if module == nil { + if module.IsNil() { return nil, missingDependencyError{[]string{moduleName}} } - if !OtherModulePointerProviderOrDefault(ctx, *module, CommonModuleInfoProvider).Enabled { + if !OtherModulePointerProviderOrDefault(ctx, module, CommonModuleInfoProvider).Enabled { return nil, missingDependencyError{[]string{moduleName}} } - outputFiles, err := outputFilesForModule(ctx, *module, tag) + outputFiles, err := outputFilesForModule(ctx, module, tag) if outputFiles != nil && err == nil { return outputFiles, nil } else { @@ -705,8 +705,8 @@ func getPathsFromModuleDep(ctx ModuleWithDepsPathContext, path, moduleName, tag // // If tag is "" then the returned module will be the dependency that was added for ":moduleName". // Otherwise, it is the dependency that was added for ":moduleName{tag}". -func GetModuleProxyFromPathDep(ctx ModuleWithDepsPathContext, moduleName, tag string) *ModuleProxy { - var found *ModuleProxy +func GetModuleProxyFromPathDep(ctx ModuleWithDepsPathContext, moduleName, tag string) ModuleProxy { + var found ModuleProxy // The sourceOrOutputDepTag uniquely identifies the module dependency as it contains both the // module name and the tag. Dependencies added automatically for properties tagged with // `android:"path"` are deduped so are guaranteed to be unique. It is possible for duplicate @@ -720,7 +720,7 @@ func GetModuleProxyFromPathDep(ctx ModuleWithDepsPathContext, moduleName, tag st // this finds the matching dependency module. expectedTag := sourceOrOutputDepTag(moduleName, tag) ctx.VisitDirectDepsProxyWithTag(expectedTag, func(module ModuleProxy) { - found = &module + found = module }) return found } diff --git a/apex/apex.go b/apex/apex.go index f45d7e3dd..ce064b70d 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -607,7 +607,7 @@ type apexFile struct { multilib string // TODO(jiyong): remove this - module *android.ModuleProxy + module android.ModuleProxy providers *providerInfoForApexFile } @@ -623,7 +623,7 @@ type providerInfoForApexFile 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.ModuleProxy) apexFile { + installDir string, class apexFileClass, module android.ModuleProxy) apexFile { ret := apexFile{ builtFile: builtFile, installDir: installDir, @@ -631,8 +631,8 @@ func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidM class: class, module: module, } - if module != nil { - if installFilesInfo, ok := android.OtherModuleProvider(ctx, *module, android.InstallFilesProvider); ok { + if !module.IsNil() { + if installFilesInfo, ok := android.OtherModuleProvider(ctx, module, android.InstallFilesProvider); ok { ret.checkbuildTarget = installFilesInfo.CheckbuildTarget } ret.moduleDir = ctx.OtherModuleDir(module) @@ -1438,7 +1438,7 @@ func apexFileForNativeLibrary(ctx android.BaseModuleContext, module android.Modu fileToCopy := android.OutputFileForModule(ctx, module, "") androidMkModuleName := commonInfo.BaseModuleName + ccMod.SubName - return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, &module) + return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, module) } func apexFileForExecutable(ctx android.BaseModuleContext, module android.ModuleProxy, @@ -1449,7 +1449,7 @@ func apexFileForExecutable(ctx android.BaseModuleContext, module android.ModuleP 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 := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, module) af.symlinks = linkableInfo.Symlinks af.dataPaths = ccInfo.DataPaths return af @@ -1463,7 +1463,7 @@ func apexFileForRustExecutable(ctx android.BaseModuleContext, module android.Mod 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 := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, module) return af } @@ -1472,7 +1472,7 @@ func apexFileForShBinary(ctx android.BaseModuleContext, module android.ModulePro dirInApex := filepath.Join("bin", sh.SubDir) setDirInApexForNativeBridge(commonInfo, &dirInApex) fileToCopy := sh.OutputFile - af := newApexFile(ctx, fileToCopy, commonInfo.BaseModuleName, dirInApex, shBinary, &module) + af := newApexFile(ctx, fileToCopy, commonInfo.BaseModuleName, dirInApex, shBinary, module) af.symlinks = sh.Symlinks return af } @@ -1481,21 +1481,21 @@ 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, &module) + return newApexFile(ctx, outputFile, makeModuleName, dirInApex, etc, module) } func apexFileForCompatConfig(ctx android.BaseModuleContext, module android.ModuleProxy, config *java.PlatformCompatConfigInfo, depName string) apexFile { dirInApex := filepath.Join("etc", config.SubDir) fileToCopy := config.CompatConfig - return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, &module) + return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, module) } func apexFileForVintfFragment(ctx android.BaseModuleContext, module android.ModuleProxy, commonInfo *android.CommonModuleInfo, vf *android.VintfFragmentInfo) apexFile { dirInApex := filepath.Join("etc", "vintf") - return newApexFile(ctx, vf.OutputFile, commonInfo.BaseModuleName, dirInApex, etc, &module) + 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 @@ -1524,7 +1524,7 @@ func apexFileForJavaModuleWithFile(ctx android.ModuleContext, module android.Mod javaInfo *java.JavaInfo, dexImplementationJar android.Path) apexFile { dirInApex := "javalib" commonInfo := android.OtherModulePointerProviderOrDefault(ctx, module, android.CommonModuleInfoProvider) - af := newApexFile(ctx, dexImplementationJar, commonInfo.BaseModuleName, dirInApex, javaSharedLib, &module) + 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 @@ -1544,7 +1544,7 @@ func apexFileForJavaModuleProfile(ctx android.BaseModuleContext, commonInfo *and javaInfo *java.JavaInfo) *apexFile { if profilePathOnHost := javaInfo.DexpreopterInfo.OutputProfilePathOnHost; profilePathOnHost != nil { dirInApex := "javalib" - af := newApexFile(ctx, profilePathOnHost, commonInfo.BaseModuleName+"-profile", dirInApex, etc, nil) + af := newApexFile(ctx, profilePathOnHost, commonInfo.BaseModuleName+"-profile", dirInApex, etc, android.ModuleProxy{}) af.customStem = javaInfo.Stem + ".jar.prof" return &af } @@ -1579,7 +1579,7 @@ func apexFilesForAndroidApp(ctx android.BaseModuleContext, module android.Module dirInApex := filepath.Join(appDir, aapp.InstallApkName+"@"+sanitizedBuildIdForPath(ctx)) fileToCopy := aapp.OutputFile - af := newApexFile(ctx, fileToCopy, commonInfo.BaseModuleName, dirInApex, app, &module) + 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 @@ -1594,7 +1594,7 @@ func apexFilesForAndroidApp(ctx android.BaseModuleContext, module android.Module if allowlist := aapp.PrivAppAllowlist; allowlist.Valid() { dirInApex := filepath.Join("etc", "permissions") - privAppAllowlist := newApexFile(ctx, allowlist.Path(), commonInfo.BaseModuleName+"_privapp", dirInApex, etc, &module) + privAppAllowlist := newApexFile(ctx, allowlist.Path(), commonInfo.BaseModuleName+"_privapp", dirInApex, etc, module) apexFiles = append(apexFiles, privAppAllowlist) } @@ -1607,7 +1607,7 @@ func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, module and rroDir := "overlay" dirInApex := filepath.Join(rroDir, rro.Theme) fileToCopy := rro.OutputFile - af := newApexFile(ctx, fileToCopy, module.Name(), dirInApex, app, &module) + af := newApexFile(ctx, fileToCopy, module.Name(), dirInApex, app, module) af.certificate = rro.Certificate return af @@ -1615,12 +1615,12 @@ func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, module and func apexFileForBpfProgram(ctx android.BaseModuleContext, builtFile android.Path, apex_sub_dir string, bpfProgram android.ModuleProxy) apexFile { dirInApex := filepath.Join("etc", "bpf", apex_sub_dir) - return newApexFile(ctx, builtFile, builtFile.Base(), dirInApex, etc, &bpfProgram) + return newApexFile(ctx, builtFile, builtFile.Base(), dirInApex, etc, bpfProgram) } func apexFileForFilesystem(ctx android.BaseModuleContext, buildFile android.Path, module android.ModuleProxy) apexFile { dirInApex := filepath.Join("etc", "fs") - return newApexFile(ctx, buildFile, buildFile.Base(), dirInApex, etc, &module) + return newApexFile(ctx, buildFile, buildFile.Base(), dirInApex, etc, module) } // WalkPayloadDeps visits dependencies that contributes to the payload of this APEX. For each of the @@ -1784,7 +1784,7 @@ func (vctx *visitorContext) normalizeFileInfo(mctx android.ModuleContext) { // TODO(b/295593640) // Needs additional verification for the resulting APEX to ensure that skipped artifacts don't make problems. // For example, DT_NEEDED modules should be found within the APEX unless they are marked in `requiredNativeLibs`. - if f.transitiveDep && f.module != nil && android.InList(mctx.OtherModuleName(f.module), vctx.unwantedTransitiveDeps) { + if f.transitiveDep && !f.module.IsNil() && android.InList(mctx.OtherModuleName(f.module), vctx.unwantedTransitiveDeps) { vctx.unwantedTransitiveFilesInfo = append(vctx.unwantedTransitiveFilesInfo, f) continue } @@ -1948,7 +1948,7 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, // 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 := newApexFile(ctx, appInfo.OutputFile, commonInfo.BaseModuleName, appDirName, appSet, child) af.certificate = java.PresignedCertificate vctx.filesInfo = append(vctx.filesInfo, af) } else { @@ -2383,7 +2383,7 @@ func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module android.Mo } androidMkModuleName := filepath.Base(pathInApex) - af := newApexFile(ctx, tempPath, androidMkModuleName, filepath.Dir(pathInApex), etc, nil) + af := newApexFile(ctx, tempPath, androidMkModuleName, filepath.Dir(pathInApex), etc, android.ModuleProxy{}) filesToAdd = append(filesToAdd, af) } @@ -2398,7 +2398,7 @@ func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module android.Mo return nil } classpathProtoOutput := info.ClasspathFragmentProtoOutput - af := newApexFile(ctx, classpathProtoOutput, classpathProtoOutput.Base(), info.ClasspathFragmentProtoInstallDir.Rel(), etc, nil) + af := newApexFile(ctx, classpathProtoOutput, classpathProtoOutput.Base(), info.ClasspathFragmentProtoInstallDir.Rel(), etc, android.ModuleProxy{}) return &af } diff --git a/apex/builder.go b/apex/builder.go index becda2ba9..d611b7363 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -248,7 +248,7 @@ var ( func (a *apexBundle) buildAconfigFiles(ctx android.ModuleContext) []apexFile { var aconfigFiles android.Paths for _, file := range a.filesInfo { - if file.module == nil { + if file.module.IsNil() { continue } if dep, ok := android.OtherModuleProvider(ctx, file.module, android.AconfigPropagatingProviderKey); ok { @@ -276,7 +276,7 @@ func (a *apexBundle) buildAconfigFiles(ctx android.ModuleContext) []apexFile { "cache_files": android.JoinPathsWithPrefix(aconfigFiles, "--cache "), }, }) - files = append(files, newApexFile(ctx, apexAconfigFile, "aconfig_flags", "etc", etc, nil)) + files = append(files, newApexFile(ctx, apexAconfigFile, "aconfig_flags", "etc", etc, android.ModuleProxy{})) // To enable fingerprint, we need to have v2 storage files. The default version is 1. storageFilesVersion := 1 @@ -298,7 +298,7 @@ func (a *apexBundle) buildAconfigFiles(ctx android.ModuleContext) []apexFile { "version": strconv.Itoa(storageFilesVersion), }, }) - files = append(files, newApexFile(ctx, outputFile, info.File_type, "etc", etc, nil)) + files = append(files, newApexFile(ctx, outputFile, info.File_type, "etc", etc, android.ModuleProxy{})) } } return files @@ -408,8 +408,8 @@ func (a *apexBundle) buildFileContexts(ctx android.ModuleContext) android.Path { if m, t := android.SrcIsModuleWithTag(*a.properties.File_contexts); m != "" { isFileContextsModule = true otherModule := android.GetModuleProxyFromPathDep(ctx, m, t) - if otherModule != nil { - fileContextsDir = ctx.OtherModuleDir(*otherModule) + if !otherModule.IsNil() { + fileContextsDir = ctx.OtherModuleDir(otherModule) } } fileContexts = android.PathForModuleSrc(ctx, *a.properties.File_contexts) diff --git a/cc/ndk_library.go b/cc/ndk_library.go index c21fe564b..69092b79c 100644 --- a/cc/ndk_library.go +++ b/cc/ndk_library.go @@ -298,17 +298,17 @@ func CompileStubLibrary(ctx android.ModuleContext, flags Flags, src android.Path func (this *stubDecorator) findImplementationLibrary(ctx ModuleContext) android.Path { dep := ctx.GetDirectDepProxyWithTag(strings.TrimSuffix(ctx.ModuleName(), ndkLibrarySuffix), stubImplementation) - if dep == nil { + if dep.IsNil() { ctx.ModuleErrorf("Could not find implementation for stub: ") return nil } - if _, ok := android.OtherModuleProvider(ctx, *dep, CcInfoProvider); !ok { + if _, ok := android.OtherModuleProvider(ctx, dep, CcInfoProvider); !ok { ctx.ModuleErrorf("Implementation for stub is not correct module type") return nil } - output := android.OtherModuleProviderOrDefault(ctx, *dep, LinkableInfoProvider).UnstrippedOutputFile + output := android.OtherModuleProviderOrDefault(ctx, dep, LinkableInfoProvider).UnstrippedOutputFile if output == nil { - ctx.ModuleErrorf("implementation module (%s) has no output", *dep) + ctx.ModuleErrorf("implementation module (%s) has no output", dep) return nil } diff --git a/java/droiddoc.go b/java/droiddoc.go index 225f201a9..67bd61318 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -429,8 +429,8 @@ func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps { for _, src := range j.properties.Srcs { if moduleName, tag := android.SrcIsModuleWithTag(src); moduleName != "" { otherModule := android.GetModuleProxyFromPathDep(ctx, moduleName, tag) - if otherModule != nil { - if dep, ok := android.OtherModuleProvider(ctx, *otherModule, android.CodegenInfoProvider); ok { + if !otherModule.IsNil() { + if dep, ok := android.OtherModuleProvider(ctx, otherModule, android.CodegenInfoProvider); ok { deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...) } } diff --git a/java/ravenwood.go b/java/ravenwood.go index a71195d79..01aa25cd6 100644 --- a/java/ravenwood.go +++ b/java/ravenwood.go @@ -14,9 +14,9 @@ package java import ( - "android/soong/aconfig" "strconv" + "android/soong/aconfig" "android/soong/android" "android/soong/tradefed" @@ -371,7 +371,7 @@ func (r *ravenwoodLibgroup) GenerateAndroidBuildActions(ctx android.ModuleContex installPath := android.PathForModuleInstall(ctx, r.BaseModuleName()) for _, lib := range r.ravenwoodLibgroupProperties.Libs { libModule := ctx.GetDirectDepProxyWithTag(lib, ravenwoodLibContentTag) - if libModule == nil { + if libModule.IsNil() { if ctx.Config().AllowMissingDependencies() { ctx.AddMissingDependencies([]string{lib}) } else { @@ -403,7 +403,7 @@ func (r *ravenwoodLibgroup) GenerateAndroidBuildActions(ctx android.ModuleContex // Copy aconfig flag storage files. if r.Name() == ravenwoodRuntimeName { allAconfigFound := false - if allAconfig := ctx.GetDirectDepProxyWithTag(aconfig.AllAconfigModule, allAconfigModuleTag); allAconfig != nil { + if allAconfig := ctx.GetDirectDepProxyWithTag(aconfig.AllAconfigModule, allAconfigModuleTag); !allAconfig.IsNil() { aadi, ok := android.OtherModuleProvider(ctx, allAconfig, aconfig.AllAconfigDeclarationsInfoProvider) if ok { // Binary proto file and the text proto. diff --git a/java/robolectric.go b/java/robolectric.go index 1d204a4e0..9c98f5d9b 100644 --- a/java/robolectric.go +++ b/java/robolectric.go @@ -406,7 +406,7 @@ func (r *robolectricRuntimes) GenerateAndroidBuildActions(ctx android.ModuleCont if !ctx.Config().AlwaysUsePrebuiltSdks() && r.props.Lib != nil { runtimeFromSourceModule := ctx.GetDirectDepProxyWithTag(String(r.props.Lib), libTag) - if runtimeFromSourceModule == nil { + if runtimeFromSourceModule.IsNil() { if ctx.Config().AllowMissingDependencies() { ctx.AddMissingDependencies([]string{String(r.props.Lib)}) } else { -- cgit v1.2.3 From ef54847185165e856b6ed8e3169f6f315b1205c6 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Fri, 4 Apr 2025 09:51:57 -0700 Subject: Simplify android.ModuleProxy and use blueprint.ModuleBase Make android.ModuleProxy a wrapper around blueprint.ModuleProxy now that blueprint.getWrappedModule no longer needs to type assert on the concrete blueprint.ModuleProxy type. Remove the unnecessary android.getWrappedModule. Also make android.ModuleBase implement the info() method by embedding blueprint.ModuleBase. Test: all soong tests pass Change-Id: I9f8bf55b5e0245e4038d1741afafa1f9f78fd39f --- android/base_module_context.go | 28 +++++++++------------------- android/early_module_context.go | 2 +- android/module.go | 1 + android/module_proxy.go | 18 +----------------- android/module_test.go | 13 +++++++++---- android/namespace_test.go | 1 + android/provider.go | 2 +- android/singleton.go | 22 ++++++++++------------ golang/golang.go | 18 ++++++++++++++++-- 9 files changed, 49 insertions(+), 56 deletions(-) diff --git a/android/base_module_context.go b/android/base_module_context.go index 86c6b4491..80e1c47d0 100644 --- a/android/base_module_context.go +++ b/android/base_module_context.go @@ -259,34 +259,24 @@ type baseModuleContext struct { } -func getWrappedModule(module blueprint.Module) blueprint.Module { - if mp, isProxy := module.(*ModuleProxy); isProxy { - return mp.module - } - if mp, isProxy := module.(ModuleProxy); isProxy { - return mp.module - } - return module -} - func EqualModules(m1, m2 Module) bool { - return blueprint.EqualModules(getWrappedModule(m1), getWrappedModule(m2)) + return blueprint.EqualModules(m1, m2) } func (b *baseModuleContext) OtherModuleName(m blueprint.Module) string { - return b.bp.OtherModuleName(getWrappedModule(m)) + return b.bp.OtherModuleName(m) } func (b *baseModuleContext) OtherModuleDir(m blueprint.Module) string { - return b.bp.OtherModuleDir(getWrappedModule(m)) + return b.bp.OtherModuleDir(m) } func (b *baseModuleContext) OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{}) { - b.bp.OtherModuleErrorf(getWrappedModule(m), fmt, args...) + b.bp.OtherModuleErrorf(m, fmt, args...) } func (b *baseModuleContext) OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag { - return b.bp.OtherModuleDependencyTag(getWrappedModule(m)) + return b.bp.OtherModuleDependencyTag(m) } func (b *baseModuleContext) OtherModuleSubDir(m blueprint.Module) string { - return b.bp.OtherModuleSubDir(getWrappedModule(m)) + return b.bp.OtherModuleSubDir(m) } func (b *baseModuleContext) OtherModuleExists(name string) bool { return b.bp.OtherModuleExists(name) } func (b *baseModuleContext) OtherModuleDependencyVariantExists(variations []blueprint.Variation, name string) bool { @@ -299,15 +289,15 @@ func (b *baseModuleContext) OtherModuleReverseDependencyVariantExists(name strin return b.bp.OtherModuleReverseDependencyVariantExists(name) } func (b *baseModuleContext) OtherModuleType(m blueprint.Module) string { - return b.bp.OtherModuleType(getWrappedModule(m)) + return b.bp.OtherModuleType(m) } func (b *baseModuleContext) otherModuleProvider(m blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) { - return b.bp.OtherModuleProvider(getWrappedModule(m), provider) + return b.bp.OtherModuleProvider(m, provider) } func (b *baseModuleContext) OtherModuleHasProvider(m blueprint.Module, provider blueprint.AnyProviderKey) bool { - return b.bp.OtherModuleHasProvider(getWrappedModule(m), provider) + return b.bp.OtherModuleHasProvider(m, provider) } func (b *baseModuleContext) OtherModuleIsAutoGenerated(m blueprint.Module) bool { diff --git a/android/early_module_context.go b/android/early_module_context.go index 300edf194..d6651ff9f 100644 --- a/android/early_module_context.go +++ b/android/early_module_context.go @@ -189,7 +189,7 @@ func (e *earlyModuleContext) Namespace() *Namespace { } func (e *earlyModuleContext) OtherModulePropertyErrorf(module Module, property string, fmt string, args ...interface{}) { - e.EarlyModuleContext.OtherModulePropertyErrorf(getWrappedModule(module), property, fmt, args...) + e.EarlyModuleContext.OtherModulePropertyErrorf(module, property, fmt, args...) } func (e *earlyModuleContext) HasMutatorFinished(mutatorName string) bool { diff --git a/android/module.go b/android/module.go index 9f43d86e7..96430d4fa 100644 --- a/android/module.go +++ b/android/module.go @@ -851,6 +851,7 @@ func InitCommonOSAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupport // // ... // } type ModuleBase struct { + blueprint.ModuleBase // Putting the curiously recurring thing pointing to the thing that contains // the thing pattern to good use. // TODO: remove this diff --git a/android/module_proxy.go b/android/module_proxy.go index cb374bf1d..5b201f859 100644 --- a/android/module_proxy.go +++ b/android/module_proxy.go @@ -6,23 +6,11 @@ import ( ) type ModuleProxy struct { - module blueprint.ModuleProxy + blueprint.ModuleProxy } var _ Module = ModuleProxy{} -func (m ModuleProxy) IsNil() bool { - return m.module.IsNil() -} - -func (m ModuleProxy) Name() string { - return m.module.Name() -} - -func (m ModuleProxy) GenerateBuildActions(context blueprint.ModuleContext) { - m.module.GenerateBuildActions(context) -} - func (m ModuleProxy) GenerateAndroidBuildActions(context ModuleContext) { panic("method is not implemented on ModuleProxy") } @@ -192,10 +180,6 @@ func (m ModuleProxy) VariablesForTests() map[string]string { panic("method is not implemented on ModuleProxy") } -func (m ModuleProxy) String() string { - return m.module.String() -} - func (m ModuleProxy) qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName { panic("method is not implemented on ModuleProxy") } diff --git a/android/module_test.go b/android/module_test.go index 5331e4970..41a27e24b 100644 --- a/android/module_test.go +++ b/android/module_test.go @@ -983,6 +983,7 @@ func (o outputFilesTestModule) GenerateAndroidBuildActions(ctx ModuleContext) { type pathContextAddMissingDependenciesWrapper struct { PathContext OtherModuleProviderContext + module Module missingDeps []string } @@ -993,7 +994,7 @@ func (p *pathContextAddMissingDependenciesWrapper) OtherModuleName(module bluepr return module.Name() } -func (p *pathContextAddMissingDependenciesWrapper) Module() Module { return nil } +func (p *pathContextAddMissingDependenciesWrapper) Module() Module { return p.module } func (p *pathContextAddMissingDependenciesWrapper) GetOutputFiles() OutputFilesInfo { return OutputFilesInfo{} @@ -1030,7 +1031,7 @@ func TestOutputFileForModule(t *testing.T) { a: "", b: "empty.txt", } - `, + `, tag: "", expected: "empty.txt", }, @@ -1050,7 +1051,7 @@ func TestOutputFileForModule(t *testing.T) { bp: `oft_module { name: "test_module", } - `, + `, tag: "missing", expected: "missing_output_file/test_module", missingDeps: []string{"test_module"}, @@ -1062,13 +1063,16 @@ func TestOutputFileForModule(t *testing.T) { for _, tt := range testcases { t.Run(tt.name, func(t *testing.T) { + extraBp := `oft_module { + name: "other_module" + }` result := GroupFixturePreparers( PrepareForTestWithDefaults, FixtureRegisterWithContext(func(ctx RegistrationContext) { ctx.RegisterModuleType("spt_module", sourceProducerTestModuleFactory) ctx.RegisterModuleType("oft_module", outputFilesTestModuleFactory) }), - FixtureWithRootAndroidBp(tt.bp), + FixtureWithRootAndroidBp(tt.bp+extraBp), ).RunTest(t) config := TestConfig(buildDir, tt.env, tt.bp, nil) @@ -1078,6 +1082,7 @@ func TestOutputFileForModule(t *testing.T) { ctx := &pathContextAddMissingDependenciesWrapper{ PathContext: PathContextForTesting(config), OtherModuleProviderContext: result.TestContext.OtherModuleProviderAdaptor(), + module: result.ModuleForTests(t, "other_module", "").Module(), } got := OutputFileForModule(ctx, result.ModuleForTests(t, "test_module", "").Module(), tt.tag) AssertPathRelativeToTopEquals(t, "expected output path", tt.expected, got) diff --git a/android/namespace_test.go b/android/namespace_test.go index a183bbf0d..335a9b2eb 100644 --- a/android/namespace_test.go +++ b/android/namespace_test.go @@ -734,6 +734,7 @@ func newTestModule() Module { type blueprintTestModule struct { blueprint.SimpleName + blueprint.ModuleBase properties struct { Deps []string } diff --git a/android/provider.go b/android/provider.go index aae93ef88..875929137 100644 --- a/android/provider.go +++ b/android/provider.go @@ -28,7 +28,7 @@ type ConfigAndOtherModuleProviderContext interface { // // OtherModuleProviderContext is a helper interface that accepts ModuleContext or BottomUpMutatorContext. func OtherModuleProvider[K any](ctx OtherModuleProviderContext, module blueprint.Module, provider blueprint.ProviderKey[K]) (K, bool) { - value, ok := ctx.otherModuleProvider(getWrappedModule(module), provider) + value, ok := ctx.otherModuleProvider(module, provider) if !ok { var k K return k, false diff --git a/android/singleton.go b/android/singleton.go index 64bafa31f..86e0e8e03 100644 --- a/android/singleton.go +++ b/android/singleton.go @@ -262,9 +262,7 @@ func visitAdaptor(visit func(Module)) func(blueprint.Module) { // a function that takes a blueprint.ModuleProxy parameter. func visitProxyAdaptor(visit func(proxy ModuleProxy)) func(proxy blueprint.ModuleProxy) { return func(module blueprint.ModuleProxy) { - visit(ModuleProxy{ - module: module, - }) + visit(ModuleProxy{module}) } } @@ -282,23 +280,23 @@ func predAdaptor(pred func(Module) bool) func(blueprint.Module) bool { } func (s *singletonContextAdaptor) ModuleName(module blueprint.Module) string { - return s.SingletonContext.ModuleName(getWrappedModule(module)) + return s.SingletonContext.ModuleName(module) } func (s *singletonContextAdaptor) ModuleDir(module blueprint.Module) string { - return s.SingletonContext.ModuleDir(getWrappedModule(module)) + return s.SingletonContext.ModuleDir(module) } func (s *singletonContextAdaptor) ModuleSubDir(module blueprint.Module) string { - return s.SingletonContext.ModuleSubDir(getWrappedModule(module)) + return s.SingletonContext.ModuleSubDir(module) } func (s *singletonContextAdaptor) ModuleType(module blueprint.Module) string { - return s.SingletonContext.ModuleType(getWrappedModule(module)) + return s.SingletonContext.ModuleType(module) } func (s *singletonContextAdaptor) BlueprintFile(module blueprint.Module) string { - return s.SingletonContext.BlueprintFile(getWrappedModule(module)) + return s.SingletonContext.BlueprintFile(module) } func (s *singletonContextAdaptor) VisitAllModulesBlueprint(visit func(blueprint.Module)) { @@ -338,7 +336,7 @@ func (s *singletonContextAdaptor) VisitAllModuleVariants(module Module, visit fu } func (s *singletonContextAdaptor) VisitAllModuleVariantProxies(module Module, visit func(proxy ModuleProxy)) { - s.SingletonContext.VisitAllModuleVariantProxies(getWrappedModule(module), visitProxyAdaptor(visit)) + s.SingletonContext.VisitAllModuleVariantProxies(module, visitProxyAdaptor(visit)) } func (s *singletonContextAdaptor) PrimaryModule(module Module) Module { @@ -346,18 +344,18 @@ func (s *singletonContextAdaptor) PrimaryModule(module Module) Module { } func (s *singletonContextAdaptor) PrimaryModuleProxy(module ModuleProxy) ModuleProxy { - return ModuleProxy{s.SingletonContext.PrimaryModuleProxy(module.module)} + return ModuleProxy{s.SingletonContext.PrimaryModuleProxy(module.ModuleProxy)} } func (s *singletonContextAdaptor) IsFinalModule(module Module) bool { - return s.SingletonContext.IsFinalModule(getWrappedModule(module)) + return s.SingletonContext.IsFinalModule(module) } func (s *singletonContextAdaptor) ModuleVariantsFromName(referer ModuleProxy, name string) []ModuleProxy { // get module reference for visibility enforcement qualified := createVisibilityModuleProxyReference(s, s.ModuleName(referer), s.ModuleDir(referer), referer) - modules := s.SingletonContext.ModuleVariantsFromName(referer.module, name) + modules := s.SingletonContext.ModuleVariantsFromName(referer.ModuleProxy, name) result := make([]ModuleProxy, 0, len(modules)) for _, module := range modules { // enforce visibility diff --git a/golang/golang.go b/golang/golang.go index 9e0744aaf..1bf7e32c2 100644 --- a/golang/golang.go +++ b/golang/golang.go @@ -38,10 +38,17 @@ func RegisterGoModuleTypes(ctx android.RegistrationContext) { ctx.RegisterModuleType("blueprint_go_binary", goBinaryModuleFactory) } +// wrapGoPackage is used to increase the depth of the blueprint.ModuleBase struct embedded in bootstrap.GoPackage +// so that the Go selector rules will choose the blueprint.ModuleBase in android.ModuleBase instead of throwing +// an ambiguous method error. +type wrapGoPackage struct { + bootstrap.GoPackage +} + // A GoPackage is a module for building Go packages. type GoPackage struct { android.ModuleBase - bootstrap.GoPackage + wrapGoPackage } func goPackageModuleFactory() android.Module { @@ -63,10 +70,17 @@ func (g *GoPackage) GenerateAndroidBuildActions(ctx android.ModuleContext) { g.GoPackage.GenerateBuildActions(ctx.BlueprintModuleContext()) } +// wrapGoBinary is used to increase the depth of the blueprint.ModuleBase struct embedded in bootstrap.GoBinary +// so that the Go selector rules will choose the blueprint.ModuleBase in android.ModuleBase instead of throwing +// an ambiguous method error. +type wrapGoBinary struct { + bootstrap.GoBinary +} + // A GoBinary is a module for building executable binaries from Go sources. type GoBinary struct { android.ModuleBase - bootstrap.GoBinary + wrapGoBinary outputFile android.Path } -- cgit v1.2.3 From 0ff7457e523fa258472ff93a4b6a5e14196c2efb Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 3 Apr 2025 19:48:48 -0700 Subject: Separate ModuleProxy from Module ModuleProxy currently implements Module by stubbing out all the methods. Use the new blueprint.ModuleOrProxy type instead that can take either a Module or a ModuleProxy, and simplify ModuleProxy so that it no longer implements Module. Convert the methods can work on either to ModuleOrProxy. Test: all soong tests pass Change-Id: I0fc53a2dd7a6d4c54bea2f46435546da99ba78a9 --- android/aconfig_providers.go | 4 +- android/androidmk.go | 10 +- android/apex.go | 4 +- android/base_module_context.go | 92 +++++++++++------ android/container.go | 2 +- android/early_module_context.go | 4 +- android/makevars.go | 18 ++-- android/module.go | 12 +-- android/module_proxy.go | 220 ---------------------------------------- android/module_test.go | 2 +- android/paths.go | 16 +-- android/prebuilt.go | 10 +- android/provider.go | 12 +-- android/singleton.go | 40 ++++---- android/symbols.go | 2 +- android/test_suites.go | 4 +- android/testing.go | 10 +- apex/apex.go | 4 +- cc/cc.go | 7 +- cc/library_sdk_member.go | 2 +- ci_tests/ci_test_package_zip.go | 14 +-- filesystem/android_device.go | 16 +-- fuzz/fuzz_common.go | 4 +- java/bootclasspath_fragment.go | 2 +- java/java.go | 10 +- java/sdk_library.go | 24 ++--- python/python.go | 4 +- 27 files changed, 181 insertions(+), 368 deletions(-) diff --git a/android/aconfig_providers.go b/android/aconfig_providers.go index bb73f0bdd..91c39a462 100644 --- a/android/aconfig_providers.go +++ b/android/aconfig_providers.go @@ -67,7 +67,7 @@ type CodegenInfo struct { var CodegenInfoProvider = blueprint.NewProvider[CodegenInfo]() -func propagateModeInfos(ctx ModuleContext, module Module, to, from map[string]ModeInfo) { +func propagateModeInfos(ctx ModuleContext, module ModuleProxy, to, from map[string]ModeInfo) { if len(from) > 0 { depTag := ctx.OtherModuleDependencyTag(module) if tag, ok := depTag.(PropagateAconfigValidationDependencyTag); ok && tag.PropagateAconfigValidation() { @@ -83,7 +83,7 @@ type aconfigPropagatingDeclarationsInfo struct { var AconfigPropagatingProviderKey = blueprint.NewProvider[aconfigPropagatingDeclarationsInfo]() -func VerifyAconfigBuildMode(ctx ModuleContext, container string, module blueprint.Module, asError bool) { +func VerifyAconfigBuildMode(ctx ModuleContext, container string, module blueprint.ModuleOrProxy, asError bool) { if dep, ok := OtherModuleProvider(ctx, module, AconfigPropagatingProviderKey); ok { for k, v := range dep.ModeInfos { msg := fmt.Sprintf("%s/%s depends on %s/%s/%s across containers\n", diff --git a/android/androidmk.go b/android/androidmk.go index e32835946..423f149d9 100644 --- a/android/androidmk.go +++ b/android/androidmk.go @@ -501,12 +501,12 @@ func (a *AndroidMkEntries) GetDistForGoals(mod Module) []string { // fillInEntries goes through the common variable processing and calls the extra data funcs to // generate and fill in AndroidMkEntries's in-struct data, ready to be flushed to a file. type fillInEntriesContext interface { - ModuleDir(module blueprint.Module) string - ModuleSubDir(module blueprint.Module) string + ModuleDir(module blueprint.ModuleOrProxy) string + ModuleSubDir(module blueprint.ModuleOrProxy) string Config() Config - otherModuleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) - ModuleType(module blueprint.Module) string - OtherModulePropertyErrorf(module Module, property string, fmt string, args ...interface{}) + otherModuleProvider(module blueprint.ModuleOrProxy, provider blueprint.AnyProviderKey) (any, bool) + ModuleType(module blueprint.ModuleOrProxy) string + OtherModulePropertyErrorf(module blueprint.ModuleOrProxy, property string, fmt string, args ...interface{}) HasMutatorFinished(mutatorName string) bool } diff --git a/android/apex.go b/android/apex.go index e6b54a877..598809308 100644 --- a/android/apex.go +++ b/android/apex.go @@ -188,7 +188,7 @@ type DepInSameApexInfo struct { var DepInSameApexInfoProvider = blueprint.NewMutatorProvider[DepInSameApexInfo]("apex_unique") -func IsDepInSameApex(ctx BaseModuleContext, module, dep Module) bool { +func IsDepInSameApex(ctx BaseModuleContext, module, dep blueprint.ModuleOrProxy) bool { depTag := ctx.OtherModuleDependencyTag(dep) if _, ok := depTag.(ExcludeFromApexContentsTag); ok { // The tag defines a dependency that never requires the child module to be part of the same @@ -765,7 +765,7 @@ type MinSdkVersionFromValueContext interface { // error if not. No default implementation is provided for this method. A module type // implementing this interface should provide an implementation. A module supports an sdk // version when the module's min_sdk_version is equal to or less than the given sdk version. -func ShouldSupportSdkVersion(ctx BaseModuleContext, module Module, sdkVersion ApiLevel) error { +func ShouldSupportSdkVersion(ctx BaseModuleContext, module blueprint.ModuleOrProxy, sdkVersion ApiLevel) error { info, ok := OtherModuleProvider(ctx, module, CommonModuleInfoProvider) if !ok || info.MinSdkVersionSupported.IsNone() { return fmt.Errorf("min_sdk_version is not specified") diff --git a/android/base_module_context.go b/android/base_module_context.go index 80e1c47d0..5929f83cb 100644 --- a/android/base_module_context.go +++ b/android/base_module_context.go @@ -36,23 +36,23 @@ type BaseModuleContext interface { // OtherModuleName returns the name of another Module. See BaseModuleContext.ModuleName for more information. // It is intended for use inside the visit functions of Visit* and WalkDeps. - OtherModuleName(m blueprint.Module) string + OtherModuleName(m blueprint.ModuleOrProxy) string // OtherModuleDir returns the directory of another Module. See BaseModuleContext.ModuleDir for more information. // It is intended for use inside the visit functions of Visit* and WalkDeps. - OtherModuleDir(m blueprint.Module) string + OtherModuleDir(m blueprint.ModuleOrProxy) string // OtherModuleErrorf reports an error on another Module. See BaseModuleContext.ModuleErrorf for more information. // It is intended for use inside the visit functions of Visit* and WalkDeps. - OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{}) + OtherModuleErrorf(m blueprint.ModuleOrProxy, fmt string, args ...interface{}) // OtherModuleDependencyTag returns the dependency tag used to depend on a module, or nil if there is no dependency // on the module. When called inside a Visit* method with current module being visited, and there are multiple // dependencies on the module being visited, it returns the dependency tag used for the current dependency. - OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag + OtherModuleDependencyTag(m blueprint.ModuleOrProxy) blueprint.DependencyTag // OtherModuleSubDir returns the string representing the variations of a module. - OtherModuleSubDir(m blueprint.Module) string + OtherModuleSubDir(m blueprint.ModuleOrProxy) 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. @@ -80,23 +80,23 @@ type BaseModuleContext interface { // OtherModuleType returns the type of another Module. See BaseModuleContext.ModuleType for more information. // It is intended for use inside the visit functions of Visit* and WalkDeps. - OtherModuleType(m blueprint.Module) string + OtherModuleType(m blueprint.ModuleOrProxy) string // otherModuleProvider returns the value for a provider for the given module. If the value is // not set it returns nil and false. The value returned may be a deep copy of the value originally // passed to SetProvider. // // This method shouldn't be used directly, prefer the type-safe android.OtherModuleProvider instead. - otherModuleProvider(m blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) + otherModuleProvider(m blueprint.ModuleOrProxy, 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 + OtherModuleHasProvider(m blueprint.ModuleOrProxy, 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 + OtherModuleIsAutoGenerated(m blueprint.ModuleOrProxy) bool // Provider returns the value for a provider for the current module. If the value is // not set it returns nil and false. It panics if called before the appropriate @@ -178,11 +178,10 @@ type BaseModuleContext interface { // invalidated by future mutators. WalkDeps(visit func(child, parent Module) bool) - // WalkDeps calls visit for each transitive dependency, traversing the dependency tree in top down order. visit may + // WalkDepsProxy calls visit for each transitive dependency, traversing the dependency tree in top down order. visit may // be called multiple times for the same (child, parent) pair if there are multiple direct dependencies between the // child and parent with different tags. OtherModuleDependencyTag will return the tag for the currently visited - // (child, parent) pair. If visit returns false WalkDeps will not continue recursing down to child. It skips - // any dependencies that are not an android.Module. + // (child, parent) pair. If visit returns false WalkDepsProxy will not continue recursing down to child. // // The Modules passed to the visit function should not be retained outside of the visit function, they may be // invalidated by future mutators. @@ -192,6 +191,10 @@ type BaseModuleContext interface { // and returns a top-down dependency path from a start module to current child module. GetWalkPath() []Module + // GetProxyWalkPath is supposed to be called in visit function passed in WalkDepsProxy() + // and returns a top-down dependency path from a start module to current child module. + GetProxyWalkPath() []ModuleProxy + // PrimaryModule returns the first variant of the current module. Variants of a module are always visited in // order by mutators and GenerateBuildActions, so the data created by the current mutator can be read from the // Module returned by PrimaryModule without data races. This can be used to perform singleton actions that are @@ -208,7 +211,7 @@ type BaseModuleContext interface { // order by mutators and GenerateBuildActions, so the data created by the current mutator can be read from all // variants using VisitAllModuleVariants if the current module is the last one. This can be used to perform // singleton actions that are only done once for all variants of a module. - IsFinalModule(module Module) bool + IsFinalModule(module blueprint.ModuleOrProxy) bool // VisitAllModuleVariants calls visit for each variant of the current module. Variants of a module are always // visited in order by mutators and GenerateBuildActions, so the data created by the current mutator can be read @@ -252,30 +255,31 @@ type baseModuleContext struct { earlyModuleContext archModuleContext - walkPath []Module - tagPath []blueprint.DependencyTag + walkPath []Module + proxyWalkPath []ModuleProxy + tagPath []blueprint.DependencyTag strictVisitDeps bool // If true, enforce that all dependencies are enabled } -func EqualModules(m1, m2 Module) bool { +func EqualModules(m1, m2 blueprint.ModuleOrProxy) bool { return blueprint.EqualModules(m1, m2) } -func (b *baseModuleContext) OtherModuleName(m blueprint.Module) string { +func (b *baseModuleContext) OtherModuleName(m blueprint.ModuleOrProxy) string { return b.bp.OtherModuleName(m) } -func (b *baseModuleContext) OtherModuleDir(m blueprint.Module) string { +func (b *baseModuleContext) OtherModuleDir(m blueprint.ModuleOrProxy) string { return b.bp.OtherModuleDir(m) } -func (b *baseModuleContext) OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{}) { +func (b *baseModuleContext) OtherModuleErrorf(m blueprint.ModuleOrProxy, fmt string, args ...interface{}) { b.bp.OtherModuleErrorf(m, fmt, args...) } -func (b *baseModuleContext) OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag { +func (b *baseModuleContext) OtherModuleDependencyTag(m blueprint.ModuleOrProxy) blueprint.DependencyTag { return b.bp.OtherModuleDependencyTag(m) } -func (b *baseModuleContext) OtherModuleSubDir(m blueprint.Module) string { +func (b *baseModuleContext) OtherModuleSubDir(m blueprint.ModuleOrProxy) string { return b.bp.OtherModuleSubDir(m) } func (b *baseModuleContext) OtherModuleExists(name string) bool { return b.bp.OtherModuleExists(name) } @@ -288,19 +292,19 @@ func (b *baseModuleContext) OtherModuleFarDependencyVariantExists(variations []b func (b *baseModuleContext) OtherModuleReverseDependencyVariantExists(name string) bool { return b.bp.OtherModuleReverseDependencyVariantExists(name) } -func (b *baseModuleContext) OtherModuleType(m blueprint.Module) string { +func (b *baseModuleContext) OtherModuleType(m blueprint.ModuleOrProxy) string { return b.bp.OtherModuleType(m) } -func (b *baseModuleContext) otherModuleProvider(m blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) { +func (b *baseModuleContext) otherModuleProvider(m blueprint.ModuleOrProxy, provider blueprint.AnyProviderKey) (any, bool) { return b.bp.OtherModuleProvider(m, provider) } -func (b *baseModuleContext) OtherModuleHasProvider(m blueprint.Module, provider blueprint.AnyProviderKey) bool { +func (b *baseModuleContext) OtherModuleHasProvider(m blueprint.ModuleOrProxy, provider blueprint.AnyProviderKey) bool { return b.bp.OtherModuleHasProvider(m, provider) } -func (b *baseModuleContext) OtherModuleIsAutoGenerated(m blueprint.Module) bool { +func (b *baseModuleContext) OtherModuleIsAutoGenerated(m blueprint.ModuleOrProxy) bool { return b.bp.OtherModuleIsAutoGenerated(m) } @@ -542,6 +546,7 @@ func (b *baseModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func (b *baseModuleContext) WalkDeps(visit func(Module, Module) bool) { b.walkPath = []Module{b.Module()} + b.proxyWalkPath = nil b.tagPath = []blueprint.DependencyTag{} b.bp.WalkDeps(func(child, parent blueprint.Module) bool { childAndroidModule, _ := child.(Module) @@ -559,29 +564,43 @@ func (b *baseModuleContext) WalkDeps(visit func(Module, Module) bool) { return false } }) + b.walkPath = nil } func (b *baseModuleContext) WalkDepsProxy(visit func(ModuleProxy, ModuleProxy) bool) { - b.walkPath = []Module{ModuleProxy{blueprint.CreateModuleProxy(b.Module())}} + startProxy := blueprint.CreateModuleProxy(b.Module()) + b.proxyWalkPath = []ModuleProxy{{startProxy}} + b.walkPath = nil b.tagPath = []blueprint.DependencyTag{} b.bp.WalkDepsProxy(func(child, parent blueprint.ModuleProxy) bool { childAndroidModule := ModuleProxy{child} parentAndroidModule := ModuleProxy{parent} // record walkPath before visit - for b.walkPath[len(b.walkPath)-1] != parentAndroidModule { - b.walkPath = b.walkPath[0 : len(b.walkPath)-1] + for b.proxyWalkPath[len(b.proxyWalkPath)-1] != parentAndroidModule { + b.proxyWalkPath = b.proxyWalkPath[0 : len(b.proxyWalkPath)-1] b.tagPath = b.tagPath[0 : len(b.tagPath)-1] } - b.walkPath = append(b.walkPath, childAndroidModule) + b.proxyWalkPath = append(b.proxyWalkPath, childAndroidModule) b.tagPath = append(b.tagPath, b.OtherModuleDependencyTag(childAndroidModule)) return visit(childAndroidModule, parentAndroidModule) }) + b.proxyWalkPath = nil } func (b *baseModuleContext) GetWalkPath() []Module { + if b.walkPath == nil { + panic("GetWalkPath called from outside WalkDeps, did you mean GetProxyWalkPath?") + } return slices.Clone(b.walkPath) } +func (b *baseModuleContext) GetProxyWalkPath() []ModuleProxy { + if b.proxyWalkPath == nil { + panic("GetProxyWalkPath called from outside WalkDeps, did you mean GetWalkPath?") + } + return slices.Clone(b.proxyWalkPath) +} + func (b *baseModuleContext) GetTagPath() []blueprint.DependencyTag { return b.tagPath } @@ -604,7 +623,7 @@ func (b *baseModuleContext) FinalModule() Module { return b.bp.FinalModule().(Module) } -func (b *baseModuleContext) IsFinalModule(module Module) bool { +func (b *baseModuleContext) IsFinalModule(module blueprint.ModuleOrProxy) bool { return b.bp.IsFinalModule(module) } @@ -643,7 +662,18 @@ func PrettyPrintTag(tag blueprint.DependencyTag) string { func (b *baseModuleContext) GetPathString(skipFirst bool) string { sb := strings.Builder{} tagPath := b.GetTagPath() - walkPath := b.GetWalkPath() + var walkPath []blueprint.ModuleOrProxy + if b.walkPath != nil { + for _, w := range b.walkPath { + walkPath = append(walkPath, w) + } + } else if b.proxyWalkPath != nil { + for _, w := range b.proxyWalkPath { + walkPath = append(walkPath, w) + } + } else { + panic(fmt.Errorf("GetPathString must be called inside WalkDeps or WalkDepsProxy")) + } if !skipFirst { sb.WriteString(walkPath[0].String()) } diff --git a/android/container.go b/android/container.go index 547fe816c..856fa7876 100644 --- a/android/container.go +++ b/android/container.go @@ -448,7 +448,7 @@ func generateContainerInfo(ctx ModuleContext) ContainersInfo { } } -func getContainerModuleInfo(ctx ModuleContext, module Module) (ContainersInfo, bool) { +func getContainerModuleInfo(ctx ModuleContext, module blueprint.ModuleOrProxy) (ContainersInfo, bool) { if EqualModules(ctx.Module(), module) { return ctx.getContainersInfo(), true } diff --git a/android/early_module_context.go b/android/early_module_context.go index d6651ff9f..a7b8ffc6c 100644 --- a/android/early_module_context.go +++ b/android/early_module_context.go @@ -61,7 +61,7 @@ type EarlyModuleContext interface { Errorf(pos scanner.Position, fmt string, args ...interface{}) // OtherModulePropertyErrorf reports an error at the line number of a property in the given module definition. - OtherModulePropertyErrorf(module Module, property, fmt string, args ...interface{}) + OtherModulePropertyErrorf(module blueprint.ModuleOrProxy, property, fmt string, args ...interface{}) // Failed returns true if any errors have been reported. In most cases the module can continue with generating // build rules after an error, allowing it to report additional errors in a single run, but in cases where the error @@ -188,7 +188,7 @@ func (e *earlyModuleContext) Namespace() *Namespace { return e.EarlyModuleContext.Namespace().(*Namespace) } -func (e *earlyModuleContext) OtherModulePropertyErrorf(module Module, property string, fmt string, args ...interface{}) { +func (e *earlyModuleContext) OtherModulePropertyErrorf(module blueprint.ModuleOrProxy, property string, fmt string, args ...interface{}) { e.EarlyModuleContext.OtherModulePropertyErrorf(module, property, fmt, args...) } diff --git a/android/makevars.go b/android/makevars.go index 7017e7db0..92b35c37c 100644 --- a/android/makevars.go +++ b/android/makevars.go @@ -72,15 +72,15 @@ type BaseMakeVarsContext interface { type MakeVarsContext interface { BaseMakeVarsContext - ModuleName(module blueprint.Module) string - ModuleDir(module blueprint.Module) string - ModuleSubDir(module blueprint.Module) string - ModuleType(module blueprint.Module) string - otherModuleProvider(module blueprint.Module, key blueprint.AnyProviderKey) (any, bool) - BlueprintFile(module blueprint.Module) string - - ModuleErrorf(module blueprint.Module, format string, args ...interface{}) - OtherModulePropertyErrorf(module Module, property, format string, args ...interface{}) + ModuleName(module blueprint.ModuleOrProxy) string + ModuleDir(module blueprint.ModuleOrProxy) string + ModuleSubDir(module blueprint.ModuleOrProxy) string + ModuleType(module blueprint.ModuleOrProxy) string + otherModuleProvider(module blueprint.ModuleOrProxy, key blueprint.AnyProviderKey) (any, bool) + BlueprintFile(module blueprint.ModuleOrProxy) string + + ModuleErrorf(module blueprint.ModuleOrProxy, format string, args ...interface{}) + OtherModulePropertyErrorf(module blueprint.ModuleOrProxy, property, format string, args ...interface{}) Errorf(format string, args ...interface{}) VisitAllModules(visit func(Module)) diff --git a/android/module.go b/android/module.go index 96430d4fa..88453008c 100644 --- a/android/module.go +++ b/android/module.go @@ -2828,7 +2828,7 @@ type ConfigContext interface { type ConfigurableEvaluatorContext interface { OtherModuleProviderContext Config() Config - OtherModulePropertyErrorf(module Module, property string, fmt string, args ...interface{}) + OtherModulePropertyErrorf(module blueprint.ModuleOrProxy, property string, fmt string, args ...interface{}) HasMutatorFinished(mutatorName string) bool } @@ -3126,7 +3126,7 @@ type SourceFileProducer interface { // OutputFilesForModule returns the output file paths with the given tag. On error, including if the // module produced zero paths, it reports errors to the ctx and returns nil. -func OutputFilesForModule(ctx PathContext, module Module, tag string) Paths { +func OutputFilesForModule(ctx PathContext, module blueprint.ModuleOrProxy, tag string) Paths { paths, err := outputFilesForModule(ctx, module, tag) if err != nil { reportPathError(ctx, err) @@ -3139,7 +3139,7 @@ func OutputFilesForModule(ctx PathContext, module Module, tag string) Paths { // module produced zero or multiple paths, it reports errors to the ctx and returns nil. // TODO(b/397766191): Change the signature to take ModuleProxy // Please only access the module's internal data through providers. -func OutputFileForModule(ctx PathContext, module Module, tag string) Path { +func OutputFileForModule(ctx PathContext, module blueprint.ModuleOrProxy, tag string) Path { paths, err := outputFilesForModule(ctx, module, tag) if err != nil { reportPathError(ctx, err) @@ -3148,7 +3148,7 @@ func OutputFileForModule(ctx PathContext, module Module, tag string) Path { if len(paths) == 0 { type addMissingDependenciesIntf interface { AddMissingDependencies([]string) - OtherModuleName(blueprint.Module) string + OtherModuleName(blueprint.ModuleOrProxy) string } if mctx, ok := ctx.(addMissingDependenciesIntf); ok && ctx.Config().AllowMissingDependencies() { mctx.AddMissingDependencies([]string{mctx.OtherModuleName(module)}) @@ -3180,7 +3180,7 @@ type OutputFilesProviderModuleContext interface { // TODO(b/397766191): Change the signature to take ModuleProxy // Please only access the module's internal data through providers. -func outputFilesForModule(ctx PathContext, module Module, tag string) (Paths, error) { +func outputFilesForModule(ctx PathContext, module blueprint.ModuleOrProxy, tag string) (Paths, error) { outputFilesFromProvider, err := outputFilesForModuleFromProvider(ctx, module, tag) if outputFilesFromProvider != nil || err != OutputFilesProviderNotSet { return outputFilesFromProvider, err @@ -3210,7 +3210,7 @@ func outputFilesForModule(ctx PathContext, module Module, tag string) (Paths, er // from outputFiles property of module base, to avoid both setting and // reading OutputFilesProvider before GenerateBuildActions is finished. // If a module doesn't have the OutputFilesProvider, nil is returned. -func outputFilesForModuleFromProvider(ctx PathContext, module Module, tag string) (Paths, error) { +func outputFilesForModuleFromProvider(ctx PathContext, module blueprint.ModuleOrProxy, tag string) (Paths, error) { var outputFiles OutputFilesInfo if mctx, isMctx := ctx.(OutputFilesProviderModuleContext); isMctx { diff --git a/android/module_proxy.go b/android/module_proxy.go index 5b201f859..b1063ec75 100644 --- a/android/module_proxy.go +++ b/android/module_proxy.go @@ -2,228 +2,8 @@ package android import ( "github.com/google/blueprint" - "github.com/google/blueprint/proptools" ) type ModuleProxy struct { blueprint.ModuleProxy } - -var _ Module = ModuleProxy{} - -func (m ModuleProxy) GenerateAndroidBuildActions(context ModuleContext) { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) CleanupAfterBuildActions() { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) ComponentDepsMutator(ctx BottomUpMutatorContext) { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) DepsMutator(context BottomUpMutatorContext) { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) base() *ModuleBase { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) Disable() { - - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) Enabled(ctx ConfigurableEvaluatorContext) bool { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) Target() Target { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) MultiTargets() []Target { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) ImageVariation() blueprint.Variation { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) Owner() string { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) InstallInData() bool { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) InstallInTestcases() bool { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) InstallInSanitizerDir() bool { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) InstallInRamdisk() bool { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) InstallInVendorRamdisk() bool { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) InstallInDebugRamdisk() bool { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) InstallInRecovery() bool { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) InstallInRoot() bool { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) InstallInOdm() bool { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) InstallInProduct() bool { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) InstallInVendor() bool { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) InstallInSystemExt() bool { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) InstallInSystemDlkm() bool { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) InstallInVendorDlkm() bool { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) InstallInOdmDlkm() bool { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) InstallForceOS() (*OsType, *ArchType) { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) PartitionTag(d DeviceConfig) string { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) HideFromMake() { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) IsHideFromMake() bool { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) SkipInstall() { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) IsSkipInstall() bool { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) MakeUninstallable() { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) ReplacedByPrebuilt() { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) IsReplacedByPrebuilt() bool { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) ExportedToMake() bool { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) EffectiveLicenseFiles() Paths { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) AddProperties(props ...interface{}) { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) GetProperties() []interface{} { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) BuildParamsForTests() []BuildParams { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) VariablesForTests() map[string]string { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) visibilityProperties() []visibilityProperty { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) HostRequiredModuleNames() []string { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) TargetRequiredModuleNames() []string { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) VintfFragmentModuleNames(ctx ConfigurableEvaluatorContext) []string { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) ConfigurableEvaluator(ctx ConfigurableEvaluatorContext) proptools.ConfigurableEvaluator { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) DecodeMultilib(ctx ConfigContext) (string, string) { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) Overrides() []string { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) VintfFragments(ctx ConfigurableEvaluatorContext) []string { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) UseGenericConfig() bool { - panic("method is not implemented on ModuleProxy") -} - -func (m ModuleProxy) NoFullInstall() bool { - panic("method is not implemented on ModuleProxy") -} diff --git a/android/module_test.go b/android/module_test.go index 41a27e24b..c5d7c191f 100644 --- a/android/module_test.go +++ b/android/module_test.go @@ -990,7 +990,7 @@ type pathContextAddMissingDependenciesWrapper struct { func (p *pathContextAddMissingDependenciesWrapper) AddMissingDependencies(deps []string) { p.missingDeps = append(p.missingDeps, deps...) } -func (p *pathContextAddMissingDependenciesWrapper) OtherModuleName(module blueprint.Module) string { +func (p *pathContextAddMissingDependenciesWrapper) OtherModuleName(module blueprint.ModuleOrProxy) string { return module.Name() } diff --git a/android/paths.go b/android/paths.go index 2d740b1e7..ec5d0521e 100644 --- a/android/paths.go +++ b/android/paths.go @@ -60,7 +60,7 @@ type EarlyModulePathContext interface { ModuleDir() string ModuleErrorf(fmt string, args ...interface{}) - OtherModulePropertyErrorf(module Module, property, fmt string, args ...interface{}) + OtherModulePropertyErrorf(module blueprint.ModuleOrProxy, property, fmt string, args ...interface{}) } var _ EarlyModulePathContext = ModuleContext(nil) @@ -93,7 +93,7 @@ type ModuleWithDepsPathContext interface { VisitDirectDeps(visit func(Module)) VisitDirectDepsProxy(visit func(ModuleProxy)) VisitDirectDepsProxyWithTag(tag blueprint.DependencyTag, visit func(ModuleProxy)) - OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag + OtherModuleDependencyTag(m blueprint.ModuleOrProxy) blueprint.DependencyTag HasMutatorFinished(mutatorName string) bool } @@ -235,12 +235,14 @@ func ReportPathErrorf(ctx PathContext, format string, args ...interface{}) { } } -// TODO(b/397766191): Change the signature to take ModuleProxy -// Please only access the module's internal data through providers. -func pathContextName(ctx PathContext, module blueprint.Module) string { - if x, ok := ctx.(interface{ ModuleName(blueprint.Module) string }); ok { +func pathContextName(ctx PathContext, module blueprint.ModuleOrProxy) string { + if x, ok := ctx.(interface { + ModuleName(blueprint.ModuleOrProxy) string + }); ok { return x.ModuleName(module) - } else if x, ok := ctx.(interface{ OtherModuleName(blueprint.Module) string }); ok { + } else if x, ok := ctx.(interface { + OtherModuleName(blueprint.ModuleOrProxy) string + }); ok { return x.OtherModuleName(module) } return "unknown" diff --git a/android/prebuilt.go b/android/prebuilt.go index 8ce0842fa..18517c306 100644 --- a/android/prebuilt.go +++ b/android/prebuilt.go @@ -396,7 +396,7 @@ func GetEmbeddedPrebuilt(module Module) *Prebuilt { // run - any dependency that is registered before that will already reference // the right module. This function is only safe to call after all TransitionMutators // have run, e.g. in GenerateAndroidBuildActions. -func PrebuiltGetPreferred(ctx BaseModuleContext, module Module) Module { +func PrebuiltGetPreferred(ctx BaseModuleContext, module ModuleProxy) ModuleProxy { if !OtherModulePointerProviderOrDefault(ctx, module, CommonModuleInfoProvider).ReplacedByPrebuilt { return module } @@ -406,15 +406,15 @@ func PrebuiltGetPreferred(ctx BaseModuleContext, module Module) Module { } sourceModDepFound := false - var prebuiltMod Module + var prebuiltMod ModuleProxy ctx.WalkDepsProxy(func(child, parent ModuleProxy) bool { - if prebuiltMod != nil { + if !prebuiltMod.IsNil() { return false } if EqualModules(parent, ctx.Module()) { // First level: Only recurse if the module is found as a direct dependency. - sourceModDepFound = child == module + sourceModDepFound = EqualModules(child, module) return sourceModDepFound } // Second level: Follow PrebuiltDepTag to the prebuilt. @@ -424,7 +424,7 @@ func PrebuiltGetPreferred(ctx BaseModuleContext, module Module) Module { return false }) - if prebuiltMod == nil { + if prebuiltMod.IsNil() { if !sourceModDepFound { panic(fmt.Errorf("Failed to find source module as a direct dependency: %s", module)) } else { diff --git a/android/provider.go b/android/provider.go index 875929137..412465d6d 100644 --- a/android/provider.go +++ b/android/provider.go @@ -7,7 +7,7 @@ import ( // OtherModuleProviderContext is a helper interface that is a subset of ModuleContext or BottomUpMutatorContext // for use in OtherModuleProvider. type OtherModuleProviderContext interface { - otherModuleProvider(m blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) + otherModuleProvider(m blueprint.ModuleOrProxy, provider blueprint.AnyProviderKey) (any, bool) } var _ OtherModuleProviderContext = BaseModuleContext(nil) @@ -27,7 +27,7 @@ type ConfigAndOtherModuleProviderContext interface { // and the boolean is false. The value returned may be a deep copy of the value originally passed to SetProvider. // // OtherModuleProviderContext is a helper interface that accepts ModuleContext or BottomUpMutatorContext. -func OtherModuleProvider[K any](ctx OtherModuleProviderContext, module blueprint.Module, provider blueprint.ProviderKey[K]) (K, bool) { +func OtherModuleProvider[K any](ctx OtherModuleProviderContext, module blueprint.ModuleOrProxy, provider blueprint.ProviderKey[K]) (K, bool) { value, ok := ctx.otherModuleProvider(module, provider) if !ok { var k K @@ -36,12 +36,12 @@ func OtherModuleProvider[K any](ctx OtherModuleProviderContext, module blueprint return value.(K), ok } -func OtherModuleProviderOrDefault[K any](ctx OtherModuleProviderContext, module blueprint.Module, provider blueprint.ProviderKey[K]) K { +func OtherModuleProviderOrDefault[K any](ctx OtherModuleProviderContext, module blueprint.ModuleOrProxy, provider blueprint.ProviderKey[K]) K { value, _ := OtherModuleProvider(ctx, module, provider) return value } -func OtherModulePointerProviderOrDefault[K *T, T any](ctx OtherModuleProviderContext, module blueprint.Module, provider blueprint.ProviderKey[K]) K { +func OtherModulePointerProviderOrDefault[K *T, T any](ctx OtherModuleProviderContext, module blueprint.ModuleOrProxy, provider blueprint.ProviderKey[K]) K { if value, ok := OtherModuleProvider(ctx, module, provider); ok { return value } @@ -97,13 +97,13 @@ var _ OtherModuleProviderContext = (*otherModuleProviderAdaptor)(nil) // An OtherModuleProviderFunc can be passed to NewOtherModuleProviderAdaptor to create an OtherModuleProviderContext // for use in tests. -type OtherModuleProviderFunc func(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) +type OtherModuleProviderFunc func(module blueprint.ModuleOrProxy, provider blueprint.AnyProviderKey) (any, bool) type otherModuleProviderAdaptor struct { otherModuleProviderFunc OtherModuleProviderFunc } -func (p *otherModuleProviderAdaptor) otherModuleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) { +func (p *otherModuleProviderAdaptor) otherModuleProvider(module blueprint.ModuleOrProxy, provider blueprint.AnyProviderKey) (any, bool) { return p.otherModuleProviderFunc(module, provider) } diff --git a/android/singleton.go b/android/singleton.go index 86e0e8e03..a61202d5b 100644 --- a/android/singleton.go +++ b/android/singleton.go @@ -30,19 +30,19 @@ type SingletonContext interface { Config() Config DeviceConfig() DeviceConfig - ModuleName(module blueprint.Module) string - ModuleDir(module blueprint.Module) string - ModuleSubDir(module blueprint.Module) string - ModuleType(module blueprint.Module) string - BlueprintFile(module blueprint.Module) string + ModuleName(module blueprint.ModuleOrProxy) string + ModuleDir(module blueprint.ModuleOrProxy) string + ModuleSubDir(module blueprint.ModuleOrProxy) string + ModuleType(module blueprint.ModuleOrProxy) string + BlueprintFile(module blueprint.ModuleOrProxy) string // ModuleVariantsFromName returns the list of module variants named `name` in the same namespace as `referer` enforcing visibility rules. // Allows generating build actions for `referer` based on the metadata for `name` deferred until the singleton context. ModuleVariantsFromName(referer ModuleProxy, name string) []ModuleProxy - otherModuleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) + otherModuleProvider(module blueprint.ModuleOrProxy, provider blueprint.AnyProviderKey) (any, bool) - ModuleErrorf(module blueprint.Module, format string, args ...interface{}) + ModuleErrorf(module blueprint.ModuleOrProxy, format string, args ...interface{}) Errorf(format string, args ...interface{}) Failed() bool @@ -83,13 +83,13 @@ type SingletonContext interface { VisitAllModuleVariants(module Module, visit func(Module)) - VisitAllModuleVariantProxies(module Module, visit func(proxy ModuleProxy)) + VisitAllModuleVariantProxies(module ModuleProxy, visit func(proxy ModuleProxy)) PrimaryModule(module Module) Module PrimaryModuleProxy(module ModuleProxy) ModuleProxy - IsFinalModule(module Module) bool + IsFinalModule(module blueprint.ModuleOrProxy) bool AddNinjaFileDeps(deps ...string) @@ -100,7 +100,7 @@ type SingletonContext interface { GlobWithDeps(pattern string, excludes []string) ([]string, error) // OtherModulePropertyErrorf reports an error on the line number of the given property of the given module - OtherModulePropertyErrorf(module Module, property string, format string, args ...interface{}) + OtherModulePropertyErrorf(module blueprint.ModuleOrProxy, property string, format string, args ...interface{}) // HasMutatorFinished returns true if the given mutator has finished running. // It will panic if given an invalid mutator name. @@ -279,23 +279,23 @@ func predAdaptor(pred func(Module) bool) func(blueprint.Module) bool { } } -func (s *singletonContextAdaptor) ModuleName(module blueprint.Module) string { +func (s *singletonContextAdaptor) ModuleName(module blueprint.ModuleOrProxy) string { return s.SingletonContext.ModuleName(module) } -func (s *singletonContextAdaptor) ModuleDir(module blueprint.Module) string { +func (s *singletonContextAdaptor) ModuleDir(module blueprint.ModuleOrProxy) string { return s.SingletonContext.ModuleDir(module) } -func (s *singletonContextAdaptor) ModuleSubDir(module blueprint.Module) string { +func (s *singletonContextAdaptor) ModuleSubDir(module blueprint.ModuleOrProxy) string { return s.SingletonContext.ModuleSubDir(module) } -func (s *singletonContextAdaptor) ModuleType(module blueprint.Module) string { +func (s *singletonContextAdaptor) ModuleType(module blueprint.ModuleOrProxy) string { return s.SingletonContext.ModuleType(module) } -func (s *singletonContextAdaptor) BlueprintFile(module blueprint.Module) string { +func (s *singletonContextAdaptor) BlueprintFile(module blueprint.ModuleOrProxy) string { return s.SingletonContext.BlueprintFile(module) } @@ -335,8 +335,8 @@ func (s *singletonContextAdaptor) VisitAllModuleVariants(module Module, visit fu s.SingletonContext.VisitAllModuleVariants(module, visitAdaptor(visit)) } -func (s *singletonContextAdaptor) VisitAllModuleVariantProxies(module Module, visit func(proxy ModuleProxy)) { - s.SingletonContext.VisitAllModuleVariantProxies(module, visitProxyAdaptor(visit)) +func (s *singletonContextAdaptor) VisitAllModuleVariantProxies(module ModuleProxy, visit func(proxy ModuleProxy)) { + s.SingletonContext.VisitAllModuleVariantProxies(module.ModuleProxy, visitProxyAdaptor(visit)) } func (s *singletonContextAdaptor) PrimaryModule(module Module) Module { @@ -347,7 +347,7 @@ func (s *singletonContextAdaptor) PrimaryModuleProxy(module ModuleProxy) ModuleP return ModuleProxy{s.SingletonContext.PrimaryModuleProxy(module.ModuleProxy)} } -func (s *singletonContextAdaptor) IsFinalModule(module Module) bool { +func (s *singletonContextAdaptor) IsFinalModule(module blueprint.ModuleOrProxy) bool { return s.SingletonContext.IsFinalModule(module) } @@ -376,11 +376,11 @@ func (s *singletonContextAdaptor) ModuleVariantsFromName(referer ModuleProxy, na return result } -func (s *singletonContextAdaptor) otherModuleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) { +func (s *singletonContextAdaptor) otherModuleProvider(module blueprint.ModuleOrProxy, provider blueprint.AnyProviderKey) (any, bool) { return s.SingletonContext.ModuleProvider(module, provider) } -func (s *singletonContextAdaptor) OtherModulePropertyErrorf(module Module, property string, format string, args ...interface{}) { +func (s *singletonContextAdaptor) OtherModulePropertyErrorf(module blueprint.ModuleOrProxy, property string, format string, args ...interface{}) { s.blueprintSingletonContext().OtherModulePropertyErrorf(module, property, format, args...) } diff --git a/android/symbols.go b/android/symbols.go index f6cabcf19..20022da4c 100644 --- a/android/symbols.go +++ b/android/symbols.go @@ -64,7 +64,7 @@ type symbolsContext interface { // Defines the build rules to generate the symbols.zip file and the merged elf mapping textproto // file. Modules in depModules that provide [SymbolInfosProvider] and are exported to make // will be listed in the symbols.zip and the merged proto file. -func BuildSymbolsZip(ctx symbolsContext, depModules []Module, iden string, symbolsZipFile, mergedMappingProtoFile WritablePath) { +func BuildSymbolsZip(ctx symbolsContext, depModules []ModuleProxy, iden string, symbolsZipFile, mergedMappingProtoFile WritablePath) { var allSymbolicOutputPaths, allElfMappingProtoPaths Paths for _, mod := range depModules { if commonInfo, _ := OtherModuleProvider(ctx, mod, CommonModuleInfoProvider); commonInfo.SkipAndroidMkProcessing { diff --git a/android/test_suites.go b/android/test_suites.go index a250af65d..81ece7bdf 100644 --- a/android/test_suites.go +++ b/android/test_suites.go @@ -85,9 +85,9 @@ type testSuiteInstallsInfo struct { var testSuiteInstallsInfoProvider = blueprint.NewProvider[testSuiteInstallsInfo]() -type testModulesInstallsMap map[Module]InstallPaths +type testModulesInstallsMap map[ModuleProxy]InstallPaths -func (t testModulesInstallsMap) testModules() []Module { +func (t testModulesInstallsMap) testModules() []ModuleProxy { return slices.Collect(maps.Keys(t)) } diff --git a/android/testing.go b/android/testing.go index d2949ec8e..7490025ca 100644 --- a/android/testing.go +++ b/android/testing.go @@ -238,7 +238,7 @@ func (ctx *TestContext) HardCodedPreArchMutators(f RegisterMutatorFunc) { ctx.PreArchMutators(f) } -func (ctx *TestContext) otherModuleProvider(m blueprint.Module, p blueprint.AnyProviderKey) (any, bool) { +func (ctx *TestContext) otherModuleProvider(m blueprint.ModuleOrProxy, p blueprint.AnyProviderKey) (any, bool) { return ctx.Context.ModuleProvider(m, p) } @@ -259,12 +259,12 @@ func (ctx *TestContext) FinalDepsMutators(f RegisterMutatorFunc) { } func (ctx *TestContext) OtherModuleProviderAdaptor() OtherModuleProviderContext { - return NewOtherModuleProviderAdaptor(func(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) { + return NewOtherModuleProviderAdaptor(func(module blueprint.ModuleOrProxy, provider blueprint.AnyProviderKey) (any, bool) { return ctx.otherModuleProvider(module, provider) }) } -func (ctx *TestContext) OtherModulePropertyErrorf(module Module, property string, fmt_ string, args ...interface{}) { +func (ctx *TestContext) OtherModulePropertyErrorf(module blueprint.ModuleOrProxy, property string, fmt_ string, args ...interface{}) { panic(fmt.Sprintf(fmt_, args...)) } @@ -1378,7 +1378,7 @@ type panickingConfigAndErrorContext struct { ctx *TestContext } -func (ctx *panickingConfigAndErrorContext) OtherModulePropertyErrorf(module Module, property, fmt string, args ...interface{}) { +func (ctx *panickingConfigAndErrorContext) OtherModulePropertyErrorf(module blueprint.ModuleOrProxy, property, fmt string, args ...interface{}) { panic(ctx.ctx.PropertyErrorf(module, property, fmt, args...).Error()) } @@ -1390,7 +1390,7 @@ func (ctx *panickingConfigAndErrorContext) HasMutatorFinished(mutatorName string return ctx.ctx.HasMutatorFinished(mutatorName) } -func (ctx *panickingConfigAndErrorContext) otherModuleProvider(m blueprint.Module, p blueprint.AnyProviderKey) (any, bool) { +func (ctx *panickingConfigAndErrorContext) otherModuleProvider(m blueprint.ModuleOrProxy, p blueprint.AnyProviderKey) (any, bool) { return ctx.ctx.otherModuleProvider(m, p) } diff --git a/apex/apex.go b/apex/apex.go index ce064b70d..271dee0bb 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -2903,7 +2903,7 @@ 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 + var depPath []android.ModuleProxy ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool { if depPath != nil { return false @@ -2919,7 +2919,7 @@ func (a *apexBundle) verifyNativeImplementationLibs(ctx android.ModuleContext) { if checkTransitiveTag(tag) { if android.OutputFileForModule(ctx, child, "") == lib { - depPath = ctx.GetWalkPath() + depPath = ctx.GetProxyWalkPath() } return true } diff --git a/cc/cc.go b/cc/cc.go index ea9d76598..dbec4fd9d 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -3724,7 +3724,8 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { commonInfo := android.OtherModulePointerProviderOrDefault(ctx, dep, android.CommonModuleInfoProvider) if commonInfo.Target.Os != ctx.Os() { - ctx.ModuleErrorf("OS mismatch between %q (%s) and %q (%s)", ctx.ModuleName(), ctx.Os().Name, depName, dep.Target().Os.Name) + ctx.ModuleErrorf("OS mismatch between %q (%s) and %q (%s)", ctx.ModuleName(), ctx.Os().Name, depName, + commonInfo.Target.Os.Name) return } if commonInfo.Target.Arch.ArchType != ctx.Arch().ArchType { @@ -4044,11 +4045,11 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { return depPaths } -func ShouldUseStubForApex(ctx android.ModuleContext, parent android.Module, dep android.ModuleProxy) bool { +func ShouldUseStubForApex(ctx android.ModuleContext, parent blueprint.ModuleOrProxy, dep android.ModuleProxy) bool { inVendorOrProduct := false bootstrap := false if android.EqualModules(ctx.Module(), parent) { - if linkable, ok := parent.(LinkableInterface); !ok { + if linkable, ok := ctx.Module().(LinkableInterface); !ok { ctx.ModuleErrorf("Not a Linkable module: %q", ctx.ModuleName()) } else { inVendorOrProduct = linkable.InVendorOrProduct() diff --git a/cc/library_sdk_member.go b/cc/library_sdk_member.go index 1db60e5df..8c0b730ac 100644 --- a/cc/library_sdk_member.go +++ b/cc/library_sdk_member.go @@ -577,7 +577,7 @@ func (p *nativeLibInfoProperties) PopulateFromVariant(ctx android.SdkMemberConte } } -func getRequiredMemberOutputFile(ctx android.SdkMemberContext, module android.Module) android.Path { +func getRequiredMemberOutputFile(ctx android.SdkMemberContext, module blueprint.ModuleOrProxy) android.Path { var path android.Path if info, ok := android.OtherModuleProvider(ctx.SdkModuleContext(), module, LinkableInfoProvider); ok && info.OutputFile.Valid() { path = info.OutputFile.Path() diff --git a/ci_tests/ci_test_package_zip.go b/ci_tests/ci_test_package_zip.go index 7ec1ffb81..f96397c65 100644 --- a/ci_tests/ci_test_package_zip.go +++ b/ci_tests/ci_test_package_zip.go @@ -169,10 +169,10 @@ func (p *testPackageZip) GenerateAndroidBuildActions(ctx android.ModuleContext) ctx.SetOutputFiles(android.Paths{p.output}, "") } -func getAllTestModules(ctx android.ModuleContext) []android.Module { - var ret []android.Module - ctx.WalkDeps(func(child, parent android.Module) bool { - if !child.Enabled(ctx) { +func getAllTestModules(ctx android.ModuleContext) []android.ModuleProxy { + var ret []android.ModuleProxy + ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool { + if info, ok := android.OtherModuleProvider(ctx, child, android.CommonModuleInfoProvider); !ok || !info.Enabled { return false } if android.EqualModules(parent, ctx.Module()) && ctx.OtherModuleDependencyTag(child) == testPackageZipDepTag { @@ -188,7 +188,7 @@ func getAllTestModules(ctx android.ModuleContext) []android.Module { } }) ret = android.FirstUniqueInPlace(ret) - slices.SortFunc(ret, func(a, b android.Module) int { + slices.SortFunc(ret, func(a, b android.ModuleProxy) int { return cmp.Compare(a.String(), b.String()) }) return ret @@ -224,7 +224,7 @@ func createOutput(ctx android.ModuleContext, pctx android.PackageContext) androi return output } -func createSymbolsZip(ctx android.ModuleContext, allModules []android.Module) { +func createSymbolsZip(ctx android.ModuleContext, allModules []android.ModuleProxy) { symbolsZipFile := android.PathForModuleOut(ctx, "symbols.zip") symbolsMappingFile := android.PathForModuleOut(ctx, "symbols-mapping.textproto") android.BuildSymbolsZip(ctx, allModules, ctx.ModuleName(), symbolsZipFile, symbolsMappingFile) @@ -233,7 +233,7 @@ func createSymbolsZip(ctx android.ModuleContext, allModules []android.Module) { ctx.SetOutputFiles(android.Paths{symbolsMappingFile}, ".elf_mapping") } -func extendBuilderCommand(ctx android.ModuleContext, m android.Module, builder *android.RuleBuilder, stagingDir android.ModuleOutPath, productOut, arch, secondArch string) { +func extendBuilderCommand(ctx android.ModuleContext, m blueprint.ModuleOrProxy, builder *android.RuleBuilder, stagingDir android.ModuleOutPath, productOut, arch, secondArch string) { info, ok := android.OtherModuleProvider(ctx, m, android.ModuleInfoJSONProvider) if !ok { ctx.OtherModuleErrorf(m, "doesn't set ModuleInfoJSON provider") diff --git a/filesystem/android_device.go b/filesystem/android_device.go index 0da65bdf7..d14ba91f8 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -347,7 +347,7 @@ type installedOwnerInfo struct { // 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 { +func (a *androidDevice) allInstalledModules(ctx android.ModuleContext) []android.ModuleProxy { fsInfoMap := a.getFsInfos(ctx) allOwners := make(map[string][]installedOwnerInfo) @@ -361,7 +361,7 @@ func (a *androidDevice) allInstalledModules(ctx android.ModuleContext) []android } } - ret := []android.Module{} + ret := []android.ModuleProxy{} ctx.WalkDepsProxy(func(mod, _ android.ModuleProxy) bool { commonInfo, ok := android.OtherModuleProvider(ctx, mod, android.CommonModuleInfoProvider) if !(ok && commonInfo.ExportedToMake) { @@ -381,7 +381,7 @@ func (a *androidDevice) allInstalledModules(ctx android.ModuleContext) []android ret = android.FirstUniqueInPlace(ret) // Sort the modules by their names and variants - slices.SortFunc(ret, func(a, b android.Module) int { + slices.SortFunc(ret, func(a, b android.ModuleProxy) int { return cmp.Compare(a.String(), b.String()) }) return ret @@ -392,7 +392,7 @@ type symbolicOutputInfo struct { symbolicOutputPath android.InstallPath } -func (a *androidDevice) buildSymbolsZip(ctx android.ModuleContext, allInstalledModules []android.Module) { +func (a *androidDevice) buildSymbolsZip(ctx android.ModuleContext, allInstalledModules []android.ModuleProxy) { a.symbolsZipFile = android.PathForModuleOut(ctx, "symbols.zip") a.symbolsMappingFile = android.PathForModuleOut(ctx, "symbols-mapping.textproto") android.BuildSymbolsZip(ctx, allInstalledModules, ctx.ModuleName(), a.symbolsZipFile, a.symbolsMappingFile) @@ -462,7 +462,7 @@ func (a *androidDevice) MakeVars(_ android.MakeVarsModuleContext) []android.Modu return nil } -func (a *androidDevice) buildProguardZips(ctx android.ModuleContext, allInstalledModules []android.Module) { +func (a *androidDevice) buildProguardZips(ctx android.ModuleContext, allInstalledModules []android.ModuleProxy) { dictZip := android.PathForModuleOut(ctx, "proguard-dict.zip") dictZipBuilder := android.NewRuleBuilder(pctx, ctx) dictZipCmd := dictZipBuilder.Command().BuiltTool("soong_zip").Flag("-d").FlagWithOutput("-o ", dictZip) @@ -523,7 +523,7 @@ type targetFilesystemZipCopy struct { destSubdir string } -func (a *androidDevice) buildTargetFilesZip(ctx android.ModuleContext, allInstalledModules []android.Module) { +func (a *androidDevice) buildTargetFilesZip(ctx android.ModuleContext, allInstalledModules []android.ModuleProxy) { targetFilesDir := android.PathForModuleOut(ctx, "target_files_dir") targetFilesZip := android.PathForModuleOut(ctx, "target_files.zip") @@ -695,7 +695,7 @@ func (a *androidDevice) copyImagesToTargetZip(ctx android.ModuleContext, builder } } -func (a *androidDevice) copyMetadataToTargetZip(ctx android.ModuleContext, builder *android.RuleBuilder, targetFilesDir android.WritablePath, allInstalledModules []android.Module) { +func (a *androidDevice) copyMetadataToTargetZip(ctx android.ModuleContext, builder *android.RuleBuilder, targetFilesDir android.WritablePath, allInstalledModules []android.ModuleProxy) { // Create a META/ subdirectory builder.Command().Textf("mkdir -p %s/META", targetFilesDir.String()) if proptools.Bool(a.deviceProps.Ab_ota_updater) { @@ -1154,7 +1154,7 @@ func (a *androidDevice) extractKernelVersionAndConfigs(ctx android.ModuleContext return extractedVersionFile, extractedConfigsFile } -func (a *androidDevice) buildApkCertsInfo(ctx android.ModuleContext, allInstalledModules []android.Module) android.Path { +func (a *androidDevice) buildApkCertsInfo(ctx android.ModuleContext, allInstalledModules []android.ModuleProxy) android.Path { // TODO (spandandas): Add compressed formatLine := func(cert java.Certificate, name, partition string) string { pem := cert.AndroidMkString() diff --git a/fuzz/fuzz_common.go b/fuzz/fuzz_common.go index f08378d67..6539f1dec 100644 --- a/fuzz/fuzz_common.go +++ b/fuzz/fuzz_common.go @@ -568,7 +568,7 @@ func IsValid(ctx android.ConfigurableEvaluatorContext, fuzzModule FuzzModule) bo // TODO(b/397766191): Change the signature to take ModuleProxy // Please only access the module's internal data through providers. -func (s *FuzzPackager) PackageArtifacts(ctx android.SingletonContext, module android.Module, fuzzModule *FuzzPackagedModuleInfo, archDir android.OutputPath, builder *android.RuleBuilder) []FileToZip { +func (s *FuzzPackager) PackageArtifacts(ctx android.SingletonContext, module blueprint.ModuleOrProxy, fuzzModule *FuzzPackagedModuleInfo, archDir android.OutputPath, builder *android.RuleBuilder) []FileToZip { // Package the corpora into a zipfile. var files []FileToZip if fuzzModule.Corpus != nil { @@ -609,7 +609,7 @@ func (s *FuzzPackager) PackageArtifacts(ctx android.SingletonContext, module and // TODO(b/397766191): Change the signature to take ModuleProxy // Please only access the module's internal data through providers. -func (s *FuzzPackager) BuildZipFile(ctx android.SingletonContext, module android.Module, fuzzModule *FuzzPackagedModuleInfo, files []FileToZip, builder *android.RuleBuilder, archDir android.OutputPath, archString string, hostOrTargetString string, archOs ArchOs, archDirs map[ArchOs][]FileToZip) ([]FileToZip, bool) { +func (s *FuzzPackager) BuildZipFile(ctx android.SingletonContext, module blueprint.ModuleOrProxy, fuzzModule *FuzzPackagedModuleInfo, files []FileToZip, builder *android.RuleBuilder, archDir android.OutputPath, archString string, hostOrTargetString string, archOs ArchOs, archDirs map[ArchOs][]FileToZip) ([]FileToZip, bool) { fuzzZip := archDir.Join(ctx, module.Name()+".zip") command := builder.Command().BuiltTool("soong_zip"). diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go index 8ee37ab9f..46f6b18a0 100644 --- a/java/bootclasspath_fragment.go +++ b/java/bootclasspath_fragment.go @@ -398,7 +398,7 @@ type BootclasspathFragmentApexContentInfo struct { // DexBootJarPathForContentModule returns the path to the dex boot jar for specified module. // // The dex boot jar is one which has had hidden API encoding performed on it. -func (i BootclasspathFragmentApexContentInfo) DexBootJarPathForContentModule(module android.Module) (android.Path, error) { +func (i BootclasspathFragmentApexContentInfo) DexBootJarPathForContentModule(module blueprint.ModuleOrProxy) (android.Path, error) { // A bootclasspath_fragment cannot use a prebuilt library so Name() will return the base name // without a prebuilt_ prefix so is safe to use as the key for the contentModuleDexJarPaths. name := module.Name() diff --git a/java/java.go b/java/java.go index 2fb8b0d0a..f0ecc435f 100644 --- a/java/java.go +++ b/java/java.go @@ -103,7 +103,7 @@ var ( PropertyName: "java_header_libs", SupportsSdk: true, }, - func(_ android.SdkMemberContext, j android.Module, javaInfo *JavaInfo) android.Path { + func(_ android.SdkMemberContext, j android.ModuleProxy, javaInfo *JavaInfo) android.Path { headerJars := javaInfo.HeaderJars if len(headerJars) != 1 { panic(fmt.Errorf("there must be only one header jar from %q", j.Name())) @@ -116,7 +116,7 @@ var ( } // Export implementation classes jar as part of the sdk. - exportImplementationClassesJar = func(_ android.SdkMemberContext, j android.Module, javaInfo *JavaInfo) android.Path { + exportImplementationClassesJar = func(_ android.SdkMemberContext, j android.ModuleProxy, javaInfo *JavaInfo) android.Path { implementationJars := javaInfo.ImplementationAndResourcesJars if len(implementationJars) != 1 { panic(fmt.Errorf("there must be only one implementation jar from %q", j.Name())) @@ -160,7 +160,7 @@ var ( PropertyName: "java_boot_libs", SupportsSdk: true, }, - func(ctx android.SdkMemberContext, j android.Module, javaInfo *JavaInfo) android.Path { + func(ctx android.SdkMemberContext, j android.ModuleProxy, javaInfo *JavaInfo) android.Path { if snapshotRequiresImplementationJar(ctx) { return exportImplementationClassesJar(ctx, j, javaInfo) } @@ -202,7 +202,7 @@ var ( // This was only added in Tiramisu. SupportedBuildReleaseSpecification: "Tiramisu+", }, - func(ctx android.SdkMemberContext, _ android.Module, _ *JavaInfo) android.Path { + func(ctx android.SdkMemberContext, _ android.ModuleProxy, _ *JavaInfo) android.Path { // Java systemserver libs are only provided in the SDK to provide access to their dex // implementation jar for use by dexpreopting. They do not need to provide an actual // implementation jar but the java_import will need a file that exists so just copy an empty @@ -1354,7 +1354,7 @@ type librarySdkMemberType struct { // Function to retrieve the appropriate output jar (implementation or header) from // the library. - jarToExportGetter func(ctx android.SdkMemberContext, j android.Module, javaInfo *JavaInfo) android.Path + jarToExportGetter func(ctx android.SdkMemberContext, j android.ModuleProxy, javaInfo *JavaInfo) android.Path // Function to compute the snapshot relative path to which the named library's // jar should be copied. diff --git a/java/sdk_library.go b/java/sdk_library.go index 10647d027..28d141640 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -38,11 +38,11 @@ type scopeDependencyTag struct { apiScope *apiScope // Function for extracting appropriate path information from the dependency. - depInfoExtractor func(paths *scopePaths, ctx android.ModuleContext, dep android.Module) error + depInfoExtractor func(paths *scopePaths, ctx android.ModuleContext, dep android.ModuleProxy) error } // Extract tag specific information from the dependency. -func (tag scopeDependencyTag) extractDepInfo(ctx android.ModuleContext, dep android.Module, paths *scopePaths) { +func (tag scopeDependencyTag) extractDepInfo(ctx android.ModuleContext, dep android.ModuleProxy, paths *scopePaths) { err := tag.depInfoExtractor(paths, ctx, dep) if err != nil { ctx.ModuleErrorf("has an invalid {scopeDependencyTag: %s} dependency on module %s: %s", tag.name, ctx.OtherModuleName(dep), err.Error()) @@ -697,7 +697,7 @@ type scopePaths struct { latestRemovedApiPaths android.Paths } -func (paths *scopePaths) extractStubsLibraryInfoFromDependency(ctx android.ModuleContext, dep android.Module) error { +func (paths *scopePaths) extractStubsLibraryInfoFromDependency(ctx android.ModuleContext, dep android.ModuleProxy) error { if lib, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider); ok { paths.stubsHeaderPath = lib.HeaderJars paths.stubsImplPath = lib.ImplementationJars @@ -711,7 +711,7 @@ func (paths *scopePaths) extractStubsLibraryInfoFromDependency(ctx android.Modul } } -func (paths *scopePaths) extractEverythingStubsLibraryInfoFromDependency(ctx android.ModuleContext, dep android.Module) error { +func (paths *scopePaths) extractEverythingStubsLibraryInfoFromDependency(ctx android.ModuleContext, dep android.ModuleProxy) error { if lib, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider); ok { paths.stubsHeaderPath = lib.HeaderJars if !ctx.Config().ReleaseHiddenApiExportableStubs() { @@ -726,7 +726,7 @@ func (paths *scopePaths) extractEverythingStubsLibraryInfoFromDependency(ctx and } } -func (paths *scopePaths) extractExportableStubsLibraryInfoFromDependency(ctx android.ModuleContext, dep android.Module) error { +func (paths *scopePaths) extractExportableStubsLibraryInfoFromDependency(ctx android.ModuleContext, dep android.ModuleProxy) error { if lib, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider); ok { if ctx.Config().ReleaseHiddenApiExportableStubs() { paths.stubsImplPath = lib.ImplementationJars @@ -740,7 +740,7 @@ func (paths *scopePaths) extractExportableStubsLibraryInfoFromDependency(ctx and } } -func (paths *scopePaths) treatDepAsApiStubsProvider(ctx android.ModuleContext, dep android.Module, +func (paths *scopePaths) treatDepAsApiStubsProvider(ctx android.ModuleContext, dep android.ModuleProxy, action func(*DroidStubsInfo, *StubsSrcInfo) error) error { apiStubsProvider, ok := android.OtherModuleProvider(ctx, dep, DroidStubsInfoProvider) if !ok { @@ -755,7 +755,7 @@ func (paths *scopePaths) treatDepAsApiStubsProvider(ctx android.ModuleContext, d } func (paths *scopePaths) treatDepAsApiStubsSrcProvider( - ctx android.ModuleContext, dep android.Module, action func(provider *StubsSrcInfo) error) error { + ctx android.ModuleContext, dep android.ModuleProxy, action func(provider *StubsSrcInfo) error) error { if apiStubsProvider, ok := android.OtherModuleProvider(ctx, dep, StubsSrcInfoProvider); ok { err := action(&apiStubsProvider) if err != nil { @@ -797,7 +797,7 @@ func (paths *scopePaths) extractStubsSourceInfoFromApiStubsProviders(provider *S return err } -func (paths *scopePaths) extractStubsSourceInfoFromDep(ctx android.ModuleContext, dep android.Module) error { +func (paths *scopePaths) extractStubsSourceInfoFromDep(ctx android.ModuleContext, dep android.ModuleProxy) error { stubsType := Everything if ctx.Config().ReleaseHiddenApiExportableStubs() { stubsType = Exportable @@ -807,7 +807,7 @@ func (paths *scopePaths) extractStubsSourceInfoFromDep(ctx android.ModuleContext }) } -func (paths *scopePaths) extractStubsSourceAndApiInfoFromApiStubsProvider(ctx android.ModuleContext, dep android.Module) error { +func (paths *scopePaths) extractStubsSourceAndApiInfoFromApiStubsProvider(ctx android.ModuleContext, dep android.ModuleProxy) error { stubsType := Everything if ctx.Config().ReleaseHiddenApiExportableStubs() { stubsType = Exportable @@ -819,7 +819,7 @@ func (paths *scopePaths) extractStubsSourceAndApiInfoFromApiStubsProvider(ctx an }) } -func extractOutputPaths(ctx android.ModuleContext, dep android.Module) (android.Paths, error) { +func extractOutputPaths(ctx android.ModuleContext, dep android.ModuleProxy) (android.Paths, error) { var paths android.Paths if sourceFileProducer, ok := android.OtherModuleProvider(ctx, dep, android.SourceFilesInfoProvider); ok { paths = sourceFileProducer.Srcs @@ -829,13 +829,13 @@ func extractOutputPaths(ctx android.ModuleContext, dep android.Module) (android. } } -func (paths *scopePaths) extractLatestApiPath(ctx android.ModuleContext, dep android.Module) error { +func (paths *scopePaths) extractLatestApiPath(ctx android.ModuleContext, dep android.ModuleProxy) error { outputPaths, err := extractOutputPaths(ctx, dep) paths.latestApiPaths = outputPaths return err } -func (paths *scopePaths) extractLatestRemovedApiPath(ctx android.ModuleContext, dep android.Module) error { +func (paths *scopePaths) extractLatestRemovedApiPath(ctx android.ModuleContext, dep android.ModuleProxy) error { outputPaths, err := extractOutputPaths(ctx, dep) paths.latestRemovedApiPaths = outputPaths return err diff --git a/python/python.go b/python/python.go index f0f25f5ab..7af8d9d18 100644 --- a/python/python.go +++ b/python/python.go @@ -680,7 +680,7 @@ func (p *PythonLibraryModule) collectPathsFromTransitiveDeps(ctx android.ModuleC destToPyData[path.dest] = path.src.String() } - seen := make(map[android.Module]bool) + seen := make(map[android.ModuleProxy]bool) var result android.Paths @@ -726,7 +726,7 @@ func (p *PythonLibraryModule) collectPathsFromTransitiveDeps(ctx android.ModuleC } func (p *PythonLibraryModule) collectSharedLibDeps(ctx android.ModuleContext) android.Paths { - seen := make(map[android.Module]bool) + seen := make(map[android.ModuleProxy]bool) var result android.Paths -- cgit v1.2.3 From 5b24c29f2903ed33753b4a11464575d0c5329fd1 Mon Sep 17 00:00:00 2001 From: Jared Duke Date: Fri, 4 Apr 2025 18:50:08 +0000 Subject: Use D8 release mode when PRODUCT_MINIMIZE_JAVA_DEBUG_INFO is set This will still preserve line numbers for frames that can throw, but further reduces the set of debug info embedded in Java-specific artifacts. For framework.jar, this saves >1MB (~3%) of dex. Bug: 349177664 Bug: 388940908 Test: lunch eos-trunk_staging-userdebug && m + compare dex Flag: EXEMPT product-specific optimization Change-Id: Ica3c5815dbd774614870dff49737f81a82f1ae94 --- java/dex.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java/dex.go b/java/dex.go index e3058e9bf..13dcd86ad 100644 --- a/java/dex.go +++ b/java/dex.go @@ -362,6 +362,8 @@ func (d *dexer) dexCommonFlags(ctx android.ModuleContext, flags = append(flags, "--release") } else if ctx.Config().Eng() { flags = append(flags, "--debug") + } else if ctx.Config().MinimizeJavaDebugInfo() { + flags = append(flags, "--release") } else if !d.effectiveOptimizeEnabled(ctx) && d.dexProperties.Optimize.EnabledByDefault { // D8 uses --debug by default, whereas R8 uses --release by default. // For targets that default to R8 usage (e.g., apps), but override this default, we still -- cgit v1.2.3 From 5283dd8fa6fb569dc27ab6ab77767411e7c97c26 Mon Sep 17 00:00:00 2001 From: Himanshu Gupta Date: Tue, 25 Mar 2025 13:35:56 +0000 Subject: Adding `incremental_javac_input` cmd wrapper This tool will be used in incremental javac execution to determine the subset of input srcs to be passed to javac Bug: 387798027 Flag: NA Test: go test ./cmd/incremental_javac_input{,/incremental_javac_input_lib} Ignore-AOSP-First: No AOSP uploads anymore Change-Id: Iaf26ed93c53040d81aab235ec3c873cd83a537b2 --- cmd/incremental_javac_input/Android.bp | 27 + cmd/incremental_javac_input/README.md | 45 ++ .../incremental_javac_input_lib/Android.bp | 30 + .../generate_incremental_input.go | 278 ++++++++ .../generate_incremental_input_test.go | 710 +++++++++++++++++++++ cmd/incremental_javac_input/main.go | 63 ++ go.work | 2 + 7 files changed, 1155 insertions(+) create mode 100644 cmd/incremental_javac_input/Android.bp create mode 100644 cmd/incremental_javac_input/README.md create mode 100644 cmd/incremental_javac_input/incremental_javac_input_lib/Android.bp create mode 100644 cmd/incremental_javac_input/incremental_javac_input_lib/generate_incremental_input.go create mode 100644 cmd/incremental_javac_input/incremental_javac_input_lib/generate_incremental_input_test.go create mode 100644 cmd/incremental_javac_input/main.go diff --git a/cmd/incremental_javac_input/Android.bp b/cmd/incremental_javac_input/Android.bp new file mode 100644 index 000000000..9d3f076ed --- /dev/null +++ b/cmd/incremental_javac_input/Android.bp @@ -0,0 +1,27 @@ +// 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 { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +blueprint_go_binary { + name: "incremental_javac_input", + srcs: [ + "main.go", + ], + deps: [ + "soong-cmd-incremental_javac_input-lib", + ], +} diff --git a/cmd/incremental_javac_input/README.md b/cmd/incremental_javac_input/README.md new file mode 100644 index 000000000..dee1cba3d --- /dev/null +++ b/cmd/incremental_javac_input/README.md @@ -0,0 +1,45 @@ +// 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. + +# Incremental Javac Input + +[incremental_javac_input] command line tool. This tool can be used to find the correct subset +of java files to be passed for incremental javac compilation. + +# Getting Started + +## Inputs +* rsp file, containing list of java source files separated by whitespace. +* deps file, containing the cross-module dependencies for javac. +* javacTarget path to the output jar of javac +* srcDepsProto, path to a proto file representing dependencies across java source files. +* localHeaderJars optional space separated file paths representing header jars for java sources. + +## Output +* [javacTarget].inc.rsp file, representing list of java source files for incremental compilation. +* [javacTarget].rem.rsp file, representing the list of .class files whose sources were removed and hence should be cleaned. +* [javacTarget].input.pc_state.new temp state file, representing the current state of all java sources. +* [javacTarget].deps.pc_state.new temp state file, representing the current state of cross-module dependencies. +* [javacTarget].headers.pc_state.new temp state file, representing the current state of java source headers. + +## Usage +``` +incremental_javac_input --srcs [srcRspFile] --deps [depsRspFile] --javacTarget [javacTargetPath] --srcDepsProto [srcDepsProtoPath] --localHeaderJars [headerJarPath1] [headerJarPath2] +``` + +## Notes +* This tool internally references the core logic of [find_input_delta] tool. +* All outputs are relative to the javacTarget path +* Same sources, deps, headers when used for different targets will output different results. +* Once javac succeeds, the temp state files should be saved as current state files, to prepare for next iteration. \ No newline at end of file diff --git a/cmd/incremental_javac_input/incremental_javac_input_lib/Android.bp b/cmd/incremental_javac_input/incremental_javac_input_lib/Android.bp new file mode 100644 index 000000000..42219a222 --- /dev/null +++ b/cmd/incremental_javac_input/incremental_javac_input_lib/Android.bp @@ -0,0 +1,30 @@ +// 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 { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +bootstrap_go_package { + name: "soong-cmd-incremental_javac_input-lib", + pkgPath: "android/soong/cmd/incremental_javac_input/incremental_javac_input_lib", + deps: [ + "blueprint-pathtools", + "soong-cmd-find_input_delta-lib", + "golang-dependency-mapper-protoimpl", + ], + srcs: [ + "generate_incremental_input.go", + ], +} diff --git a/cmd/incremental_javac_input/incremental_javac_input_lib/generate_incremental_input.go b/cmd/incremental_javac_input/incremental_javac_input_lib/generate_incremental_input.go new file mode 100644 index 000000000..5f829d7ae --- /dev/null +++ b/cmd/incremental_javac_input/incremental_javac_input_lib/generate_incremental_input.go @@ -0,0 +1,278 @@ +// 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 incremental_javac_input_lib + +import ( + "errors" + "fmt" + "io/fs" + "os" + "regexp" + "strings" + + fid_lib "android/soong/cmd/find_input_delta/find_input_delta_lib" + "github.com/google/blueprint/pathtools" + dependency_proto "go.dependencymapper/protoimpl" + "google.golang.org/protobuf/proto" +) + +var fileSepRegex = regexp.MustCompile("[^[:space:]]+") + +type UsageMap struct { + FilePath string + + Usages []string + + IsDependencyToAll bool + + GeneratedClasses []string +} + +func GenerateIncrementalInput(srcs, deps, javacTarget, srcDeps, localHeaderJars string) (err error) { + incInputPath := javacTarget + ".inc.rsp" + removedClassesPath := javacTarget + ".rem.rsp" + inputPcState := javacTarget + ".input.pc_state" + depsPcState := javacTarget + ".deps.pc_state" + headersPcState := javacTarget + ".headers.pc_state" + + var classesForRemoval []string + var incAllSources bool + + // Read the srcRspFile contents + srcList := readRspFile(srcs) + // run find_input_delta, save [add + ch] as a []string, and [del] as another []string + addF, delF, chF := findInputDelta(srcList, inputPcState, javacTarget) + var incInputList []string + incInputList = append(incInputList, addF...) + incInputList = append(incInputList, chF...) + + // check if deps have changed + depsList := readRspFile(deps) + if addD, delD, chD := findInputDelta(depsList, depsPcState, javacTarget); len(addD)+len(delD)+len(chD) > 0 { + incAllSources = true + } + + // If we are not doing a partial compile, we can just return the full list. + // We can do this earlier as well, but allowing findInputDelta to run outputs + // the changed sources to build metrics as well as maintains the state of + // inputs we require if the partialCompile is switched on again. + if !usePartialCompile() { + return writeOutput(incInputPath, removedClassesPath, srcList, classesForRemoval) + } + + // if javacTarget does not exist, we can include all sources + if incAllSources || !fileExists(javacTarget) { + incAllSources = true + } + + // if incInputList has the same size as srcList (all files touched), we can + // just include all sources + if incAllSources || len(incInputList) == len(srcList) { + incAllSources = true + } + + // if dependencyMap does not exist, we can include all sources + if incAllSources || !fileExists(srcDeps) { + incAllSources = true + } + + headersChanged := false + // if headers do not change, we can just keep the incInputList as is. + // Read the srcRspFile contents + headersList := readRspFile(localHeaderJars) + if addH, delH, chH := findInputDelta(headersList, headersPcState, javacTarget); len(addH)+len(delH)+len(chH) > 0 { + headersChanged = true + } + // if headers do not change, there should not be [added] or [deleted] files. + if !headersChanged && (len(addF) > 0 || len(delF) > 0) { + headerErrMsg := "Headers did not change, but source files were added/removed" + panic(headerErrMsg) + } + + // use revDepsMap to find all usages, add them to output, alongside [add + ch] files + if fileExists(srcDeps) { + usageMap, _ := generateUsageMap(srcDeps) + // if including all sources, no need to check the usageMap + if headersChanged && !incAllSources { + incInputList, incAllSources = getUsages(usageMap, incInputList, delF, headersChanged) + } + // use usageMap to add all classes that were generated from removed files. + classesForRemoval = generateRemovalList(usageMap, delF) + } + + if incAllSources { + incInputList = srcList + } + + // write the output to output path(s) + return writeOutput(incInputPath, removedClassesPath, incInputList, classesForRemoval) +} + +// Checks if Full Compile is enabled or not +func usePartialCompile() bool { + usePartialCompileVar := os.Getenv("SOONG_USE_PARTIAL_COMPILE") + if usePartialCompileVar == "true" { + return true + } + return false +} + +// Returns the list of files that use added, modified or deleted files. +// Returns whether to include all src Files in incremental src set +func getUsages(usageMap map[string]UsageMap, modifiedFiles, deletedFiles []string, headersChanged bool) ([]string, bool) { + usagesSet := make(map[string]bool) + + // First add all the modified files in the output + for _, incInput := range modifiedFiles { + usagesSet[incInput] = true + } + // Add all the usages of modified + deleted files + for _, modFile := range append(modifiedFiles, deletedFiles...) { + if um, exists := usageMap[modFile]; exists { + if um.IsDependencyToAll { + return nil, true + } + if headersChanged { + for _, usage := range um.Usages { + usagesSet[usage] = true + } + } + } + } + + var usages []string + for usage := range usagesSet { + usages = append(usages, usage) + } + return usages, false +} + +// Returns the list of class files to be removed, as a result of deleting a source file. +func generateRemovalList(usageMap map[string]UsageMap, delFiles []string) []string { + var classesForRemoval []string + for _, delFile := range delFiles { + if _, exists := usageMap[delFile]; exists { + classesForRemoval = append(classesForRemoval, usageMap[delFile].GeneratedClasses...) + } + } + return classesForRemoval +} + +// Generates the usage map, by reading the supplied dependency map as a proto +// Throws error if the map is unparsable. +func generateUsageMap(srcDeps string) (map[string]UsageMap, error) { + var message = &dependency_proto.FileDependencyList{} + + usageMapSet := make(map[string]UsageMap) + + data, err := os.ReadFile(srcDeps) + if err != nil && errors.Is(err, fs.ErrNotExist) { + fmt.Println("err: ", err) + panic(err) + } + err = proto.Unmarshal(data, message) + if err != nil { + fmt.Println("err: ", err) + panic(err) + } + for _, dep := range message.FileDependency { + addUsageMapIfNotPresent(usageMapSet, *dep.FilePath) + for _, depV := range dep.FileDependencies { + addUsageMapIfNotPresent(usageMapSet, depV) + updatedUsageMap := usageMapSet[depV] + updatedUsageMap.Usages = append(updatedUsageMap.Usages, *dep.FilePath) + usageMapSet[depV] = updatedUsageMap + } + updatedUsageMap := usageMapSet[*dep.FilePath] + updatedUsageMap.IsDependencyToAll = *dep.IsDependencyToAll + updatedUsageMap.GeneratedClasses = dep.GeneratedClasses + usageMapSet[*dep.FilePath] = updatedUsageMap + } + return usageMapSet, nil +} + +func addUsageMapIfNotPresent(usageMapSet map[string]UsageMap, key string) { + if _, exists := usageMapSet[key]; !exists { + usageMap := UsageMap{ + FilePath: key, + Usages: []string{}, + IsDependencyToAll: false, + GeneratedClasses: []string{}, + } + usageMapSet[key] = usageMap + } +} + +func fileExists(filePath string) bool { + if file, err := os.Open(filePath); err != nil { + if os.IsNotExist(err) { + return false + } + panic(err) + } else { + file.Close() + } + return true +} + +func readRspFile(rspFile string) (list []string) { + data, err := os.ReadFile(rspFile) + if err != nil { + panic(err) + } + list = append(list, fileSepRegex.FindAllString(string(data), -1)...) + return list +} + +// Writes incInput and classesForRemoval to output paths +func writeOutput(incInputPath, removedClassesPath string, incInputList, classesForRemoval []string) (err error) { + err = pathtools.WriteFileIfChanged(incInputPath, []byte(strings.Join(incInputList, "\n")), 0644) + if err != nil { + return err + } + return pathtools.WriteFileIfChanged(removedClassesPath, []byte(strings.Join(classesForRemoval, "\n")), 0644) +} + +// Computes the diff of the inputs provided, saving the temp state in the +// priorStateFile. +func findInputDelta(inputs []string, priorStateFile, target string) ([]string, []string, []string) { + newStateFile := priorStateFile + ".new" + fileList, err := fid_lib.GenerateFileList(target, priorStateFile, newStateFile, inputs, false, fid_lib.OsFs) + if err != nil { + panic(err) + } + return flattenChanges(fileList) +} + +// Flattens the output of find_input_delta for javac's consumption. +func flattenChanges(root *fid_lib.FileList) ([]string, []string, []string) { + var allAdditions []string + var allDeletions []string + var allChangedFiles []string + + for _, addition := range root.Additions { + allAdditions = append(allAdditions, addition) + } + + for _, del := range root.Deletions { + allDeletions = append(allDeletions, del) + } + + for _, ch := range root.Changes { + allChangedFiles = append(allChangedFiles, ch.Name) + } + + return allAdditions, allDeletions, allChangedFiles +} diff --git a/cmd/incremental_javac_input/incremental_javac_input_lib/generate_incremental_input_test.go b/cmd/incremental_javac_input/incremental_javac_input_lib/generate_incremental_input_test.go new file mode 100644 index 000000000..b1970de4e --- /dev/null +++ b/cmd/incremental_javac_input/incremental_javac_input_lib/generate_incremental_input_test.go @@ -0,0 +1,710 @@ +package incremental_javac_input_lib + +import ( + "fmt" + "os" + "path/filepath" + "reflect" + "sort" + "strings" + "testing" + "time" + + fid_lib "android/soong/cmd/find_input_delta/find_input_delta_lib" + dependency_proto "go.dependencymapper/protoimpl" + "google.golang.org/protobuf/proto" +) + +// --- Tests for `getUsages` --- +func TestGetUsages(t *testing.T) { + usageMap := map[string]UsageMap{ + "file1.java": {Usages: []string{"file3.java", "file4.java"}}, + "file2.java": {Usages: []string{"file3.java"}}, + "file3.java": {Usages: []string{}}, + "fileAll.java": {Usages: []string{}, IsDependencyToAll: true}, + } + + testCases := []struct { + name string + modifiedFiles []string + deletedFiles []string + expected []string + expectedAll bool + }{ + { + name: "Basic", + modifiedFiles: []string{"file1.java"}, + deletedFiles: []string{"file2.java"}, + expected: []string{"file1.java", "file3.java", "file4.java"}, // file3 is used by both + expectedAll: false, + }, + { + name: "Empty", + modifiedFiles: []string{}, + deletedFiles: []string{}, + expected: nil, + expectedAll: false, + }, + { + name: "NonExistentFile", + modifiedFiles: []string{"nonexistent.java"}, + deletedFiles: []string{}, + expected: []string{"nonexistent.java"}, + expectedAll: false, + }, + { + name: "DependencyToAll", + modifiedFiles: []string{"file1.java"}, + deletedFiles: []string{"fileAll.java"}, + expected: nil, + expectedAll: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + actual, all := getUsages(usageMap, tc.modifiedFiles, tc.deletedFiles, true) + if all != tc.expectedAll { + t.Errorf("getUsages() all sources; expected %v, got %v", tc.expectedAll, all) + } + + // Sort for consistent comparison, as map iteration order isn't guaranteed + sort.Strings(actual) + sort.Strings(tc.expected) + if !reflect.DeepEqual(actual, tc.expected) { + t.Errorf("getUsages(); expected %v, got %v", tc.expected, actual) + } + }) + } +} + +// --- Tests for `generateRemovalList` --- +func TestGenerateRemovalList(t *testing.T) { + usageMap := map[string]UsageMap{ + "file1.java": {GeneratedClasses: []string{"Class1", "Class2"}}, + "file2.java": {GeneratedClasses: []string{"Class3"}}, + "file3.java": {}, + } + + testCases := []struct { + name string + delFiles []string + expected []string + }{ + {"Basic", []string{"file1.java", "file2.java"}, []string{"Class1", "Class2", "Class3"}}, + {"Empty", []string{}, nil}, + {"NonExistent", []string{"nonexistent.java"}, nil}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + actual := generateRemovalList(usageMap, tc.delFiles) + sort.Strings(actual) + sort.Strings(tc.expected) + if !reflect.DeepEqual(actual, tc.expected) { + t.Errorf("generateRemovalList(); expected %v, got %v", tc.expected, actual) + } + }) + } +} + +// --- Tests for `generateUsageMap` --- +func TestGenerateUsageMap(t *testing.T) { + tmpDir := t.TempDir() + + // 1. Test with a valid proto file. + protoFile := filepath.Join(tmpDir, "deps.pb") + createProtoFile(t, protoFile) + + usageMap, err := generateUsageMap(protoFile) + if err != nil { + t.Fatalf("generateUsageMap() returned an error: %v", err) + } + + expectedUsageMap := map[string]UsageMap{ + "file1.java": {FilePath: "file1.java", Usages: []string{}, IsDependencyToAll: false, GeneratedClasses: []string{"ClassA", "ClassB"}}, + "file2.java": {FilePath: "file2.java", Usages: []string{"file1.java"}, IsDependencyToAll: true, GeneratedClasses: []string{"ClassC"}}, + "file3.java": {FilePath: "file3.java", Usages: []string{"file1.java"}, IsDependencyToAll: false, GeneratedClasses: []string{"ClassD"}}, + } + + if !reflect.DeepEqual(usageMap, expectedUsageMap) { + t.Errorf("generateUsageMap() returned unexpected map.\nGot: %+v\nWant:%+v", usageMap, expectedUsageMap) + } + + // 2. Test with a non-existent file (should panic) + t.Run("Panic on non-existent proto", func(t *testing.T) { + defer func() { + if r := recover(); r == nil { //should have panicked + t.Errorf("generateUsageMap() did not panic on non-existent proto") + } + }() + _, _ = generateUsageMap("nonexistent.pb") + }) + + // 3. Test with an invalid proto file (should panic) + invalidProtoFile := filepath.Join(tmpDir, "invalid.pb") + writeFile(t, invalidProtoFile, "This is not a valid proto file") // Create invalid file + t.Run("Panic on invalid proto file", func(t *testing.T) { + defer func() { + if r := recover(); r == nil { //should have panicked + t.Errorf("generateUsageMap() did not panic on invalid proto") + } + }() + _, _ = generateUsageMap(invalidProtoFile) + }) +} + +// --- Tests for `readRspFile` --- +func TestReadRspFile(t *testing.T) { + tmpDir := t.TempDir() + + testCases := []struct { + name string + content string + expected []string + }{ + {"Empty", "", nil}, + {"SingleLine", "file1.java", []string{"file1.java"}}, + {"MultipleLines", "file1.java\nfile2.java\nfile3.java", []string{"file1.java", "file2.java", "file3.java"}}, + {"WithSpaces", " file1.java \n file2.java ", []string{"file1.java", "file2.java"}}, //Should be trimmed. + {"WithEmptyLines", "file1.java\n\nfile2.java", []string{"file1.java", "file2.java"}}, + {"WithCarriageReturn", "file1.java\r\nfile2.java", []string{"file1.java", "file2.java"}}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + rspFile := filepath.Join(tmpDir, "test.rsp") + writeFile(t, rspFile, tc.content) + + actual := readRspFile(rspFile) + if !reflect.DeepEqual(actual, tc.expected) { + t.Errorf("readRspFile(); expected %v, got %v", tc.expected, actual) + } + }) + } + + //Test for panic + t.Run("Panic on non-existent file", func(t *testing.T) { + defer func() { + if r := recover(); r == nil { //should have panicked + t.Errorf("readRspFile() did not panic on non-existent file") + } + }() + _ = readRspFile("nonexistent_file.rsp") + }) +} + +// --- Tests for `flattenChanges` --- + +func TestFlattenChanges(t *testing.T) { + fileList := &fid_lib.FileList{ + Additions: []string{"add1.java", "add2.java"}, + Deletions: []string{"del1.java"}, + Changes: []fid_lib.FileList{ + {Name: "change1.java"}, + {Name: "change2.java"}, + }, + } + + expectedAdditions := []string{"add1.java", "add2.java"} + expectedDeletions := []string{"del1.java"} + expectedChanges := []string{"change1.java", "change2.java"} + + actualAdditions, actualDeletions, actualChanges := flattenChanges(fileList) + + // Sort for consistent comparison + sort.Strings(expectedAdditions) + sort.Strings(actualAdditions) + sort.Strings(expectedDeletions) + sort.Strings(actualDeletions) + sort.Strings(expectedChanges) + sort.Strings(actualChanges) + + if !reflect.DeepEqual(actualAdditions, expectedAdditions) { + t.Errorf("flattenChanges() additions; expected %v, got %v", expectedAdditions, actualAdditions) + } + if !reflect.DeepEqual(actualDeletions, expectedDeletions) { + t.Errorf("flattenChanges() deletions; expected %v, got %v", expectedDeletions, actualDeletions) + } + if !reflect.DeepEqual(actualChanges, expectedChanges) { + t.Errorf("flattenChanges() changes; expected %v, got %v", expectedChanges, actualChanges) + } +} + +// --- Tests for `GenerateIncrementalInput` --- + +func TestGenerateIncrementalInput(t *testing.T) { + // Set the environment variable to enable inc-compilation + t.Setenv("SOONG_USE_PARTIAL_COMPILE", "true") + + // Shared setup for all subtests + tf := newTestFixture(t) + // No need for top-level defer os.RemoveAll(tmpDir) because t.TempDir() handles it + + // --- Subtest: Initial Full Compile --- + t.Run("InitialFullCompile", func(t *testing.T) { + // Arrange (already done by newTestFixture) + + // Act + tf.runGenerator() + + // Assert + checkOutput( + t, + tf.incOutputPath(), + fmt.Sprintf("%s\n%s\n%s", tf.JavaFile1, tf.JavaFile2, tf.JavaFile3), // All files included initially + tf.remOutputPath(), + "", // No removals initially + ) + tf.savePriorState() + }) + + // --- Subtest: Incremental - One File Modified --- + t.Run("Incremental_OneFileModified", func(t *testing.T) { + // Arrange: Modify one file (ensure timestamp changes) + modifyFile(t, tf.JavaFile3, "Incremental_OneFileModified") + + // Act + tf.runGenerator() + + // Assert: Only the modified file should be in inc.rsp + checkOutput( + t, + tf.incOutputPath(), + fmt.Sprintf("%s", tf.JavaFile3), + tf.remOutputPath(), + "", // No removals + ) + tf.savePriorState() + }) + + // --- Subtest: Incremental - One File and Header Modified --- + t.Run("Incremental_FileAndHeaderModified", func(t *testing.T) { + // Arrange: Modify a different file and the header jar + modifyFile(t, tf.JavaFile3, "Incremental_FileAndHeaderModified") + modifyFile(t, tf.HeaderJar, "Incremental_FileAndHeaderModified") + + // Act + tf.runGenerator() + + // Assert: All source files and their usages should be in inc.rsp + checkOutput( + t, + tf.incOutputPath(), + fmt.Sprintf("%s\n%s", tf.JavaFile1, tf.JavaFile3), + tf.remOutputPath(), + "", // No removals + ) + tf.savePriorState() + }) + + // --- Subtest: Incremental - Dependency Change --- + t.Run("Incremental_DependencyChanged", func(t *testing.T) { + // Arrange: Modify the DepJar + modifyFile(t, tf.DepJar, "Incremental_DependencyChanged") + + // Act + tf.runGenerator() + + // Assert: All source files should be in inc.rsp + checkOutput( + t, + tf.incOutputPath(), + fmt.Sprintf("%s\n%s\n%s", tf.JavaFile1, tf.JavaFile2, tf.JavaFile3), + tf.remOutputPath(), + "", // No removals + ) + tf.savePriorState() + }) + + // --- Subtest: Incremental - File which is dependency to all files is Changed --- + t.Run("Incremental_DependencyToAllChanged", func(t *testing.T) { + // Arrange: Modify the DepsRspFile or JavaSrcDeps proto + modifyFile(t, tf.JavaFile2, "Incremental_DependencyToAllChanged") + + // Act + tf.runGenerator() + + // Assert: All source files should be in inc.rsp + checkOutput( + t, + tf.incOutputPath(), + fmt.Sprintf("%s", tf.JavaFile2), + tf.remOutputPath(), + "", // No removals + ) + tf.savePriorState() + }) + + // --- Subtest: Incremental - File which is dependency to all files is changed along with headers--- + t.Run("Incremental_DependencyToAllChanged", func(t *testing.T) { + // Arrange: Modify the DepsRspFile or JavaSrcDeps proto + modifyFile(t, tf.JavaFile2, "Incremental_DependencyToAllChangedWithHeader") + modifyFile(t, tf.HeaderJar, "Incremental_DependencyToAllChangedWithHeader") + + // Act + tf.runGenerator() + + // Assert: All source files should be in inc.rsp + checkOutput( + t, + tf.incOutputPath(), + fmt.Sprintf("%s\n%s\n%s", tf.JavaFile1, tf.JavaFile2, tf.JavaFile3), + tf.remOutputPath(), + "", // No removals + ) + tf.savePriorState() + }) + + // --- Subtest: Incremental - One File Deleted, Header Modified --- + t.Run("Incremental_FileDeletedHeaderModified", func(t *testing.T) { + // Arrange: Delete one file and modify header + deleteFile(t, tf.JavaFile3, tf.SrcRspFile) + // Modify Headers + modifyFile(t, tf.HeaderJar, "Incremental_FileDeletedHeaderModified") + + // Act + tf.runGenerator() + + // Assert: Check usages of deleted file in inc.rsp, and class files + // corresponding to deleted files in rem.rsp + checkOutput( + t, + tf.incOutputPath(), + fmt.Sprintf("%s", tf.JavaFile1), // usages of deleted file + tf.remOutputPath(), + "org.another.ClassD", // class name corresponding to the deleted file path + ) + tf.savePriorState() // Save state if needed for subsequent tests + }) + + // --- Subtest: Panic on Removal without Header Change --- + t.Run("Panic_FileRemovedNoHeaderChange", func(t *testing.T) { + // Arrange: Delete a file BUT DO NOT modify headers + deleteFile(t, tf.JavaFile2, tf.SrcRspFile) + + // Act & Assert: Expecting a panic + defer func() { + if r := recover(); r == nil { + t.Errorf("GenerateIncrementalInput did not panic when a file was removed without header change") + } + }() + + tf.runGenerator() // This call should panic + }) +} + +func TestGenerateIncrementalInputPartialCompileOff(t *testing.T) { + // Set the environment variable to disable inc-compilation + t.Setenv("SOONG_USE_PARTIAL_COMPILE", "") + + // Shared setup for all subtests + tf := newTestFixture(t) + // No need for top-level defer os.RemoveAll(tmpDir) because t.TempDir() handles it + + // --- Subtest: Initial Full Compile --- + t.Run("InitialFullCompile", func(t *testing.T) { + // Arrange (already done by newTestFixture) + + // Act + tf.runGenerator() + + // Assert + checkOutput( + t, + tf.incOutputPath(), + fmt.Sprintf("%s\n%s\n%s", tf.JavaFile1, tf.JavaFile2, tf.JavaFile3), // All files included initially + tf.remOutputPath(), + "", // No removals initially + ) + tf.savePriorState() + }) + + // --- Subtest: Incremental - One File Modified, should add all files --- + t.Run("Incremental_OneFileModified_AddsAllFiles", func(t *testing.T) { + // Arrange: Modify one file (ensure timestamp changes) + modifyFile(t, tf.JavaFile3, "Incremental_OneFileModified") + + // Act + tf.runGenerator() + + // Assert: Only the modified file should be in inc.rsp + checkOutput( + t, + tf.incOutputPath(), + fmt.Sprintf("%s\n%s\n%s", tf.JavaFile1, tf.JavaFile2, tf.JavaFile3), + tf.remOutputPath(), + "", // No removals + ) + tf.savePriorState() + }) +} + +// --- Test Fixture Setup --- +// Struct to hold common test file paths +type testFixture struct { + t *testing.T + tmpDir string + SrcRspFile string + DepsRspFile string + JavacTargetJar string + JavaSrcDeps string + HeadersRspFile string + JavaFile1 string + JavaFile2 string + JavaFile3 string + DepJar string + HeaderJar string +} + +// newTestFixture creates the temporary directory and necessary files +func newTestFixture(t *testing.T) *testFixture { + tmpDir := t.TempDir() // Use t.TempDir for automatic cleanup + + // Create dummy files needed for the tests + fixture := &testFixture{ + t: t, + tmpDir: tmpDir, + SrcRspFile: filepath.Join(tmpDir, "sources.rsp"), + DepsRspFile: filepath.Join(tmpDir, "deps.rsp"), + JavacTargetJar: filepath.Join(tmpDir, "output.jar"), + JavaSrcDeps: filepath.Join(tmpDir, "srcdeps.pb"), // Example proto file path + HeadersRspFile: filepath.Join(tmpDir, "localHeaders.rsp"), + JavaFile1: filepath.Join(tmpDir, "src/com/example/ClassA.java"), + JavaFile2: filepath.Join(tmpDir, "src/com/example/ClassC.java"), + JavaFile3: filepath.Join(tmpDir, "src/org/another/ClassD.java"), // Example different package + DepJar: filepath.Join(tmpDir, "deps.jar"), + HeaderJar: filepath.Join(tmpDir, "headers.jar"), + } + + // Create directories and initial file contents + createDir(t, filepath.Dir(fixture.JavaFile1)) + createDir(t, filepath.Dir(fixture.JavaFile3)) + + writeFile(t, fixture.JavaFile1, "package com.example; class File1 {}") + writeFile(t, fixture.JavaFile2, "package com.example; class File2 {}") + writeFile(t, fixture.JavaFile3, "package org.another; class ClassD {}") + + writeFile(t, fixture.DepJar, "Dep jar") + writeFile(t, fixture.HeaderJar, "Header jar") + + writeFile(t, fixture.SrcRspFile, fmt.Sprintf("%s\n%s\n%s", fixture.JavaFile1, fixture.JavaFile2, fixture.JavaFile3)) + writeFile(t, fixture.DepsRspFile, fmt.Sprintf("%s", fixture.DepJar)) + writeFile(t, fixture.HeadersRspFile, fmt.Sprintf("%s", fixture.HeaderJar)) + writeFile(t, fixture.JavacTargetJar, "Javac Jar") + writeFile(t, fixture.JavaSrcDeps, "") + createProtoFileWithActualPaths(t, fixture.JavaSrcDeps, fixture.JavaFile1, fixture.JavaFile2, fixture.JavaFile3) + + return fixture +} + +// runGenerator calls GenerateIncrementalInput for the testFixture +func (tf *testFixture) runGenerator() { + // Small delay often needed for filesystem timestamp granularity + time.Sleep(15 * time.Millisecond) + err := GenerateIncrementalInput(tf.SrcRspFile, tf.DepsRspFile, tf.JavacTargetJar, tf.JavaSrcDeps, tf.HeadersRspFile) + if err != nil { + tf.t.Fatalf("GenerateIncrementalInput() returned an error: %v", err) + } +} + +// returns incOutputPath for testFixture +func (tf *testFixture) incOutputPath() string { + return tf.JavacTargetJar + ".inc.rsp" +} + +// returns remOutputPath for testFixture +func (tf *testFixture) remOutputPath() string { + return tf.JavacTargetJar + ".rem.rsp" +} + +// Verifies the test output against expected output +func checkOutput(t *testing.T, incOutputPath, expectedIncContent, remOutputPath, expectedRemContent string) { + checkFileContent(t, incOutputPath, expectedIncContent) + checkFileContent(t, remOutputPath, expectedRemContent) +} + +// Helper to check if the content of a file matches the expected content (order insensitive) +func checkFileContent(t *testing.T, filePath, expectedContent string) { + contentBytes, err := os.ReadFile(filePath) + if err != nil { + t.Fatalf("Failed to read output file %q: %v", filePath, err) + } + actualContent := strings.TrimSpace(string(contentBytes)) + + actualLines := strings.Split(actualContent, "\n") + expectedLines := strings.Split(expectedContent, "\n") + sort.Strings(actualLines) + sort.Strings(expectedLines) + actualContent = strings.Join(actualLines, "\n") + expectedContent = strings.Join(expectedLines, "\n") + + if actualContent != expectedContent { + t.Errorf("Unexpected content in %q.\nGot:\n%s\nWant:\n%s", filePath, actualContent, expectedContent) + } +} + +// Helper to save prior state +func (tf *testFixture) savePriorState() { + tf.t.Helper() + // Implement your logic to save the necessary state files + // e.g., copy *.pc_state.new to *.pc_state + inputStateNew := tf.JavacTargetJar + ".input.pc_state.new" + inputState := tf.JavacTargetJar + ".input.pc_state" + depsStateNew := tf.JavacTargetJar + ".deps.pc_state.new" + depsState := tf.JavacTargetJar + ".deps.pc_state" + headerStateNew := tf.JavacTargetJar + ".headers.pc_state.new" + headerState := tf.JavacTargetJar + ".headers.pc_state" + + os.Rename(inputStateNew, inputState) + os.Rename(depsStateNew, depsState) + os.Rename(headerStateNew, headerState) +} + +// --- File Create/Mod/Delete helpers --- + +func createDir(t *testing.T, dirPath string) { + t.Helper() + err := os.MkdirAll(dirPath, 0755) + if err != nil { + t.Fatalf("Failed to create directory %q: %v", dirPath, err) + } +} + +func writeFile(t *testing.T, filePath, content string) { + t.Helper() + err := os.WriteFile(filePath, []byte(content), 0644) + if err != nil { + t.Fatalf("Failed to write file %q: %v", filePath, err) + } +} + +func modifyFile(t *testing.T, filePath, newContentSuffix string) { + t.Helper() + // Append suffix to ensure modification time changes reliably + contentBytes, err := os.ReadFile(filePath) + if err != nil && !os.IsNotExist(err) { // Allow modification even if file was deleted before + t.Fatalf("Failed to read file for modification %q: %v", filePath, err) + } + newContent := string(contentBytes) + "// " + newContentSuffix + writeFile(t, filePath, newContent) +} + +func deleteFile(t *testing.T, filePath, srcRspFilePath string) { + t.Helper() + err := os.Remove(filePath) + if err != nil && !os.IsNotExist(err) { // Ignore error if already deleted + t.Fatalf("Failed to delete file %q: %v", filePath, err) + } + // Also update the source rsp file! + updateSrcRsp(t, srcRspFilePath, filePath, true) +} + +func updateSrcRsp(t *testing.T, rspPath, filePath string, remove bool) { + t.Helper() + contentBytes, err := os.ReadFile(rspPath) + if err != nil { + t.Fatalf("Failed to read source rsp file %q: %v", rspPath, err) + } + lines := strings.Split(string(contentBytes), "\n") + var newLines []string + found := false + for _, line := range lines { + trimmedLine := strings.TrimSpace(line) + if trimmedLine == "" { + continue + } + if trimmedLine == filePath { + found = true + if !remove { // Keep it if not removing + newLines = append(newLines, trimmedLine) + } + } else { + newLines = append(newLines, trimmedLine) + } + } + // Add back if it wasn't found and we are not removing (e.g., restoring) + if !found && !remove { + newLines = append(newLines, filePath) + } + + writeFile(t, rspPath, strings.Join(newLines, "\n")) +} + +// --- ProtoFile Creation helpers --- + +func createProtoFile(t *testing.T, filePath string) string { + t.Helper() + + dep1 := &dependency_proto.FileDependency{ + FilePath: proto.String("file1.java"), + FileDependencies: []string{"file2.java", "file3.java"}, + IsDependencyToAll: proto.Bool(false), + GeneratedClasses: []string{"ClassA", "ClassB"}, + } + dep2 := &dependency_proto.FileDependency{ + FilePath: proto.String("file2.java"), + FileDependencies: []string{}, + IsDependencyToAll: proto.Bool(true), + GeneratedClasses: []string{"ClassC"}, + } + dep3 := &dependency_proto.FileDependency{ + FilePath: proto.String("file3.java"), + FileDependencies: []string{}, + IsDependencyToAll: proto.Bool(false), + GeneratedClasses: []string{"ClassD"}, + } + + message := &dependency_proto.FileDependencyList{ + FileDependency: []*dependency_proto.FileDependency{dep1, dep2, dep3}, + } + + data, err := proto.Marshal(message) + if err != nil { + t.Fatalf("Failed to marshal proto message: %v", err) + } + + if err := os.WriteFile(filePath, data, 0644); err != nil { + t.Fatalf("Failed to write proto file: %v", err) + } + + return filePath +} + +func createProtoFileWithActualPaths(t *testing.T, protoFilePath, javaFile1, javaFile2, javaFile3 string) string { + t.Helper() + + dep1 := &dependency_proto.FileDependency{ + FilePath: proto.String(javaFile1), + FileDependencies: []string{javaFile2, javaFile3}, + IsDependencyToAll: proto.Bool(false), + GeneratedClasses: []string{"src/com/example/ClassA", "src/com/example/ClassB"}, + } + dep2 := &dependency_proto.FileDependency{ + FilePath: proto.String(javaFile2), + FileDependencies: []string{}, + IsDependencyToAll: proto.Bool(true), + GeneratedClasses: []string{"src/com/example/ClassC"}, + } + dep3 := &dependency_proto.FileDependency{ + FilePath: proto.String(javaFile3), + FileDependencies: []string{}, + IsDependencyToAll: proto.Bool(false), + GeneratedClasses: []string{"org.another.ClassD"}, + } + + message := &dependency_proto.FileDependencyList{ + FileDependency: []*dependency_proto.FileDependency{dep1, dep2, dep3}, + } + + data, err := proto.Marshal(message) + if err != nil { + t.Fatalf("Failed to marshal proto message: %v", err) + } + + if err := os.WriteFile(protoFilePath, data, 0644); err != nil { + t.Fatalf("Failed to write proto file: %v", err) + } + + return protoFilePath +} diff --git a/cmd/incremental_javac_input/main.go b/cmd/incremental_javac_input/main.go new file mode 100644 index 000000000..b3c820ba1 --- /dev/null +++ b/cmd/incremental_javac_input/main.go @@ -0,0 +1,63 @@ +// 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 main + +import ( + "flag" + "fmt" + + iji_lib "android/soong/cmd/incremental_javac_input/incremental_javac_input_lib" +) + +func main() { + var srcs, deps, javacTarget, srcDepsProto, localHeaderJars string + + flag.StringVar(&srcs, "srcs", "", "rsp file containing java source paths") + flag.StringVar(&deps, "deps", "", "rsp file enlisting all module deps") + flag.StringVar(&javacTarget, "javacTarget", "", "javac output") + flag.StringVar(&srcDepsProto, "srcDepsProto", "", "dependency map between src files in a proto") + flag.StringVar(&localHeaderJars, "localHeaderJars", "", "rsp file enlisting all local header jars") + + flag.Parse() + + if deps == "" { + panic("must specify --deps") + } + + if javacTarget == "" { + panic("must specify --javacTarget") + } + + if localHeaderJars == "" { + panic("must specify --localHeaderJars") + } + + if srcDepsProto == "" { + panic("must specify --depsProto") + } + + if srcs == "" { + panic("must specify --srcs") + } + + if srcs != "" { + err := iji_lib.GenerateIncrementalInput(srcs, deps, javacTarget, srcDepsProto, localHeaderJars) + if err != nil { + panic("errored") + } + } else { + fmt.Println("No source files provided via --srcs flag.") + } +} diff --git a/go.work b/go.work index e5389156c..0e49119a8 100644 --- a/go.work +++ b/go.work @@ -6,6 +6,7 @@ use ( ../../external/golang-protobuf ../../external/starlark-go ../blueprint + ../../build/make/tools/dependency_mapper/proto ) replace ( @@ -14,4 +15,5 @@ replace ( github.com/google/go-cmp v0.0.0 => ../../external/go-cmp google.golang.org/protobuf v0.0.0 => ../../external/golang-protobuf go.starlark.net v0.0.0 => ../../external/starlark-go + go.dependencymapper/protoimpl v0.0.0 => ../../build/make/tools/dependency_mapper/proto ) -- cgit v1.2.3 From 076ba4295f613be6be9ef17533d5cf0e6be61e76 Mon Sep 17 00:00:00 2001 From: Himanshu Gupta Date: Tue, 25 Mar 2025 15:32:26 +0000 Subject: Adding inc_javac ninja rule This rule runs javac incrementally by reducing the input src set. Planned for local developer flows, the rule is off by default, can be enabled by setting `export SOONG_PARTIAL_COMPILE=enabled,+inc_javac` Bug: 387798027 Test: manual & th Ignore-AOSP-First: No AOSP uploads anymore Change-Id: Ia0d10f4fb34bfcefbe3d5a545afda635b4cf33c1 --- android/config.go | 10 ++ android/config_test.go | 15 ++- java/base.go | 54 +++++++++-- java/builder.go | 245 ++++++++++++++++++++++++++++++++++++++++++++++++- java/config/config.go | 2 + 5 files changed, 316 insertions(+), 10 deletions(-) diff --git a/android/config.go b/android/config.go index bf952d71e..ab5e860a0 100644 --- a/android/config.go +++ b/android/config.go @@ -414,6 +414,9 @@ type partialCompileFlags struct { // To run the validation checks, use `m {MODULE_NAME}-stub-validation`. Disable_stub_validation bool + // Whether to enable incremental java compilation. + Enable_inc_javac bool + // Add others as needed. } @@ -424,12 +427,14 @@ var defaultPartialCompileFlags = partialCompileFlags{} var enabledPartialCompileFlags = partialCompileFlags{ Use_d8: true, Disable_stub_validation: true, + Enable_inc_javac: false, } // These are the flags when `SOONG_PARTIAL_COMPILE=all`. var allPartialCompileFlags = partialCompileFlags{ Use_d8: true, Disable_stub_validation: true, + Enable_inc_javac: true, } type deviceConfig struct { @@ -513,6 +518,11 @@ func (c *config) parsePartialCompileFlags(isEngBuild bool) (partialCompileFlags, ret = allPartialCompileFlags // Individual flags. + case "inc_javac", "enable_inc_javac": + ret.Enable_inc_javac = makeVal(state, !defaultPartialCompileFlags.Enable_inc_javac) + case "disable_inc_javac": + ret.Enable_inc_javac = !makeVal(state, defaultPartialCompileFlags.Enable_inc_javac) + case "stub_validation", "enable_stub_validation": ret.Disable_stub_validation = !makeVal(state, !defaultPartialCompileFlags.Disable_stub_validation) case "disable_stub_validation": diff --git a/android/config_test.go b/android/config_test.go index 22827f58e..e7bdfe75c 100644 --- a/android/config_test.go +++ b/android/config_test.go @@ -223,6 +223,11 @@ func (p partialCompileFlags) updateDisableStubValidation(value bool) partialComp return p } +func (p partialCompileFlags) updateEnableIncJavac(value bool) partialCompileFlags { + p.Enable_inc_javac = value + return p +} + func TestPartialCompile(t *testing.T) { mockConfig := func(value string) *config { c := &config{ @@ -241,7 +246,7 @@ func TestPartialCompile(t *testing.T) { {"false", true, partialCompileFlags{}}, {"true", true, enabledPartialCompileFlags}, {"true", false, partialCompileFlags{}}, - {"all", true, partialCompileFlags{}.updateUseD8(true).updateDisableStubValidation(true)}, + {"all", true, partialCompileFlags{}.updateUseD8(true).updateDisableStubValidation(true).updateEnableIncJavac(true)}, // This verifies both use_d8 and the processing order. {"true,use_d8", true, enabledPartialCompileFlags.updateUseD8(true)}, @@ -256,6 +261,14 @@ func TestPartialCompile(t *testing.T) { {"false,+stub_validation", true, partialCompileFlags{}.updateDisableStubValidation(false)}, {"false,+enable_stub_validation", true, partialCompileFlags{}.updateDisableStubValidation(false)}, {"false,-disable_stub_validation", true, partialCompileFlags{}.updateDisableStubValidation(false)}, + + // enable_inc_javac can be specified with any of 3 options. + {"false,-inc_javac", true, partialCompileFlags{}.updateEnableIncJavac(false)}, + {"false,-enable_inc_javac", true, partialCompileFlags{}.updateEnableIncJavac(false)}, + {"false,+disable_inc_javac", true, partialCompileFlags{}.updateEnableIncJavac(false)}, + {"false,+inc_javac", true, partialCompileFlags{}.updateEnableIncJavac(true)}, + {"false,+enable_inc_javac", true, partialCompileFlags{}.updateEnableIncJavac(true)}, + {"false,-disable_inc_javac", true, partialCompileFlags{}.updateEnableIncJavac(true)}, } for _, test := range tests { diff --git a/java/base.go b/java/base.go index 0f0a50524..f1bcd8518 100644 --- a/java/base.go +++ b/java/base.go @@ -1474,6 +1474,24 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath break } } + + // turbine is disabled when API generating APs are present, in which case, + // we would want to process annotations before moving to incremental javac + if ctx.Device() && ctx.Config().PartialCompileFlags().Enable_inc_javac && disableTurbine { + if len(flags.processorPath) > 0 { + annoSrcJars, classes := j.generateJavaAnnotations(ctx, jarName, -1, uniqueJavaFiles, srcJars, flags, nil) + srcJars = append(srcJars, annoSrcJars) + localImplementationJars = append(localImplementationJars, classes) + flags.processorPath = nil + flags.processors = nil + } + // turbine was disabled, lets run it now + extraJars1 := slices.Clone(kotlinHeaderJars) + extraJars1 = append(extraJars1, extraCombinedJars...) + localHeaderJars, _ = j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName, extraJars1) + shardingHeaderJars = localHeaderJars + } + var extraJarDeps android.Paths if Bool(j.properties.Errorprone.Enabled) { // If error-prone is enabled, enable errorprone flags on the regular @@ -1496,7 +1514,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath errorprone := android.PathForModuleOut(ctx, "errorprone", jarName) errorproneAnnoSrcJar := android.PathForModuleOut(ctx, "errorprone", "anno.srcjar") - transformJavaToClasses(ctx, errorprone, -1, uniqueJavaFiles, srcJars, errorproneAnnoSrcJar, errorproneFlags, nil, + transformJavaToClasses(ctx, errorprone, -1, uniqueJavaFiles, srcJars, errorproneAnnoSrcJar, false, errorproneFlags, nil, "errorprone", "errorprone") extraJarDeps = append(extraJarDeps, errorprone) @@ -1513,7 +1531,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath shardSrcs = android.ShardPaths(uniqueJavaFiles, shardSize) for idx, shardSrc := range shardSrcs { classes := j.compileJavaClasses(ctx, jarName, idx, shardSrc, - nil, flags, extraJarDeps) + nil, nil, flags, extraJarDeps) classes, _ = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac-"+strconv.Itoa(idx)) localImplementationJars = append(localImplementationJars, classes) } @@ -1526,13 +1544,13 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath shardSrcJarsList := android.ShardPaths(srcJars, shardSize/5) for idx, shardSrcJars := range shardSrcJarsList { classes := j.compileJavaClasses(ctx, jarName, startIdx+idx, - nil, shardSrcJars, flags, extraJarDeps) + nil, shardSrcJars, nil, flags, extraJarDeps) classes, _ = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac-"+strconv.Itoa(startIdx+idx)) localImplementationJars = append(localImplementationJars, classes) } } } else { - classes := j.compileJavaClasses(ctx, jarName, -1, uniqueJavaFiles, srcJars, flags, extraJarDeps) + classes := j.compileJavaClasses(ctx, jarName, -1, uniqueJavaFiles, srcJars, shardingHeaderJars, flags, extraJarDeps) classes, _ = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac") localImplementationJars = append(localImplementationJars, classes) } @@ -2032,7 +2050,7 @@ func enableErrorproneFlags(flags javaBuilderFlags) javaBuilderFlags { } func (j *Module) compileJavaClasses(ctx android.ModuleContext, jarName string, idx int, - srcFiles, srcJars android.Paths, flags javaBuilderFlags, extraJarDeps android.Paths) android.Path { + srcFiles, srcJars, localHeaderJars android.Paths, flags javaBuilderFlags, extraJarDeps android.Paths) android.Path { kzipName := pathtools.ReplaceExtension(jarName, "kzip") annoSrcJar := android.PathForModuleOut(ctx, "javac", "anno.srcjar") @@ -2043,7 +2061,13 @@ func (j *Module) compileJavaClasses(ctx android.ModuleContext, jarName string, i } classes := android.PathForModuleOut(ctx, "javac", jarName) - TransformJavaToClasses(ctx, classes, idx, srcFiles, srcJars, annoSrcJar, flags, extraJarDeps) + // enable incremental javac when corresponding flags are enabled and + // header jars are present + if ctx.Config().PartialCompileFlags().Enable_inc_javac && len(localHeaderJars) > 0 { + TransformJavaToClassesInc(ctx, classes, srcFiles, srcJars, localHeaderJars, annoSrcJar, flags, extraJarDeps) + } else { + TransformJavaToClasses(ctx, classes, idx, srcFiles, srcJars, annoSrcJar, flags, extraJarDeps) + } if ctx.Config().EmitXrefRules() && ctx.Module() == ctx.PrimaryModule() { extractionFile := android.PathForModuleOut(ctx, kzipName) @@ -2058,6 +2082,24 @@ func (j *Module) compileJavaClasses(ctx android.ModuleContext, jarName string, i return classes } +func (j *Module) generateJavaAnnotations(ctx android.ModuleContext, jarName string, idx int, + srcFiles, srcJars android.Paths, flags javaBuilderFlags, extraJarDeps android.Paths) (android.Path, android.Path) { + + annoSrcJar := android.PathForModuleOut(ctx, "javac-apt", "anno.srcjar") + if idx >= 0 { + annoSrcJar = android.PathForModuleOut(ctx, "javac-apt", "anno-"+strconv.Itoa(idx)+".srcjar") + jarName += strconv.Itoa(idx) + } + + classes := android.PathForModuleOut(ctx, "javac-apt", jarName) + GenerateJavaAnnotations(ctx, classes, idx, srcFiles, srcJars, annoSrcJar, flags, extraJarDeps) + + if len(flags.processorPath) > 0 { + j.annoSrcJars = append(j.annoSrcJars, annoSrcJar) + } + return annoSrcJar, classes +} + // Check for invalid kotlinc flags. Only use this for flags explicitly passed by the user, // since some of these flags may be used internally. func CheckKotlincFlags(ctx android.ModuleContext, flags []string) { diff --git a/java/builder.go b/java/builder.go index dff0032d8..e468b1f04 100644 --- a/java/builder.go +++ b/java/builder.go @@ -20,6 +20,7 @@ package java import ( "path/filepath" + "slices" "strconv" "strings" @@ -33,6 +34,92 @@ import ( var ( pctx = android.NewPackageContext("android/soong/java") + // Unzips jar files into a directory provided. + extractZip = pctx.AndroidStaticRule("javac-extract-zip", + blueprint.RuleParams{ + Command: `rm -rf "$srcJarDir" && mkdir -p "$srcJarDir" && ${config.ZipSyncCmd} -d "$srcJarDir" -l "$out" -f "*.java" $srcJars`, + CommandDeps: []string{ + "${config.ZipSyncCmd}", + }, + }, "srcJarDir", "srcJars", + ) + + // Removes all outputs of inc-javac rule + javacIncClean = pctx.AndroidStaticRule("javac-inc-partialcompileclean", + blueprint.RuleParams{ + Command: `rm -rf "${srcJarDir}" "${outDir}" "${annoDir}" "${annoSrcJar}" "${builtOut}"`, + }, "srcJarDir", "outDir", "annoDir", "annoSrcJar", "builtOut", + ) + + // Incremental javac rule + // The idea of this rule is to make javac incremental, i.e. use the input and + // output of previous javac execution to reduce the src lists. + // This rule is very similar to the normal javac rule with a few differences: + // * Does not unzip srcJars in the rule + // * Does not remove the temp directories containing classes/generated sources + // * Saves the states of a bunch of input params, when javac executes successfully. + // * Runs additional tools on the output to prepare for next iteration + javacInc, javacIncRE = pctx.MultiCommandRemoteStaticRules("javac-inc", + blueprint.RuleParams{ + Command: `rm -rf "$annoDir" "$annoSrcJar.tmp" "$out.tmp" && ` + + `mkdir -p "$outDir" "$annoDir" && ` + + `if [ -s $out.rsp ] && [ -s $srcJarList ] ; then ` + + `echo >> $out.rsp; fi && ` + + `cat $srcJarList >> $out.rsp && ` + + `${config.IncrementalJavacInputCmd} ` + + `--srcs $out.rsp --deps $javacDeps --javacTarget $out --srcDepsProto $out.proto --localHeaderJars $localHeaderJars && ` + + `(if [ -s $out.inc.rsp ] ; then ` + + `${config.SoongJavacWrapper} $javaTemplate${config.JavacCmd} ` + + `${config.JavacHeapFlags} ${config.JavacVmFlags} ${config.CommonJdkFlags} ` + + `$processorpath $processor $javacFlags $bootClasspath $classpath ` + + `-source $javaVersion -target $javaVersion ` + + `-d $outDir -s $annoDir @$out.inc.rsp ; fi ) && ` + + `cat $out.rem.rsp | xargs rm -f && ` + + `$annoSrcJarTemplate${config.SoongZipCmd} -jar -o $annoSrcJar.tmp -C $annoDir -D $annoDir && ` + + `$zipTemplate${config.SoongZipCmd} -jar -o $out.tmp -C $outDir -D $outDir && ` + + `if ! cmp -s "$out.tmp" "$out"; then mv "$out.tmp" "$out"; fi && ` + + `if ! cmp -s "$annoSrcJar.tmp" "$annoSrcJar"; then mv "$annoSrcJar.tmp" "$annoSrcJar"; fi && ` + + `if [ -f "$out.input.pc_state.new" ]; then mv "$out.input.pc_state.new" "$out.input.pc_state" && ` + + `rm -rf $out.input.pc_state.new; fi && ` + + `if [ -f "$out.deps.pc_state.new" ]; then mv "$out.deps.pc_state.new" "$out.deps.pc_state" && ` + + `rm -rf $out.deps.pc_state.new; fi && ` + + `if [ -f "$out.headers.pc_state.new" ]; then mv "$out.headers.pc_state.new" "$out.headers.pc_state" && ` + + `rm -rf $out.headers.pc_state.new; fi && ` + + `if [ -f $out.rsp ] && [ -f $out ]; then ` + + `${config.DependencyMapperJavacCmd} --src-path $out.rsp --jar-path $out --dependency-map-path $out.proto; fi`, + CommandDeps: []string{ + "${config.DependencyMapperJavacCmd}", + "${config.IncrementalJavacInputCmd}", + "${config.JavacCmd}", + "${config.ZipSyncCmd}", + }, + CommandOrderOnly: []string{"${config.SoongJavacWrapper}"}, + Restat: true, + Rspfile: "$out.rsp", + RspfileContent: "$in", + }, map[string]*remoteexec.REParams{ + "$javaTemplate": &remoteexec.REParams{ + Labels: map[string]string{"type": "compile", "lang": "java", "compiler": "javac"}, + ExecStrategy: "${config.REJavacExecStrategy}", + 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{"$out.tmp"}, + ExecStrategy: "${config.REJavacExecStrategy}", + Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"}, + }, + "$annoSrcJarTemplate": &remoteexec.REParams{ + Labels: map[string]string{"type": "tool", "name": "soong_zip"}, + Inputs: []string{"${config.SoongZipCmd}", "$annoDir"}, + OutputFiles: []string{"$annoSrcJar.tmp"}, + ExecStrategy: "${config.REJavacExecStrategy}", + Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"}, + }, + }, []string{"javacFlags", "bootClasspath", "classpath", "processorpath", "processor", "srcJarList", + "outDir", "annoDir", "annoSrcJar", "javaVersion", "javacDeps", "localHeaderJars"}, nil) + // Compiling java is not conducive to proper dependency tracking. The path-matches-class-name // requirement leads to unpredictable generated source file names, and a single .java file // will get compiled into multiple .class files if it contains inner classes. To work around @@ -387,6 +474,14 @@ func DefaultJavaBuilderFlags() javaBuilderFlags { } } +func TransformJavaToClassesInc(ctx android.ModuleContext, outputFile android.WritablePath, + srcFiles, srcJars, headerJars android.Paths, annoSrcJar android.WritablePath, flags javaBuilderFlags, deps android.Paths) { + + // Compile java sources into .class files + desc := "javac-inc" + transformJavaToClassesInc(ctx, outputFile, srcFiles, srcJars, headerJars, annoSrcJar, flags, deps, "javac", desc) +} + func TransformJavaToClasses(ctx android.ModuleContext, outputFile android.WritablePath, shardIdx int, srcFiles, srcJars android.Paths, annoSrcJar android.WritablePath, flags javaBuilderFlags, deps android.Paths) { @@ -395,8 +490,18 @@ func TransformJavaToClasses(ctx android.ModuleContext, outputFile android.Writab if shardIdx >= 0 { desc += strconv.Itoa(shardIdx) } + transformJavaToClasses(ctx, outputFile, shardIdx, srcFiles, srcJars, annoSrcJar, false, flags, deps, "javac", desc) +} +func GenerateJavaAnnotations(ctx android.ModuleContext, outputFile android.WritablePath, shardIdx int, + srcFiles, srcJars android.Paths, annoSrcJar android.WritablePath, flags javaBuilderFlags, deps android.Paths) { + + // Generate src files from Java Annotations. + desc := "javac-apt" + if shardIdx >= 0 { + desc += strconv.Itoa(shardIdx) + } - transformJavaToClasses(ctx, outputFile, shardIdx, srcFiles, srcJars, annoSrcJar, flags, deps, "javac", desc) + transformJavaToClasses(ctx, outputFile, shardIdx, srcFiles, srcJars, annoSrcJar, true, flags, deps, "javac-apt", desc) } // Emits the rule to generate Xref input file (.kzip file) for the given set of source files and source jars @@ -588,6 +693,133 @@ func TurbineApt(ctx android.ModuleContext, outputSrcJar, outputResJar android.Wr }) } +// Similar to transformJavaToClasses, with additional tweaks to make java +// compilation work incrementally (i.e. work with a smaller subset of src java files +// rather than the full set) +func transformJavaToClassesInc(ctx android.ModuleContext, outputFile android.WritablePath, + srcFiles, srcJars, shardingHeaderJars android.Paths, annoSrcJar android.WritablePath, + flags javaBuilderFlags, deps android.Paths, intermediatesDir, desc string) { + + javacClasspath := flags.classpath + + var bootClasspath string + if flags.javaVersion.usesJavaModules() { + var systemModuleDeps android.Paths + bootClasspath, systemModuleDeps = flags.systemModules.FormJavaSystemModulesPath(ctx.Device()) + deps = append(deps, systemModuleDeps...) + javacClasspath = append(flags.java9Classpath, javacClasspath...) + } else { + deps = append(deps, flags.bootClasspath...) + if len(flags.bootClasspath) == 0 && ctx.Device() { + // explicitly specify -bootclasspath "" if the bootclasspath is empty to + // ensure java does not fall back to the default bootclasspath. + bootClasspath = `-bootclasspath ""` + } else { + bootClasspath = flags.bootClasspath.FormJavaClassPath("-bootclasspath") + } + } + + deps = append(deps, flags.processorPath...) + deps = append(deps, javacClasspath...) + + // The file containing dependencies of the current module + // Any change in them may warrant changes in the incremental compilation + // source set. + javacDeps := outputFile.ReplaceExtension(ctx, "jar.deps.rsp") + android.WriteFileRule(ctx, javacDeps, strings.Join(deps.Strings(), "\n")) + deps = append(deps, javacDeps) + + // Add localHeader Jars in classpath, they are required for incremental compilation. + // These are conspicuously not added to javacDeps file, as a change in them + // does not warrant full re-compilation. + javacClasspath = append(classpath(slices.Clone(shardingHeaderJars)), javacClasspath...) + deps = append(deps, shardingHeaderJars...) + shardingHeaderRsp := outputFile.ReplaceExtension(ctx, "jar.headers.rsp") + android.WriteFileRule(ctx, shardingHeaderRsp, strings.Join(shardingHeaderJars.Strings(), "\n")) + deps = append(deps, shardingHeaderRsp) + + // Doing this now, sow that they are not added to javacDeps file + deps = append(deps, srcJars...) + + classpathArg := javacClasspath.FormJavaClassPath("-classpath") + + // Keep the command line under the MAX_ARG_STRLEN limit by putting the classpath argument into an rsp file + // if it is too long. + const classpathLimit = 64 * 1024 + if len(classpathArg) > classpathLimit { + classpathRspFile := outputFile.ReplaceExtension(ctx, "classpath") + android.WriteFileRule(ctx, classpathRspFile, classpathArg) + deps = append(deps, classpathRspFile) + classpathArg = "@" + classpathRspFile.String() + } + + processor := "-proc:none" + if len(flags.processors) > 0 { + processor = "-processor " + strings.Join(flags.processors, ",") + } + + srcJarDir := "srcjars" + outDir := "classes" + annoDir := "anno" + srcJarList := android.PathForModuleOut(ctx, intermediatesDir, srcJarDir, "list") + deps = append(deps, srcJarList) + + ctx.Build(pctx, android.BuildParams{ + Rule: extractZip, + Description: "javacExtractZip", + Inputs: srcJars, + Output: srcJarList, + Args: map[string]string{ + "srcJarDir": android.PathForModuleOut(ctx, intermediatesDir, srcJarDir).String(), + "srcJars": strings.Join(srcJars.Strings(), " "), + }, + }) + + rule := javacInc + ctx.Build(pctx, android.BuildParams{ + Rule: rule, + Description: desc, + Output: outputFile, + ImplicitOutput: annoSrcJar, + Inputs: srcFiles, + Implicits: deps, + Args: map[string]string{ + "javacFlags": flags.javacFlags, + "bootClasspath": bootClasspath, + "classpath": classpathArg, + "processorpath": flags.processorPath.FormJavaClassPath("-processorpath"), + "processor": processor, + "srcJarList": srcJarList.String(), + "outDir": android.PathForModuleOut(ctx, intermediatesDir, outDir).String(), + "annoDir": android.PathForModuleOut(ctx, intermediatesDir, annoDir).String(), + "annoSrcJar": annoSrcJar.String(), + "javaVersion": flags.javaVersion.String(), + "javacDeps": javacDeps.String(), + "localHeaderJars": shardingHeaderRsp.String(), + }, + }) + + // The Phony Clean rule allows javac to move from incremental to full, without + // re-analysis by removing all the outputs of javac, triggering all rules + // that generate them. + cleanPhonyPath := android.PathForModuleOut(ctx, "dex", outputFile.String()+"-partialcompileclean").OutputPath + // Generate the rule for partial compile clean. + ctx.Build(pctx, android.BuildParams{ + Rule: javacIncClean, + Description: "javacIncClean", + Output: cleanPhonyPath, + Args: map[string]string{ + "srcJarDir": android.PathForModuleOut(ctx, intermediatesDir, srcJarDir).String(), + "outDir": android.PathForModuleOut(ctx, intermediatesDir, outDir).String(), + "annoDir": android.PathForModuleOut(ctx, intermediatesDir, annoDir).String(), + "annoSrcJar": annoSrcJar.String(), + "builtOut": outputFile.String(), + }, + PhonyOutput: true, + }) + ctx.Phony("partialcompileclean", cleanPhonyPath) +} + // transformJavaToClasses takes source files and converts them to a jar containing .class files. // srcFiles is a list of paths to sources, srcJars is a list of paths to jar files that contain // sources. flags contains various command line flags to be passed to the compiler. @@ -597,8 +829,11 @@ func TurbineApt(ctx android.ModuleContext, outputSrcJar, outputResJar android.Wr // be printed at build time. The stem argument provides the file name of the output jar, and // suffix will be appended to various intermediate files and directories to avoid collisions when // this function is called twice in the same module directory. +// +// This method can also be used to only process Annotations, without completely +// compiling java sources. func transformJavaToClasses(ctx android.ModuleContext, outputFile android.WritablePath, - shardIdx int, srcFiles, srcJars android.Paths, annoSrcJar android.WritablePath, + shardIdx int, srcFiles, srcJars android.Paths, annoSrcJar android.WritablePath, onlyGenerateAnnotations bool, flags javaBuilderFlags, deps android.Paths, intermediatesDir, desc string) { @@ -640,7 +875,11 @@ func transformJavaToClasses(ctx android.ModuleContext, outputFile android.Writab processor := "-proc:none" if len(flags.processors) > 0 { - processor = "-processor " + strings.Join(flags.processors, ",") + if onlyGenerateAnnotations { + processor = "-proc:only -processor " + strings.Join(flags.processors, ",") + } else { + processor = "-processor " + strings.Join(flags.processors, ",") + } } srcJarDir := "srcjars" diff --git a/java/config/config.go b/java/config/config.go index fdb8d7886..0e4613ca6 100644 --- a/java/config/config.go +++ b/java/config/config.go @@ -160,6 +160,8 @@ func init() { pctx.HostBinToolVariable("GenKotlinBuildFileCmd", "gen-kotlin-build-file") pctx.HostBinToolVariable("FindInputDeltaCmd", "find_input_delta") + pctx.HostBinToolVariable("IncrementalJavacInputCmd", "incremental_javac_input") + pctx.HostBinToolVariable("DependencyMapperJavacCmd", "dependency-mapper") pctx.SourcePathVariable("JarArgsCmd", "build/soong/scripts/jar-args.sh") pctx.SourcePathVariable("PackageCheckCmd", "build/soong/scripts/package-check.sh") -- cgit v1.2.3 From 1771ff30c6a3a3514a27fd9ef7539790b2bb3313 Mon Sep 17 00:00:00 2001 From: Wei Li Date: Fri, 4 Apr 2025 14:58:47 -0700 Subject: Add compliance metadata for /system_other/system-other-odex-marker Bug: 401369898 Test: presubmits Change-Id: I3581ce7f84eee80e97d4fe66220466f2b798900f --- filesystem/system_other.go | 1 + 1 file changed, 1 insertion(+) diff --git a/filesystem/system_other.go b/filesystem/system_other.go index 67e5f2fce..5451b10e7 100644 --- a/filesystem/system_other.go +++ b/filesystem/system_other.go @@ -199,6 +199,7 @@ func (m *systemOtherImage) GenerateAndroidBuildActions(ctx android.ModuleContext // Dump compliance metadata complianceMetadataInfo := ctx.ComplianceMetadataInfo() complianceMetadataInfo.SetFilesContained(fullInstallPaths) + complianceMetadataInfo.SetPlatformGeneratedFiles(fullInstallPaths) } func (s *systemOtherImage) generateFilesystemConfig(ctx android.ModuleContext, stagingDir, stagingDirTimestamp android.Path) android.Path { -- cgit v1.2.3 From 36e9b75b9db5d9b35bd77fe8ef4fa72c451e9e93 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Fri, 4 Apr 2025 15:09:02 -0700 Subject: Add DisableTestConfig To be the soong equivalent of LOCAL_DISABLE_TEST_CONFIG, which is only set by AndroidTestHelperApp. Also add test_module_config's CompatibilitySupportFiles. Both of these are needed to build device-tests.zip Bug: 405184090 Test: Presubmits Change-Id: I30ad67c82908f3261ff6841bb24e39a5860cb0da --- android/module.go | 22 ++++++++++++---------- android/test_suites.go | 3 +++ java/app.go | 1 + tradefed_modules/test_module_config.go | 13 +++++++------ 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/android/module.go b/android/module.go index 9f43d86e7..a57b762ac 100644 --- a/android/module.go +++ b/android/module.go @@ -2562,16 +2562,18 @@ func (m *ModuleBase) setupTestSuites(ctx ModuleContext, info TestSuiteInfo) []fi }) } - if info.ConfigFile != nil { - oneVariantInstalls = append(oneVariantInstalls, filePair{ - src: info.ConfigFile, - dst: joinWriteablePath(ctx, suite.dir, name+".config"+info.ConfigFileSuffix), - }) - } else if config := ExistentPathForSource(ctx, ctx.ModuleDir(), "AndroidTest.xml"); config.Valid() { - oneVariantInstalls = append(oneVariantInstalls, filePair{ - src: config.Path(), - dst: joinWriteablePath(ctx, suite.dir, name+".config"), - }) + if !info.DisableTestConfig { + if info.ConfigFile != nil { + oneVariantInstalls = append(oneVariantInstalls, filePair{ + src: info.ConfigFile, + dst: joinWriteablePath(ctx, suite.dir, name+".config"+info.ConfigFileSuffix), + }) + } else if config := ExistentPathForSource(ctx, ctx.ModuleDir(), "AndroidTest.xml"); config.Valid() { + oneVariantInstalls = append(oneVariantInstalls, filePair{ + src: config.Path(), + dst: joinWriteablePath(ctx, suite.dir, name+".config"), + }) + } } dynamicConfig := ExistentPathForSource(ctx, ctx.ModuleDir(), "DynamicConfig.xml") diff --git a/android/test_suites.go b/android/test_suites.go index c1b7d9e5f..181cceb2a 100644 --- a/android/test_suites.go +++ b/android/test_suites.go @@ -69,6 +69,9 @@ type TestSuiteInfo struct { NonArchData []DataPath CompatibilitySupportFiles []Path + + // Eqivalent of LOCAL_DISABLE_TEST_CONFIG in make + DisableTestConfig bool } var TestSuiteInfoProvider = blueprint.NewProvider[TestSuiteInfo]() diff --git a/java/app.go b/java/app.go index 2840c7f3f..42eb21c62 100644 --- a/java/app.go +++ b/java/app.go @@ -444,6 +444,7 @@ func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleCon NeedsArchFolder: true, NonArchData: data, PerTestcaseDirectory: proptools.Bool(a.appTestHelperAppProperties.Per_testcase_directory), + DisableTestConfig: true, }) } diff --git a/tradefed_modules/test_module_config.go b/tradefed_modules/test_module_config.go index 10f7c8f33..c24eddccf 100644 --- a/tradefed_modules/test_module_config.go +++ b/tradefed_modules/test_module_config.go @@ -434,12 +434,13 @@ func (m *testModuleConfigModule) generateManifestAndConfig(ctx android.ModuleCon } ctx.SetTestSuiteInfo(android.TestSuiteInfo{ - TestSuites: m.tradefedProperties.Test_suites, - MainFile: m.manifest, - MainFileStem: fmt.Sprintf("UNUSED-%s", *m.Base), - MainFileExt: mainFileExt, - ConfigFile: m.testConfig, - NeedsArchFolder: ctx.Device(), + TestSuites: m.tradefedProperties.Test_suites, + MainFile: m.manifest, + MainFileStem: fmt.Sprintf("UNUSED-%s", *m.Base), + MainFileExt: mainFileExt, + ConfigFile: m.testConfig, + CompatibilitySupportFiles: m.supportFiles.Paths(), + NeedsArchFolder: ctx.Device(), }) } -- cgit v1.2.3 From 34efe59ab2358d21aa6d7e3d518179b40cb6191a Mon Sep 17 00:00:00 2001 From: Ivan Lozano Date: Fri, 4 Apr 2025 19:08:53 +0000 Subject: rust: Disable host dylib modules. There's no way for hosts to explicitly request dylib dependencies, so there's no reason to be providing these variants. This drops support for them so they're not built as part of checkbuilds. Bug: 374811858 Test: m Change-Id: I24d2de22fa83f79a838e243cd7a3223b6dfede25 --- rust/compiler_test.go | 16 ++++++++-------- rust/library.go | 9 ++++++++- rust/library_test.go | 36 ++++++++++++++++++------------------ 3 files changed, 34 insertions(+), 27 deletions(-) diff --git a/rust/compiler_test.go b/rust/compiler_test.go index 8805d15eb..381c03909 100644 --- a/rust/compiler_test.go +++ b/rust/compiler_test.go @@ -24,7 +24,7 @@ import ( // Test that feature flags are being correctly generated. func TestFeaturesToFlags(t *testing.T) { ctx := testRust(t, ` - rust_library_host_dylib { + rust_library_dylib { name: "libfoo", srcs: ["foo.rs"], crate_name: "foo", @@ -34,7 +34,7 @@ func TestFeaturesToFlags(t *testing.T) { ], }`) - libfooDylib := ctx.ModuleForTests(t, "libfoo", "linux_glibc_x86_64_dylib").Rule("rustc") + libfooDylib := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_dylib").Rule("rustc") if !strings.Contains(libfooDylib.Args["rustcFlags"], "cfg 'feature=\"fizz\"'") || !strings.Contains(libfooDylib.Args["rustcFlags"], "cfg 'feature=\"buzz\"'") { @@ -45,7 +45,7 @@ func TestFeaturesToFlags(t *testing.T) { // Test that cfgs flags are being correctly generated. func TestCfgsToFlags(t *testing.T) { ctx := testRust(t, ` - rust_library_host { + rust_library { name: "libfoo", srcs: ["foo.rs"], crate_name: "foo", @@ -55,7 +55,7 @@ func TestCfgsToFlags(t *testing.T) { ], }`) - libfooDylib := ctx.ModuleForTests(t, "libfoo", "linux_glibc_x86_64_dylib").Rule("rustc") + libfooDylib := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_dylib").Rule("rustc") if !strings.Contains(libfooDylib.Args["rustcFlags"], "cfg 'std'") || !strings.Contains(libfooDylib.Args["rustcFlags"], "cfg 'cfg1=\"one\"'") { @@ -65,7 +65,7 @@ func TestCfgsToFlags(t *testing.T) { func TestLtoFlag(t *testing.T) { ctx := testRust(t, ` - rust_library_host { + rust_library { name: "libfoo", srcs: ["foo.rs"], crate_name: "foo", @@ -74,15 +74,15 @@ func TestLtoFlag(t *testing.T) { } } - rust_library_host { + rust_library { name: "libfoo_lto", srcs: ["foo.rs"], crate_name: "foo", } `) - libfoo := ctx.ModuleForTests(t, "libfoo", "linux_glibc_x86_64_dylib").Rule("rustc") - libfooLto := ctx.ModuleForTests(t, "libfoo_lto", "linux_glibc_x86_64_dylib").Rule("rustc") + libfoo := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_dylib").Rule("rustc") + libfooLto := ctx.ModuleForTests(t, "libfoo_lto", "android_arm64_armv8-a_dylib").Rule("rustc") if strings.Contains(libfoo.Args["rustcFlags"], "-C lto=thin") { t.Fatalf("libfoo expected to disable lto -- rustcFlags: %#v", libfoo.Args["rustcFlags"]) diff --git a/rust/library.go b/rust/library.go index 415785a16..3e11b60c8 100644 --- a/rust/library.go +++ b/rust/library.go @@ -311,6 +311,8 @@ func (library *libraryDecorator) stdLinkage(device bool) RustLinkage { return RlibLinkage } else if library.baseCompiler.preferRlib() { return RlibLinkage + } else if !device { + return RlibLinkage } return DylibLinkage } @@ -942,7 +944,8 @@ func (libraryTransitionMutator) Split(ctx android.BaseModuleContext) []string { if library.buildRlib() { variants = append(variants, rlibVariation) } - if library.buildDylib() { + if library.buildDylib() && !ctx.Host() { + // Hosts do not produce dylib variants. variants = append(variants, dylibVariation) } @@ -1039,6 +1042,10 @@ func (libstdTransitionMutator) Split(ctx android.BaseModuleContext) []string { // Only create a variant if a library is actually being built. if library, ok := m.compiler.(libraryInterface); ok { if library.rlib() && !library.sysroot() { + if ctx.Host() { + // Hosts do not produce dylib variants, so there's only one std option. + return []string{"rlib-std"} + } return []string{"rlib-std", "dylib-std"} } } diff --git a/rust/library_test.go b/rust/library_test.go index 6cc4f2517..8d1739623 100644 --- a/rust/library_test.go +++ b/rust/library_test.go @@ -25,27 +25,27 @@ import ( func TestLibraryVariants(t *testing.T) { ctx := testRust(t, ` - rust_library_host { + rust_library { name: "libfoo", srcs: ["foo.rs"], crate_name: "foo", } - rust_ffi_host { + rust_ffi { name: "libfoo.ffi", srcs: ["foo.rs"], crate_name: "foo" } - rust_ffi_host_static { + rust_ffi_static { name: "libfoo.ffi_static", srcs: ["foo.rs"], crate_name: "foo" }`) // Test all variants are being built. - libfooRlib := ctx.ModuleForTests(t, "libfoo", "linux_glibc_x86_64_rlib_rlib-std").Rule("rustc") - libfooDylib := ctx.ModuleForTests(t, "libfoo", "linux_glibc_x86_64_dylib").Rule("rustc") - libfooFFIRlib := ctx.ModuleForTests(t, "libfoo.ffi", "linux_glibc_x86_64_rlib_rlib-std").Rule("rustc") - libfooShared := ctx.ModuleForTests(t, "libfoo.ffi", "linux_glibc_x86_64_shared").Rule("rustc") + libfooRlib := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_rlib_rlib-std").Rule("rustc") + libfooDylib := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_dylib").Rule("rustc") + libfooFFIRlib := ctx.ModuleForTests(t, "libfoo.ffi", "android_arm64_armv8-a_rlib_rlib-std").Rule("rustc") + libfooShared := ctx.ModuleForTests(t, "libfoo.ffi", "android_arm64_armv8-a_shared").Rule("rustc") rlibCrateType := "rlib" dylibCrateType := "dylib" @@ -76,13 +76,13 @@ func TestLibraryVariants(t *testing.T) { // Test that dylibs are not statically linking the standard library. func TestDylibPreferDynamic(t *testing.T) { ctx := testRust(t, ` - rust_library_host_dylib { + rust_library_dylib { name: "libfoo", srcs: ["foo.rs"], crate_name: "foo", }`) - libfooDylib := ctx.ModuleForTests(t, "libfoo", "linux_glibc_x86_64_dylib").Rule("rustc") + libfooDylib := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_dylib").Rule("rustc") if !strings.Contains(libfooDylib.Args["rustcFlags"], "prefer-dynamic") { t.Errorf("missing prefer-dynamic flag for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"]) @@ -247,17 +247,17 @@ func TestNativeDependencyOfRlib(t *testing.T) { func TestAutoDeps(t *testing.T) { ctx := testRust(t, ` - rust_library_host { + rust_library { name: "libbar", srcs: ["bar.rs"], crate_name: "bar", } - rust_library_host_rlib { + rust_library_rlib { name: "librlib_only", srcs: ["bar.rs"], crate_name: "rlib_only", } - rust_library_host { + rust_library { name: "libfoo", srcs: ["foo.rs"], crate_name: "foo", @@ -266,7 +266,7 @@ func TestAutoDeps(t *testing.T) { "librlib_only", ], } - rust_ffi_host { + rust_ffi { name: "libfoo.ffi", srcs: ["foo.rs"], crate_name: "foo", @@ -275,7 +275,7 @@ func TestAutoDeps(t *testing.T) { "librlib_only", ], } - rust_ffi_host_static { + rust_ffi_static { name: "libfoo.ffi.static", srcs: ["foo.rs"], crate_name: "foo", @@ -285,10 +285,10 @@ func TestAutoDeps(t *testing.T) { ], }`) - libfooRlib := ctx.ModuleForTests(t, "libfoo", "linux_glibc_x86_64_rlib_rlib-std") - libfooDylib := ctx.ModuleForTests(t, "libfoo", "linux_glibc_x86_64_dylib") - libfooFFIRlib := ctx.ModuleForTests(t, "libfoo.ffi", "linux_glibc_x86_64_rlib_rlib-std") - libfooShared := ctx.ModuleForTests(t, "libfoo.ffi", "linux_glibc_x86_64_shared") + libfooRlib := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_rlib_rlib-std") + libfooDylib := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_dylib") + libfooFFIRlib := ctx.ModuleForTests(t, "libfoo.ffi", "android_arm64_armv8-a_rlib_rlib-std") + libfooShared := ctx.ModuleForTests(t, "libfoo.ffi", "android_arm64_armv8-a_shared") for _, static := range []android.TestingModule{libfooRlib, libfooFFIRlib} { if !android.InList("libbar.rlib-std", static.Module().(*Module).Properties.AndroidMkRlibs) { -- cgit v1.2.3 From ef20f94d2f0a6336879a9b2c6b8602a737bde2ec Mon Sep 17 00:00:00 2001 From: Ivan Lozano Date: Wed, 2 Apr 2025 16:21:49 +0000 Subject: rust: Add support for emitting object files. The Windows runtime is written in Rust and expected to be included as a bare object file. This adds support for rust_object modules and a toolchain variant that will be used for the Windows CRT. Bug: 331798788 Test: m blueprint_tests Change-Id: I7b8b0ad9cfd7f8f1a2dbde37e25fda21c93950a8 --- rust/Android.bp | 3 ++ rust/androidmk.go | 6 +++ rust/builder.go | 20 ++++++-- rust/compiler.go | 8 +++ rust/object.go | 121 ++++++++++++++++++++++++++++++++++++++++++++++ rust/object_test.go | 35 ++++++++++++++ rust/rust.go | 5 +- rust/testing.go | 2 + rust/toolchain_library.go | 27 +++++++++-- rust/toolchain_object.go | 96 ++++++++++++++++++++++++++++++++++++ 10 files changed, 314 insertions(+), 9 deletions(-) create mode 100644 rust/object.go create mode 100644 rust/object_test.go create mode 100644 rust/toolchain_object.go diff --git a/rust/Android.bp b/rust/Android.bp index 54ba9d49c..d8f7b9d47 100644 --- a/rust/Android.bp +++ b/rust/Android.bp @@ -27,6 +27,7 @@ bootstrap_go_package { "fuzz.go", "image.go", "library.go", + "object.go", "prebuilt.go", "proc_macro.go", "project_json.go", @@ -38,6 +39,7 @@ bootstrap_go_package { "test.go", "testing.go", "toolchain_library.go", + "toolchain_object.go", ], testSrcs: [ "afdo_test.go", @@ -51,6 +53,7 @@ bootstrap_go_package { "fuzz_test.go", "image_test.go", "library_test.go", + "object_test.go", "proc_macro_test.go", "project_json_test.go", "protobuf_test.go", diff --git a/rust/androidmk.go b/rust/androidmk.go index 98946844d..bc6704986 100644 --- a/rust/androidmk.go +++ b/rust/androidmk.go @@ -95,6 +95,12 @@ func (binary *binaryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.Andr ret.Class = "EXECUTABLES" } +func (object *objectDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkEntries) { + ctx.SubAndroidMk(ret, object.baseCompiler) + + ret.Class = "STATIC_LIBRARIES" +} + func (test *testDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkEntries) { ctx.SubAndroidMk(ret, test.binaryDecorator) diff --git a/rust/builder.go b/rust/builder.go index 1b6a6c117..c71149cbd 100644 --- a/rust/builder.go +++ b/rust/builder.go @@ -32,7 +32,7 @@ var ( Command: "$envVars $rustcCmd " + "-C linker=${RustcLinkerCmd} " + "-C link-args=\"--android-clang-bin=${config.ClangCmd} ${crtBegin} ${earlyLinkFlags} ${linkFlags} ${crtEnd}\" " + - "--emit link -o $out --emit dep-info=$out.d.raw $in ${libFlags} $rustcFlags" + + "--emit ${emitType} -o $out --emit dep-info=$out.d.raw $in ${libFlags} $rustcFlags" + " && grep ^$out: $out.d.raw > $out.d", CommandDeps: []string{"$rustcCmd", "${RustcLinkerCmd}", "${config.ClangCmd}"}, // Rustc deps-info writes out make compatible dep files: https://github.com/rust-lang/rust/issues/7633 @@ -43,7 +43,7 @@ var ( Deps: blueprint.DepsGCC, Depfile: "$out.d", }, - "rustcFlags", "earlyLinkFlags", "linkFlags", "libFlags", "crtBegin", "crtEnd", "envVars") + "rustcFlags", "earlyLinkFlags", "linkFlags", "libFlags", "crtBegin", "crtEnd", "emitType", "envVars") _ = pctx.SourcePathVariable("rustdocCmd", "${config.RustBin}/rustdoc") rustdoc = pctx.AndroidStaticRule("rustdoc", @@ -134,6 +134,7 @@ type transformProperties struct { cargoOutDir android.OptionalPath synthetic bool crateType string + emitType string } // Populates a standard transformProperties struct for Rust modules @@ -154,6 +155,8 @@ func getTransformProperties(ctx ModuleContext, crateType string) transformProper // synthetic indicates whether this is an actual Rust module or not synthetic: false, + + emitType: module.compiler.emitType(), } } @@ -166,6 +169,13 @@ func TransformSrcToBinary(ctx ModuleContext, mainSrc android.Path, deps PathDeps return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "bin")) } +func TransformSrcToObject(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags, + outputFile android.WritablePath) buildOutput { + + // There's no "obj" crate-type since it doesn't get linked, so don't define one. + return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "")) +} + func TransformSrctoRlib(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags, outputFile android.WritablePath) buildOutput { return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "rlib")) @@ -199,6 +209,7 @@ func TransformRlibstoStaticlib(ctx android.ModuleContext, mainSrc android.Path, inRecovery: mod.InRecovery(), inRamdisk: mod.InRamdisk(), inVendorRamdisk: mod.InVendorRamdisk(), + emitType: "link", // crateType indicates what type of crate to build crateType: "staticlib", @@ -358,7 +369,9 @@ func transformSrctoCrate(ctx android.ModuleContext, main android.Path, deps Path // Collect rustc flags rustcFlags = append(rustcFlags, flags.GlobalRustFlags...) rustcFlags = append(rustcFlags, flags.RustFlags...) - rustcFlags = append(rustcFlags, "--crate-type="+t.crateType) + if t.crateType != "" { + rustcFlags = append(rustcFlags, "--crate-type="+t.crateType) + } if t.crateName != "" { rustcFlags = append(rustcFlags, "--crate-name="+t.crateName) } @@ -491,6 +504,7 @@ func transformSrctoCrate(ctx android.ModuleContext, main android.Path, deps Path "crtBegin": strings.Join(deps.CrtBegin.Strings(), " "), "crtEnd": strings.Join(deps.CrtEnd.Strings(), " "), "envVars": strings.Join(envVars, " "), + "emitType": t.emitType, }, }) diff --git a/rust/compiler.go b/rust/compiler.go index c3bc937da..9ca91d00d 100644 --- a/rust/compiler.go +++ b/rust/compiler.go @@ -80,6 +80,8 @@ type compiler interface { Aliases() map[string]string moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) + + emitType() string } func (compiler *baseCompiler) edition() string { @@ -108,6 +110,7 @@ type installLocation int const ( InstallInSystem installLocation = 0 InstallInData = iota + NoInstall = iota incorrectSourcesError = "srcs can only contain one path for a rust file and source providers prefixed by \":\"" genSubDir = "out/" @@ -692,3 +695,8 @@ func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) (android.Path, erro } return paths[srcIndex], nil } + +// Returns an emit type corresponding to the `--emit=` rustc flag. +func (compiler *baseCompiler) emitType() string { + return "link" +} diff --git a/rust/object.go b/rust/object.go new file mode 100644 index 000000000..89fc0ec17 --- /dev/null +++ b/rust/object.go @@ -0,0 +1,121 @@ +// Copyright 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 rust + +import ( + "android/soong/android" +) + +func init() { + // Rust objects are object files built with --emit=obj. + android.RegisterModuleType("rust_object", RustObjectFactory) + android.RegisterModuleType("rust_object_host", RustObjectHostFactory) +} + +type ObjectProperties struct { + // Indicates that this module is a CRT object. CRT objects will be split + // into a variant per-API level between min_sdk_version and current. + Crt *bool +} + +type objectDecorator struct { + *baseCompiler + Properties ObjectProperties +} + +type objectInterface interface { + crt() bool +} + +var _ objectInterface = (*objectDecorator)(nil) +var _ compiler = (*objectDecorator)(nil) + +// rust_object produces an object file. +func RustObjectFactory() android.Module { + module, _ := NewRustObject(android.HostAndDeviceSupported) + return module.Init() +} + +// rust_object_host produces an object file for host only. +func RustObjectHostFactory() android.Module { + module, _ := NewRustObject(android.HostSupported) + return module.Init() +} + +func NewRustObject(hod android.HostOrDeviceSupported) (*Module, *objectDecorator) { + module := newModule(hod, android.MultilibFirst) + + object := &objectDecorator{ + baseCompiler: NewBaseCompiler("", "", NoInstall), + } + + module.compiler = object + + return module, object +} + +func (object *objectDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags { + flags = object.baseCompiler.compilerFlags(ctx, flags) + return flags +} + +func (object *objectDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps { + deps = object.baseCompiler.compilerDeps(ctx, deps) + return deps +} + +func (object *objectDecorator) crt() bool { + return Bool(object.Properties.Crt) +} + +func (object *objectDecorator) compilerProps() []interface{} { + return append(object.baseCompiler.compilerProps(), + &object.Properties) +} + +func (object *objectDecorator) nativeCoverage() bool { + return true +} + +func (object *objectDecorator) emitType() string { + return "obj" +} + +func (object *objectDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput { + fileName := object.getStem(ctx) + ".o" + outputFile := android.PathForModuleOut(ctx, fileName) + ret := buildOutput{outputFile: outputFile} + crateRootPath := crateRootPath(ctx, object) + + flags.RustFlags = append(flags.RustFlags, deps.depFlags...) + object.baseCompiler.unstrippedOutputFile = outputFile + + ret.kytheFile = TransformSrcToObject(ctx, crateRootPath, deps, flags, outputFile).kytheFile + return ret +} + +func (object *objectDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep { + // rust_objects are not linked so selecting deps for them doesn't make sense. + panic("rust_objects should not declare rustlibs dependencies") +} + +func (object *objectDecorator) install(ctx ModuleContext) { + // Objects aren't installable, so do nothing. +} + +func (object *objectDecorator) everInstallable() bool { + // Objects aren't installable. + return false +} diff --git a/rust/object_test.go b/rust/object_test.go new file mode 100644 index 000000000..3c07ed1da --- /dev/null +++ b/rust/object_test.go @@ -0,0 +1,35 @@ +// Copyright 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 rust + +import ( + "strings" + "testing" +) + +// Smoke test rust_object_host and also check the emit type is correct. +func TestObjectEmitType(t *testing.T) { + ctx := testRust(t, ` + rust_object_host { + name: "foors", + srcs: ["foo.rs"], + crate_name: "foo", + }`) + + libfooRlib := ctx.ModuleForTests(t, "foors", "linux_glibc_x86_64").Rule("rustc") + if !strings.Contains(libfooRlib.Args["emitType"], "obj") { + t.Errorf("rust_object_host not emitting type obj") + } +} diff --git a/rust/rust.go b/rust/rust.go index 5941530a6..5bd162c27 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -664,6 +664,7 @@ func DefaultsFactory(props ...interface{}) android.Module { &BenchmarkProperties{}, &BindgenProperties{}, &BaseCompilerProperties{}, + &ObjectProperties{}, &BinaryCompilerProperties{}, &LibraryCompilerProperties{}, &ProcMacroCompilerProperties{}, @@ -861,7 +862,9 @@ func (mod *Module) Multilib() string { } func (mod *Module) IsCrt() bool { - // Rust does not currently provide any crt modules. + if obj, ok := mod.compiler.(objectInterface); ok { + return obj.crt() + } return false } diff --git a/rust/testing.go b/rust/testing.go index 2082b524e..42138f95c 100644 --- a/rust/testing.go +++ b/rust/testing.go @@ -190,6 +190,8 @@ func registerRequiredBuildComponentsForTest(ctx android.RegistrationContext) { ctx.RegisterModuleType("rust_library_host", RustLibraryHostFactory) ctx.RegisterModuleType("rust_library_host_dylib", RustLibraryDylibHostFactory) ctx.RegisterModuleType("rust_library_host_rlib", RustLibraryRlibHostFactory) + ctx.RegisterModuleType("rust_object", RustObjectFactory) + ctx.RegisterModuleType("rust_object_host", RustObjectHostFactory) ctx.RegisterModuleType("rust_fuzz", RustFuzzFactory) ctx.RegisterModuleType("rust_fuzz_host", RustFuzzHostFactory) ctx.RegisterModuleType("rust_ffi", RustFFIFactory) diff --git a/rust/toolchain_library.go b/rust/toolchain_library.go index 054104ccc..b174daf28 100644 --- a/rust/toolchain_library.go +++ b/rust/toolchain_library.go @@ -52,6 +52,16 @@ type toolchainLibraryDecorator struct { Properties toolchainLibraryProperties } +// toolchainCrateRoot implements toolchainCompiler. +func (t *toolchainLibraryDecorator) toolchainCrateRoot() *string { + return t.Properties.Toolchain_crate_root +} + +// toolchainSrcs implements toolchainCompiler. +func (t *toolchainLibraryDecorator) toolchainSrcs() []string { + return t.Properties.Toolchain_srcs +} + // rust_toolchain_library produces all rust variants. func rustToolchainLibraryFactory() android.Module { module, library := NewRustLibrary(android.HostAndDeviceSupported) @@ -87,12 +97,19 @@ func initToolchainLibrary(module *Module, library *libraryDecorator) android.Mod return module.Init() } +type toolchainCompiler interface { + toolchainCrateRoot() *string + toolchainSrcs() []string +} + +var _ toolchainCompiler = (*toolchainLibraryDecorator)(nil) + func rustSetToolchainSource(ctx android.LoadHookContext) { - if toolchainLib, ok := ctx.Module().(*Module).compiler.(*toolchainLibraryDecorator); ok { + if toolchainLib, ok := ctx.Module().(*Module).compiler.(toolchainCompiler); ok { prefix := filepath.Join("linux-x86", GetRustPrebuiltVersion(ctx)) - versionedCrateRoot := path.Join(prefix, android.String(toolchainLib.Properties.Toolchain_crate_root)) - versionedSrcs := make([]string, len(toolchainLib.Properties.Toolchain_srcs)) - for i, src := range toolchainLib.Properties.Toolchain_srcs { + versionedCrateRoot := path.Join(prefix, android.String(toolchainLib.toolchainCrateRoot())) + versionedSrcs := make([]string, len(toolchainLib.toolchainSrcs())) + for i, src := range toolchainLib.toolchainSrcs() { versionedSrcs[i] = path.Join(prefix, src) } @@ -105,7 +122,7 @@ func rustSetToolchainSource(ctx android.LoadHookContext) { p.Srcs = versionedSrcs ctx.AppendProperties(p) } else { - ctx.ModuleErrorf("Called rustSetToolchainSource on a non-Rust Module.") + ctx.ModuleErrorf("Called rustSetToolchainSource on a non-Toolchain Module.") } } diff --git a/rust/toolchain_object.go b/rust/toolchain_object.go new file mode 100644 index 000000000..ac16483a1 --- /dev/null +++ b/rust/toolchain_object.go @@ -0,0 +1,96 @@ +// +// 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 rust + +import ( + "android/soong/android" +) + +// This module is used to compile the rust toolchain objects +// When RUST_PREBUILTS_VERSION is set, the object will generated +// from the given Rust version. +func init() { + android.RegisterModuleType("rust_toolchain_object", + rustToolchainObjectFactory) + android.RegisterModuleType("rust_toolchain_object_host", + rustToolchainObjectHostFactory) +} + +type toolchainObjectProperties struct { + // path to the toolchain object crate root, relative to the top of the toolchain source + Toolchain_crate_root *string `android:"arch_variant"` + // path to the rest of the toolchain srcs, relative to the top of the toolchain source + Toolchain_srcs []string `android:"arch_variant"` +} + +type toolchainObjectDecorator struct { + *objectDecorator + Properties toolchainObjectProperties +} + +// toolchainCrateRoot implements toolchainCompiler. +func (t *toolchainObjectDecorator) toolchainCrateRoot() *string { + return t.Properties.Toolchain_crate_root +} + +// toolchainSrcs implements toolchainCompiler. +func (t *toolchainObjectDecorator) toolchainSrcs() []string { + return t.Properties.Toolchain_srcs +} + +// rust_toolchain_library produces all rust variants. +func rustToolchainObjectFactory() android.Module { + module, object := NewRustObject(android.HostAndDeviceSupported) + return initToolchainObject(module, object) +} + +// rust_toolchain_library produces all rust variants. +func rustToolchainObjectHostFactory() android.Module { + module, object := NewRustObject(android.HostSupported) + return initToolchainObject(module, object) +} + +func initToolchainObject(module *Module, object *objectDecorator) android.Module { + toolchainObject := &toolchainObjectDecorator{ + objectDecorator: object, + } + module.compiler = toolchainObject + module.AddProperties(&toolchainObject.Properties) + + android.AddLoadHook(module, rustSetToolchainSource) + + return module.Init() +} + +func (t *toolchainObjectDecorator) compilerProps() []interface{} { + return append(t.objectDecorator.compilerProps(), &t.Properties) +} + +func (t *toolchainObjectDecorator) crt() bool { + return t.objectDecorator.crt() +} + +func (t *toolchainObjectDecorator) install(ctx ModuleContext) { + // Objects aren't installable, so do nothing. +} + +func (t *toolchainObjectDecorator) everInstallable() bool { + // Objects aren't installable. + return false +} + +var _ toolchainCompiler = (*toolchainObjectDecorator)(nil) -- cgit v1.2.3 From 455edbeffaa3d125613ca1e0ac6b1820f9f42124 Mon Sep 17 00:00:00 2001 From: Karthik Rathlavath Date: Fri, 4 Apr 2025 17:52:59 +0530 Subject: converting SystemExtSepolicyPrebuiltApiDirs and ProductSepolicyPrebuiltApiDirs from string to list of strings. Bug: 406924614 Test: TH Change-Id: I9f6f9ab870ae3389901059878b33f8d3247e8f0b --- android/config.go | 10 +++++----- android/variable.go | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/android/config.go b/android/config.go index 71e051d96..90b5c43e9 100644 --- a/android/config.go +++ b/android/config.go @@ -2105,16 +2105,16 @@ func (c *deviceConfig) BoardSepolicyVers() string { return c.PlatformSepolicyVersion() } -func (c *deviceConfig) SystemExtSepolicyPrebuiltApiDir() string { - return String(c.config.productVariables.SystemExtSepolicyPrebuiltApiDir) +func (c *deviceConfig) SystemExtSepolicyPrebuiltApiDirs() []string { + return c.config.productVariables.SystemExtSepolicyPrebuiltApiDirs } -func (c *deviceConfig) ProductSepolicyPrebuiltApiDir() string { - return String(c.config.productVariables.ProductSepolicyPrebuiltApiDir) +func (c *deviceConfig) ProductSepolicyPrebuiltApiDirs() []string { + return c.config.productVariables.ProductSepolicyPrebuiltApiDirs } func (c *deviceConfig) IsPartnerTrebleSepolicyTestEnabled() bool { - return c.SystemExtSepolicyPrebuiltApiDir() != "" || c.ProductSepolicyPrebuiltApiDir() != "" + return len(c.SystemExtSepolicyPrebuiltApiDirs()) > 0 || len(c.ProductSepolicyPrebuiltApiDirs()) > 0 } func createDirsMap(previous map[string]bool, dirs []string) (map[string]bool, error) { diff --git a/android/variable.go b/android/variable.go index e1f667cf5..bbb96e845 100644 --- a/android/variable.go +++ b/android/variable.go @@ -396,8 +396,8 @@ type ProductVariables struct { BoardSepolicyVers *string `json:",omitempty"` PlatformSepolicyVersion *string `json:",omitempty"` - SystemExtSepolicyPrebuiltApiDir *string `json:",omitempty"` - ProductSepolicyPrebuiltApiDir *string `json:",omitempty"` + SystemExtSepolicyPrebuiltApiDirs []string `json:",omitempty"` + ProductSepolicyPrebuiltApiDirs []string `json:",omitempty"` PlatformSepolicyCompatVersions []string `json:",omitempty"` -- cgit v1.2.3 From c554f4e763fd988928898c2bbe5a678edae823e6 Mon Sep 17 00:00:00 2001 From: Inseob Kim Date: Mon, 7 Apr 2025 16:08:03 +0900 Subject: Use thumbprint based hash for generic modules The fingerprint contains target-specific extra information, so using thumbprint makes more sense if the filesystem module is generic. Bug: 407876468 Test: compare contents of virt apex Change-Id: I8a39318d183aaf234c897b64e6dfa18b9168791a --- filesystem/filesystem.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index d75a081dd..31ab4deaa 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -1306,7 +1306,11 @@ func (f *filesystem) getAvbAddHashtreeFooterArgs(ctx android.ModuleContext) stri // We're not going to add BuildFingerPrintFile as a dep. If it changed, it's likely because // the build number changed, and we don't want to trigger rebuilds solely based on the build // number. - avb_add_hashtree_footer_args += fmt.Sprintf(" --prop com.android.build.%s.fingerprint:{CONTENTS_OF:%s}", f.partitionName(), ctx.Config().BuildFingerprintFile(ctx)) + if ctx.Module().UseGenericConfig() { + avb_add_hashtree_footer_args += fmt.Sprintf(" --prop com.android.build.%s.fingerprint:{CONTENTS_OF:%s}", f.partitionName(), ctx.Config().BuildThumbprintFile(ctx)) + } else { + avb_add_hashtree_footer_args += fmt.Sprintf(" --prop com.android.build.%s.fingerprint:{CONTENTS_OF:%s}", f.partitionName(), ctx.Config().BuildFingerprintFile(ctx)) + } if f.properties.Security_patch != nil && proptools.String(f.properties.Security_patch) != "" { avb_add_hashtree_footer_args += fmt.Sprintf(" --prop com.android.build.%s.security_patch:%s", f.partitionName(), proptools.String(f.properties.Security_patch)) } -- cgit v1.2.3 From 5510f3c5433ca14c8c14862c15f6caabeef7daca Mon Sep 17 00:00:00 2001 From: Jared Duke Date: Mon, 7 Apr 2025 09:46:36 -0700 Subject: Revert "Use D8 release mode when PRODUCT_MINIMIZE_JAVA_DEBUG_INFO is set" This reverts commit 5b24c29f2903ed33753b4a11464575d0c5329fd1. Reason for revert: Breaks ART CTS tests that rely on debug info Change-Id: I9a387371f7b618e56b12e5119e22aa6fedcda4ab --- java/dex.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/java/dex.go b/java/dex.go index 13dcd86ad..e3058e9bf 100644 --- a/java/dex.go +++ b/java/dex.go @@ -362,8 +362,6 @@ func (d *dexer) dexCommonFlags(ctx android.ModuleContext, flags = append(flags, "--release") } else if ctx.Config().Eng() { flags = append(flags, "--debug") - } else if ctx.Config().MinimizeJavaDebugInfo() { - flags = append(flags, "--release") } else if !d.effectiveOptimizeEnabled(ctx) && d.dexProperties.Optimize.EnabledByDefault { // D8 uses --debug by default, whereas R8 uses --release by default. // For targets that default to R8 usage (e.g., apps), but override this default, we still -- cgit v1.2.3 From 47740001b1e3d42a851c52414e1bb1601ab57712 Mon Sep 17 00:00:00 2001 From: Taylor Santiago Date: Mon, 7 Apr 2025 14:04:12 -0700 Subject: Mount-details lookup needs to use pre-sandbox path. Bug: 409077588 Change-Id: I0b2b284d6211b814c7b2887a465b87074a433ac7 --- ui/build/sandbox_linux.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ui/build/sandbox_linux.go b/ui/build/sandbox_linux.go index 8da0e3f2e..51cbc9382 100644 --- a/ui/build/sandbox_linux.go +++ b/ui/build/sandbox_linux.go @@ -218,7 +218,8 @@ func (c *Cmd) workDir() string { return abfsSrcDir } -func abfsCacheFromMount(mntDir string) (string, error) { +func abfsCacheFromMount() (string, error) { + wd, _ := os.Getwd() type Config struct { CacheDir string } @@ -226,7 +227,7 @@ func abfsCacheFromMount(mntDir string) (string, error) { Config Config } var m MountDetails - file, err := os.Open(filepath.Join(mntDir, ".repo/mount-details")) + file, err := os.Open(filepath.Join(wd, ".repo/mount-details")) if err != nil { return "", err } @@ -299,7 +300,7 @@ func (c *Cmd) wrapSandbox() { "-q", ) if c.config.UseABFS() { - cacheDir, err := abfsCacheFromMount(wd) + cacheDir, err := abfsCacheFromMount() if err != nil { c.ctx.Fatalln(err) } -- cgit v1.2.3 From 825009c77a8f130374294f7a0d1e93b2fdf3b8df Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Wed, 2 Apr 2025 15:30:32 -0700 Subject: Introduce soong only diff test The script runs soong only build and soong + make build, and compares the SHA256 checksum values within the target_files.zip files of each builds. Test: build/soong/scripts/soong_only_diff_test.py aosp_cf_x86_64_phone Bug: 406344416 Change-Id: Id502a8686a215cbe1a9a039da7d86141655fc6eb --- scripts/soong_only_diff_test.py | 207 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100755 scripts/soong_only_diff_test.py diff --git a/scripts/soong_only_diff_test.py b/scripts/soong_only_diff_test.py new file mode 100755 index 000000000..b63ce698d --- /dev/null +++ b/scripts/soong_only_diff_test.py @@ -0,0 +1,207 @@ +#!/usr/bin/env python3 +# +# Copyright 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. +# + +import argparse +import os +import struct +import subprocess +import sys +import zipfile + +from ninja_determinism_test import Product, get_top + +def run_build_target_files_zip(product: Product, soong_only: bool) -> bool: + """Runs a build and returns if it succeeded or not.""" + soong_only_arg = '--no-soong-only' + if soong_only: + soong_only_arg = '--soong-only' + + with open(os.path.join(os.getenv('OUT_DIR', 'out'), 'build.log'), 'wb') as f: + result = subprocess.run([ + 'build/soong/soong_ui.bash', + '--make-mode', + 'USE_RBE=true', + 'BUILD_DATETIME=1', + 'USE_FIXED_TIMESTAMP_IMG_FILES=true', + f'TARGET_PRODUCT={product.product}', + f'TARGET_RELEASE={product.release}', + f'TARGET_BUILD_VARIANT={product.variant}', + 'target-files-package', + 'dist', + soong_only_arg, + ], stdout=f, stderr=subprocess.STDOUT, env=os.environ) + return result.returncode == 0 + +# These values are defined in build/soong/zip/zip.go +SHA_256_HEADER_ID = 0x4967 +SHA_256_HEADER_SIGNATURE = 0x9514 + +def get_local_file_sha256_fields(zip_filepath: os.PathLike) -> dict[str, bytes]: + if not os.path.exists(zip_filepath): + print(f"Error: File not found at {zip_filepath}", file=sys.stderr) + return None + + sha256_checksums: dict[str, bytes] = {} + + with zipfile.ZipFile(zip_filepath, 'r') as zip_ref: + infolist = zip_ref.infolist() + + for member_info in infolist: + # Skip if the entry is a directory or does not contain the sha256 value, which + # is included in the extra field. + if member_info.is_dir() or len(member_info.extra) == 0: + continue + + local_extra_data = member_info.extra + + i = 0 + found_sha_in_file = None + while i + 4 <= len(local_extra_data): # Need at least 4 (header ID + data size) + block_header_id, block_data_size = struct.unpack('= 2: + data_bytes = local_extra_data[i+4 : current_block_end] + + # Check internal signature + internal_sig = struct.unpack(' str | None: + tag_file_path = os.path.join(os.getenv('OUT_DIR', 'out'), 'file_name_tag.txt') + build_id = None + + with open(tag_file_path, 'r', encoding='utf-8') as f: + build_id = f.read().strip() + + return build_id + +SHA_DIFF_ALLOWLIST = { + "IMAGES/init_boot.img", + "IMAGES/odm_dlkm.img", + "IMAGES/odm.img", + "IMAGES/product.img", + "IMAGES/system_dlkm.img", + "IMAGES/system_ext.img", + "IMAGES/system.img", + "IMAGES/system.map", + "IMAGES/system_other.img", + "IMAGES/userdata.img", + "IMAGES/vbmeta.img", + "IMAGES/vbmeta_system_dlkm.img", + "IMAGES/vbmeta_system.img", + "IMAGES/vbmeta_vendor_dlkm.img", + "IMAGES/vendor_boot.img", + "IMAGES/vendor_dlkm.img", + "IMAGES/vendor.img", + "IMAGES/vendor.map", + "META/care_map.pb", + "META/file_contexts.bin", + "META/kernel_version.txt", + "META/misc_info.txt", + "META/vbmeta_digest.txt", + "ODM_DLKM/etc/NOTICE.xml.gz", + "ODM/etc/NOTICE.xml.gz", + "PRODUCT/etc/NOTICE.xml.gz", + "SYSTEM_DLKM/etc/NOTICE.xml.gz", + "SYSTEM/etc/NOTICE.xml.gz", + "SYSTEM_EXT/etc/NOTICE.xml.gz", + "VENDOR_DLKM/etc/NOTICE.xml.gz", + "VENDOR/etc/NOTICE.xml.gz", +} + +def compare_sha_maps(soong_only_map: dict[str, bytes], soong_plus_make_map: dict[str, bytes]) -> bool: + """Compares two sha maps and reports any missing or different entries.""" + + all_keys = list(soong_only_map.keys() | soong_plus_make_map.keys()) + all_identical = True + for key in all_keys: + if key in SHA_DIFF_ALLOWLIST: + continue + if key not in soong_only_map: + print(f'{key} not found in soong only build target_files.zip', file=sys.stderr) + all_identical = False + if key not in soong_plus_make_map: + print(f'{key} not found in soong plus make build target_files.zip', file=sys.stderr) + all_identical = False + if soong_only_map[key] != soong_plus_make_map[key]: + print(f'{key} sha value differ between soong only build and soong plus make build', file=sys.stderr) + all_identical = False + + return all_identical + +def get_zip_sha_map(product: Product, soong_only: bool) -> dict[str, bytes]: + """Runs the build and returns the map of entries to its SHA256 values of target_files.zip.""" + + out_dir = os.getenv('OUT_DIR', 'out') + + build_type = "soong only" if soong_only else "soong plus make" + + build_success = run_build_target_files_zip(product, soong_only) + if not build_success: + with open(os.path.join(out_dir, 'build.log'), 'r') as f: + print(f.read(), file=sys.stderr) + sys.exit(f'{build_type} build failed') + + build_id = find_build_id() + target_files_zip = os.path.join(out_dir, "dist", f'{product.product}-target_files-{build_id}.zip') + zip_sha_map = get_local_file_sha256_fields(target_files_zip) + if zip_sha_map is None: + sys.exit("Could not construct sha map for target_files.zip entries for soong only build") + + return zip_sha_map + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument("product", help="target product name") + return parser.parse_args() + +def main(): + os.chdir(get_top()) + + args = parse_args() + + product = Product( + args.product, + 'trunk_staging', + 'userdebug', + ) + + soong_only_zip_sha_map = get_zip_sha_map(product, True) + soong_plus_make_zip_sha_map = get_zip_sha_map(product, False) + + if not compare_sha_maps(soong_only_zip_sha_map, soong_plus_make_zip_sha_map): + sys.exit("target_files.zip differ between soong only build and soong plus make build") + + print("target_files.zip are identical between soong only build and soong plus make build") + +if __name__ == "__main__": + main() -- cgit v1.2.3 From 6fc14b91764bfbf24d7fd1d631a7a721a9cf7f10 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Tue, 8 Apr 2025 07:31:08 +0000 Subject: Fix typo in soong_config_modules comments Quick fix replacing 'sonng' with 'soong' in one of the comments. Bug: None Test: presubmit Flag: EXEMPT comments only Change-Id: I2e77d0128895584879007c96d4260bd282d095c9 --- android/soong_config_modules.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/soong_config_modules.go b/android/soong_config_modules.go index a61c9d33d..e8b271abc 100644 --- a/android/soong_config_modules.go +++ b/android/soong_config_modules.go @@ -139,7 +139,7 @@ type soongConfigModuleTypeImportProperties struct { // } // // If an acme BoardConfig.mk file contained: -// $(call add_sonng_config_namespace, acme) +// $(call add_soong_config_namespace, acme) // $(call add_soong_config_var_value, acme, board, soc_a) // $(call add_soong_config_var_value, acme, feature, true) // $(call add_soong_config_var_value, acme, width, 200) -- cgit v1.2.3 From e6d8da9697d70a847f7067b86a556ce3f9306f1a Mon Sep 17 00:00:00 2001 From: Ivan Lozano Date: Wed, 2 Apr 2025 17:03:08 +0000 Subject: rust: Clarify handling of host static libs Some host platforms don't support static executables. Make sure we're handling these correctly for Darwin in particular, but also eventually Windows binaries. Bug: 331798788 Test: m blueprint_tests Change-Id: I76b95726c751cd3a3511845a64a183581952c1bd --- rust/binary.go | 28 ++++++++++++++++++++++++---- rust/compiler.go | 8 ++++++++ rust/config/toolchain.go | 10 ++++++++++ rust/config/x86_linux_host.go | 16 ++++++++++++++++ rust/object.go | 4 ++++ rust/rust.go | 3 +++ 6 files changed, 65 insertions(+), 4 deletions(-) diff --git a/rust/binary.go b/rust/binary.go index 5a03d91c2..4a4fb6fb8 100644 --- a/rust/binary.go +++ b/rust/binary.go @@ -16,6 +16,8 @@ package rust import ( "android/soong/android" + + "github.com/google/blueprint/proptools" ) func init() { @@ -69,6 +71,24 @@ func NewRustBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator return module, binary } +func (binary *binaryDecorator) begin(ctx BaseModuleContext) { + binary.baseCompiler.begin(ctx) + + if ctx.Os().Linux() && ctx.Host() && ctx.toolchain().Musl() { + // Unless explicitly specified otherwise, host static binaries are built statically + // if HostStaticBinaries is true for the product configuration. + // In Rust however this is only supported for musl targets. + if binary.Properties.Static_executable == nil && ctx.Config().HostStaticBinaries() { + binary.Properties.Static_executable = proptools.BoolPtr(true) + } + } + + if ctx.Darwin() || (ctx.Os().Linux() && ctx.Host() && ctx.toolchain().Glibc()) { + // Static executables are not supported on Darwin + binary.Properties.Static_executable = nil + } +} + func (binary *binaryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags { flags = binary.baseCompiler.compilerFlags(ctx, flags) @@ -79,11 +99,11 @@ func (binary *binaryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Fla "-Wl,--gc-sections", "-Wl,-z,nocopyreloc", "-Wl,--no-undefined-version") + } - if Bool(binary.Properties.Static_executable) { - flags.LinkFlags = append(flags.LinkFlags, "-static") - flags.RustFlags = append(flags.RustFlags, "-C relocation-model=static") - } + if Bool(binary.Properties.Static_executable) { + flags.LinkFlags = append(flags.LinkFlags, "-static") + flags.RustFlags = append(flags.RustFlags, "-C relocation-model=static") } return flags diff --git a/rust/compiler.go b/rust/compiler.go index 9ca91d00d..d5ad4e733 100644 --- a/rust/compiler.go +++ b/rust/compiler.go @@ -48,6 +48,7 @@ type compiler interface { features(ctx android.ConfigurableEvaluatorContext, module *Module) []string rustdoc(ctx ModuleContext, flags Flags, deps PathDeps) android.OptionalPath Thinlto() bool + begin(ctx BaseModuleContext) // Output directory in which source-generated code from dependencies is // copied. This is equivalent to Cargo's OUT_DIR variable. @@ -282,6 +283,8 @@ type baseCompiler struct { cachedCrateRootError error } +func (compiler *baseCompiler) begin(ctx BaseModuleContext) {} + func (compiler *baseCompiler) Disabled() bool { return false } @@ -356,6 +359,7 @@ func (compiler *baseCompiler) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON * } var _ compiler = (*baseCompiler)(nil) +var _ autoDeppable = (*baseCompiler)(nil) func (compiler *baseCompiler) inData() bool { return compiler.location == InstallInData @@ -700,3 +704,7 @@ func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) (android.Path, erro func (compiler *baseCompiler) emitType() string { return "link" } + +func (compiler *baseCompiler) autoDep(ctx android.BottomUpMutatorContext) autoDep { + panic("baseCompiler does not implement autoDep()") +} diff --git a/rust/config/toolchain.go b/rust/config/toolchain.go index 9c9d5724a..3b3923008 100644 --- a/rust/config/toolchain.go +++ b/rust/config/toolchain.go @@ -34,6 +34,8 @@ type Toolchain interface { Supported() bool Bionic() bool + Musl() bool + Glibc() bool LibclangRuntimeLibraryArch() string } @@ -61,6 +63,14 @@ func (toolchainBase) Bionic() bool { return true } +func (toolchainBase) Musl() bool { + return false +} + +func (toolchainBase) Glibc() bool { + return false +} + type toolchain64Bit struct { toolchainBase } diff --git a/rust/config/x86_linux_host.go b/rust/config/x86_linux_host.go index 4d7c42219..512b0430d 100644 --- a/rust/config/x86_linux_host.go +++ b/rust/config/x86_linux_host.go @@ -105,6 +105,10 @@ func (t *toolchainLinuxX8664) RustTriple() string { return "x86_64-unknown-linux-gnu" } +func (t *toolchainLinuxGlibcX8664) Glibc() bool { + return true +} + func (t *toolchainLinuxGlibcX8664) ToolchainLinkFlags() string { return t.toolchainLinuxX8664.ToolchainLinkFlags() + " " + "${config.LinuxGlibcToolchainLinkFlags}" } @@ -135,6 +139,10 @@ func linuxMuslX8664ToolchainFactory(arch android.Arch) Toolchain { return toolchainLinuxMuslX8664Singleton } +func (t *toolchainLinuxMuslX8664) Musl() bool { + return true +} + // Base 32-bit linux rust toolchain type toolchainLinuxX86 struct { toolchain32Bit @@ -180,6 +188,10 @@ func (t *toolchainLinuxGlibcX86) RustTriple() string { return "i686-unknown-linux-gnu" } +func (t *toolchainLinuxGlibcX86) Glibc() bool { + return true +} + func (t *toolchainLinuxGlibcX86) ToolchainLinkFlags() string { return t.toolchainLinuxX86.ToolchainLinkFlags() + " " + "${config.LinuxGlibcToolchainLinkFlags}" } @@ -206,6 +218,10 @@ func (t *toolchainLinuxMuslX86) ToolchainRustFlags() string { return t.toolchainLinuxX86.ToolchainRustFlags() + " " + "${config.LinuxMuslToolchainRustFlags}" } +func (t *toolchainLinuxMuslX86) Musl() bool { + return true +} + func linuxMuslX86ToolchainFactory(arch android.Arch) Toolchain { return toolchainLinuxMuslX86Singleton } diff --git a/rust/object.go b/rust/object.go index 89fc0ec17..2334988ca 100644 --- a/rust/object.go +++ b/rust/object.go @@ -66,6 +66,10 @@ func NewRustObject(hod android.HostOrDeviceSupported) (*Module, *objectDecorator return module, object } +func (object *objectDecorator) begin(ctx BaseModuleContext) { + object.baseCompiler.begin(ctx) +} + func (object *objectDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags { flags = object.baseCompiler.compilerFlags(ctx, flags) return flags diff --git a/rust/rust.go b/rust/rust.go index 5bd162c27..559f96cc8 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -1457,6 +1457,9 @@ func (mod *Module) begin(ctx BaseModuleContext) { if mod.sanitize != nil { mod.sanitize.begin(ctx) } + if mod.compiler != nil { + mod.compiler.begin(ctx) + } if mod.UseSdk() && mod.IsSdkVariant() { sdkVersion := "" -- cgit v1.2.3 From 2794015a352d057afcd93c76a1e3af3b5b72151a Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Tue, 8 Apr 2025 17:22:44 +0000 Subject: Skip phony target generation for Androidmk hidden modules Prior to ag/32854612, the renamed module name was used as the phony name. In the case of apache-xml, we had two phony targets ``` phony apache-xml # build source phony prebuilt_apache-xml # build prebuilts ``` The latter is intentionally unbuildable. It checks in a corrupt file so that rdeps that do not inadvertently compile against the implementation library from prebuilts/module_sdk, which is not available (module sdk contains stubs). After ag/32854612, the phony changed to ``` phony apache-xml # build source and prebuilts ``` This CL still uses BaseModuleName (name as it appears in Android.bp), but does so only if the module is exported to make. This makes it closer to the make implementation Bug: 409225101 Test: lunch aosp_cf_x86_64_phone-trunk_staging-userdebug Test: aninja -t path apache-xml out/soong/.intermediates/prebuilts/module_sdk/art/current/sdk/prebuilt_apache-xml/android_common_prebuilt_com.android.art/local-combined/apache-xml.jar (path no longer exists) Change-Id: I267b07505cc4a0b70f70c635f34f646dc3b40afd --- android/module.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/android/module.go b/android/module.go index a57b762ac..8387d591f 100644 --- a/android/module.go +++ b/android/module.go @@ -1709,7 +1709,7 @@ func (m *ModuleBase) generateModuleTarget(ctx *moduleContext, testSuiteInstalls var deps Paths var info ModuleBuildTargetsInfo - if len(ctx.installFiles) > 0 { + if len(ctx.installFiles) > 0 && !shouldSkipAndroidMkProcessing(ctx, m) { name := namespacePrefix + ctx.module.base().BaseModuleName() + "-install" installFiles := ctx.installFiles.Paths() ctx.Phony(name, installFiles...) @@ -1727,7 +1727,7 @@ func (m *ModuleBase) generateModuleTarget(ctx *moduleContext, testSuiteInstalls deps = append(deps, ctx.checkbuildTarget) } - if outputFiles, err := outputFilesForModule(ctx, ctx.Module(), ""); err == nil && len(outputFiles) > 0 { + if outputFiles, err := outputFilesForModule(ctx, ctx.Module(), ""); err == nil && len(outputFiles) > 0 && !shouldSkipAndroidMkProcessing(ctx, m) { name := namespacePrefix + ctx.module.base().BaseModuleName() + "-outputs" ctx.Phony(name, outputFiles...) deps = append(deps, outputFiles...) -- cgit v1.2.3 From c93979f60d79f51d8432d50f5f5eac2ff347fe91 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Tue, 8 Apr 2025 11:28:41 -0700 Subject: Introduce android.ModuleOrProxy android.ModuleOrProxy is just a wrapper around blueprint.ModuleOrProxy, but improves ergonimics by allowing replacing android.Module with android.ModuleOrProxy and not having to remember to use blueprint.ModuleOrProxy instead. Test: all soong tests pass Change-Id: Ief9a56ecec1391469b8220eeb36311e3155a26a3 --- android/aconfig_providers.go | 2 +- android/androidmk.go | 10 +++++----- android/apex.go | 4 ++-- android/base_module_context.go | 44 ++++++++++++++++++++--------------------- android/container.go | 2 +- android/early_module_context.go | 4 ++-- android/makevars.go | 18 ++++++++--------- android/module.go | 12 +++++------ android/module_proxy.go | 4 ++++ android/module_test.go | 4 +--- android/paths.go | 10 +++++----- android/provider.go | 12 +++++------ android/singleton.go | 38 +++++++++++++++++++---------------- android/testing.go | 26 +++++++++++++++++++----- cc/cc.go | 2 +- cc/library_sdk_member.go | 2 +- ci_tests/ci_test_package_zip.go | 2 +- fuzz/fuzz_common.go | 4 ++-- java/bootclasspath_fragment.go | 2 +- 19 files changed, 112 insertions(+), 90 deletions(-) diff --git a/android/aconfig_providers.go b/android/aconfig_providers.go index 91c39a462..758fe008c 100644 --- a/android/aconfig_providers.go +++ b/android/aconfig_providers.go @@ -83,7 +83,7 @@ type aconfigPropagatingDeclarationsInfo struct { var AconfigPropagatingProviderKey = blueprint.NewProvider[aconfigPropagatingDeclarationsInfo]() -func VerifyAconfigBuildMode(ctx ModuleContext, container string, module blueprint.ModuleOrProxy, asError bool) { +func VerifyAconfigBuildMode(ctx ModuleContext, container string, module ModuleOrProxy, asError bool) { if dep, ok := OtherModuleProvider(ctx, module, AconfigPropagatingProviderKey); ok { for k, v := range dep.ModeInfos { msg := fmt.Sprintf("%s/%s depends on %s/%s/%s across containers\n", diff --git a/android/androidmk.go b/android/androidmk.go index 423f149d9..f6d0dc390 100644 --- a/android/androidmk.go +++ b/android/androidmk.go @@ -501,12 +501,12 @@ func (a *AndroidMkEntries) GetDistForGoals(mod Module) []string { // fillInEntries goes through the common variable processing and calls the extra data funcs to // generate and fill in AndroidMkEntries's in-struct data, ready to be flushed to a file. type fillInEntriesContext interface { - ModuleDir(module blueprint.ModuleOrProxy) string - ModuleSubDir(module blueprint.ModuleOrProxy) string + ModuleDir(module ModuleOrProxy) string + ModuleSubDir(module ModuleOrProxy) string Config() Config - otherModuleProvider(module blueprint.ModuleOrProxy, provider blueprint.AnyProviderKey) (any, bool) - ModuleType(module blueprint.ModuleOrProxy) string - OtherModulePropertyErrorf(module blueprint.ModuleOrProxy, property string, fmt string, args ...interface{}) + otherModuleProvider(module ModuleOrProxy, provider blueprint.AnyProviderKey) (any, bool) + ModuleType(module ModuleOrProxy) string + OtherModulePropertyErrorf(module ModuleOrProxy, property string, fmt string, args ...interface{}) HasMutatorFinished(mutatorName string) bool } diff --git a/android/apex.go b/android/apex.go index 598809308..1d2911ed0 100644 --- a/android/apex.go +++ b/android/apex.go @@ -188,7 +188,7 @@ type DepInSameApexInfo struct { var DepInSameApexInfoProvider = blueprint.NewMutatorProvider[DepInSameApexInfo]("apex_unique") -func IsDepInSameApex(ctx BaseModuleContext, module, dep blueprint.ModuleOrProxy) bool { +func IsDepInSameApex(ctx BaseModuleContext, module, dep ModuleOrProxy) bool { depTag := ctx.OtherModuleDependencyTag(dep) if _, ok := depTag.(ExcludeFromApexContentsTag); ok { // The tag defines a dependency that never requires the child module to be part of the same @@ -765,7 +765,7 @@ type MinSdkVersionFromValueContext interface { // error if not. No default implementation is provided for this method. A module type // implementing this interface should provide an implementation. A module supports an sdk // version when the module's min_sdk_version is equal to or less than the given sdk version. -func ShouldSupportSdkVersion(ctx BaseModuleContext, module blueprint.ModuleOrProxy, sdkVersion ApiLevel) error { +func ShouldSupportSdkVersion(ctx BaseModuleContext, module ModuleOrProxy, sdkVersion ApiLevel) error { info, ok := OtherModuleProvider(ctx, module, CommonModuleInfoProvider) if !ok || info.MinSdkVersionSupported.IsNone() { return fmt.Errorf("min_sdk_version is not specified") diff --git a/android/base_module_context.go b/android/base_module_context.go index 5929f83cb..244b13f79 100644 --- a/android/base_module_context.go +++ b/android/base_module_context.go @@ -36,23 +36,23 @@ type BaseModuleContext interface { // OtherModuleName returns the name of another Module. See BaseModuleContext.ModuleName for more information. // It is intended for use inside the visit functions of Visit* and WalkDeps. - OtherModuleName(m blueprint.ModuleOrProxy) string + OtherModuleName(m ModuleOrProxy) string // OtherModuleDir returns the directory of another Module. See BaseModuleContext.ModuleDir for more information. // It is intended for use inside the visit functions of Visit* and WalkDeps. - OtherModuleDir(m blueprint.ModuleOrProxy) string + OtherModuleDir(m ModuleOrProxy) string // OtherModuleErrorf reports an error on another Module. See BaseModuleContext.ModuleErrorf for more information. // It is intended for use inside the visit functions of Visit* and WalkDeps. - OtherModuleErrorf(m blueprint.ModuleOrProxy, fmt string, args ...interface{}) + OtherModuleErrorf(m ModuleOrProxy, fmt string, args ...interface{}) // OtherModuleDependencyTag returns the dependency tag used to depend on a module, or nil if there is no dependency // on the module. When called inside a Visit* method with current module being visited, and there are multiple // dependencies on the module being visited, it returns the dependency tag used for the current dependency. - OtherModuleDependencyTag(m blueprint.ModuleOrProxy) blueprint.DependencyTag + OtherModuleDependencyTag(m ModuleOrProxy) blueprint.DependencyTag // OtherModuleSubDir returns the string representing the variations of a module. - OtherModuleSubDir(m blueprint.ModuleOrProxy) string + OtherModuleSubDir(m ModuleOrProxy) 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. @@ -80,23 +80,23 @@ type BaseModuleContext interface { // OtherModuleType returns the type of another Module. See BaseModuleContext.ModuleType for more information. // It is intended for use inside the visit functions of Visit* and WalkDeps. - OtherModuleType(m blueprint.ModuleOrProxy) string + OtherModuleType(m ModuleOrProxy) string // otherModuleProvider returns the value for a provider for the given module. If the value is // not set it returns nil and false. The value returned may be a deep copy of the value originally // passed to SetProvider. // // This method shouldn't be used directly, prefer the type-safe android.OtherModuleProvider instead. - otherModuleProvider(m blueprint.ModuleOrProxy, provider blueprint.AnyProviderKey) (any, bool) + otherModuleProvider(m ModuleOrProxy, 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.ModuleOrProxy, provider blueprint.AnyProviderKey) bool + OtherModuleHasProvider(m ModuleOrProxy, 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.ModuleOrProxy) bool + OtherModuleIsAutoGenerated(m ModuleOrProxy) bool // Provider returns the value for a provider for the current module. If the value is // not set it returns nil and false. It panics if called before the appropriate @@ -211,7 +211,7 @@ type BaseModuleContext interface { // order by mutators and GenerateBuildActions, so the data created by the current mutator can be read from all // variants using VisitAllModuleVariants if the current module is the last one. This can be used to perform // singleton actions that are only done once for all variants of a module. - IsFinalModule(module blueprint.ModuleOrProxy) bool + IsFinalModule(module ModuleOrProxy) bool // VisitAllModuleVariants calls visit for each variant of the current module. Variants of a module are always // visited in order by mutators and GenerateBuildActions, so the data created by the current mutator can be read @@ -263,23 +263,23 @@ type baseModuleContext struct { } -func EqualModules(m1, m2 blueprint.ModuleOrProxy) bool { +func EqualModules(m1, m2 ModuleOrProxy) bool { return blueprint.EqualModules(m1, m2) } -func (b *baseModuleContext) OtherModuleName(m blueprint.ModuleOrProxy) string { +func (b *baseModuleContext) OtherModuleName(m ModuleOrProxy) string { return b.bp.OtherModuleName(m) } -func (b *baseModuleContext) OtherModuleDir(m blueprint.ModuleOrProxy) string { +func (b *baseModuleContext) OtherModuleDir(m ModuleOrProxy) string { return b.bp.OtherModuleDir(m) } -func (b *baseModuleContext) OtherModuleErrorf(m blueprint.ModuleOrProxy, fmt string, args ...interface{}) { +func (b *baseModuleContext) OtherModuleErrorf(m ModuleOrProxy, fmt string, args ...interface{}) { b.bp.OtherModuleErrorf(m, fmt, args...) } -func (b *baseModuleContext) OtherModuleDependencyTag(m blueprint.ModuleOrProxy) blueprint.DependencyTag { +func (b *baseModuleContext) OtherModuleDependencyTag(m ModuleOrProxy) blueprint.DependencyTag { return b.bp.OtherModuleDependencyTag(m) } -func (b *baseModuleContext) OtherModuleSubDir(m blueprint.ModuleOrProxy) string { +func (b *baseModuleContext) OtherModuleSubDir(m ModuleOrProxy) string { return b.bp.OtherModuleSubDir(m) } func (b *baseModuleContext) OtherModuleExists(name string) bool { return b.bp.OtherModuleExists(name) } @@ -292,19 +292,19 @@ func (b *baseModuleContext) OtherModuleFarDependencyVariantExists(variations []b func (b *baseModuleContext) OtherModuleReverseDependencyVariantExists(name string) bool { return b.bp.OtherModuleReverseDependencyVariantExists(name) } -func (b *baseModuleContext) OtherModuleType(m blueprint.ModuleOrProxy) string { +func (b *baseModuleContext) OtherModuleType(m ModuleOrProxy) string { return b.bp.OtherModuleType(m) } -func (b *baseModuleContext) otherModuleProvider(m blueprint.ModuleOrProxy, provider blueprint.AnyProviderKey) (any, bool) { +func (b *baseModuleContext) otherModuleProvider(m ModuleOrProxy, provider blueprint.AnyProviderKey) (any, bool) { return b.bp.OtherModuleProvider(m, provider) } -func (b *baseModuleContext) OtherModuleHasProvider(m blueprint.ModuleOrProxy, provider blueprint.AnyProviderKey) bool { +func (b *baseModuleContext) OtherModuleHasProvider(m ModuleOrProxy, provider blueprint.AnyProviderKey) bool { return b.bp.OtherModuleHasProvider(m, provider) } -func (b *baseModuleContext) OtherModuleIsAutoGenerated(m blueprint.ModuleOrProxy) bool { +func (b *baseModuleContext) OtherModuleIsAutoGenerated(m ModuleOrProxy) bool { return b.bp.OtherModuleIsAutoGenerated(m) } @@ -623,7 +623,7 @@ func (b *baseModuleContext) FinalModule() Module { return b.bp.FinalModule().(Module) } -func (b *baseModuleContext) IsFinalModule(module blueprint.ModuleOrProxy) bool { +func (b *baseModuleContext) IsFinalModule(module ModuleOrProxy) bool { return b.bp.IsFinalModule(module) } @@ -662,7 +662,7 @@ func PrettyPrintTag(tag blueprint.DependencyTag) string { func (b *baseModuleContext) GetPathString(skipFirst bool) string { sb := strings.Builder{} tagPath := b.GetTagPath() - var walkPath []blueprint.ModuleOrProxy + var walkPath []ModuleOrProxy if b.walkPath != nil { for _, w := range b.walkPath { walkPath = append(walkPath, w) diff --git a/android/container.go b/android/container.go index 856fa7876..b2a774c7d 100644 --- a/android/container.go +++ b/android/container.go @@ -448,7 +448,7 @@ func generateContainerInfo(ctx ModuleContext) ContainersInfo { } } -func getContainerModuleInfo(ctx ModuleContext, module blueprint.ModuleOrProxy) (ContainersInfo, bool) { +func getContainerModuleInfo(ctx ModuleContext, module ModuleOrProxy) (ContainersInfo, bool) { if EqualModules(ctx.Module(), module) { return ctx.getContainersInfo(), true } diff --git a/android/early_module_context.go b/android/early_module_context.go index a7b8ffc6c..75c8b1eb6 100644 --- a/android/early_module_context.go +++ b/android/early_module_context.go @@ -61,7 +61,7 @@ type EarlyModuleContext interface { Errorf(pos scanner.Position, fmt string, args ...interface{}) // OtherModulePropertyErrorf reports an error at the line number of a property in the given module definition. - OtherModulePropertyErrorf(module blueprint.ModuleOrProxy, property, fmt string, args ...interface{}) + OtherModulePropertyErrorf(module ModuleOrProxy, property, fmt string, args ...interface{}) // Failed returns true if any errors have been reported. In most cases the module can continue with generating // build rules after an error, allowing it to report additional errors in a single run, but in cases where the error @@ -188,7 +188,7 @@ func (e *earlyModuleContext) Namespace() *Namespace { return e.EarlyModuleContext.Namespace().(*Namespace) } -func (e *earlyModuleContext) OtherModulePropertyErrorf(module blueprint.ModuleOrProxy, property string, fmt string, args ...interface{}) { +func (e *earlyModuleContext) OtherModulePropertyErrorf(module ModuleOrProxy, property string, fmt string, args ...interface{}) { e.EarlyModuleContext.OtherModulePropertyErrorf(module, property, fmt, args...) } diff --git a/android/makevars.go b/android/makevars.go index 92b35c37c..4cf222885 100644 --- a/android/makevars.go +++ b/android/makevars.go @@ -72,15 +72,15 @@ type BaseMakeVarsContext interface { type MakeVarsContext interface { BaseMakeVarsContext - ModuleName(module blueprint.ModuleOrProxy) string - ModuleDir(module blueprint.ModuleOrProxy) string - ModuleSubDir(module blueprint.ModuleOrProxy) string - ModuleType(module blueprint.ModuleOrProxy) string - otherModuleProvider(module blueprint.ModuleOrProxy, key blueprint.AnyProviderKey) (any, bool) - BlueprintFile(module blueprint.ModuleOrProxy) string - - ModuleErrorf(module blueprint.ModuleOrProxy, format string, args ...interface{}) - OtherModulePropertyErrorf(module blueprint.ModuleOrProxy, property, format string, args ...interface{}) + ModuleName(module ModuleOrProxy) string + ModuleDir(module ModuleOrProxy) string + ModuleSubDir(module ModuleOrProxy) string + ModuleType(module ModuleOrProxy) string + otherModuleProvider(module ModuleOrProxy, key blueprint.AnyProviderKey) (any, bool) + BlueprintFile(module ModuleOrProxy) string + + ModuleErrorf(module ModuleOrProxy, format string, args ...interface{}) + OtherModulePropertyErrorf(module ModuleOrProxy, property, format string, args ...interface{}) Errorf(format string, args ...interface{}) VisitAllModules(visit func(Module)) diff --git a/android/module.go b/android/module.go index f8b4ce7ac..74e870ec0 100644 --- a/android/module.go +++ b/android/module.go @@ -2830,7 +2830,7 @@ type ConfigContext interface { type ConfigurableEvaluatorContext interface { OtherModuleProviderContext Config() Config - OtherModulePropertyErrorf(module blueprint.ModuleOrProxy, property string, fmt string, args ...interface{}) + OtherModulePropertyErrorf(module ModuleOrProxy, property string, fmt string, args ...interface{}) HasMutatorFinished(mutatorName string) bool } @@ -3128,7 +3128,7 @@ type SourceFileProducer interface { // OutputFilesForModule returns the output file paths with the given tag. On error, including if the // module produced zero paths, it reports errors to the ctx and returns nil. -func OutputFilesForModule(ctx PathContext, module blueprint.ModuleOrProxy, tag string) Paths { +func OutputFilesForModule(ctx PathContext, module ModuleOrProxy, tag string) Paths { paths, err := outputFilesForModule(ctx, module, tag) if err != nil { reportPathError(ctx, err) @@ -3141,7 +3141,7 @@ func OutputFilesForModule(ctx PathContext, module blueprint.ModuleOrProxy, tag s // module produced zero or multiple paths, it reports errors to the ctx and returns nil. // TODO(b/397766191): Change the signature to take ModuleProxy // Please only access the module's internal data through providers. -func OutputFileForModule(ctx PathContext, module blueprint.ModuleOrProxy, tag string) Path { +func OutputFileForModule(ctx PathContext, module ModuleOrProxy, tag string) Path { paths, err := outputFilesForModule(ctx, module, tag) if err != nil { reportPathError(ctx, err) @@ -3150,7 +3150,7 @@ func OutputFileForModule(ctx PathContext, module blueprint.ModuleOrProxy, tag st if len(paths) == 0 { type addMissingDependenciesIntf interface { AddMissingDependencies([]string) - OtherModuleName(blueprint.ModuleOrProxy) string + OtherModuleName(ModuleOrProxy) string } if mctx, ok := ctx.(addMissingDependenciesIntf); ok && ctx.Config().AllowMissingDependencies() { mctx.AddMissingDependencies([]string{mctx.OtherModuleName(module)}) @@ -3182,7 +3182,7 @@ type OutputFilesProviderModuleContext interface { // TODO(b/397766191): Change the signature to take ModuleProxy // Please only access the module's internal data through providers. -func outputFilesForModule(ctx PathContext, module blueprint.ModuleOrProxy, tag string) (Paths, error) { +func outputFilesForModule(ctx PathContext, module ModuleOrProxy, tag string) (Paths, error) { outputFilesFromProvider, err := outputFilesForModuleFromProvider(ctx, module, tag) if outputFilesFromProvider != nil || err != OutputFilesProviderNotSet { return outputFilesFromProvider, err @@ -3212,7 +3212,7 @@ func outputFilesForModule(ctx PathContext, module blueprint.ModuleOrProxy, tag s // from outputFiles property of module base, to avoid both setting and // reading OutputFilesProvider before GenerateBuildActions is finished. // If a module doesn't have the OutputFilesProvider, nil is returned. -func outputFilesForModuleFromProvider(ctx PathContext, module blueprint.ModuleOrProxy, tag string) (Paths, error) { +func outputFilesForModuleFromProvider(ctx PathContext, module ModuleOrProxy, tag string) (Paths, error) { var outputFiles OutputFilesInfo if mctx, isMctx := ctx.(OutputFilesProviderModuleContext); isMctx { diff --git a/android/module_proxy.go b/android/module_proxy.go index b1063ec75..c442e08f3 100644 --- a/android/module_proxy.go +++ b/android/module_proxy.go @@ -7,3 +7,7 @@ import ( type ModuleProxy struct { blueprint.ModuleProxy } + +type ModuleOrProxy interface { + blueprint.ModuleOrProxy +} diff --git a/android/module_test.go b/android/module_test.go index c5d7c191f..0556624af 100644 --- a/android/module_test.go +++ b/android/module_test.go @@ -18,8 +18,6 @@ import ( "path/filepath" "runtime" "testing" - - "github.com/google/blueprint" ) func TestSrcIsModule(t *testing.T) { @@ -990,7 +988,7 @@ type pathContextAddMissingDependenciesWrapper struct { func (p *pathContextAddMissingDependenciesWrapper) AddMissingDependencies(deps []string) { p.missingDeps = append(p.missingDeps, deps...) } -func (p *pathContextAddMissingDependenciesWrapper) OtherModuleName(module blueprint.ModuleOrProxy) string { +func (p *pathContextAddMissingDependenciesWrapper) OtherModuleName(module ModuleOrProxy) string { return module.Name() } diff --git a/android/paths.go b/android/paths.go index ec5d0521e..45a1e76fb 100644 --- a/android/paths.go +++ b/android/paths.go @@ -60,7 +60,7 @@ type EarlyModulePathContext interface { ModuleDir() string ModuleErrorf(fmt string, args ...interface{}) - OtherModulePropertyErrorf(module blueprint.ModuleOrProxy, property, fmt string, args ...interface{}) + OtherModulePropertyErrorf(module ModuleOrProxy, property, fmt string, args ...interface{}) } var _ EarlyModulePathContext = ModuleContext(nil) @@ -93,7 +93,7 @@ type ModuleWithDepsPathContext interface { VisitDirectDeps(visit func(Module)) VisitDirectDepsProxy(visit func(ModuleProxy)) VisitDirectDepsProxyWithTag(tag blueprint.DependencyTag, visit func(ModuleProxy)) - OtherModuleDependencyTag(m blueprint.ModuleOrProxy) blueprint.DependencyTag + OtherModuleDependencyTag(m ModuleOrProxy) blueprint.DependencyTag HasMutatorFinished(mutatorName string) bool } @@ -235,13 +235,13 @@ func ReportPathErrorf(ctx PathContext, format string, args ...interface{}) { } } -func pathContextName(ctx PathContext, module blueprint.ModuleOrProxy) string { +func pathContextName(ctx PathContext, module ModuleOrProxy) string { if x, ok := ctx.(interface { - ModuleName(blueprint.ModuleOrProxy) string + ModuleName(ModuleOrProxy) string }); ok { return x.ModuleName(module) } else if x, ok := ctx.(interface { - OtherModuleName(blueprint.ModuleOrProxy) string + OtherModuleName(ModuleOrProxy) string }); ok { return x.OtherModuleName(module) } diff --git a/android/provider.go b/android/provider.go index 412465d6d..4f4a4a0e8 100644 --- a/android/provider.go +++ b/android/provider.go @@ -7,7 +7,7 @@ import ( // OtherModuleProviderContext is a helper interface that is a subset of ModuleContext or BottomUpMutatorContext // for use in OtherModuleProvider. type OtherModuleProviderContext interface { - otherModuleProvider(m blueprint.ModuleOrProxy, provider blueprint.AnyProviderKey) (any, bool) + otherModuleProvider(m ModuleOrProxy, provider blueprint.AnyProviderKey) (any, bool) } var _ OtherModuleProviderContext = BaseModuleContext(nil) @@ -27,7 +27,7 @@ type ConfigAndOtherModuleProviderContext interface { // and the boolean is false. The value returned may be a deep copy of the value originally passed to SetProvider. // // OtherModuleProviderContext is a helper interface that accepts ModuleContext or BottomUpMutatorContext. -func OtherModuleProvider[K any](ctx OtherModuleProviderContext, module blueprint.ModuleOrProxy, provider blueprint.ProviderKey[K]) (K, bool) { +func OtherModuleProvider[K any](ctx OtherModuleProviderContext, module ModuleOrProxy, provider blueprint.ProviderKey[K]) (K, bool) { value, ok := ctx.otherModuleProvider(module, provider) if !ok { var k K @@ -36,12 +36,12 @@ func OtherModuleProvider[K any](ctx OtherModuleProviderContext, module blueprint return value.(K), ok } -func OtherModuleProviderOrDefault[K any](ctx OtherModuleProviderContext, module blueprint.ModuleOrProxy, provider blueprint.ProviderKey[K]) K { +func OtherModuleProviderOrDefault[K any](ctx OtherModuleProviderContext, module ModuleOrProxy, provider blueprint.ProviderKey[K]) K { value, _ := OtherModuleProvider(ctx, module, provider) return value } -func OtherModulePointerProviderOrDefault[K *T, T any](ctx OtherModuleProviderContext, module blueprint.ModuleOrProxy, provider blueprint.ProviderKey[K]) K { +func OtherModulePointerProviderOrDefault[K *T, T any](ctx OtherModuleProviderContext, module ModuleOrProxy, provider blueprint.ProviderKey[K]) K { if value, ok := OtherModuleProvider(ctx, module, provider); ok { return value } @@ -97,13 +97,13 @@ var _ OtherModuleProviderContext = (*otherModuleProviderAdaptor)(nil) // An OtherModuleProviderFunc can be passed to NewOtherModuleProviderAdaptor to create an OtherModuleProviderContext // for use in tests. -type OtherModuleProviderFunc func(module blueprint.ModuleOrProxy, provider blueprint.AnyProviderKey) (any, bool) +type OtherModuleProviderFunc func(module ModuleOrProxy, provider blueprint.AnyProviderKey) (any, bool) type otherModuleProviderAdaptor struct { otherModuleProviderFunc OtherModuleProviderFunc } -func (p *otherModuleProviderAdaptor) otherModuleProvider(module blueprint.ModuleOrProxy, provider blueprint.AnyProviderKey) (any, bool) { +func (p *otherModuleProviderAdaptor) otherModuleProvider(module ModuleOrProxy, provider blueprint.AnyProviderKey) (any, bool) { return p.otherModuleProviderFunc(module, provider) } diff --git a/android/singleton.go b/android/singleton.go index a61202d5b..18b2f5c71 100644 --- a/android/singleton.go +++ b/android/singleton.go @@ -30,19 +30,19 @@ type SingletonContext interface { Config() Config DeviceConfig() DeviceConfig - ModuleName(module blueprint.ModuleOrProxy) string - ModuleDir(module blueprint.ModuleOrProxy) string - ModuleSubDir(module blueprint.ModuleOrProxy) string - ModuleType(module blueprint.ModuleOrProxy) string - BlueprintFile(module blueprint.ModuleOrProxy) string + ModuleName(module ModuleOrProxy) string + ModuleDir(module ModuleOrProxy) string + ModuleSubDir(module ModuleOrProxy) string + ModuleType(module ModuleOrProxy) string + BlueprintFile(module ModuleOrProxy) string // ModuleVariantsFromName returns the list of module variants named `name` in the same namespace as `referer` enforcing visibility rules. // Allows generating build actions for `referer` based on the metadata for `name` deferred until the singleton context. ModuleVariantsFromName(referer ModuleProxy, name string) []ModuleProxy - otherModuleProvider(module blueprint.ModuleOrProxy, provider blueprint.AnyProviderKey) (any, bool) + otherModuleProvider(module ModuleOrProxy, provider blueprint.AnyProviderKey) (any, bool) - ModuleErrorf(module blueprint.ModuleOrProxy, format string, args ...interface{}) + ModuleErrorf(module ModuleOrProxy, format string, args ...interface{}) Errorf(format string, args ...interface{}) Failed() bool @@ -89,7 +89,7 @@ type SingletonContext interface { PrimaryModuleProxy(module ModuleProxy) ModuleProxy - IsFinalModule(module blueprint.ModuleOrProxy) bool + IsFinalModule(module ModuleOrProxy) bool AddNinjaFileDeps(deps ...string) @@ -100,7 +100,7 @@ type SingletonContext interface { GlobWithDeps(pattern string, excludes []string) ([]string, error) // OtherModulePropertyErrorf reports an error on the line number of the given property of the given module - OtherModulePropertyErrorf(module blueprint.ModuleOrProxy, property string, format string, args ...interface{}) + OtherModulePropertyErrorf(module ModuleOrProxy, property string, format string, args ...interface{}) // HasMutatorFinished returns true if the given mutator has finished running. // It will panic if given an invalid mutator name. @@ -247,6 +247,10 @@ func (s *singletonContextAdaptor) Eval(pctx PackageContext, ninjaStr string) (st return s.SingletonContext.Eval(pctx.PackageContext, ninjaStr) } +func (s *singletonContextAdaptor) ModuleErrorf(module ModuleOrProxy, fmt string, args ...any) { + s.SingletonContext.ModuleErrorf(module, fmt, args...) +} + // visitAdaptor wraps a visit function that takes an android.Module parameter into // a function that takes a blueprint.Module parameter and only calls the visit function if the // blueprint.Module is an android.Module. @@ -279,23 +283,23 @@ func predAdaptor(pred func(Module) bool) func(blueprint.Module) bool { } } -func (s *singletonContextAdaptor) ModuleName(module blueprint.ModuleOrProxy) string { +func (s *singletonContextAdaptor) ModuleName(module ModuleOrProxy) string { return s.SingletonContext.ModuleName(module) } -func (s *singletonContextAdaptor) ModuleDir(module blueprint.ModuleOrProxy) string { +func (s *singletonContextAdaptor) ModuleDir(module ModuleOrProxy) string { return s.SingletonContext.ModuleDir(module) } -func (s *singletonContextAdaptor) ModuleSubDir(module blueprint.ModuleOrProxy) string { +func (s *singletonContextAdaptor) ModuleSubDir(module ModuleOrProxy) string { return s.SingletonContext.ModuleSubDir(module) } -func (s *singletonContextAdaptor) ModuleType(module blueprint.ModuleOrProxy) string { +func (s *singletonContextAdaptor) ModuleType(module ModuleOrProxy) string { return s.SingletonContext.ModuleType(module) } -func (s *singletonContextAdaptor) BlueprintFile(module blueprint.ModuleOrProxy) string { +func (s *singletonContextAdaptor) BlueprintFile(module ModuleOrProxy) string { return s.SingletonContext.BlueprintFile(module) } @@ -347,7 +351,7 @@ func (s *singletonContextAdaptor) PrimaryModuleProxy(module ModuleProxy) ModuleP return ModuleProxy{s.SingletonContext.PrimaryModuleProxy(module.ModuleProxy)} } -func (s *singletonContextAdaptor) IsFinalModule(module blueprint.ModuleOrProxy) bool { +func (s *singletonContextAdaptor) IsFinalModule(module ModuleOrProxy) bool { return s.SingletonContext.IsFinalModule(module) } @@ -376,11 +380,11 @@ func (s *singletonContextAdaptor) ModuleVariantsFromName(referer ModuleProxy, na return result } -func (s *singletonContextAdaptor) otherModuleProvider(module blueprint.ModuleOrProxy, provider blueprint.AnyProviderKey) (any, bool) { +func (s *singletonContextAdaptor) otherModuleProvider(module ModuleOrProxy, provider blueprint.AnyProviderKey) (any, bool) { return s.SingletonContext.ModuleProvider(module, provider) } -func (s *singletonContextAdaptor) OtherModulePropertyErrorf(module blueprint.ModuleOrProxy, property string, format string, args ...interface{}) { +func (s *singletonContextAdaptor) OtherModulePropertyErrorf(module ModuleOrProxy, property string, format string, args ...interface{}) { s.blueprintSingletonContext().OtherModulePropertyErrorf(module, property, format, args...) } diff --git a/android/testing.go b/android/testing.go index 7490025ca..8b1920810 100644 --- a/android/testing.go +++ b/android/testing.go @@ -238,7 +238,7 @@ func (ctx *TestContext) HardCodedPreArchMutators(f RegisterMutatorFunc) { ctx.PreArchMutators(f) } -func (ctx *TestContext) otherModuleProvider(m blueprint.ModuleOrProxy, p blueprint.AnyProviderKey) (any, bool) { +func (ctx *TestContext) otherModuleProvider(m ModuleOrProxy, p blueprint.AnyProviderKey) (any, bool) { return ctx.Context.ModuleProvider(m, p) } @@ -259,12 +259,28 @@ func (ctx *TestContext) FinalDepsMutators(f RegisterMutatorFunc) { } func (ctx *TestContext) OtherModuleProviderAdaptor() OtherModuleProviderContext { - return NewOtherModuleProviderAdaptor(func(module blueprint.ModuleOrProxy, provider blueprint.AnyProviderKey) (any, bool) { + return NewOtherModuleProviderAdaptor(func(module ModuleOrProxy, provider blueprint.AnyProviderKey) (any, bool) { return ctx.otherModuleProvider(module, provider) }) } -func (ctx *TestContext) OtherModulePropertyErrorf(module blueprint.ModuleOrProxy, property string, fmt_ string, args ...interface{}) { +func (ctx *TestContext) ModuleDir(module ModuleOrProxy) string { + return ctx.Context.ModuleDir(module) +} + +func (ctx *TestContext) ModuleSubDir(module ModuleOrProxy) string { + return ctx.Context.ModuleSubDir(module) +} + +func (ctx *TestContext) ModuleType(module ModuleOrProxy) string { + return ctx.Context.ModuleType(module) +} + +func (ctx *TestContext) ModuleErrorf(module ModuleOrProxy, fmt string, args ...any) error { + return ctx.Context.ModuleErrorf(module, fmt, args...) +} + +func (ctx *TestContext) OtherModulePropertyErrorf(module ModuleOrProxy, property string, fmt_ string, args ...interface{}) { panic(fmt.Sprintf(fmt_, args...)) } @@ -1378,7 +1394,7 @@ type panickingConfigAndErrorContext struct { ctx *TestContext } -func (ctx *panickingConfigAndErrorContext) OtherModulePropertyErrorf(module blueprint.ModuleOrProxy, property, fmt string, args ...interface{}) { +func (ctx *panickingConfigAndErrorContext) OtherModulePropertyErrorf(module ModuleOrProxy, property, fmt string, args ...interface{}) { panic(ctx.ctx.PropertyErrorf(module, property, fmt, args...).Error()) } @@ -1390,7 +1406,7 @@ func (ctx *panickingConfigAndErrorContext) HasMutatorFinished(mutatorName string return ctx.ctx.HasMutatorFinished(mutatorName) } -func (ctx *panickingConfigAndErrorContext) otherModuleProvider(m blueprint.ModuleOrProxy, p blueprint.AnyProviderKey) (any, bool) { +func (ctx *panickingConfigAndErrorContext) otherModuleProvider(m ModuleOrProxy, p blueprint.AnyProviderKey) (any, bool) { return ctx.ctx.otherModuleProvider(m, p) } diff --git a/cc/cc.go b/cc/cc.go index dbec4fd9d..2b0684320 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -4045,7 +4045,7 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { return depPaths } -func ShouldUseStubForApex(ctx android.ModuleContext, parent blueprint.ModuleOrProxy, dep android.ModuleProxy) bool { +func ShouldUseStubForApex(ctx android.ModuleContext, parent android.ModuleOrProxy, dep android.ModuleProxy) bool { inVendorOrProduct := false bootstrap := false if android.EqualModules(ctx.Module(), parent) { diff --git a/cc/library_sdk_member.go b/cc/library_sdk_member.go index 8c0b730ac..03103f7bf 100644 --- a/cc/library_sdk_member.go +++ b/cc/library_sdk_member.go @@ -577,7 +577,7 @@ func (p *nativeLibInfoProperties) PopulateFromVariant(ctx android.SdkMemberConte } } -func getRequiredMemberOutputFile(ctx android.SdkMemberContext, module blueprint.ModuleOrProxy) android.Path { +func getRequiredMemberOutputFile(ctx android.SdkMemberContext, module android.ModuleOrProxy) android.Path { var path android.Path if info, ok := android.OtherModuleProvider(ctx.SdkModuleContext(), module, LinkableInfoProvider); ok && info.OutputFile.Valid() { path = info.OutputFile.Path() diff --git a/ci_tests/ci_test_package_zip.go b/ci_tests/ci_test_package_zip.go index f96397c65..46edebb4b 100644 --- a/ci_tests/ci_test_package_zip.go +++ b/ci_tests/ci_test_package_zip.go @@ -233,7 +233,7 @@ func createSymbolsZip(ctx android.ModuleContext, allModules []android.ModuleProx ctx.SetOutputFiles(android.Paths{symbolsMappingFile}, ".elf_mapping") } -func extendBuilderCommand(ctx android.ModuleContext, m blueprint.ModuleOrProxy, builder *android.RuleBuilder, stagingDir android.ModuleOutPath, productOut, arch, secondArch string) { +func extendBuilderCommand(ctx android.ModuleContext, m android.ModuleOrProxy, builder *android.RuleBuilder, stagingDir android.ModuleOutPath, productOut, arch, secondArch string) { info, ok := android.OtherModuleProvider(ctx, m, android.ModuleInfoJSONProvider) if !ok { ctx.OtherModuleErrorf(m, "doesn't set ModuleInfoJSON provider") diff --git a/fuzz/fuzz_common.go b/fuzz/fuzz_common.go index 6539f1dec..ea42fc29c 100644 --- a/fuzz/fuzz_common.go +++ b/fuzz/fuzz_common.go @@ -568,7 +568,7 @@ func IsValid(ctx android.ConfigurableEvaluatorContext, fuzzModule FuzzModule) bo // TODO(b/397766191): Change the signature to take ModuleProxy // Please only access the module's internal data through providers. -func (s *FuzzPackager) PackageArtifacts(ctx android.SingletonContext, module blueprint.ModuleOrProxy, fuzzModule *FuzzPackagedModuleInfo, archDir android.OutputPath, builder *android.RuleBuilder) []FileToZip { +func (s *FuzzPackager) PackageArtifacts(ctx android.SingletonContext, module android.ModuleOrProxy, fuzzModule *FuzzPackagedModuleInfo, archDir android.OutputPath, builder *android.RuleBuilder) []FileToZip { // Package the corpora into a zipfile. var files []FileToZip if fuzzModule.Corpus != nil { @@ -609,7 +609,7 @@ func (s *FuzzPackager) PackageArtifacts(ctx android.SingletonContext, module blu // TODO(b/397766191): Change the signature to take ModuleProxy // Please only access the module's internal data through providers. -func (s *FuzzPackager) BuildZipFile(ctx android.SingletonContext, module blueprint.ModuleOrProxy, fuzzModule *FuzzPackagedModuleInfo, files []FileToZip, builder *android.RuleBuilder, archDir android.OutputPath, archString string, hostOrTargetString string, archOs ArchOs, archDirs map[ArchOs][]FileToZip) ([]FileToZip, bool) { +func (s *FuzzPackager) BuildZipFile(ctx android.SingletonContext, module android.ModuleOrProxy, fuzzModule *FuzzPackagedModuleInfo, files []FileToZip, builder *android.RuleBuilder, archDir android.OutputPath, archString string, hostOrTargetString string, archOs ArchOs, archDirs map[ArchOs][]FileToZip) ([]FileToZip, bool) { fuzzZip := archDir.Join(ctx, module.Name()+".zip") command := builder.Command().BuiltTool("soong_zip"). diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go index 46f6b18a0..17fb8128b 100644 --- a/java/bootclasspath_fragment.go +++ b/java/bootclasspath_fragment.go @@ -398,7 +398,7 @@ type BootclasspathFragmentApexContentInfo struct { // DexBootJarPathForContentModule returns the path to the dex boot jar for specified module. // // The dex boot jar is one which has had hidden API encoding performed on it. -func (i BootclasspathFragmentApexContentInfo) DexBootJarPathForContentModule(module blueprint.ModuleOrProxy) (android.Path, error) { +func (i BootclasspathFragmentApexContentInfo) DexBootJarPathForContentModule(module android.ModuleOrProxy) (android.Path, error) { // A bootclasspath_fragment cannot use a prebuilt library so Name() will return the base name // without a prebuilt_ prefix so is safe to use as the key for the contentModuleDexJarPaths. name := module.Name() -- cgit v1.2.3 From 3262f5c5face6eda806b5cbd974208b0ecb7a520 Mon Sep 17 00:00:00 2001 From: Yu Liu Date: Tue, 8 Apr 2025 18:55:51 +0000 Subject: Treat nil amd empty slice the same when generating cc fuzz corpus and data zip files. Bug: 358427516 Test: Unit tests and CI. Change-Id: Id1e8643f8e49c68404aa7a4b5068a6dbbae8f6c7 --- fuzz/fuzz_common.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fuzz/fuzz_common.go b/fuzz/fuzz_common.go index f08378d67..422cbcd53 100644 --- a/fuzz/fuzz_common.go +++ b/fuzz/fuzz_common.go @@ -571,7 +571,7 @@ func IsValid(ctx android.ConfigurableEvaluatorContext, fuzzModule FuzzModule) bo func (s *FuzzPackager) PackageArtifacts(ctx android.SingletonContext, module android.Module, fuzzModule *FuzzPackagedModuleInfo, archDir android.OutputPath, builder *android.RuleBuilder) []FileToZip { // Package the corpora into a zipfile. var files []FileToZip - if fuzzModule.Corpus != nil { + if len(fuzzModule.Corpus) > 0 { corpusZip := archDir.Join(ctx, module.Name()+"_seed_corpus.zip") command := builder.Command().BuiltTool("soong_zip"). Flag("-j"). @@ -582,7 +582,7 @@ func (s *FuzzPackager) PackageArtifacts(ctx android.SingletonContext, module and } // Package the data into a zipfile. - if fuzzModule.Data != nil { + if len(fuzzModule.Data) > 0 { dataZip := archDir.Join(ctx, module.Name()+"_data.zip") command := builder.Command().BuiltTool("soong_zip"). FlagWithOutput("-o ", dataZip) -- cgit v1.2.3 From e2a57c3a0890df0e360c414bafd49f325c0b66dc Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Tue, 8 Apr 2025 13:43:19 -0700 Subject: Remove usages of echo in target_files.zip generation This change replaces the usages of `echo` in target_files.zip generation in soong only build, as the `-e` flag may not be recognized by the shell used in the buildbot. Test: CI && ABTD Bug: 409368614 Change-Id: I8a3f88b7b042397587cb6e797555a6e014b81210 --- filesystem/android_device.go | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/filesystem/android_device.go b/filesystem/android_device.go index d14ba91f8..0b3115400 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -526,6 +526,7 @@ type targetFilesystemZipCopy struct { func (a *androidDevice) buildTargetFilesZip(ctx android.ModuleContext, allInstalledModules []android.ModuleProxy) { targetFilesDir := android.PathForModuleOut(ctx, "target_files_dir") targetFilesZip := android.PathForModuleOut(ctx, "target_files.zip") + var targetFilesDeps android.Paths builder := android.NewRuleBuilder(pctx, ctx) builder.Command().Textf("rm -rf %s", targetFilesDir.String()) @@ -638,7 +639,7 @@ func (a *androidDevice) buildTargetFilesZip(ctx android.ModuleContext, allInstal } a.copyImagesToTargetZip(ctx, builder, targetFilesDir) - a.copyMetadataToTargetZip(ctx, builder, targetFilesDir, allInstalledModules) + targetFilesDeps = append(targetFilesDeps, a.copyMetadataToTargetZip(ctx, builder, targetFilesDir, allInstalledModules)...) a.targetFilesZip = targetFilesZip builder.Command(). @@ -647,7 +648,8 @@ func (a *androidDevice) buildTargetFilesZip(ctx android.ModuleContext, allInstal FlagWithOutput("-o ", targetFilesZip). FlagWithArg("-C ", targetFilesDir.String()). FlagWithArg("-D ", targetFilesDir.String()). - Text("-sha256") + Text("-sha256"). + Implicits(targetFilesDeps) builder.Build("target_files_"+ctx.ModuleName(), "Build target_files.zip") } @@ -695,7 +697,19 @@ func (a *androidDevice) copyImagesToTargetZip(ctx android.ModuleContext, builder } } -func (a *androidDevice) copyMetadataToTargetZip(ctx android.ModuleContext, builder *android.RuleBuilder, targetFilesDir android.WritablePath, allInstalledModules []android.ModuleProxy) { +func writeFileWithNewLines(ctx android.ModuleContext, path android.WritablePath, contents []string) { + builder := &strings.Builder{} + for i, content := range contents { + builder.WriteString(content) + // Do not write a new line at the end + if i < len(contents)-1 { + builder.WriteString("\n") + } + } + android.WriteFileRule(ctx, path, builder.String()) +} + +func (a *androidDevice) copyMetadataToTargetZip(ctx android.ModuleContext, builder *android.RuleBuilder, targetFilesDir android.ModuleOutPath, allInstalledModules []android.ModuleProxy) (deps android.Paths) { // Create a META/ subdirectory builder.Command().Textf("mkdir -p %s/META", targetFilesDir.String()) if proptools.Bool(a.deviceProps.Ab_ota_updater) { @@ -710,15 +724,18 @@ func (a *androidDevice) copyMetadataToTargetZip(ctx android.ModuleContext, build } // ab_partitions.txt abPartitionsSorted := android.SortedUniqueStrings(a.deviceProps.Ab_ota_partitions) - abPartitionsSortedString := proptools.ShellEscape(strings.Join(abPartitionsSorted, "\\n")) - builder.Command().Textf("echo -e").Flag(abPartitionsSortedString).Textf(" > %s/META/ab_partitions.txt", targetFilesDir.String()) + abPartitionsFilePath := targetFilesDir.Join(ctx, "META", "ab_partitions.txt") + writeFileWithNewLines(ctx, abPartitionsFilePath, abPartitionsSorted) + deps = append(deps, abPartitionsFilePath) // otakeys.txt abOtaKeysSorted := android.SortedUniqueStrings(a.deviceProps.Ab_ota_keys) - abOtaKeysSortedString := proptools.ShellEscape(strings.Join(abOtaKeysSorted, "\\n")) - builder.Command().Textf("echo -e").Flag(abOtaKeysSortedString).Textf(" > %s/META/otakeys.txt", targetFilesDir.String()) + abOtaKeysFilePath := targetFilesDir.Join(ctx, "META", "otakeys.txt") + writeFileWithNewLines(ctx, abOtaKeysFilePath, abOtaKeysSorted) + deps = append(deps, abOtaKeysFilePath) // postinstall_config.txt - abOtaPostInstallConfigString := proptools.ShellEscape(strings.Join(a.deviceProps.Ab_ota_postinstall_config, "\\n")) - builder.Command().Textf("echo -e").Flag(abOtaPostInstallConfigString).Textf(" > %s/META/postinstall_config.txt", targetFilesDir.String()) + abOtaPostInstallConfigFilePath := targetFilesDir.Join(ctx, "META", "postinstall_config.txt") + writeFileWithNewLines(ctx, abOtaPostInstallConfigFilePath, a.deviceProps.Ab_ota_postinstall_config) + deps = append(deps, abOtaPostInstallConfigFilePath) // selinuxfc if a.getFsInfos(ctx)["system"].SelinuxFc != nil { builder.Command().Textf("cp").Input(a.getFsInfos(ctx)["system"].SelinuxFc).Textf(" %s/META/file_contexts.bin", targetFilesDir.String()) @@ -808,6 +825,7 @@ func (a *androidDevice) copyMetadataToTargetZip(ctx android.ModuleContext, build } } + return deps } var ( -- cgit v1.2.3 From 3b11550c33ba576ff020e52e358e6903486fc027 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Mon, 7 Apr 2025 19:58:18 -0700 Subject: Remove unused module context methods Remove VisitDepsDepthFirst, VisitDepsDepthFirstIf, FinalModule, VisitAllModuleVariants and VisitAllModuleVariantProxies. These methods are unused in Soong. Test: builds Change-Id: I2d85837b01cccccb99d0a0ef03299b53bc695b56 --- android/base_module_context.go | 60 ------------------------------------------ 1 file changed, 60 deletions(-) diff --git a/android/base_module_context.go b/android/base_module_context.go index 244b13f79..55220fe9b 100644 --- a/android/base_module_context.go +++ b/android/base_module_context.go @@ -163,10 +163,6 @@ type BaseModuleContext interface { // The Module passed to the visit function should not be retained outside of the visit function, it may be // invalidated by future mutators. VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) - // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module - VisitDepsDepthFirst(visit func(Module)) - // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module - VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) // WalkDeps calls visit for each transitive dependency, traversing the dependency tree in top down order. visit may // be called multiple times for the same (child, parent) pair if there are multiple direct dependencies between the @@ -201,30 +197,12 @@ type BaseModuleContext interface { // only done once for all variants of a module. PrimaryModule() Module - // FinalModule returns the last variant of the current module. Variants of a module are always visited in - // order by mutators and GenerateBuildActions, so the data created by the current mutator can be read from all - // variants using VisitAllModuleVariants if the current module == FinalModule(). This can be used to perform - // singleton actions that are only done once for all variants of a module. - FinalModule() Module - // IsFinalModule returns if the current module is the last variant. Variants of a module are always visited in // order by mutators and GenerateBuildActions, so the data created by the current mutator can be read from all // variants using VisitAllModuleVariants if the current module is the last one. This can be used to perform // singleton actions that are only done once for all variants of a module. IsFinalModule(module ModuleOrProxy) bool - // VisitAllModuleVariants calls visit for each variant of the current module. Variants of a module are always - // visited in order by mutators and GenerateBuildActions, so the data created by the current mutator can be read - // from all variants if the current module is the last one. Otherwise, care must be taken to not access any - // data modified by the current mutator. - VisitAllModuleVariants(visit func(Module)) - - // VisitAllModuleVariantProxies calls visit for each variant of the current module. Variants of a module are always - // visited in order by mutators and GenerateBuildActions, so the data created by the current mutator can be read - // from all variants if the current module is the last one. Otherwise, care must be taken to not access any - // data modified by the current mutator. - VisitAllModuleVariantProxies(visit func(proxy ModuleProxy)) - // GetTagPath is supposed to be called in visit function passed in WalkDeps() // and returns a top-down dependency tags path from a start module to current child module. // It has one less entry than GetWalkPath() as it contains the dependency tags that @@ -520,30 +498,6 @@ func (b *baseModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func }) } -func (b *baseModuleContext) VisitDepsDepthFirst(visit func(Module)) { - b.bp.VisitDepsDepthFirst(func(module blueprint.Module) { - if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil { - visit(aModule) - } - }) -} - -func (b *baseModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) { - b.bp.VisitDepsDepthFirstIf( - // pred - func(module blueprint.Module) bool { - if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil { - return pred(aModule) - } else { - return false - } - }, - // visit - func(module blueprint.Module) { - visit(module.(Module)) - }) -} - func (b *baseModuleContext) WalkDeps(visit func(Module, Module) bool) { b.walkPath = []Module{b.Module()} b.proxyWalkPath = nil @@ -605,24 +559,10 @@ func (b *baseModuleContext) GetTagPath() []blueprint.DependencyTag { return b.tagPath } -func (b *baseModuleContext) VisitAllModuleVariants(visit func(Module)) { - b.bp.VisitAllModuleVariants(func(module blueprint.Module) { - visit(module.(Module)) - }) -} - -func (b *baseModuleContext) VisitAllModuleVariantProxies(visit func(ModuleProxy)) { - b.bp.VisitAllModuleVariantProxies(visitProxyAdaptor(visit)) -} - func (b *baseModuleContext) PrimaryModule() Module { return b.bp.PrimaryModule().(Module) } -func (b *baseModuleContext) FinalModule() Module { - return b.bp.FinalModule().(Module) -} - func (b *baseModuleContext) IsFinalModule(module ModuleOrProxy) bool { return b.bp.IsFinalModule(module) } -- cgit v1.2.3 From ef4741599495db597abf789155c7eb835035aac9 Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Tue, 8 Apr 2025 15:19:37 -0700 Subject: Respect DIST_DIR in soong only diff test script CI builds usually specify `DIST_DIR` property that is different from `out/dist`. This change modifies the script to respect the `DIST_DIR` property. Test: CI && ABTD Bug: 409368614 Change-Id: Ibcfcaf0ba2d412c231f71cbae7057aac3ceddf4c --- scripts/soong_only_diff_test.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/soong_only_diff_test.py b/scripts/soong_only_diff_test.py index b63ce698d..3575ff537 100755 --- a/scripts/soong_only_diff_test.py +++ b/scripts/soong_only_diff_test.py @@ -172,7 +172,8 @@ def get_zip_sha_map(product: Product, soong_only: bool) -> dict[str, bytes]: sys.exit(f'{build_type} build failed') build_id = find_build_id() - target_files_zip = os.path.join(out_dir, "dist", f'{product.product}-target_files-{build_id}.zip') + dist_dir = os.getenv('DIST_DIR', os.path.join(out_dir, 'dist')) + target_files_zip = os.path.join(dist_dir, f'{product.product}-target_files-{build_id}.zip') zip_sha_map = get_local_file_sha256_fields(target_files_zip) if zip_sha_map is None: sys.exit("Could not construct sha map for target_files.zip entries for soong only build") -- cgit v1.2.3 From a416637288ff5624356451102afc8e8e85991e37 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Mon, 7 Apr 2025 14:56:04 -0700 Subject: Factor out common android.HasDirectDep and android.AssertHasDirectDep There are multiple implementations of HasDirectDep and AssertHasDirectDep around the tree, put a single implementation in android/testing.go. Test: all soong tests pass Change-Id: Ife0456fd6d2a3796657625756123559cf1fd35b9 --- android/testing.go | 29 +++++++++++++++++++++++ apex/apex_test.go | 18 ++------------- cc/afdo_test.go | 48 +++++++++++++------------------------- cc/cc_test.go | 16 ++----------- cc/lto_test.go | 26 ++++++--------------- cc/orderfile_test.go | 20 ++++++++-------- cc/prebuilt_test.go | 65 ++++++++++------------------------------------------ java/java_test.go | 13 ++--------- 8 files changed, 80 insertions(+), 155 deletions(-) diff --git a/android/testing.go b/android/testing.go index 8b1920810..00ede57ef 100644 --- a/android/testing.go +++ b/android/testing.go @@ -1415,3 +1415,32 @@ func PanickingConfigAndErrorContext(ctx *TestContext) ConfigurableEvaluatorConte ctx: ctx, } } + +type visitDirectDepsInterface interface { + VisitDirectDeps(blueprint.Module, func(dep blueprint.Module)) +} + +// HasDirectDep returns true if wantDep is a direct dependency of m. +func HasDirectDep(ctx visitDirectDepsInterface, m Module, wantDep ModuleOrProxy) bool { + var found bool + ctx.VisitDirectDeps(m, func(dep blueprint.Module) { + if EqualModules(dep, wantDep) { + found = true + } + }) + return found +} + +// AssertHasDirectDep asserts that wantDep is a direct dependency of m. +func AssertHasDirectDep(t *testing.T, ctx visitDirectDepsInterface, m Module, wantDep ModuleOrProxy) { + t.Helper() + found := false + ctx.VisitDirectDeps(m, func(dep blueprint.Module) { + if EqualModules(dep, wantDep) { + found = true + } + }) + if !found { + t.Errorf("Could not find a dependency from %v to %v\n", m, wantDep) + } +} diff --git a/apex/apex_test.go b/apex/apex_test.go index dd17d7794..6387a50e4 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -27,7 +27,6 @@ import ( "android/soong/aconfig/codegen" - "github.com/google/blueprint" "github.com/google/blueprint/proptools" "android/soong/android" @@ -11794,19 +11793,6 @@ func TestApexMinSdkVersionOverride(t *testing.T) { } } - checkHasDep := func(t *testing.T, ctx *android.TestContext, m android.Module, wantDep android.Module) { - t.Helper() - found := false - ctx.VisitDirectDeps(m, func(dep blueprint.Module) { - if dep == wantDep { - found = true - } - }) - if !found { - t.Errorf("Could not find a dependency from %v to %v\n", m, wantDep) - } - } - ctx := testApex(t, ` apex { name: "com.android.apex30", @@ -11853,13 +11839,13 @@ func TestApexMinSdkVersionOverride(t *testing.T) { overridingModuleSameMinSdkVersion := ctx.ModuleForTests(t, "com.android.apex30", "android_common_com.mycompany.android.apex30_com.mycompany.android.apex30") javalibApex30Variant := ctx.ModuleForTests(t, "javalib", "android_common_apex30") checkMinSdkVersion(t, overridingModuleSameMinSdkVersion, "30") - checkHasDep(t, ctx, overridingModuleSameMinSdkVersion.Module(), javalibApex30Variant.Module()) + android.AssertHasDirectDep(t, ctx, overridingModuleSameMinSdkVersion.Module(), javalibApex30Variant.Module()) // Override module, uses different min_sdk_version overridingModuleDifferentMinSdkVersion := ctx.ModuleForTests(t, "com.android.apex30", "android_common_com.mycompany.android.apex31_com.mycompany.android.apex31") javalibApex31Variant := ctx.ModuleForTests(t, "javalib", "android_common_apex31") checkMinSdkVersion(t, overridingModuleDifferentMinSdkVersion, "31") - checkHasDep(t, ctx, overridingModuleDifferentMinSdkVersion.Module(), javalibApex31Variant.Module()) + android.AssertHasDirectDep(t, ctx, overridingModuleDifferentMinSdkVersion.Module(), javalibApex31Variant.Module()) } func TestOverrideApexWithPrebuiltApexPreferred(t *testing.T) { diff --git a/cc/afdo_test.go b/cc/afdo_test.go index d2d5584ff..940cb697f 100644 --- a/cc/afdo_test.go +++ b/cc/afdo_test.go @@ -20,24 +20,8 @@ import ( "testing" "android/soong/android" - - "github.com/google/blueprint" ) -type visitDirectDepsInterface interface { - VisitDirectDeps(blueprint.Module, func(dep blueprint.Module)) -} - -func hasDirectDep(ctx visitDirectDepsInterface, m android.Module, wantDep android.Module) bool { - var found bool - ctx.VisitDirectDeps(m, func(dep blueprint.Module) { - if dep == wantDep { - found = true - } - }) - return found -} - func TestAfdoDeps(t *testing.T) { t.Parallel() bp := ` @@ -129,11 +113,11 @@ func TestAfdoDeps(t *testing.T) { } // Check dependency edge from afdo-enabled module to static deps - if !hasDirectDep(result, libTest.Module(), libFooAfdoVariant.Module()) { + if !android.HasDirectDep(result, libTest.Module(), libFooAfdoVariant.Module()) { t.Errorf("libTest missing dependency on afdo variant of libFoo") } - if !hasDirectDep(result, libFooAfdoVariant.Module(), libBarAfdoVariant.Module()) { + if !android.HasDirectDep(result, libFooAfdoVariant.Module(), libBarAfdoVariant.Module()) { t.Errorf("libTest missing dependency on afdo variant of libBar") } @@ -157,11 +141,11 @@ func TestAfdoDeps(t *testing.T) { } // Check dependency edges of static deps - if hasDirectDep(result, libTest.Module(), libFoo.Module()) { + if android.HasDirectDep(result, libTest.Module(), libFoo.Module()) { t.Errorf("libTest should not depend on non-afdo variant of libFoo") } - if !hasDirectDep(result, libFoo.Module(), libBar.Module()) { + if !android.HasDirectDep(result, libFoo.Module(), libBar.Module()) { t.Errorf("libFoo missing dependency on non-afdo variant of libBar") } @@ -191,11 +175,11 @@ func TestAfdoDeps(t *testing.T) { } // Check dependency edge from afdo-enabled module to static deps - if !hasDirectDep(result, libTest32.Module(), libFooAfdoVariant32.Module()) { + if !android.HasDirectDep(result, libTest32.Module(), libFooAfdoVariant32.Module()) { t.Errorf("arm32 libTest missing dependency on afdo variant of libFoo") } - if !hasDirectDep(result, libFooAfdoVariant32.Module(), libBarAfdoVariant32.Module()) { + if !android.HasDirectDep(result, libFooAfdoVariant32.Module(), libBarAfdoVariant32.Module()) { t.Errorf("arm32 libTest missing dependency on afdo variant of libBar") } @@ -240,11 +224,11 @@ func TestAfdoDeps(t *testing.T) { } // Check dependency edge from afdo-enabled module to static deps - if !hasDirectDep(result, libTestHost.Module(), libFooHost.Module()) { + if !android.HasDirectDep(result, libTestHost.Module(), libFooHost.Module()) { t.Errorf("host libTest missing dependency on non-afdo variant of libFoo") } - if !hasDirectDep(result, libFooHost.Module(), libBarHost.Module()) { + if !android.HasDirectDep(result, libFooHost.Module(), libBarHost.Module()) { t.Errorf("host libTest missing dependency on non-afdo variant of libBar") } @@ -305,11 +289,11 @@ func TestAfdoEnabledOnStaticDepNoAfdo(t *testing.T) { libFoo := result.ModuleForTests(t, "libFoo", "android_arm64_armv8-a_static") libBar := result.ModuleForTests(t, "libBar", "android_arm64_armv8-a_static").Module() - if !hasDirectDep(result, libTest, libFoo.Module()) { + if !android.HasDirectDep(result, libTest, libFoo.Module()) { t.Errorf("libTest missing dependency on non-afdo variant of libFoo") } - if !hasDirectDep(result, libFoo.Module(), libBar) { + if !android.HasDirectDep(result, libFoo.Module(), libBar) { t.Errorf("libFoo missing dependency on non-afdo variant of libBar") } @@ -503,11 +487,11 @@ func TestMultipleAfdoRDeps(t *testing.T) { } // Check dependency edges of static deps - if !hasDirectDep(result, libTest.Module(), libFooAfdoVariantWithLibTest.Module()) { + if !android.HasDirectDep(result, libTest.Module(), libFooAfdoVariantWithLibTest.Module()) { t.Errorf("libTest missing dependency on afdo variant of libFoo") } - if !hasDirectDep(result, libBar.Module(), libFooAfdoVariantWithLibBar.Module()) { + if !android.HasDirectDep(result, libBar.Module(), libFooAfdoVariantWithLibBar.Module()) { t.Errorf("libFoo missing dependency on non-afdo variant of libBar") } } @@ -563,11 +547,11 @@ func TestAfdoDepsWithoutProfile(t *testing.T) { t.Errorf("Expected 'libBarAfdoVariant' to enable afdo, but did not find %q in cflags %q", expectedCFlag, cFlags) } // Check dependency edge from afdo-enabled module to static deps - if !hasDirectDep(result, libTest.Module(), libFooAfdoVariant.Module()) { + if !android.HasDirectDep(result, libTest.Module(), libFooAfdoVariant.Module()) { t.Errorf("libTest missing dependency on afdo variant of libFoo") } - if !hasDirectDep(result, libFooAfdoVariant.Module(), libBarAfdoVariant.Module()) { + if !android.HasDirectDep(result, libFooAfdoVariant.Module(), libBarAfdoVariant.Module()) { t.Errorf("libTest missing dependency on afdo variant of libBar") } @@ -585,11 +569,11 @@ func TestAfdoDepsWithoutProfile(t *testing.T) { } // Check dependency edges of static deps - if hasDirectDep(result, libTest.Module(), libFoo.Module()) { + if android.HasDirectDep(result, libTest.Module(), libFoo.Module()) { t.Errorf("libTest should not depend on non-afdo variant of libFoo") } - if !hasDirectDep(result, libFoo.Module(), libBar.Module()) { + if !android.HasDirectDep(result, libFoo.Module(), libBar.Module()) { t.Errorf("libFoo missing dependency on non-afdo variant of libBar") } } diff --git a/cc/cc_test.go b/cc/cc_test.go index 7240ea587..e9d2474ac 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -26,8 +26,6 @@ import ( "android/soong/aidl_library" "android/soong/android" - - "github.com/google/blueprint" ) func init() { @@ -3124,17 +3122,6 @@ func TestImageVariants(t *testing.T) { ctx := prepareForCcTest.RunTestWithBp(t, bp) - hasDep := func(m android.Module, wantDep android.Module) bool { - t.Helper() - var found bool - ctx.VisitDirectDeps(m, func(dep blueprint.Module) { - if dep == wantDep { - found = true - } - }) - return found - } - testDepWithVariant := func(imageVariant string) { imageVariantStr := "" if imageVariant != "core" { @@ -3142,7 +3129,8 @@ func TestImageVariants(t *testing.T) { } binFooModule := ctx.ModuleForTests(t, "binfoo", "android"+imageVariantStr+"_arm64_armv8-a").Module() libBarModule := ctx.ModuleForTests(t, "libbar", "android"+imageVariantStr+"_arm64_armv8-a_shared").Module() - android.AssertBoolEquals(t, "binfoo should have dependency on libbar with image variant "+imageVariant, true, hasDep(binFooModule, libBarModule)) + android.AssertBoolEquals(t, "binfoo should have dependency on libbar with image variant "+imageVariant, true, + android.HasDirectDep(ctx, binFooModule, libBarModule)) } testDepWithVariant("core") diff --git a/cc/lto_test.go b/cc/lto_test.go index 3fb1f3c06..7cfbba9e1 100644 --- a/cc/lto_test.go +++ b/cc/lto_test.go @@ -19,24 +19,12 @@ import ( "testing" "android/soong/android" - - "github.com/google/blueprint" ) var LTOPreparer = android.GroupFixturePreparers( prepareForCcTest, ) -func hasDep(result *android.TestResult, m android.Module, wantDep android.Module) bool { - var found bool - result.VisitDirectDeps(m, func(dep blueprint.Module) { - if dep == wantDep { - found = true - } - }) - return found -} - func TestThinLtoDeps(t *testing.T) { t.Parallel() bp := ` @@ -73,22 +61,22 @@ func TestThinLtoDeps(t *testing.T) { libLto := result.ModuleForTests(t, "lto_enabled", "android_arm64_armv8-a_shared").Module() libFoo := result.ModuleForTests(t, "foo", "android_arm64_armv8-a_static").Module() - if !hasDep(result, libLto, libFoo) { + if !android.HasDirectDep(result, libLto, libFoo) { t.Errorf("'lto_enabled' missing dependency on the default variant of 'foo'") } libBaz := result.ModuleForTests(t, "baz", "android_arm64_armv8-a_static").Module() - if !hasDep(result, libFoo, libBaz) { + if !android.HasDirectDep(result, libFoo, libBaz) { t.Errorf("'foo' missing dependency on the default variant of transitive dep 'baz'") } libNeverLto := result.ModuleForTests(t, "lib_never_lto", "android_arm64_armv8-a_static").Module() - if !hasDep(result, libLto, libNeverLto) { + if !android.HasDirectDep(result, libLto, libNeverLto) { t.Errorf("'lto_enabled' missing dependency on the default variant of 'lib_never_lto'") } libBar := result.ModuleForTests(t, "bar", "android_arm64_armv8-a_shared").Module() - if !hasDep(result, libLto, libBar) { + if !android.HasDirectDep(result, libLto, libBar) { t.Errorf("'lto_enabled' missing dependency on the default variant of 'bar'") } @@ -142,12 +130,12 @@ func TestThinLtoOnlyOnStaticDep(t *testing.T) { libRootLtoNever := result.ModuleForTests(t, "root_no_lto", "android_arm64_armv8-a_shared").Module() libFoo := result.ModuleForTests(t, "foo", "android_arm64_armv8-a_static") - if !hasDep(result, libRoot, libFoo.Module()) { + if !android.HasDirectDep(result, libRoot, libFoo.Module()) { t.Errorf("'root' missing dependency on the default variant of 'foo'") } libFooNoLto := result.ModuleForTests(t, "foo", "android_arm64_armv8-a_static_lto-none") - if !hasDep(result, libRootLtoNever, libFooNoLto.Module()) { + if !android.HasDirectDep(result, libRootLtoNever, libFooNoLto.Module()) { t.Errorf("'root_no_lto' missing dependency on the lto_none variant of 'foo'") } @@ -157,7 +145,7 @@ func TestThinLtoOnlyOnStaticDep(t *testing.T) { } libBaz := result.ModuleForTests(t, "baz", "android_arm64_armv8-a_static") - if !hasDep(result, libFoo.Module(), libBaz.Module()) { + if !android.HasDirectDep(result, libFoo.Module(), libBaz.Module()) { t.Errorf("'foo' missing dependency on the default variant of transitive dep 'baz'") } diff --git a/cc/orderfile_test.go b/cc/orderfile_test.go index 41253adc6..b5709ae0a 100644 --- a/cc/orderfile_test.go +++ b/cc/orderfile_test.go @@ -207,11 +207,11 @@ func TestOrderfileProfilePropagateStaticDeps(t *testing.T) { } // Check dependency edge from orderfile-enabled module to orderfile variant static libraries - if !hasDirectDep(result, libTest.Module(), libFooOfVariant.Module()) { + if !android.HasDirectDep(result, libTest.Module(), libFooOfVariant.Module()) { t.Errorf("libTest missing dependency on orderfile variant of libFoo") } - if !hasDirectDep(result, libFooOfVariant.Module(), libBarOfVariant.Module()) { + if !android.HasDirectDep(result, libFooOfVariant.Module(), libBarOfVariant.Module()) { t.Errorf("libTest missing dependency on orderfile variant of libBar") } @@ -230,11 +230,11 @@ func TestOrderfileProfilePropagateStaticDeps(t *testing.T) { } // Check no dependency edge from orderfile-enabled module to non-orderfile variant static libraries - if hasDirectDep(result, libTest.Module(), libFoo.Module()) { + if android.HasDirectDep(result, libTest.Module(), libFoo.Module()) { t.Errorf("libTest has dependency on non-orderfile variant of libFoo") } - if !hasDirectDep(result, libFoo.Module(), libBar.Module()) { + if !android.HasDirectDep(result, libFoo.Module(), libBar.Module()) { t.Errorf("libTest has dependency on non-orderfile variant of libBar") } } @@ -285,11 +285,11 @@ func TestOrderfileLoadPropagateStaticDeps(t *testing.T) { libBar := result.ModuleForTests(t, "libBar", "android_arm64_armv8-a_static") // Check dependency edge from orderfile-enabled module to non-orderfile variant static libraries - if !hasDirectDep(result, libTest.Module(), libFoo.Module()) { + if !android.HasDirectDep(result, libTest.Module(), libFoo.Module()) { t.Errorf("libTest missing dependency on non-orderfile variant of libFoo") } - if !hasDirectDep(result, libFoo.Module(), libBar.Module()) { + if !android.HasDirectDep(result, libFoo.Module(), libBar.Module()) { t.Errorf("libTest missing dependency on non-orderfile variant of libBar") } @@ -365,11 +365,11 @@ func TestOrderfileProfilePropagateSharedDeps(t *testing.T) { } // Check dependency edge from orderfile-enabled module to non-orderfile variant static libraries - if !hasDirectDep(result, libTest.Module(), libFoo.Module()) { + if !android.HasDirectDep(result, libTest.Module(), libFoo.Module()) { t.Errorf("libTest missing dependency on non-orderfile variant of libFoo") } - if !hasDirectDep(result, libFoo.Module(), libBar.Module()) { + if !android.HasDirectDep(result, libFoo.Module(), libBar.Module()) { t.Errorf("libTest missing dependency on non-orderfile variant of libBar") } @@ -445,11 +445,11 @@ func TestOrderfileProfileStaticLibrary(t *testing.T) { } // Check dependency edge from orderfile-enabled module to non-orderfile variant libraries - if !hasDirectDep(result, libTest.Module(), libFoo.Module()) { + if !android.HasDirectDep(result, libTest.Module(), libFoo.Module()) { t.Errorf("libTest missing dependency on non-orderfile variant of libFoo") } - if !hasDirectDep(result, libFoo.Module(), libBar.Module()) { + if !android.HasDirectDep(result, libFoo.Module(), libBar.Module()) { t.Errorf("libTest missing dependency on non-orderfile variant of libBar") } diff --git a/cc/prebuilt_test.go b/cc/prebuilt_test.go index af68ca6bf..cade677ee 100644 --- a/cc/prebuilt_test.go +++ b/cc/prebuilt_test.go @@ -20,7 +20,6 @@ import ( "testing" "android/soong/android" - "github.com/google/blueprint" ) var prepareForPrebuiltTest = android.GroupFixturePreparers( @@ -132,42 +131,31 @@ func TestPrebuilt(t *testing.T) { prebuiltLibfShared := ctx.ModuleForTests(t, "prebuilt_libf", "android_arm64_armv8-a_shared").Module() prebuiltCrtx := ctx.ModuleForTests(t, "prebuilt_crtx", "android_arm64_armv8-a").Module() - hasDep := func(m android.Module, wantDep android.Module) bool { - t.Helper() - var found bool - ctx.VisitDirectDeps(m, func(dep blueprint.Module) { - if dep == wantDep { - found = true - } - }) - return found - } - - if !hasDep(liba, prebuiltLiba) { + if !android.HasDirectDep(ctx, liba, prebuiltLiba) { t.Errorf("liba missing dependency on prebuilt_liba") } - if !hasDep(libb, prebuiltLibb) { + if !android.HasDirectDep(ctx, libb, prebuiltLibb) { t.Errorf("libb missing dependency on prebuilt_libb") } - if !hasDep(libd, prebuiltLibd) { + if !android.HasDirectDep(ctx, libd, prebuiltLibd) { t.Errorf("libd missing dependency on prebuilt_libd") } - if !hasDep(libe, prebuiltLibe) { + if !android.HasDirectDep(ctx, libe, prebuiltLibe) { t.Errorf("libe missing dependency on prebuilt_libe") } - if !hasDep(libfStatic, prebuiltLibfStatic) { + if !android.HasDirectDep(ctx, libfStatic, prebuiltLibfStatic) { t.Errorf("libf static missing dependency on prebuilt_libf") } - if !hasDep(libfShared, prebuiltLibfShared) { + if !android.HasDirectDep(ctx, libfShared, prebuiltLibfShared) { t.Errorf("libf shared missing dependency on prebuilt_libf") } - if !hasDep(crtx, prebuiltCrtx) { + if !android.HasDirectDep(ctx, crtx, prebuiltCrtx) { t.Errorf("crtx missing dependency on prebuilt_crtx") } @@ -440,17 +428,6 @@ func TestMultiplePrebuilts(t *testing.T) { } all_apex_contributions {name: "all_apex_contributions"} ` - hasDep := func(ctx *android.TestContext, m android.Module, wantDep android.Module) bool { - t.Helper() - var found bool - ctx.VisitDirectDeps(m, func(dep blueprint.Module) { - if dep == wantDep { - found = true - } - }) - return found - } - testCases := []struct { desc string selectedDependencyName string @@ -486,7 +463,7 @@ func TestMultiplePrebuilts(t *testing.T) { }, preparer) libfoo := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared").Module() expectedDependency := ctx.ModuleForTests(t, tc.expectedDependencyName, "android_arm64_armv8-a_shared").Module() - android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from %s to %s\n", libfoo.Name(), tc.expectedDependencyName), true, hasDep(ctx, libfoo, expectedDependency)) + android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from %s to %s\n", libfoo.Name(), tc.expectedDependencyName), true, android.HasDirectDep(ctx, libfoo, expectedDependency)) // check that LOCAL_SHARED_LIBRARIES contains libbar and not libbar.v entries := android.AndroidMkInfoForTest(t, ctx, libfoo).PrimaryInfo android.AssertStringListContains(t, "Version should not be present in LOCAL_SHARED_LIBRARIES", entries.EntryMap["LOCAL_SHARED_LIBRARIES"], "libbar") @@ -539,16 +516,6 @@ func TestMultiplePrebuiltsPreferredUsingLegacyFlags(t *testing.T) { } all_apex_contributions {name: "all_apex_contributions"} ` - hasDep := func(ctx *android.TestContext, m android.Module, wantDep android.Module) bool { - t.Helper() - var found bool - ctx.VisitDirectDeps(m, func(dep blueprint.Module) { - if dep == wantDep { - found = true - } - }) - return found - } testCases := []struct { desc string @@ -587,7 +554,8 @@ func TestMultiplePrebuiltsPreferredUsingLegacyFlags(t *testing.T) { } libfoo := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared").Module() expectedDependency := ctx.ModuleForTests(t, tc.expectedDependencyName, "android_arm64_armv8-a_shared").Module() - android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from %s to %s\n", libfoo.Name(), tc.expectedDependencyName), true, hasDep(ctx, libfoo, expectedDependency)) + android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from %s to %s\n", libfoo.Name(), tc.expectedDependencyName), + true, android.HasDirectDep(ctx, libfoo, expectedDependency)) } } @@ -617,16 +585,6 @@ func TestMissingVariantInModuleSdk(t *testing.T) { } all_apex_contributions {name: "all_apex_contributions"} ` - hasDep := func(ctx *android.TestContext, m android.Module, wantDep android.Module) bool { - t.Helper() - var found bool - ctx.VisitDirectDeps(m, func(dep blueprint.Module) { - if dep == wantDep { - found = true - } - }) - return found - } preparer := android.GroupFixturePreparers( android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { @@ -642,5 +600,6 @@ func TestMissingVariantInModuleSdk(t *testing.T) { sourceLibBar := ctx.ModuleForTests(t, "libbar", "android_arm64_armv8-a_static").Module() // Even though the prebuilt is listed in apex_contributions, the prebuilt does not have a static variant. // Therefore source of libbar should be used. - android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from libfoo to source libbar"), true, hasDep(ctx, libfoo, sourceLibBar)) + android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from libfoo to source libbar"), true, + android.HasDirectDep(ctx, libfoo, sourceLibBar)) } diff --git a/java/java_test.go b/java/java_test.go index 1ba78d49b..495783e7c 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -2740,16 +2740,6 @@ func TestMultiplePrebuilts(t *testing.T) { contents: ["%v"], } ` - hasDep := func(ctx *android.TestResult, m android.Module, wantDep android.Module) bool { - t.Helper() - var found bool - ctx.VisitDirectDeps(m, func(dep blueprint.Module) { - if dep == wantDep { - found = true - } - }) - return found - } hasFileWithStem := func(m android.TestingModule, stem string) bool { t.Helper() @@ -2793,7 +2783,8 @@ func TestMultiplePrebuilts(t *testing.T) { // check that rdep gets the correct variation of dep foo := ctx.ModuleForTests(t, "foo", "android_common") expectedDependency := ctx.ModuleForTests(t, tc.expectedDependencyName, "android_common") - android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from %s to %s\n", foo.Module().Name(), tc.expectedDependencyName), true, hasDep(ctx, foo.Module(), expectedDependency.Module())) + android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from %s to %s\n", foo.Module().Name(), tc.expectedDependencyName), + true, android.HasDirectDep(ctx, foo.Module(), expectedDependency.Module())) // check that output file of dep is always bar.jar // The filename should be agnostic to source/prebuilt/prebuilt_version -- cgit v1.2.3 From 5a308ad421532dba9b54527da129aa2fcf2a92ea Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Mon, 7 Apr 2025 20:15:06 -0700 Subject: Wrap blueprint.Context.Visit* for android.TestContext Add wrappers in android.TestContext that convert the blueprint.Context.Visit* methods to using android.Module and android.ModuleProxy. This reduces the mixing of blueprint.Module and android.Module in Soong code, adn will also be used to add extra logic to VisitAllModules and VisitDirectDeps later to convert ModuleProxies to Modules in tests once Blueprint only has a ModuleProxy available. Test: all soong tests pass Change-Id: Id497dc7caf4ac5fd2c2c23d27c17e124bec6ab8d --- aconfig/aconfig_value_set_test.go | 4 +-- aconfig/codegen/cc_aconfig_library_test.go | 4 +-- android/defaults_test.go | 4 +-- android/namespace_test.go | 6 ++-- android/prebuilt_test.go | 4 +-- android/testing.go | 48 +++++++++++++++++++++++------ cc/cc_test_only_property_test.go | 8 ++--- cc/library_headers_test.go | 4 +-- cc/ndk_test.go | 4 +-- java/java_test.go | 4 +-- java/prebuilt_apis_test.go | 4 +-- java/testing.go | 4 +-- python/python_test.go | 4 +-- tradefed_modules/test_module_config_test.go | 9 +++--- 14 files changed, 62 insertions(+), 49 deletions(-) diff --git a/aconfig/aconfig_value_set_test.go b/aconfig/aconfig_value_set_test.go index 1f042442c..cc1579cee 100644 --- a/aconfig/aconfig_value_set_test.go +++ b/aconfig/aconfig_value_set_test.go @@ -18,8 +18,6 @@ import ( "testing" "android/soong/android" - - "github.com/google/blueprint" ) func TestAconfigValueSet(t *testing.T) { @@ -90,7 +88,7 @@ func TestAconfigValueSetBpGlob(t *testing.T) { t.Helper() module := result.ModuleForTests(t, name, variant).Module() depFound := false - result.VisitDirectDeps(module, func(m blueprint.Module) { + result.VisitDirectDeps(module, func(m android.Module) { if m.Name() == dep { depFound = true } diff --git a/aconfig/codegen/cc_aconfig_library_test.go b/aconfig/codegen/cc_aconfig_library_test.go index 5cb3f8b33..17abf1e07 100644 --- a/aconfig/codegen/cc_aconfig_library_test.go +++ b/aconfig/codegen/cc_aconfig_library_test.go @@ -20,8 +20,6 @@ import ( "android/soong/android" "android/soong/cc" - - "github.com/google/blueprint" ) var ccCodegenModeTestData = []struct { @@ -256,7 +254,7 @@ func TestForceReadOnly(t *testing.T) { module := result.ModuleForTests(t, "my_cc_aconfig_library", "android_arm64_armv8-a_shared").Module() dependOnReadLib := false - result.VisitDirectDeps(module, func(dep blueprint.Module) { + result.VisitDirectDeps(module, func(dep android.Module) { if dep.Name() == libAconfigStorageReadApiCcDep { dependOnReadLib = true } diff --git a/android/defaults_test.go b/android/defaults_test.go index 24f14617a..f57a7a6c1 100644 --- a/android/defaults_test.go +++ b/android/defaults_test.go @@ -16,8 +16,6 @@ package android import ( "testing" - - "github.com/google/blueprint" ) type defaultsTestProperties struct { @@ -158,7 +156,7 @@ func TestDefaultsPathProperties(t *testing.T) { collectDeps := func(m Module) []string { var deps []string - result.VisitDirectDeps(m, func(dep blueprint.Module) { + result.VisitDirectDeps(m, func(dep Module) { deps = append(deps, result.ModuleName(dep)) }) return deps diff --git a/android/namespace_test.go b/android/namespace_test.go index 335a9b2eb..f4f0b33ae 100644 --- a/android/namespace_test.go +++ b/android/namespace_test.go @@ -664,7 +664,7 @@ func dirBpToPreparer(bps map[string]string) FixturePreparer { func dependsOn(result *TestResult, module TestingModule, possibleDependency TestingModule) bool { depends := false - visit := func(dependency blueprint.Module) { + visit := func(dependency Module) { if dependency == possibleDependency.module { depends = true } @@ -675,7 +675,7 @@ func dependsOn(result *TestResult, module TestingModule, possibleDependency Test func numDeps(result *TestResult, module TestingModule) int { count := 0 - visit := func(dependency blueprint.Module) { + visit := func(dependency Module) { count++ } result.VisitDirectDeps(module.module, visit) @@ -687,7 +687,7 @@ func getModule(result *TestResult, moduleName string) TestingModule { } func findModuleById(result *TestResult, id string) (module TestingModule) { - visit := func(candidate blueprint.Module) { + visit := func(candidate Module) { testModule, ok := candidate.(*testModule) if ok { if testModule.properties.Id == id { diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go index d31fc4fcd..f215be8a9 100644 --- a/android/prebuilt_test.go +++ b/android/prebuilt_test.go @@ -16,8 +16,6 @@ package android import ( "testing" - - "github.com/google/blueprint" ) func TestPrebuilts(t *testing.T) { @@ -338,7 +336,7 @@ func TestPrebuilts(t *testing.T) { foo := result.ModuleForTests(t, "foo", variant) t.Run(foo.Module().Target().Os.String(), func(t *testing.T) { var dependsOnSourceModule, dependsOnPrebuiltModule bool - result.VisitDirectDeps(foo.Module(), func(m blueprint.Module) { + result.VisitDirectDeps(foo.Module(), func(m Module) { if _, ok := m.(*sourceModule); ok { dependsOnSourceModule = true } diff --git a/android/testing.go b/android/testing.go index 00ede57ef..1efa02421 100644 --- a/android/testing.go +++ b/android/testing.go @@ -284,6 +284,36 @@ func (ctx *TestContext) OtherModulePropertyErrorf(module ModuleOrProxy, property panic(fmt.Sprintf(fmt_, args...)) } +// VisitAllModules wraps blueprint.Context.VisitAllModules, converting blueprint.Module to android.Module. +func (ctx *TestContext) VisitAllModules(visit func(Module)) { + ctx.Context.VisitAllModules(func(module blueprint.Module) { + visit(module.(Module)) + }) +} + +// VisitAllModulesProxies wraps blueprint.Context.VisitAllModulesProxies, converting blueprint.ModuleProxy to +// android.ModuleProxy. +func (ctx *TestContext) VisitAllModulesProxies(visit func(ModuleProxy)) { + ctx.Context.VisitAllModulesProxies(func(module blueprint.ModuleProxy) { + visit(ModuleProxy{module}) + }) +} + +// VisitDirectDeps wraps blueprint.Context.VisitDirectDeps, converting blueprint.Module to android.Module. +func (ctx *TestContext) VisitDirectDeps(module Module, visit func(Module)) { + ctx.Context.VisitDirectDeps(module, func(module blueprint.Module) { + visit(module.(Module)) + }) +} + +// VisitDirectDepsProxies wraps blueprint.Context.VisitDirectDepsProxies, converting blueprint.ModuleProxy to +// android.ModuleProxy. +func (ctx *TestContext) VisitDirectDepsProxies(module ModuleOrProxy, visit func(ModuleProxy)) { + ctx.Context.VisitDirectDepsProxies(module, func(dep blueprint.ModuleProxy) { + visit(ModuleProxy{dep}) + }) +} + // registeredComponentOrder defines the order in which a sortableComponent type is registered at // runtime and provides support for reordering the components registered for a test in the same // way. @@ -549,7 +579,7 @@ func (ctx *TestContext) RegisterParallelSingletonType(name string, factory Singl func (ctx *TestContext) ModuleVariantForTests(t *testing.T, name string, matchVariations map[string]string) TestingModule { t.Helper() modules := []Module{} - ctx.VisitAllModules(func(m blueprint.Module) { + ctx.VisitAllModules(func(m Module) { if ctx.ModuleName(m) == name { am := m.(Module) amMut := am.base().commonProperties.DebugMutators @@ -571,7 +601,7 @@ func (ctx *TestContext) ModuleVariantForTests(t *testing.T, name string, matchVa // Show all the modules or module variants that do exist. var allModuleNames []string var allVariants []string - ctx.VisitAllModules(func(m blueprint.Module) { + ctx.VisitAllModules(func(m Module) { allModuleNames = append(allModuleNames, ctx.ModuleName(m)) if ctx.ModuleName(m) == name { allVariants = append(allVariants, m.(Module).String()) @@ -604,9 +634,9 @@ func (ctx *TestContext) ModuleVariantForTests(t *testing.T, name string, matchVa func (ctx *TestContext) ModuleForTests(t *testing.T, name, variant string) TestingModule { t.Helper() var module Module - ctx.VisitAllModules(func(m blueprint.Module) { + ctx.VisitAllModules(func(m Module) { if ctx.ModuleName(m) == name && ctx.ModuleSubDir(m) == variant { - module = m.(Module) + module = m } }) @@ -614,7 +644,7 @@ func (ctx *TestContext) ModuleForTests(t *testing.T, name, variant string) Testi // find all the modules that do exist var allModuleNames []string var allVariants []string - ctx.VisitAllModules(func(m blueprint.Module) { + ctx.VisitAllModules(func(m Module) { allModuleNames = append(allModuleNames, ctx.ModuleName(m)) if ctx.ModuleName(m) == name { allVariants = append(allVariants, ctx.ModuleSubDir(m)) @@ -636,7 +666,7 @@ func (ctx *TestContext) ModuleForTests(t *testing.T, name, variant string) Testi func (ctx *TestContext) ModuleVariantsForTests(name string) []string { var variants []string - ctx.VisitAllModules(func(m blueprint.Module) { + ctx.VisitAllModules(func(m Module) { if ctx.ModuleName(m) == name { variants = append(variants, ctx.ModuleSubDir(m)) } @@ -1417,13 +1447,13 @@ func PanickingConfigAndErrorContext(ctx *TestContext) ConfigurableEvaluatorConte } type visitDirectDepsInterface interface { - VisitDirectDeps(blueprint.Module, func(dep blueprint.Module)) + VisitDirectDepsProxies(ModuleOrProxy, func(dep ModuleProxy)) } // HasDirectDep returns true if wantDep is a direct dependency of m. func HasDirectDep(ctx visitDirectDepsInterface, m Module, wantDep ModuleOrProxy) bool { var found bool - ctx.VisitDirectDeps(m, func(dep blueprint.Module) { + ctx.VisitDirectDepsProxies(m, func(dep ModuleProxy) { if EqualModules(dep, wantDep) { found = true } @@ -1435,7 +1465,7 @@ func HasDirectDep(ctx visitDirectDepsInterface, m Module, wantDep ModuleOrProxy) func AssertHasDirectDep(t *testing.T, ctx visitDirectDepsInterface, m Module, wantDep ModuleOrProxy) { t.Helper() found := false - ctx.VisitDirectDeps(m, func(dep blueprint.Module) { + ctx.VisitDirectDepsProxies(m, func(dep ModuleProxy) { if EqualModules(dep, wantDep) { found = true } diff --git a/cc/cc_test_only_property_test.go b/cc/cc_test_only_property_test.go index a178cad68..fe4fb56a2 100644 --- a/cc/cc_test_only_property_test.go +++ b/cc/cc_test_only_property_test.go @@ -15,13 +15,13 @@ package cc import ( - "android/soong/android" - "android/soong/android/team_proto" "log" "strings" "testing" - "github.com/google/blueprint" + "android/soong/android" + "android/soong/android/team_proto" + "google.golang.org/protobuf/proto" ) @@ -56,7 +56,7 @@ func TestTestOnlyProvider(t *testing.T) { // marked as test-only are marked as test-only. actualTestOnly := []string{} - ctx.VisitAllModules(func(m blueprint.Module) { + ctx.VisitAllModules(func(m android.Module) { if provider, ok := android.OtherModuleProvider(ctx.TestContext.OtherModuleProviderAdaptor(), m, android.TestOnlyProviderKey); ok { if provider.TestOnly { actualTestOnly = append(actualTestOnly, m.Name()) diff --git a/cc/library_headers_test.go b/cc/library_headers_test.go index 88ccd4303..73e599672 100644 --- a/cc/library_headers_test.go +++ b/cc/library_headers_test.go @@ -19,8 +19,6 @@ import ( "testing" "android/soong/android" - - "github.com/google/blueprint" ) func TestLibraryHeaders(t *testing.T) { @@ -85,7 +83,7 @@ func TestPrebuiltLibraryHeadersPreferred(t *testing.T) { prebuiltDep := ctx.ModuleForTests(t, "prebuilt_headers", "android_arm64_armv8-a") hasSourceDep := false hasPrebuiltDep := false - ctx.VisitDirectDeps(lib.Module(), func(dep blueprint.Module) { + ctx.VisitDirectDeps(lib.Module(), func(dep android.Module) { if dep == sourceDep.Module() { hasSourceDep = true } diff --git a/cc/ndk_test.go b/cc/ndk_test.go index 8574bf148..e9804024c 100644 --- a/cc/ndk_test.go +++ b/cc/ndk_test.go @@ -17,15 +17,13 @@ package cc import ( "testing" - "github.com/google/blueprint" - "android/soong/android" ) func TestNdkHeaderDependency(t *testing.T) { isDep := func(ctx *android.TestResult, from, toExpected android.Module) bool { foundDep := false - ctx.VisitDirectDeps(from, func(toActual blueprint.Module) { + ctx.VisitDirectDeps(from, func(toActual android.Module) { if toExpected.Name() == toActual.Name() { foundDep = true } diff --git a/java/java_test.go b/java/java_test.go index 495783e7c..813b8e44f 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -3141,7 +3141,7 @@ func assertTestOnlyAndTopLevel(t *testing.T, ctx *android.TestResult, expectedTe } } - ctx.VisitAllModules(func(m blueprint.Module) { + ctx.VisitAllModules(func(m android.Module) { addActuals(m, android.TestOnlyProviderKey) }) @@ -3162,7 +3162,7 @@ func TestNativeRequiredDepOfJavaBinary(t *testing.T) { t.Parallel() findDepsOfModule := func(ctx *android.TestContext, module android.Module, depName string) []blueprint.Module { var ret []blueprint.Module - ctx.VisitDirectDeps(module, func(dep blueprint.Module) { + ctx.VisitDirectDeps(module, func(dep android.Module) { if dep.Name() == depName { ret = append(ret, dep) } diff --git a/java/prebuilt_apis_test.go b/java/prebuilt_apis_test.go index 17fdae962..7d927fc0e 100644 --- a/java/prebuilt_apis_test.go +++ b/java/prebuilt_apis_test.go @@ -20,8 +20,6 @@ import ( "testing" "android/soong/android" - - "github.com/google/blueprint" ) func intPtr(v int) *int { @@ -40,7 +38,7 @@ func TestPrebuiltApis_SystemModulesCreation(t *testing.T) { ).RunTest(t) sdkSystemModules := []string{} - result.VisitAllModules(func(module blueprint.Module) { + result.VisitAllModules(func(module android.Module) { name := android.RemoveOptionalPrebuiltPrefix(module.Name()) if strings.HasPrefix(name, "sdk_") && strings.HasSuffix(name, "_system_modules") { sdkSystemModules = append(sdkSystemModules, name) diff --git a/java/testing.go b/java/testing.go index 82dbcee89..86849f28b 100644 --- a/java/testing.go +++ b/java/testing.go @@ -583,7 +583,7 @@ func getModuleDependencies(t *testing.T, ctx *android.TestContext, name, variant t.Helper() module := ctx.ModuleForTests(t, name, variant).Module() deps := []string{} - ctx.VisitDirectDeps(module, func(m blueprint.Module) { + ctx.VisitDirectDeps(module, func(m android.Module) { deps = append(deps, m.Name()) }) return android.SortedUniqueStrings(deps) @@ -650,7 +650,7 @@ func CheckPlatformBootclasspathDependencies(t *testing.T, ctx *android.TestConte t.Helper() platformBootclasspath := ctx.ModuleForTests(t, name, variant).Module().(*platformBootclasspathModule) modules := []android.Module{} - ctx.VisitDirectDeps(platformBootclasspath, func(m blueprint.Module) { + ctx.VisitDirectDeps(platformBootclasspath, func(m android.Module) { modules = append(modules, m.(android.Module)) }) diff --git a/python/python_test.go b/python/python_test.go index ef8ae25c5..696c27ff1 100644 --- a/python/python_test.go +++ b/python/python_test.go @@ -23,8 +23,6 @@ import ( "android/soong/android" "android/soong/cc" - - "github.com/google/blueprint" ) type pyModule struct { @@ -291,7 +289,7 @@ func TestTestOnlyProvider(t *testing.T) { // marked as test-only are marked as test-only. actualTestOnly := []string{} - ctx.VisitAllModules(func(m blueprint.Module) { + ctx.VisitAllModules(func(m android.Module) { if provider, ok := android.OtherModuleProvider(ctx.TestContext.OtherModuleProviderAdaptor(), m, android.TestOnlyProviderKey); ok { if provider.TestOnly { actualTestOnly = append(actualTestOnly, m.Name()) diff --git a/tradefed_modules/test_module_config_test.go b/tradefed_modules/test_module_config_test.go index 302f9a9d5..3a5c3d7f6 100644 --- a/tradefed_modules/test_module_config_test.go +++ b/tradefed_modules/test_module_config_test.go @@ -14,15 +14,14 @@ package tradefed_modules import ( - "android/soong/android" - "android/soong/java" - "android/soong/sh" "fmt" "strconv" "strings" "testing" - "github.com/google/blueprint" + "android/soong/android" + "android/soong/java" + "android/soong/sh" ) const bp = ` @@ -510,7 +509,7 @@ func TestTestOnlyProvider(t *testing.T) { // marked as test-only are marked as test-only. actualTestOnly := []string{} - ctx.VisitAllModules(func(m blueprint.Module) { + ctx.VisitAllModules(func(m android.Module) { if provider, ok := android.OtherModuleProvider(ctx.TestContext.OtherModuleProviderAdaptor(), m, android.TestOnlyProviderKey); ok { if provider.TestOnly { actualTestOnly = append(actualTestOnly, m.Name()) -- cgit v1.2.3 From 4b7561aad70696ad03faf2edbd0dba885bc1cf33 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Tue, 8 Apr 2025 11:16:52 -0700 Subject: Use VisitDirectDepsProxy in cc/sanitize.go Replace VisitDirectDepsIf with VisitDirectDepsProxy. Bug: 377723687 Test: go test ./cc Change-Id: I0eb50e441a14895c93a17c12683fe6682c097e74 --- cc/sanitize.go | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/cc/sanitize.go b/cc/sanitize.go index f0b0308ae..86b75496a 100644 --- a/cc/sanitize.go +++ b/cc/sanitize.go @@ -1856,30 +1856,34 @@ func (txt *sanitizerLibrariesTxtModule) DepsMutator(actx android.BottomUpMutator func (txt *sanitizerLibrariesTxtModule) getSanitizerLibs(ctx android.ModuleContext) string { var sanitizerLibStems []string - ctx.VisitDirectDepsIf(func(m android.Module) bool { - if !m.Enabled(ctx) { - return false + ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) { + info := android.OtherModuleProviderOrDefault(ctx, m, android.CommonModuleInfoProvider) + if !info.Enabled { + return } - ccModule, _ := m.(*Module) - if ccModule == nil || ccModule.library == nil || !ccModule.library.shared() { - return false + if _, ok := android.OtherModuleProvider(ctx, m, SharedLibraryInfoProvider); !ok { + return } targets := ctx.Config().Targets[android.Android] + var targetMatches bool for _, target := range targets { - if m.Target().Os == target.Os && m.Target().Arch.ArchType == target.Arch.ArchType { - return true + if info.Target.Os == target.Os && info.Target.Arch.ArchType == target.Arch.ArchType { + targetMatches = true } } - return false - }, func(m android.Module) { - ccModule, _ := m.(*Module) - outputFile := ccModule.outputFile - if outputFile.Valid() { - sanitizerLibStems = append(sanitizerLibStems, outputFile.Path().Base()) + if !targetMatches { + return + } + + outputFiles := android.OutputFilesForModule(ctx, m, "") + if len(outputFiles) == 1 { + sanitizerLibStems = append(sanitizerLibStems, outputFiles[0].Base()) + } else if len(outputFiles) > 1 { + panic(fmt.Errorf("multiple output files for %s: %s", m, outputFiles.Strings())) } }) -- cgit v1.2.3 From b22e79c4af53954b55d5a2f8c7bcdec57765cdf7 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Tue, 8 Apr 2025 11:18:17 -0700 Subject: Use VisitDirectDepsProxy in bpf Replace VisitDirectDeps with VisitDirectDepsProxy. Bug: 377723687 Test: go test ./bpf Change-Id: I6f7975359f62ad56accd7ea5afe9f121c5ebe4f4 --- bpf/libbpf/libbpf_prog.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bpf/libbpf/libbpf_prog.go b/bpf/libbpf/libbpf_prog.go index 44013e5e3..b73631212 100644 --- a/bpf/libbpf/libbpf_prog.go +++ b/bpf/libbpf/libbpf_prog.go @@ -173,12 +173,12 @@ func (libbpf *libbpfProg) GenerateAndroidBuildActions(ctx android.ModuleContext) cflags = append(cflags, "-fdebug-prefix-map=/proc/self/cwd=") } - ctx.VisitDirectDeps(func(dep android.Module) { + ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) { depTag := ctx.OtherModuleDependencyTag(dep) if depTag == libbpfProgDepTag { - if genRule, ok := dep.(genrule.SourceFileGenerator); ok { - cFlagsDeps = append(cFlagsDeps, genRule.GeneratedDeps()...) - dirs := genRule.GeneratedHeaderDirs() + if info, ok := android.OtherModuleProvider(ctx, dep, android.GeneratedSourceInfoProvider); ok { + cFlagsDeps = append(cFlagsDeps, info.GeneratedDeps...) + dirs := info.GeneratedHeaderDirs for _, dir := range dirs { cflags = append(cflags, "-I "+dir.String()) } -- cgit v1.2.3 From 71f890e81e333fb1a227ac8c1bbbd9b8ed749cdb Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Mon, 7 Apr 2025 14:05:17 -0700 Subject: Add FreeModulesAfterGenerateBuildActions Forward FreeModulesAfterGenerateBuildActions from Blueprint to Soong. Calling FreeModulesAfterGenerateBuildActions marks this module as no longer necessary after the completion of GenerateBuildActions, i.e. all later accesses to the module will be via ModuleProxy and not direct access to the Module. Test: builds Change-Id: I7f665f0e5382bb882a5f44f9275e35ddbde556ec --- android/module_context.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/android/module_context.go b/android/module_context.go index 6e562bb24..516cc4cd9 100644 --- a/android/module_context.go +++ b/android/module_context.go @@ -284,6 +284,11 @@ type ModuleContext interface { // Defines this module as a compatibility suite test and gives all the information needed // to build the suite. SetTestSuiteInfo(info TestSuiteInfo) + + // FreeModuleAfterGenerateBuildActions marks this module as no longer necessary after the completion of + // GenerateBuildActions, i.e. all later accesses to the module will be via ModuleProxy and not direct access + // to the Module. + FreeModuleAfterGenerateBuildActions() } type moduleContext struct { @@ -1070,3 +1075,7 @@ func (c *moduleContext) SetTestSuiteInfo(info TestSuiteInfo) { c.testSuiteInfo = info c.testSuiteInfoSet = true } + +func (c *moduleContext) FreeModuleAfterGenerateBuildActions() { + c.bp.FreeModuleAfterGenerateBuildActions() +} -- cgit v1.2.3 From 48790adc1e8e22f353ffa207e84fdd97fe869ffc Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Tue, 8 Apr 2025 11:18:42 -0700 Subject: Use VisitDirectDepsProxy in apex Replace VisitDirectDeps with VisitDirectDepsProxy in apex/ Bug: 377723687 Test: go test ./apex Change-Id: I3c990a1b4abda8408714d789f243b6b984f47f2c --- android/androidmk.go | 9 ++++----- android/apex.go | 37 +++++++++++++------------------------ android/module.go | 2 -- apex/apex.go | 16 ++++++++++++---- apex/apex_test.go | 8 ++++---- apex/builder.go | 4 ++-- apex/key.go | 8 ++++---- apex/prebuilt.go | 4 ++-- java/app.go | 2 +- java/lint.go | 3 ++- 10 files changed, 44 insertions(+), 49 deletions(-) diff --git a/android/androidmk.go b/android/androidmk.go index f6d0dc390..a20b0d152 100644 --- a/android/androidmk.go +++ b/android/androidmk.go @@ -582,9 +582,8 @@ func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod Module) { a.AddStrings("LOCAL_TEST_DATA", androidMkDataPaths(info.TestData)...) } - if am, ok := mod.(ApexModule); ok { - a.SetBoolIfTrue("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", am.NotAvailableForPlatform()) - } + platformAvailabilityInfo := OtherModuleProviderOrDefault(ctx, mod, PlatformAvailabilityInfoProvider) + a.SetBoolIfTrue("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", platformAvailabilityInfo.NotAvailableToPlatform) archStr := base.Arch().ArchType.String() host := false @@ -1541,8 +1540,8 @@ func (a *AndroidMkInfo) fillInEntries(ctx fillInEntriesContext, mod Module, comm helperInfo.AddStrings("LOCAL_TEST_DATA", androidMkDataPaths(info.TestData)...) } - if commonInfo.IsApexModule { - helperInfo.SetBoolIfTrue("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", commonInfo.NotAvailableForPlatform) + if platformAvailabilityInfo, ok := OtherModuleProvider(ctx, mod, PlatformAvailabilityInfoProvider); ok { + helperInfo.SetBoolIfTrue("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", platformAvailabilityInfo.NotAvailableToPlatform) } archStr := commonInfo.Target.Arch.ArchType.String() diff --git a/android/apex.go b/android/apex.go index 1d2911ed0..90ece0c70 100644 --- a/android/apex.go +++ b/android/apex.go @@ -155,6 +155,12 @@ type ApexBundleInfo struct { var ApexBundleInfoProvider = blueprint.NewMutatorProvider[ApexBundleInfo]("apex_mutate") +var PlatformAvailabilityInfoProvider = blueprint.NewMutatorProvider[PlatformAvailabilityInfo]("mark_platform_availability") + +type PlatformAvailabilityInfo struct { + NotAvailableToPlatform bool +} + // DepInSameApexChecker defines an interface that should be used to determine whether a given dependency // should be considered as part of the same APEX as the current module or not. type DepInSameApexChecker interface { @@ -273,15 +279,6 @@ type ApexModule interface { // Returns false by default. AlwaysRequiresPlatformApexVariant() bool - // Returns true if this module is not available to platform (i.e. apex_available property - // doesn't have "//apex_available:platform"), or shouldn't be available to platform, which - // is the case when this module depends on other module that isn't available to platform. - NotAvailableForPlatform() bool - - // Marks that this module is not available to platform. Set by the - // check-platform-availability mutator in the apex package. - SetNotAvailableForPlatform() - // Returns the min sdk version that the module supports, . MinSdkVersionSupported(ctx BaseModuleContext) ApiLevel @@ -305,9 +302,6 @@ type ApexProperties struct { // Default is ["//apex_available:platform"]. Apex_available []string - // See ApexModule.NotAvailableForPlatform() - NotAvailableForPlatform bool `blueprint:"mutated"` - // See ApexModule.UniqueApexVariants() UniqueApexVariationsForDeps bool `blueprint:"mutated"` } @@ -389,7 +383,9 @@ func (m *ApexModuleBase) ApexTransitionMutatorMutate(ctx BottomUpMutatorContext, ApexAvailableFor: module.ApexAvailableFor(), }) } - if platformVariation && !ctx.Host() && !module.AvailableFor(AvailableToPlatform) && module.NotAvailableForPlatform() { + + platformAvailabilityInfo, _ := ModuleProvider(ctx, PlatformAvailabilityInfoProvider) + if platformVariation && !ctx.Host() && !module.AvailableFor(AvailableToPlatform) && platformAvailabilityInfo.NotAvailableToPlatform { // Do not install the module for platform, but still allow it to output // uninstallable AndroidMk entries in certain cases when they have side // effects. TODO(jiyong): move this routine to somewhere else @@ -538,16 +534,6 @@ func (m *ApexModuleBase) AlwaysRequiresPlatformApexVariant() bool { return false } -// Implements ApexModule -func (m *ApexModuleBase) NotAvailableForPlatform() bool { - return m.ApexProperties.NotAvailableForPlatform -} - -// Implements ApexModule -func (m *ApexModuleBase) SetNotAvailableForPlatform() { - m.ApexProperties.NotAvailableForPlatform = true -} - // This function makes sure that the apex_available property is valid func (m *ApexModuleBase) checkApexAvailableProperty(mctx BaseModuleContext) { for _, n := range m.ApexProperties.Apex_available { @@ -650,7 +636,10 @@ type ApexBundleDepsData struct { var ApexBundleDepsDataProvider = blueprint.NewProvider[ApexBundleDepsData]() // ApexBundleTypeInfo is used to identify the module is a apexBundle module. -type ApexBundleTypeInfo struct{} +type ApexBundleTypeInfo struct { + Pem Path + Key Path +} var ApexBundleTypeInfoProvider = blueprint.NewProvider[ApexBundleTypeInfo]() diff --git a/android/module.go b/android/module.go index ba746855c..ff93d0c8a 100644 --- a/android/module.go +++ b/android/module.go @@ -1934,7 +1934,6 @@ type CommonModuleInfo struct { CanHaveApexVariants bool MinSdkVersion ApiLevelOrPlatform SdkVersion string - NotAvailableForPlatform bool // There some subtle differences between this one and the one above. NotInPlatform bool // UninstallableApexPlatformVariant is set by MakeUninstallable called by the apex @@ -2385,7 +2384,6 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) 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() diff --git a/apex/apex.go b/apex/apex.go index 271dee0bb..17c2884bc 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -1175,12 +1175,13 @@ func markPlatformAvailability(mctx android.BottomUpMutatorContext) { // If any of the dep is not available to platform, this module is also considered as being // not available to platform even if it has "//apex_available:platform" - mctx.VisitDirectDeps(func(child android.Module) { + mctx.VisitDirectDepsProxy(func(child android.ModuleProxy) { if !android.IsDepInSameApex(mctx, am, child) { // if the dependency crosses apex boundary, don't consider it return } - if dep, ok := child.(android.ApexModule); ok && dep.NotAvailableForPlatform() { + info := android.OtherModuleProviderOrDefault(mctx, child, android.PlatformAvailabilityInfoProvider) + if info.NotAvailableToPlatform { availableToPlatform = false // TODO(b/154889534) trigger an error when 'am' has // "//apex_available:platform" @@ -1198,8 +1199,11 @@ func markPlatformAvailability(mctx android.BottomUpMutatorContext) { } if !availableToPlatform { - am.SetNotAvailableForPlatform() + android.SetProvider(mctx, android.PlatformAvailabilityInfoProvider, android.PlatformAvailabilityInfo{ + NotAvailableToPlatform: true, + }) } + } type apexTransitionMutator struct{} @@ -2282,7 +2286,11 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { android.SetProvider(ctx, java.AppInfosProvider, a.appInfos) a.setSymbolInfosProvider(ctx) - android.SetProvider(ctx, android.ApexBundleTypeInfoProvider, android.ApexBundleTypeInfo{}) + pem, key := a.getCertificateAndPrivateKey(ctx) + android.SetProvider(ctx, android.ApexBundleTypeInfoProvider, android.ApexBundleTypeInfo{ + Pem: pem, + Key: key, + }) } // Set prebuiltInfoProvider. This will be used by `apex_prebuiltinfo_singleton` to print out a metadata file diff --git a/apex/apex_test.go b/apex/apex_test.go index 6387a50e4..880d0014a 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -7194,14 +7194,14 @@ func TestApexAvailable_CheckForPlatform(t *testing.T) { // libfoo shouldn't be available to platform even though it has "//apex_available:platform", // because it depends on libbar which isn't available to platform libfoo := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared").Module().(*cc.Module) - if libfoo.NotAvailableForPlatform() != true { + if android.OtherModuleProviderOrDefault(ctx, libfoo, android.PlatformAvailabilityInfoProvider).NotAvailableToPlatform != true { t.Errorf("%q shouldn't be available to platform", libfoo.String()) } // libfoo2 however can be available to platform because it depends on libbaz which provides // stubs libfoo2 := ctx.ModuleForTests(t, "libfoo2", "android_arm64_armv8-a_shared").Module().(*cc.Module) - if libfoo2.NotAvailableForPlatform() == true { + if android.OtherModuleProviderOrDefault(ctx, libfoo2, android.PlatformAvailabilityInfoProvider).NotAvailableToPlatform == true { t.Errorf("%q should be available to platform", libfoo2.String()) } } @@ -7233,11 +7233,11 @@ func TestApexAvailable_CreatedForApex(t *testing.T) { }`) libfooShared := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared").Module().(*cc.Module) - if libfooShared.NotAvailableForPlatform() != true { + if android.OtherModuleProviderOrDefault(ctx, libfooShared, android.PlatformAvailabilityInfoProvider).NotAvailableToPlatform != true { t.Errorf("%q shouldn't be available to platform", libfooShared.String()) } libfooStatic := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_static").Module().(*cc.Module) - if libfooStatic.NotAvailableForPlatform() != false { + if android.OtherModuleProviderOrDefault(ctx, libfooStatic, android.PlatformAvailabilityInfoProvider).NotAvailableToPlatform != false { t.Errorf("%q should be available to platform", libfooStatic.String()) } } diff --git a/apex/builder.go b/apex/builder.go index d611b7363..3fda3c5f4 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -566,7 +566,7 @@ func (a *apexBundle) installApexSystemServerFiles(ctx android.ModuleContext) { } psi := android.PrebuiltSelectionInfoMap{} - ctx.VisitDirectDeps(func(am android.Module) { + ctx.VisitDirectDepsProxy(func(am android.ModuleProxy) { if info, exists := android.OtherModuleProvider(ctx, am, android.PrebuiltSelectionInfoProvider); exists { psi = info } @@ -1111,7 +1111,7 @@ func (a *apexBundle) buildApexDependencyInfo(ctx android.ModuleContext) { // Skip dependencies that are only available to APEXes; they are developed with updatability // in mind and don't need manual approval. - if android.OtherModulePointerProviderOrDefault(ctx, to, android.CommonModuleInfoProvider).NotAvailableForPlatform { + if android.OtherModuleProviderOrDefault(ctx, to, android.PlatformAvailabilityInfoProvider).NotAvailableToPlatform { return !externalDep } diff --git a/apex/key.go b/apex/key.go index cc66a131f..b43ac1e4a 100644 --- a/apex/key.go +++ b/apex/key.go @@ -196,9 +196,9 @@ type allApexCerts struct { func (_ *allApexCerts) GenerateAndroidBuildActions(ctx android.ModuleContext) { var avbpubkeys android.Paths var certificatesPem android.Paths - ctx.VisitDirectDeps(func(m android.Module) { - if apex, ok := m.(*apexBundle); ok { - pem, _ := apex.getCertificateAndPrivateKey(ctx) + ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) { + if apex, ok := android.OtherModuleProvider(ctx, m, android.ApexBundleTypeInfoProvider); ok { + pem := apex.Pem if !android.ExistentPathForSource(ctx, pem.String()).Valid() { if ctx.Config().AllowMissingDependencies() { return @@ -208,7 +208,7 @@ func (_ *allApexCerts) GenerateAndroidBuildActions(ctx android.ModuleContext) { } certificatesPem = append(certificatesPem, pem) // avbpubkey for signing the apex payload - avbpubkeys = append(avbpubkeys, apex.publicKeyFile) + avbpubkeys = append(avbpubkeys, apex.Key) } }) certificatesPem = android.SortedUniquePaths(certificatesPem) // For hermiticity diff --git a/apex/prebuilt.go b/apex/prebuilt.go index 02b392a0a..61ba6a5a2 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -357,7 +357,7 @@ func (p *prebuiltCommon) checkExportedDependenciesArePrebuilts(ctx android.Modul } // It is an error if the other module is not an ApexModule. - if _, ok := dep.(android.ApexModule); !ok { + if _, ok := android.OtherModuleProvider(ctx, dep, android.ApexInfoProvider); !ok { ctx.PropertyErrorf(propertyName, "%q is not usable within an apex", depName) } } @@ -652,7 +652,7 @@ func (p *prebuiltCommon) providePrebuiltInfo(ctx android.ModuleContext) { // PRODUCT_APEX_BOOT_JARS // This validation will only run on the apex which is active for this product/release_config func validateApexClasspathFragments(ctx android.ModuleContext) { - ctx.VisitDirectDeps(func(m android.Module) { + ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) { if info, exists := android.OtherModuleProvider(ctx, m, java.ClasspathFragmentValidationInfoProvider); exists { ctx.ModuleErrorf("%s in contents of %s must also be declared in PRODUCT_APEX_BOOT_JARS", info.UnknownJars, info.ClasspathFragmentModuleName) } diff --git a/java/app.go b/java/app.go index 42eb21c62..1e35506e3 100644 --- a/java/app.go +++ b/java/app.go @@ -1364,7 +1364,7 @@ func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) { // Skip dependencies that are only available to APEXes; they are developed with updatability // in mind and don't need manual approval. - if android.OtherModulePointerProviderOrDefault(ctx, to, android.CommonModuleInfoProvider).NotAvailableForPlatform { + if android.OtherModuleProviderOrDefault(ctx, to, android.PlatformAvailabilityInfoProvider).NotAvailableToPlatform { return true } diff --git a/java/lint.go b/java/lint.go index dc1e51ffb..5d8724669 100644 --- a/java/lint.go +++ b/java/lint.go @@ -660,11 +660,12 @@ func (l *lintSingleton) generateLintReportZips(ctx android.SingletonContext) { var dirs []string ctx.VisitAllModuleProxies(func(m android.ModuleProxy) { commonInfo := android.OtherModulePointerProviderOrDefault(ctx, m, android.CommonModuleInfoProvider) + platformAvailabilitInfo := android.OtherModuleProviderOrDefault(ctx, m, android.PlatformAvailabilityInfoProvider) if ctx.Config().KatiEnabled() && !commonInfo.ExportedToMake { return } - if commonInfo.IsApexModule && commonInfo.NotAvailableForPlatform { + if commonInfo.IsApexModule && platformAvailabilitInfo.NotAvailableToPlatform { apexInfo, _ := android.OtherModuleProvider(ctx, m, android.ApexInfoProvider) if apexInfo.IsForPlatform() { // There are stray platform variants of modules in apexes that are not available for -- cgit v1.2.3 From 3919ba7efa701ebe312155e7e0110e01eedda99a Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Tue, 8 Apr 2025 15:42:18 -0700 Subject: Add VisitAllModulesOrProxies and IsPrimaryModule to SingletonContext Singletons may need to visit a combination of modules that have been converted to use Providers and ones that haven't. Add VisitAllModulesOrProxies, which calls the visitor with a ModuleOrProxy that is either a ModuleProxy if the Module called FreeModuleAfterGenerateAndroidBuildActions, or a Module if it didn't. Also add IsPrimaryModule. Test: builds Change-Id: Ia266c87807ef9cad682640690e26feaec77ef0da --- android/singleton.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/android/singleton.go b/android/singleton.go index 18b2f5c71..8e45af80d 100644 --- a/android/singleton.go +++ b/android/singleton.go @@ -71,6 +71,7 @@ type SingletonContext interface { VisitAllModules(visit func(Module)) VisitAllModuleProxies(visit func(proxy ModuleProxy)) VisitAllModulesIf(pred func(Module) bool, visit func(Module)) + VisitAllModulesOrProxies(visit func(ModuleOrProxy)) VisitDirectDeps(module Module, visit func(Module)) VisitDirectDepsIf(module Module, pred func(Module) bool, visit func(Module)) @@ -89,6 +90,7 @@ type SingletonContext interface { PrimaryModuleProxy(module ModuleProxy) ModuleProxy + IsPrimaryModule(module ModuleOrProxy) bool IsFinalModule(module ModuleOrProxy) bool AddNinjaFileDeps(deps ...string) @@ -315,6 +317,12 @@ func (s *singletonContextAdaptor) VisitAllModuleProxies(visit func(proxy ModuleP s.SingletonContext.VisitAllModuleProxies(visitProxyAdaptor(visit)) } +func (s *singletonContextAdaptor) VisitAllModulesOrProxies(visit func(ModuleOrProxy)) { + s.SingletonContext.VisitAllModulesOrProxies(func(module blueprint.ModuleOrProxy) { + visit(module) + }) +} + func (s *singletonContextAdaptor) VisitAllModulesIf(pred func(Module) bool, visit func(Module)) { s.SingletonContext.VisitAllModulesIf(predAdaptor(pred), visitAdaptor(visit)) } @@ -351,6 +359,10 @@ func (s *singletonContextAdaptor) PrimaryModuleProxy(module ModuleProxy) ModuleP return ModuleProxy{s.SingletonContext.PrimaryModuleProxy(module.ModuleProxy)} } +func (s *singletonContextAdaptor) IsPrimaryModule(module ModuleOrProxy) bool { + return s.SingletonContext.IsPrimaryModule(module) +} + func (s *singletonContextAdaptor) IsFinalModule(module ModuleOrProxy) bool { return s.SingletonContext.IsFinalModule(module) } -- cgit v1.2.3 From d042d79ac2360baea8bfd6e7bd947dc4874cf9e2 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Tue, 8 Apr 2025 13:14:33 -0700 Subject: Use VisitDirectDepsProxy in cc/coverage.go Replace VisitDirectDeps with VisitDirectDepsProxy and GetDirectDepWithTag with GetDirectDepProxyWithTag in cc/coverage.go. Bug: 377723687 Test: go test ./cc Change-Id: Ic02ad8abc49294dc873a3f0a64f0d2af9be72670 --- cc/cc.go | 6 ++++++ cc/coverage.go | 29 ++++++++++++----------------- cc/linkable.go | 2 ++ rust/rust.go | 4 ++++ 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/cc/cc.go b/cc/cc.go index 2b0684320..89b03eaa1 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -203,6 +203,7 @@ type LinkableInfo struct { CoverageFiles android.Paths // CoverageOutputFile returns the output archive of gcno coverage information files. CoverageOutputFile android.OptionalPath + LinkCoverage bool SAbiDumpFiles android.Paths // Partition returns the partition string for this module. Partition string @@ -1484,6 +1485,10 @@ func (c *Module) CoverageOutputFile() android.OptionalPath { return android.OptionalPath{} } +func (c *Module) LinkCoverage() bool { + return c.coverage != nil && c.coverage.linkCoverage +} + func (c *Module) RelativeInstallPath() string { if c.installer != nil { return c.installer.relativeInstallPath() @@ -2744,6 +2749,7 @@ func CreateCommonLinkableInfo(ctx android.ModuleContext, mod VersionedLinkableIn OutputFile: mod.OutputFile(), UnstrippedOutputFile: mod.UnstrippedOutputFile(), CoverageOutputFile: mod.CoverageOutputFile(), + LinkCoverage: mod.LinkCoverage(), Partition: mod.Partition(), IsStubs: mod.IsStubs(), CcLibrary: mod.CcLibrary(), diff --git a/cc/coverage.go b/cc/coverage.go index 757641cba..d75657107 100644 --- a/cc/coverage.go +++ b/cc/coverage.go @@ -149,11 +149,11 @@ func (cov *coverage) flags(ctx ModuleContext, flags Flags, deps PathDeps) (Flags // For static libraries, the only thing that changes our object files // are included whole static libraries, so check to see if any of // those have coverage enabled. - ctx.VisitDirectDeps(func(m android.Module) { + ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) { if depTag, ok := ctx.OtherModuleDependencyTag(m).(libraryDependencyTag); ok { if depTag.static() && depTag.wholeStatic { - if cc, ok := m.(*Module); ok && cc.coverage != nil { - if cc.coverage.linkCoverage { + if info, ok := android.OtherModuleProvider(ctx, m, LinkableInfoProvider); ok { + if info.LinkCoverage { cov.linkCoverage = true } } @@ -163,18 +163,13 @@ func (cov *coverage) flags(ctx ModuleContext, flags Flags, deps PathDeps) (Flags } else { // For executables and shared libraries, we need to check all of // our static dependencies. - ctx.VisitDirectDeps(func(m android.Module) { - cc, ok := m.(*Module) - if !ok || cc.coverage == nil { - return - } - - if static, ok := cc.linker.(libraryInterface); !ok || !static.static() { - return - } - - if cc.coverage.linkCoverage { - cov.linkCoverage = true + ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) { + if _, ok := android.OtherModuleProvider(ctx, m, StaticLibraryInfoProvider); ok { + if info, ok := android.OtherModuleProvider(ctx, m, LinkableInfoProvider); ok { + if info.LinkCoverage { + cov.linkCoverage = true + } + } } }) } @@ -196,8 +191,8 @@ func (cov *coverage) flags(ctx ModuleContext, flags Flags, deps PathDeps) (Flags } if ctx.Device() { - coverage := ctx.GetDirectDepWithTag(getClangProfileLibraryName(ctx), CoverageDepTag).(*Module) - deps.WholeStaticLibs = append(deps.WholeStaticLibs, coverage.OutputFile().Path()) + coverage := ctx.GetDirectDepProxyWithTag(getClangProfileLibraryName(ctx), CoverageDepTag) + deps.WholeStaticLibs = append(deps.WholeStaticLibs, android.OutputFileForModule(ctx, coverage, "")) flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--wrap,open") } } diff --git a/cc/linkable.go b/cc/linkable.go index f3aff1523..cd8282526 100644 --- a/cc/linkable.go +++ b/cc/linkable.go @@ -117,6 +117,8 @@ type LinkableInterface interface { // CoverageOutputFile returns the output archive of gcno coverage information files. CoverageOutputFile() android.OptionalPath + LinkCoverage() bool + NonCcVariants() bool SelectedStl() string diff --git a/rust/rust.go b/rust/rust.go index c67a9cd85..5139da450 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -814,6 +814,10 @@ func (mod *Module) CoverageOutputFile() android.OptionalPath { return android.OptionalPath{} } +func (c *Module) LinkCoverage() bool { + return false +} + func (mod *Module) IsNdk(config android.Config) bool { return false } -- cgit v1.2.3 From 0689d2c42f36f90ba01a71e2a8fa53b97f0c2905 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Mon, 7 Apr 2025 13:15:20 -0700 Subject: Add infrastructure for host shared libs in test suites This will be used by device-tests. It's not perfectly accurate to make, it also includes some extra shared libs that are listed in runtime_deps. But it should be good enough. Bug: 405184090 Test: building and diffing device-tests (with followup cl to enable device-tests in soong) Change-Id: I90cfd5a84f2b9db1561a17174daea191915d5c59 --- android/test_suites.go | 172 ++++++++++++++++++++++++++++++++++++++++++++++--- cc/cc.go | 11 ++++ python/binary.go | 5 ++ rust/rust.go | 13 +++- 4 files changed, 190 insertions(+), 11 deletions(-) diff --git a/android/test_suites.go b/android/test_suites.go index 181cceb2a..9648679de 100644 --- a/android/test_suites.go +++ b/android/test_suites.go @@ -76,6 +76,20 @@ type TestSuiteInfo struct { var TestSuiteInfoProvider = blueprint.NewProvider[TestSuiteInfo]() +// TestSuiteSharedLibsInfo is a provider of AndroidMk names of shared lib modules, for packaging +// shared libs into test suites. It's not intended as a general-purpose shared lib tracking +// mechanism. It's added to both test modules (to track their shared libs) and also shared lib +// modules (to track their transitive shared libs). +type TestSuiteSharedLibsInfo struct { + MakeNames []string +} + +var TestSuiteSharedLibsInfoProvider = blueprint.NewProvider[TestSuiteSharedLibsInfo]() + +// MakeNameInfoProvider records the AndroidMk name for the module. This will match the names +// referenced in TestSuiteSharedLibsInfo +var MakeNameInfoProvider = blueprint.NewProvider[string]() + type filePair struct { src Path dst WritablePath @@ -95,19 +109,35 @@ func (t testModulesInstallsMap) testModules() []Module { } func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) { + hostOutTestCases := pathForInstall(ctx, ctx.Config().BuildOSTarget.Os, ctx.Config().BuildOSTarget.Arch.ArchType, "testcases") files := make(map[string]testModulesInstallsMap) + sharedLibRoots := make(map[string][]string) + sharedLibGraph := make(map[string][]string) allTestSuiteInstalls := make(map[string][]Path) var toInstall []filePair var oneVariantInstalls []filePair ctx.VisitAllModuleProxies(func(m ModuleProxy) { + commonInfo := OtherModuleProviderOrDefault(ctx, m, CommonModuleInfoProvider) + testSuiteSharedLibsInfo := OtherModuleProviderOrDefault(ctx, m, TestSuiteSharedLibsInfoProvider) + makeName := OtherModuleProviderOrDefault(ctx, m, MakeNameInfoProvider) + if makeName != "" && commonInfo.Target.Os.Class == Host { + sharedLibGraph[makeName] = append(sharedLibGraph[makeName], testSuiteSharedLibsInfo.MakeNames...) + } + if tsm, ok := OtherModuleProvider(ctx, m, TestSuiteInfoProvider); ok { + installFilesProvider := OtherModuleProviderOrDefault(ctx, m, InstallFilesProvider) + for _, testSuite := range tsm.TestSuites { if files[testSuite] == nil { files[testSuite] = make(testModulesInstallsMap) } files[testSuite][m] = append(files[testSuite][m], - OtherModuleProviderOrDefault(ctx, m, InstallFilesProvider).InstallFiles...) + installFilesProvider.InstallFiles...) + + if makeName != "" { + sharedLibRoots[testSuite] = append(sharedLibRoots[testSuite], makeName) + } } if testSuiteInstalls, ok := OtherModuleProvider(ctx, m, testSuiteInstallsInfoProvider); ok { @@ -137,6 +167,12 @@ func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) { } }) + for suite, suiteInstalls := range allTestSuiteInstalls { + allTestSuiteInstalls[suite] = SortedUniquePaths(suiteInstalls) + } + + hostSharedLibs := gatherHostSharedLibs(ctx, sharedLibRoots, sharedLibGraph) + if !ctx.Config().KatiEnabled() { for _, testSuite := range SortedKeys(files) { testSuiteSymbolsZipFile := pathForTestSymbols(ctx, fmt.Sprintf("%s-symbols.zip", testSuite)) @@ -149,8 +185,41 @@ func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) { } } - for suite, suiteInstalls := range allTestSuiteInstalls { - allTestSuiteInstalls[suite] = SortedUniquePaths(suiteInstalls) + // https://source.corp.google.com/h/googleplex-android/platform/superproject/main/+/main:build/make/core/main.mk;l=674;drc=46bd04e115d34fd62b3167128854dfed95290eb0 + testInstalledSharedLibs := make(map[string]Paths) + testInstalledSharedLibsDeduper := make(map[string]bool) + for _, install := range toInstall { + testInstalledSharedLibsDeduper[install.dst.String()] = true + } + for _, suite := range []string{"general-tests", "device-tests", "vts", "tvts", "art-host-tests", "host-unit-tests", "camera-hal-tests"} { + var myTestCases WritablePath = hostOutTestCases + switch suite { + case "vts", "tvts": + suiteInfo := ctx.Config().productVariables.CompatibilityTestcases[suite] + outDir := suiteInfo.OutDir + if outDir == "" { + continue + } + rel, err := filepath.Rel(ctx.Config().OutDir(), outDir) + if err != nil || strings.HasPrefix(rel, "..") { + panic(fmt.Sprintf("Could not make COMPATIBILITY_TESTCASES_OUT_%s (%s) relative to the out dir (%s)", suite, suiteInfo.OutDir, ctx.Config().OutDir())) + } + myTestCases = PathForArbitraryOutput(ctx, rel) + } + + for _, f := range hostSharedLibs[suite] { + dir := filepath.Base(filepath.Dir(f.String())) + out := joinWriteablePath(ctx, myTestCases, dir, filepath.Base(f.String())) + if _, ok := testInstalledSharedLibsDeduper[out.String()]; !ok { + ctx.Build(pctx, BuildParams{ + Rule: Cp, + Input: f, + Output: out, + }) + } + testInstalledSharedLibsDeduper[out.String()] = true + testInstalledSharedLibs[suite] = append(testInstalledSharedLibs[suite], out) + } } filePairSorter := func(arr []filePair) func(i, j int) bool { @@ -198,14 +267,79 @@ func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) { ctx.Phony("ravenwood-tests", ravenwoodZip, ravenwoodListZip) ctx.DistForGoal("ravenwood-tests", ravenwoodZip, ravenwoodListZip) - packageTestSuite(ctx, allTestSuiteInstalls["performance-tests"], performanceTests) - packageTestSuite(ctx, allTestSuiteInstalls["device-platinum-tests"], devicePlatinumTests) + packageTestSuite(ctx, allTestSuiteInstalls["performance-tests"], testInstalledSharedLibs["performance-tests"], performanceTests) + packageTestSuite(ctx, allTestSuiteInstalls["device-platinum-tests"], testInstalledSharedLibs["device-platinum-tests"], devicePlatinumTests) + // TODO: Enable in followup + // packageTestSuite(ctx, allTestSuiteInstalls["device-tests"], testInstalledSharedLibs["device-tests"], deviceTests) +} + +// Get a mapping from testSuite -> list of host shared libraries, given: +// - sharedLibRoots: Mapping from testSuite -> androidMk name of all test modules in the suite +// - sharedLibGraph: Mapping from androidMk name of module -> androidMk names of its shared libs +// +// This mimics how make did it historically, which is filled with inaccuracies. Make didn't +// track variants and treated all variants as if they were merged into one big module. This means +// you can have a test that's only included in the "vts" test suite on the device variant, and +// only has a shared library on the host variant, and that shared library will still be included +// into the vts test suite. +func gatherHostSharedLibs(ctx SingletonContext, sharedLibRoots, sharedLibGraph map[string][]string) map[string]Paths { + hostOutTestCases := pathForInstall(ctx, ctx.Config().BuildOSTarget.Os, ctx.Config().BuildOSTarget.Arch.ArchType, "testcases") + hostOut := filepath.Dir(hostOutTestCases.String()) + + for k, v := range sharedLibGraph { + sharedLibGraph[k] = SortedUniqueStrings(v) + } + + suiteToSharedLibModules := make(map[string]map[string]bool) + for suite, modules := range sharedLibRoots { + suiteToSharedLibModules[suite] = make(map[string]bool) + var queue []string + for _, root := range SortedUniqueStrings(modules) { + queue = append(queue, sharedLibGraph[root]...) + } + for len(queue) > 0 { + mod := queue[len(queue)-1] + queue = queue[:len(queue)-1] + if suiteToSharedLibModules[suite][mod] { + continue + } + suiteToSharedLibModules[suite][mod] = true + queue = append(queue, sharedLibGraph[mod]...) + } + } + + hostSharedLibs := make(map[string]Paths) + + ctx.VisitAllModuleProxies(func(m ModuleProxy) { + if makeName, ok := OtherModuleProvider(ctx, m, MakeNameInfoProvider); ok { + commonInfo := OtherModuleProviderOrDefault(ctx, m, CommonModuleInfoProvider) + if commonInfo.SkipInstall { + return + } + installFilesProvider := OtherModuleProviderOrDefault(ctx, m, InstallFilesProvider) + for suite, sharedLibModulesInSuite := range suiteToSharedLibModules { + if sharedLibModulesInSuite[makeName] { + for _, f := range installFilesProvider.InstallFiles { + if strings.HasSuffix(f.String(), ".so") && strings.HasPrefix(f.String(), hostOut) { + hostSharedLibs[suite] = append(hostSharedLibs[suite], f) + } + } + } + } + } + }) + for suite, files := range hostSharedLibs { + hostSharedLibs[suite] = SortedUniquePaths(files) + } + + return hostSharedLibs } type suiteKind int const ( performanceTests suiteKind = iota + deviceTests devicePlatinumTests ) @@ -213,24 +347,31 @@ func (sk suiteKind) String() string { switch sk { case performanceTests: return "performance-tests" + case deviceTests: + return "device-tests" case devicePlatinumTests: return "device-platinum-tests" default: panic(fmt.Sprintf("Unrecognized suite kind %d for use in packageTestSuite", sk)) } - return "" } func (sk suiteKind) buildHostSharedLibsZip() bool { switch sk { - case performanceTests: - return false case devicePlatinumTests: return true } return false } +func (sk suiteKind) includeHostSharedLibsInMainZip() bool { + switch sk { + case deviceTests: + return true + } + return false +} + func buildTestSuite(ctx SingletonContext, suiteName string, files testModulesInstallsMap) (Path, Path) { var installedPaths Paths for _, module := range files.testModules() { @@ -302,7 +443,7 @@ func pathForTestSymbols(ctx PathContext, pathComponents ...string) InstallPath { return pathForInstall(ctx, ctx.Config().BuildOS, ctx.Config().BuildArch, "", pathComponents...) } -func packageTestSuite(ctx SingletonContext, files Paths, sk suiteKind) { +func packageTestSuite(ctx SingletonContext, files Paths, sharedLibs Paths, sk suiteKind) { hostOutTestCases := pathForInstall(ctx, ctx.Config().BuildOSTarget.Os, ctx.Config().BuildOSTarget.Arch.ArchType, "testcases") targetOutTestCases := pathForInstall(ctx, ctx.Config().AndroidFirstDeviceTarget.Os, ctx.Config().AndroidFirstDeviceTarget.Arch.ArchType, "testcases") hostOut := filepath.Dir(hostOutTestCases.String()) @@ -348,6 +489,16 @@ func packageTestSuite(ctx SingletonContext, files Paths, sk suiteKind) { } } } + + if sk.includeHostSharedLibsInMainZip() { + for _, f := range sharedLibs { + if strings.HasPrefix(f.String(), hostOutTestCases.String()) { + testsZipCmdHostFileInputContent = append(testsZipCmdHostFileInputContent, f.String()) + testsZipCmd.Implicit(f) + } + } + } + WriteFileRule(ctx, testsZipCmdHostFileInput, strings.Join(testsZipCmdHostFileInputContent, " ")) testsZipCmd. @@ -369,6 +520,7 @@ func packageTestSuite(ctx SingletonContext, files Paths, sk suiteKind) { } } } + WriteFileRule(ctx, testsZipCmdTargetFileInput, strings.Join(testsZipCmdTargetFileInputContent, " ")) testsZipCmd.FlagWithInput("-l ", testsZipCmdTargetFileInput) @@ -384,7 +536,7 @@ func packageTestSuite(ctx SingletonContext, files Paths, sk suiteKind) { FlagWithArg("-P ", "host"). FlagWithArg("-C ", hostOut) - for _, f := range files { + for _, f := range sharedLibs { if strings.HasPrefix(f.String(), hostOutTestCases.String()) && strings.HasSuffix(f.String(), ".so") { testsHostSharedLibsZipCmd.FlagWithInput("-f ", f) } diff --git a/cc/cc.go b/cc/cc.go index ea9d76598..1feb6dd5a 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -2703,6 +2703,17 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { } android.SetProvider(ctx, CcInfoProvider, &ccInfo) + android.SetProvider(ctx, android.TestSuiteSharedLibsInfoProvider, android.TestSuiteSharedLibsInfo{ + MakeNames: c.Properties.AndroidMkSharedLibs, + }) + + // TODO: Refactor MakeLibName so we don't have to fake CommonModuleInfo like this + myCommonInfo := android.CommonModuleInfo{ + BaseModuleName: c.BaseModuleName(), + Target: ctx.Target(), + } + android.SetProvider(ctx, android.MakeNameInfoProvider, MakeLibName(&ccInfo, linkableInfo, &myCommonInfo, ctx.ModuleName())) + c.setOutputFiles(ctx) if c.makeVarsInfo != nil { diff --git a/python/binary.go b/python/binary.go index abcef73fb..cc29ec6e9 100644 --- a/python/binary.go +++ b/python/binary.go @@ -171,6 +171,11 @@ func (p *PythonBinaryModule) buildBinary(ctx android.ModuleContext) { sharedLibs = append(sharedLibs, ctx.OtherModuleName(dep)) } p.androidMkSharedLibs = sharedLibs + + android.SetProvider(ctx, android.TestSuiteSharedLibsInfoProvider, android.TestSuiteSharedLibsInfo{ + MakeNames: p.androidMkSharedLibs, + }) + android.SetProvider(ctx, android.MakeNameInfoProvider, ctx.ModuleName()) } func (p *PythonBinaryModule) AndroidMkEntries() []android.AndroidMkEntries { diff --git a/rust/rust.go b/rust/rust.go index 9643ec90a..0430046bc 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -1221,6 +1221,13 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { android.SetProvider(ctx, cc.CcInfoProvider, ccInfo) + // TODO: Refactor rustMakeLibName so we don't have to fake CommonModuleInfo like this + myCommonInfo := android.CommonModuleInfo{ + BaseModuleName: mod.BaseModuleName(), + Target: ctx.Target(), + } + android.SetProvider(ctx, android.MakeNameInfoProvider, rustMakeLibName(rustInfo, linkableInfo, &myCommonInfo, ctx.ModuleName())) + mod.setOutputFiles(ctx) buildComplianceMetadataInfo(ctx, mod, deps) @@ -1851,7 +1858,11 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { } }) - mod.transitiveAndroidMkSharedLibs = depset.New[string](depset.PREORDER, directAndroidMkSharedLibs, transitiveAndroidMkSharedLibs) + mod.transitiveAndroidMkSharedLibs = depset.New(depset.PREORDER, directAndroidMkSharedLibs, transitiveAndroidMkSharedLibs) + + android.SetProvider(ctx, android.TestSuiteSharedLibsInfoProvider, android.TestSuiteSharedLibsInfo{ + MakeNames: append(mod.transitiveAndroidMkSharedLibs.ToList(), mod.Properties.AndroidMkDylibs...), + }) var rlibDepFiles RustLibraries aliases := mod.compiler.Aliases() -- cgit v1.2.3 From 70ba68823f2ff843f238b50caba722e0751379b7 Mon Sep 17 00:00:00 2001 From: Rex Hoffman Date: Fri, 4 Apr 2025 19:23:13 +0000 Subject: Add a new android property tag type usable for dependencies, path_host_first Allows a native source build to be selected for local usage/embedding in a genrule, targeting primarily java_genrule. Test: CI Bug: 393164499 Flag: TEST_ONLY Change-Id: If0aaff21a3d0663c912d99e04cd41d21d2710fed --- android/path_properties.go | 9 +++++++++ genrule/genrule.go | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/android/path_properties.go b/android/path_properties.go index d769d58c4..31a07f136 100644 --- a/android/path_properties.go +++ b/android/path_properties.go @@ -55,6 +55,7 @@ func addPathDepsForProps(ctx BottomUpMutatorContext, props []interface{}) { var pathDeviceCommonProperties []string var pathCommonOsProperties []string var pathHostCommonProperties []string + var pathHostFirstProperties []string for _, ps := range props { pathProperties = append(pathProperties, taggedPropertiesForPropertyStruct(ctx, ps, "path")...) pathDeviceFirstProperties = append(pathDeviceFirstProperties, taggedPropertiesForPropertyStruct(ctx, ps, "path_device_first")...) @@ -62,6 +63,7 @@ func addPathDepsForProps(ctx BottomUpMutatorContext, props []interface{}) { 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")...) + pathHostFirstProperties = append(pathHostFirstProperties, taggedPropertiesForPropertyStruct(ctx, ps, "path_host_first")...) } // Remove duplicates to avoid multiple dependencies. @@ -71,6 +73,7 @@ func addPathDepsForProps(ctx BottomUpMutatorContext, props []interface{}) { pathDeviceCommonProperties = FirstUniqueStrings(pathDeviceCommonProperties) pathCommonOsProperties = FirstUniqueStrings(pathCommonOsProperties) pathHostCommonProperties = FirstUniqueStrings(pathHostCommonProperties) + pathHostFirstProperties = FirstUniqueStrings(pathHostFirstProperties) // Add dependencies to anything that is a module reference. for _, s := range pathProperties { @@ -117,6 +120,12 @@ func addPathDepsForProps(ctx BottomUpMutatorContext, props []interface{}) { ctx.AddVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), sourceOrOutputDepTag(m, t), m) } } + // properties tagged "path_host_first" get the host os variant + for _, s := range pathHostFirstProperties { + if m, t := SrcIsModuleWithTag(s); m != "" { + ctx.AddVariationDependencies(ctx.Config().BuildOSTarget.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/genrule/genrule.go b/genrule/genrule.go index a7c09e76c..bad0ed713 100644 --- a/genrule/genrule.go +++ b/genrule/genrule.go @@ -157,6 +157,9 @@ type generatorProperties struct { // Same as srcs, but will add dependencies on modules via a common_os os variation. Common_os_srcs proptools.Configurable[[]string] `android:"path_common_os"` + // Same as srcs, but will add dependencies on modules via for host os variation. + Host_first_src proptools.Configurable[[]string] `android:"path_host_first"` + // input files to exclude Exclude_srcs []string `android:"path,arch_variant"` @@ -454,6 +457,7 @@ func (g *Module) generateCommonBuildActions(ctx android.ModuleContext) { srcFiles = append(srcFiles, addLabelsForInputs("device_first_srcs", g.properties.Device_first_srcs.GetOrDefault(ctx, nil), nil)...) srcFiles = append(srcFiles, addLabelsForInputs("device_common_srcs", g.properties.Device_common_srcs.GetOrDefault(ctx, nil), nil)...) srcFiles = append(srcFiles, addLabelsForInputs("common_os_srcs", g.properties.Common_os_srcs.GetOrDefault(ctx, nil), nil)...) + srcFiles = append(srcFiles, addLabelsForInputs("host_first_src", g.properties.Host_first_src.GetOrDefault(ctx, nil), nil)...) var copyFrom android.Paths var outputFiles android.WritablePaths -- cgit v1.2.3 From b823c3d9515107f4bcf1e85eff85e405a5045adf Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Wed, 9 Apr 2025 17:45:04 +0000 Subject: Add `Native_bridge` deps property to android_filesystem Some filesystems package native bridge libraries (e.g. arm64 on x86_64 device). When building with Soong, they should set `native_bridge_supported: true`, so that the native bridge arches are returned by ctx.MultiTargets. AddFarVariationDependencies will be used to create a dependency on the native arch variant of `Native_bridge` deps. A followup CL will update fsgen to include the native bridge variants in the autogenerated android_filesystem modules. Bug: 376873507 Test: m nothing --no-skip-soong-tests Change-Id: Ica0138cbc2321516871fa9a12d95e72cd992765b --- android/packaging.go | 23 +++++++++------- filesystem/filesystem_test.go | 62 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 9 deletions(-) diff --git a/android/packaging.go b/android/packaging.go index aae7806d7..689340ee9 100644 --- a/android/packaging.go +++ b/android/packaging.go @@ -289,12 +289,13 @@ type DepsProperty struct { } type packagingMultilibProperties struct { - First DepsProperty `android:"arch_variant"` - Common DepsProperty `android:"arch_variant"` - Lib32 DepsProperty `android:"arch_variant"` - Lib64 DepsProperty `android:"arch_variant"` - Both DepsProperty `android:"arch_variant"` - Prefer32 DepsProperty `android:"arch_variant"` + First DepsProperty `android:"arch_variant"` + Common DepsProperty `android:"arch_variant"` + Lib32 DepsProperty `android:"arch_variant"` + Lib64 DepsProperty `android:"arch_variant"` + Both DepsProperty `android:"arch_variant"` + Prefer32 DepsProperty `android:"arch_variant"` + Native_bridge DepsProperty `android:"arch_variant"` } type packagingArchProperties struct { @@ -325,7 +326,8 @@ func (p *PackagingBase) packagingBase() *PackagingBase { // multi target, deps is selected for each of the targets and is NOT selected for the current // architecture which would be Common. // It returns two lists, the normal and high priority deps, respectively. -func (p *PackagingBase) getDepsForArch(ctx BaseModuleContext, arch ArchType) ([]string, []string) { +func (p *PackagingBase) getDepsForTarget(ctx BaseModuleContext, target Target) ([]string, []string) { + arch := target.Arch.ArchType var normalDeps []string var highPriorityDeps []string @@ -337,7 +339,10 @@ func (p *PackagingBase) getDepsForArch(ctx BaseModuleContext, arch ArchType) ([] return len(prop.Deps.GetOrDefault(ctx, nil)) > 0 || len(prop.High_priority_deps) > 0 } - if arch == ctx.Target().Arch.ArchType && len(ctx.MultiTargets()) == 0 { + if target.NativeBridge == NativeBridgeEnabled { + get(p.properties.Multilib.Native_bridge) + return FirstUniqueStrings(normalDeps), FirstUniqueStrings(highPriorityDeps) + } else if arch == ctx.Target().Arch.ArchType && len(ctx.MultiTargets()) == 0 { get(p.properties.DepsProperty) } else if arch.Multilib == "lib32" { get(p.properties.Multilib.Lib32) @@ -498,7 +503,7 @@ func (p *PackagingBase) AddDeps(ctx BottomUpMutatorContext, depTag blueprint.Dep ctx.AddFarVariationDependencies(targetVariation, depTagToUse, dep) } for _, t := range getSupportedTargets(ctx) { - normalDeps, highPriorityDeps := p.getDepsForArch(ctx, t.Arch.ArchType) + normalDeps, highPriorityDeps := p.getDepsForTarget(ctx, t) for _, dep := range normalDeps { addDep(t, dep, false) } diff --git a/filesystem/filesystem_test.go b/filesystem/filesystem_test.go index e57e45cb6..2e7f478ff 100644 --- a/filesystem/filesystem_test.go +++ b/filesystem/filesystem_test.go @@ -803,3 +803,65 @@ func TestRamdiskPartitionSetsDevNodes(t *testing.T) { java.CheckModuleHasDependency(t, result.TestContext, "ramdisk_filesystem", "android_common", "ramdisk_node_list"), ) } + +func TestFileSystemWithNativeBridgeDeps(t *testing.T) { + result := android.GroupFixturePreparers( + fixture, + android.PrepareForNativeBridgeEnabled, + ).RunTestWithBp(t, ` + android_filesystem { + name: "myfilesystem", + compile_multilib: "both", + native_bridge_supported: true, + deps: ["lib_no_native_bridge", "lib_both"], + multilib: { + native_bridge: { + deps: ["lib_both", "lib_only_native_bridge"], + }, + }, + } + + cc_library { + name: "lib_no_native_bridge", + stl: "none", + system_shared_libs: [], + } + // Device arch and NativeBridge arch + cc_library { + name: "lib_both", + native_bridge_supported: true, + stl: "none", + system_shared_libs: [], + } + cc_library { + name: "lib_only_native_bridge", + native_bridge_supported: true, + enabled: false, + target: { + native_bridge: { + enabled: true, + }, + }, + stl: "none", + system_shared_libs: [], + } + `) + + // produces "myfilesystem.img" + result.ModuleForTests(t, "myfilesystem", "android_common").Output("myfilesystem.img") + + fs := result.ModuleForTests(t, "myfilesystem", "android_common").Module().(*filesystem) + expected := []string{ + // Non NativeBridge + "lib64/lib_no_native_bridge.so", + "lib64/lib_both.so", + // NativeBridge + "lib/arm/lib_both.so", + "lib/arm/lib_only_native_bridge.so", + "lib64/arm64/lib_both.so", + "lib64/arm64/lib_only_native_bridge.so", + } + for _, e := range expected { + android.AssertStringListContains(t, "missing entry", fs.entries, e) + } +} -- cgit v1.2.3 From 2366067f14e819a2bb250817b764c11c1bdbbe5e Mon Sep 17 00:00:00 2001 From: Yu Liu Date: Wed, 9 Apr 2025 18:47:17 +0000 Subject: Add custom gob methods to filePair and Gob register *binarySdkMemberType. Bug: 358427516 Test: Unit tests and compare the generated ninja and mk files. Change-Id: I327d95abb93de59882ae6ee51aa0fb6948dc2989 --- android/test_suites.go | 26 ++++++++++++++++++++++++++ cc/binary_sdk_member.go | 3 +++ 2 files changed, 29 insertions(+) diff --git a/android/test_suites.go b/android/test_suites.go index 8f40f259b..f51ca9f40 100644 --- a/android/test_suites.go +++ b/android/test_suites.go @@ -21,6 +21,7 @@ import ( "strings" "github.com/google/blueprint" + "github.com/google/blueprint/gobtools" ) func init() { @@ -82,6 +83,31 @@ type filePair struct { dst WritablePath } +type filePairGob struct { + Src Path + Dst WritablePath +} + +func (f *filePair) ToGob() *filePairGob { + return &filePairGob{ + Src: f.src, + Dst: f.dst, + } +} + +func (f *filePair) FromGob(data *filePairGob) { + f.src = data.Src + f.dst = data.Dst +} + +func (p filePair) GobEncode() ([]byte, error) { + return gobtools.CustomGobEncode[filePairGob](&p) +} + +func (p *filePair) GobDecode(data []byte) error { + return gobtools.CustomGobDecode[filePairGob](data, p) +} + type testSuiteInstallsInfo struct { Files []filePair OneVariantInstalls []filePair diff --git a/cc/binary_sdk_member.go b/cc/binary_sdk_member.go index e252cf1d8..bd15cab73 100644 --- a/cc/binary_sdk_member.go +++ b/cc/binary_sdk_member.go @@ -15,6 +15,7 @@ package cc import ( + "encoding/gob" "fmt" "path/filepath" @@ -26,6 +27,8 @@ import ( func init() { android.RegisterSdkMemberType(ccBinarySdkMemberType) + + gob.Register((*binarySdkMemberType)(nil)) } var ccBinarySdkMemberType = &binarySdkMemberType{ -- cgit v1.2.3 From 792b724f8b3c05aa69b36e006ed819d14c30f975 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Wed, 9 Apr 2025 18:35:07 +0000 Subject: Use a separate intermediates for generating META files With ag/32949221, some META/ intermediates were generated in the targetFilesDir. These subsequently get wiped out since the rule for creating target_files.zip contains `rm -rf`. To prevent this, generate these files in a separate dir and copy them to target_files_dir Bug: 409368614 Test: Will verify using go/abtd before submittting Change-Id: I7de49f4271b08f636e53f634a3371911fcd14a5d --- filesystem/android_device.go | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/filesystem/android_device.go b/filesystem/android_device.go index 0b3115400..2d027ed7f 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -526,7 +526,6 @@ type targetFilesystemZipCopy struct { func (a *androidDevice) buildTargetFilesZip(ctx android.ModuleContext, allInstalledModules []android.ModuleProxy) { targetFilesDir := android.PathForModuleOut(ctx, "target_files_dir") targetFilesZip := android.PathForModuleOut(ctx, "target_files.zip") - var targetFilesDeps android.Paths builder := android.NewRuleBuilder(pctx, ctx) builder.Command().Textf("rm -rf %s", targetFilesDir.String()) @@ -639,7 +638,7 @@ func (a *androidDevice) buildTargetFilesZip(ctx android.ModuleContext, allInstal } a.copyImagesToTargetZip(ctx, builder, targetFilesDir) - targetFilesDeps = append(targetFilesDeps, a.copyMetadataToTargetZip(ctx, builder, targetFilesDir, allInstalledModules)...) + a.copyMetadataToTargetZip(ctx, builder, targetFilesDir, allInstalledModules) a.targetFilesZip = targetFilesZip builder.Command(). @@ -648,8 +647,7 @@ func (a *androidDevice) buildTargetFilesZip(ctx android.ModuleContext, allInstal FlagWithOutput("-o ", targetFilesZip). FlagWithArg("-C ", targetFilesDir.String()). FlagWithArg("-D ", targetFilesDir.String()). - Text("-sha256"). - Implicits(targetFilesDeps) + Text("-sha256") builder.Build("target_files_"+ctx.ModuleName(), "Build target_files.zip") } @@ -709,7 +707,7 @@ func writeFileWithNewLines(ctx android.ModuleContext, path android.WritablePath, android.WriteFileRule(ctx, path, builder.String()) } -func (a *androidDevice) copyMetadataToTargetZip(ctx android.ModuleContext, builder *android.RuleBuilder, targetFilesDir android.ModuleOutPath, allInstalledModules []android.ModuleProxy) (deps android.Paths) { +func (a *androidDevice) copyMetadataToTargetZip(ctx android.ModuleContext, builder *android.RuleBuilder, targetFilesDir android.ModuleOutPath, allInstalledModules []android.ModuleProxy) { // Create a META/ subdirectory builder.Command().Textf("mkdir -p %s/META", targetFilesDir.String()) if proptools.Bool(a.deviceProps.Ab_ota_updater) { @@ -724,18 +722,18 @@ func (a *androidDevice) copyMetadataToTargetZip(ctx android.ModuleContext, build } // ab_partitions.txt abPartitionsSorted := android.SortedUniqueStrings(a.deviceProps.Ab_ota_partitions) - abPartitionsFilePath := targetFilesDir.Join(ctx, "META", "ab_partitions.txt") + abPartitionsFilePath := android.PathForModuleOut(ctx, "target_files_tmp", "ab_partitions.txt") writeFileWithNewLines(ctx, abPartitionsFilePath, abPartitionsSorted) - deps = append(deps, abPartitionsFilePath) + builder.Command().Textf("cp").Input(abPartitionsFilePath).Textf(" %s/META/", targetFilesDir) // otakeys.txt abOtaKeysSorted := android.SortedUniqueStrings(a.deviceProps.Ab_ota_keys) - abOtaKeysFilePath := targetFilesDir.Join(ctx, "META", "otakeys.txt") + abOtaKeysFilePath := android.PathForModuleOut(ctx, "target_files_tmp", "otakeys.txt") writeFileWithNewLines(ctx, abOtaKeysFilePath, abOtaKeysSorted) - deps = append(deps, abOtaKeysFilePath) + builder.Command().Textf("cp").Input(abOtaKeysFilePath).Textf(" %s/META/", targetFilesDir) // postinstall_config.txt - abOtaPostInstallConfigFilePath := targetFilesDir.Join(ctx, "META", "postinstall_config.txt") + abOtaPostInstallConfigFilePath := android.PathForModuleOut(ctx, "target_files_tmp", "postinstall_config.txt") writeFileWithNewLines(ctx, abOtaPostInstallConfigFilePath, a.deviceProps.Ab_ota_postinstall_config) - deps = append(deps, abOtaPostInstallConfigFilePath) + builder.Command().Textf("cp").Input(abOtaPostInstallConfigFilePath).Textf(" %s/META/", targetFilesDir) // selinuxfc if a.getFsInfos(ctx)["system"].SelinuxFc != nil { builder.Command().Textf("cp").Input(a.getFsInfos(ctx)["system"].SelinuxFc).Textf(" %s/META/file_contexts.bin", targetFilesDir.String()) @@ -824,8 +822,6 @@ func (a *androidDevice) copyMetadataToTargetZip(ctx android.ModuleContext, build ctx.ModuleErrorf("Super partition %s does set SuperImageProvider\n", superPartition.Name()) } } - - return deps } var ( -- cgit v1.2.3 From 5c156bd2686252f1110487943e45e6416f56010d Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Wed, 9 Apr 2025 12:59:07 -0700 Subject: Build device-tests with soong For soong-only builds. Bug: 405184090 Test: m device-tests dist, the result has a few extra shared libs but I'm going to say that's fine: https://paste.googleplex.com/5099922817548288 Change-Id: If3b77a7007000755b90ba33e57c225104640f310 --- android/test_suites.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/android/test_suites.go b/android/test_suites.go index b8bca9560..4b8cea3b5 100644 --- a/android/test_suites.go +++ b/android/test_suites.go @@ -267,10 +267,9 @@ func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) { ctx.Phony("ravenwood-tests", ravenwoodZip, ravenwoodListZip) ctx.DistForGoal("ravenwood-tests", ravenwoodZip, ravenwoodListZip) - packageTestSuite(ctx, allTestSuiteInstalls["performance-tests"], testInstalledSharedLibs["performance-tests"], performanceTests) - packageTestSuite(ctx, allTestSuiteInstalls["device-platinum-tests"], testInstalledSharedLibs["device-platinum-tests"], devicePlatinumTests) - // TODO: Enable in followup - // packageTestSuite(ctx, allTestSuiteInstalls["device-tests"], testInstalledSharedLibs["device-tests"], deviceTests) + packageTestSuite(ctx, allTestSuiteInstalls["performance-tests"], nil, performanceTests) + packageTestSuite(ctx, allTestSuiteInstalls["device-platinum-tests"], nil, devicePlatinumTests) + packageTestSuite(ctx, allTestSuiteInstalls["device-tests"], testInstalledSharedLibs["device-tests"], deviceTests) } // Get a mapping from testSuite -> list of host shared libraries, given: -- cgit v1.2.3 From 768d8665cad4fd56f7f8846ef51db1f96f43b11c Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Wed, 9 Apr 2025 20:12:39 +0000 Subject: Apply gofmt to build/soong/java Test: go build ./java Change-Id: I418caafe54bbe0fd61d1527872366287f3a7d47a --- java/aapt2.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/aapt2.go b/java/aapt2.go index 14bc9dcee..fb451b2a2 100644 --- a/java/aapt2.go +++ b/java/aapt2.go @@ -354,7 +354,7 @@ func aapt2Convert(ctx android.ModuleContext, out android.WritablePath, in androi Description: "convert to " + format, Args: map[string]string{ "format": format, - "flags": strings.Join(extraFlags, " "), + "flags": strings.Join(extraFlags, " "), }, }) } -- cgit v1.2.3 From 19e4c0a4dcd05199d010536a13e61d1fdeb83261 Mon Sep 17 00:00:00 2001 From: Zhi Dou Date: Wed, 9 Apr 2025 19:53:17 +0000 Subject: remove build flag parameters This change removes build flag parameters from the build file 1. RELEASE_READ_FROM_NEW_STORAGE 2. RELEASE_ACONFIG_NEW_EXPORTED 3. RELEASE_ACONFIG_CHECK_API_LEVEL Since these flags are enabled in release, and feature need to be enabled Test: m Bug: 378936061 Bug: 395899938 Change-Id: I239ec4e048a8a2002727c348b9254d65cfdc8cd3 --- aconfig/codegen/init.go | 5 +---- aconfig/codegen/java_aconfig_library.go | 14 +------------- aconfig/exported_java_aconfig_library.go | 17 +---------------- aconfig/init.go | 5 +---- android/config.go | 8 -------- 5 files changed, 4 insertions(+), 45 deletions(-) diff --git a/aconfig/codegen/init.go b/aconfig/codegen/init.go index 325e367ba..059b7a332 100644 --- a/aconfig/codegen/init.go +++ b/aconfig/codegen/init.go @@ -33,9 +33,6 @@ var ( ` --mode ${mode}` + ` --cache ${in}` + ` --out ${out}.tmp` + - ` --allow-instrumentation ${debug}` + - ` --new-exported ${new_exported}` + - ` --check-api-level ${check_api_level}` + ` && $soong_zip -write_if_changed -jar -o ${out} -C ${out}.tmp -D ${out}.tmp` + ` && rm -rf ${out}.tmp`, // LINT.ThenChange(/aconfig/init.go) @@ -44,7 +41,7 @@ var ( "$soong_zip", }, Restat: true, - }, "mode", "debug", "new_exported", "check_api_level") + }, "mode") // For cc_aconfig_library: Generate C++ library cppRule = pctx.AndroidStaticRule("cc_aconfig_library", diff --git a/aconfig/codegen/java_aconfig_library.go b/aconfig/codegen/java_aconfig_library.go index 7b9da8eb4..bb734a02d 100644 --- a/aconfig/codegen/java_aconfig_library.go +++ b/aconfig/codegen/java_aconfig_library.go @@ -20,7 +20,6 @@ import ( "github.com/google/blueprint" "github.com/google/blueprint/proptools" - "strconv" ) type declarationsTagType struct { @@ -98,24 +97,13 @@ func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) GenerateSourceJarBuild ctx.PropertyErrorf("mode", "exported mode requires its aconfig_declaration has exportable prop true") } - var newExported bool - if useNewExported, ok := ctx.Config().GetBuildFlag("RELEASE_ACONFIG_NEW_EXPORTED"); ok { - // The build flag (RELEASE_ACONFIG_REQUIRE_ALL_READ_ONLY) is the negation of the aconfig flag - // (allow-read-write) for historical reasons. - // Bool build flags are always "" for false, and generally "true" for true. - newExported = useNewExported == "true" - } - ctx.Build(pctx, android.BuildParams{ Rule: javaRule, Input: declarations.IntermediateCacheOutputPath, Output: srcJarPath, Description: "aconfig.srcjar", Args: map[string]string{ - "mode": mode, - "debug": strconv.FormatBool(ctx.Config().ReleaseReadFromNewStorage()), - "new_exported": strconv.FormatBool(newExported), - "check_api_level": strconv.FormatBool(ctx.Config().ReleaseAconfigCheckApiLevel()), + "mode": mode, }, }) diff --git a/aconfig/exported_java_aconfig_library.go b/aconfig/exported_java_aconfig_library.go index ffb2a0cbe..37c1364a7 100644 --- a/aconfig/exported_java_aconfig_library.go +++ b/aconfig/exported_java_aconfig_library.go @@ -15,8 +15,6 @@ package aconfig import ( - "strconv" - "android/soong/android" ) @@ -39,16 +37,6 @@ func (this *exportedJavaDeclarationsLibrarySingleton) GenerateBuildActions(ctx a cacheFiles = append(cacheFiles, decl.IntermediateCacheOutputPath) }) - var newExported bool - if useNewExported, ok := ctx.Config().GetBuildFlag("RELEASE_ACONFIG_NEW_EXPORTED"); ok { - newExported = useNewExported == "true" - } - - var newStorage bool - if useNewStorage, ok := ctx.Config().GetBuildFlag("RELEASE_READ_FROM_NEW_STORAGE"); ok { - newStorage = useNewStorage == "true" - } - // Generate build action for aconfig this.intermediatePath = android.PathForIntermediates(ctx, "exported_java_aconfig_library.jar") ctx.Build(pctx, android.BuildParams{ @@ -57,10 +45,7 @@ func (this *exportedJavaDeclarationsLibrarySingleton) GenerateBuildActions(ctx a Output: this.intermediatePath, Description: "exported_java_aconfig_library", Args: map[string]string{ - "cache_files": android.JoinPathsWithPrefix(cacheFiles, " "), - "use_new_storage": strconv.FormatBool(newStorage), - "use_new_exported": strconv.FormatBool(newExported), - "check_api_level": strconv.FormatBool(ctx.Config().ReleaseAconfigCheckApiLevel()), + "cache_files": android.JoinPathsWithPrefix(cacheFiles, " "), }, }) ctx.Phony("exported_java_aconfig_library", this.intermediatePath) diff --git a/aconfig/init.go b/aconfig/init.go index 6f22a6a6d..5c053978a 100644 --- a/aconfig/init.go +++ b/aconfig/init.go @@ -143,10 +143,7 @@ var ( ` ${aconfig} create-java-lib` + ` --cache ${out}.pb.tmp/$$cache` + ` --mode=exported` + - ` --allow-instrumentation ${use_new_storage}` + - ` --new-exported ${use_new_exported}` + ` --single-exported-file true` + - ` --check-api-level ${check_api_level}` + ` --out ${out}.tmp; ` + // LINT.ThenChange(/aconfig/codegen/init.go) ` fi ` + @@ -159,7 +156,7 @@ var ( "$soong_zip", "$exported-flag-check", }, - }, "cache_files", "use_new_storage", "use_new_exported", "check_api_level") + }, "cache_files") ) func init() { diff --git a/android/config.go b/android/config.go index fcc687bdb..3a30ca261 100644 --- a/android/config.go +++ b/android/config.go @@ -283,10 +283,6 @@ func (c Config) ReleaseHiddenApiExportableStubs() bool { } // Enable read flag from new storage -func (c Config) ReleaseReadFromNewStorage() bool { - return c.config.productVariables.GetBuildFlagBool("RELEASE_READ_FROM_NEW_STORAGE") -} - func (c Config) ReleaseCreateAconfigStorageFile() bool { return c.config.productVariables.GetBuildFlagBool("RELEASE_CREATE_ACONFIG_STORAGE_FILE") } @@ -299,10 +295,6 @@ func (c Config) ReleaseFingerprintAconfigPackages() bool { return c.config.productVariables.GetBuildFlagBool("RELEASE_FINGERPRINT_ACONFIG_PACKAGES") } -func (c Config) ReleaseAconfigCheckApiLevel() bool { - return c.config.productVariables.GetBuildFlagBool("RELEASE_ACONFIG_CHECK_API_LEVEL") -} - func (c Config) ReleaseRustUseArmTargetArchVariant() bool { return c.config.productVariables.GetBuildFlagBool("RELEASE_RUST_USE_ARM_TARGET_ARCH_VARIANT") } -- cgit v1.2.3 From dfe027f3f86dacb43ded15ffcb38f812a89399a4 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Wed, 9 Apr 2025 21:35:54 +0000 Subject: Allowlist some files for diff_test The map file of product.img is not identical between make and soong. One possible explanation (unverified) for this is due to differences in NOTICE.xml.gz file trusty_security_vm.elf seems to be non hermetic. To repro, build as ``` OUT_DIR=out1 m trusty_security_vm.elf OUT_DIR=out2 m trusty_security_vm.elf ``` Bug: 409368614 Test: Will use go/abtd to verify before submitting Change-Id: I99b5c34fd9094f09306cbddc55957b318c9f04e8 --- scripts/soong_only_diff_test.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/soong_only_diff_test.py b/scripts/soong_only_diff_test.py index 3575ff537..67313fd40 100755 --- a/scripts/soong_only_diff_test.py +++ b/scripts/soong_only_diff_test.py @@ -109,6 +109,7 @@ SHA_DIFF_ALLOWLIST = { "IMAGES/odm_dlkm.img", "IMAGES/odm.img", "IMAGES/product.img", + "IMAGES/product.map", "IMAGES/system_dlkm.img", "IMAGES/system_ext.img", "IMAGES/system.img", @@ -136,6 +137,7 @@ SHA_DIFF_ALLOWLIST = { "SYSTEM_EXT/etc/NOTICE.xml.gz", "VENDOR_DLKM/etc/NOTICE.xml.gz", "VENDOR/etc/NOTICE.xml.gz", + "SYSTEM_EXT/etc/vm/trusty_vm/trusty_security_vm.elf", # TODO: Make this hermetic } def compare_sha_maps(soong_only_map: dict[str, bytes], soong_plus_make_map: dict[str, bytes]) -> bool: -- cgit v1.2.3 From c45b36c8a8039c2673006cf0a2dcad14a3725e40 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Tue, 8 Apr 2025 16:04:08 -0700 Subject: Clone override properties Passing the overriding properties into a provider can cause errors if they are later modified. Make a cloned copy to place in the provider. Test: builds Change-Id: I70df4a002a0b8d62053133a90212ca8c9113e678 --- android/override_module.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/android/override_module.go b/android/override_module.go index 9a0ce9e3d..7552a57a6 100644 --- a/android/override_module.go +++ b/android/override_module.go @@ -29,6 +29,8 @@ package android import ( "fmt" + "reflect" + "slices" "github.com/google/blueprint" "github.com/google/blueprint/proptools" @@ -224,9 +226,16 @@ func overrideModuleDepsMutator(ctx BottomUpMutatorContext) { ctx.AddDependency(ctx.Module(), overrideBaseDepTag, *module.getOverrideModuleProperties().Base) + // Make a copy of module.getOverridingProperties so that it won't be modified by any future + // mutators, which would violate the immutable providers requirement. + overridingProps := slices.Clone(module.getOverridingProperties()) + for i, props := range overridingProps { + overridingProps[i] = proptools.CloneProperties(reflect.ValueOf(props)).Interface() + } + info := overrideTransitionMutatorInfo{ name: module.Name(), - overridingProperties: module.getOverridingProperties(), + overridingProperties: overridingProps, } prebuiltDeps := ctx.GetDirectDepsWithTag(PrebuiltDepTag) -- cgit v1.2.3 From 5a43934f0a653d75f9d722a680ec3a3bd3f05ade Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Mon, 7 Apr 2025 14:01:51 -0700 Subject: Track modules for tests in Soong A future change to Blueprint will allow it to drop its last references to Modules after their GenerateBuildActions is complete. That will prevent tests from retreiving the Module objects with ModuleForTests. When running with a test Config, keep a list of all of the modules that ModuleForTests can iterate over. Test: all soong tests pass Change-Id: I2dc7696887c49d8b25bb55a0116c4abdc5e7350b --- android/config.go | 7 +++- android/module.go | 5 +++ android/mutator.go | 6 +++ android/namespace.go | 1 + android/test_config.go | 7 +++- android/testing.go | 104 +++++++++++++++++++++++++++++++++++++++++++++---- android/transition.go | 3 ++ 7 files changed, 122 insertions(+), 11 deletions(-) diff --git a/android/config.go b/android/config.go index fcc687bdb..5608f4eaa 100644 --- a/android/config.go +++ b/android/config.go @@ -29,8 +29,6 @@ import ( "sync" "unicode" - "android/soong/shared" - "github.com/google/blueprint" "github.com/google/blueprint/bootstrap" "github.com/google/blueprint/pathtools" @@ -38,6 +36,7 @@ import ( "android/soong/android/soongconfig" "android/soong/remoteexec" + "android/soong/shared" ) // Bool re-exports proptools.Bool for the android package. @@ -406,6 +405,10 @@ type config struct { // Copy of this config struct but some product-specific variables are // replaced with the generic configuration values. genericConfig *config + + // modulesForTests stores the list of modules that exist during Soong tests. It is nil + // when not running Soong tests. + modulesForTests *modulesForTests } type partialCompileFlags struct { diff --git a/android/module.go b/android/module.go index ff93d0c8a..a6308382e 100644 --- a/android/module.go +++ b/android/module.go @@ -511,6 +511,7 @@ type commonProperties struct { // Name and variant strings stored by mutators to enable Module.String() DebugName string `blueprint:"mutated"` + DebugNamespace string `blueprint:"mutated"` DebugMutators []string `blueprint:"mutated"` DebugVariations []string `blueprint:"mutated"` @@ -2027,6 +2028,10 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) phonies: make(map[string]Paths), } + if ctx.config.captureBuild { + ctx.config.modulesForTests.Insert(ctx.ModuleName(), ctx.Module()) + } + setContainerInfo(ctx) if ctx.Config().Getenv("DISABLE_CONTAINER_CHECK") != "true" { checkContainerViolations(ctx) diff --git a/android/mutator.go b/android/mutator.go index 12861c074..969c57457 100644 --- a/android/mutator.go +++ b/android/mutator.go @@ -302,6 +302,9 @@ func (x *registerMutatorsContext) BottomUp(name string, m BottomUpMutator) Mutat if a, ok := ctx.Module().(Module); ok { mctx := bottomUpMutatorContextFactory(ctx, a, finalPhase) defer bottomUpMutatorContextPool.Put(mctx) + if mctx.config.captureBuild { + mctx.config.modulesForTests.Insert(mctx.ModuleName(), mctx.Module()) + } m(mctx) } } @@ -494,6 +497,9 @@ func registerDepsMutator(ctx RegisterMutatorsContext) { func (b *bottomUpMutatorContext) Rename(name string) { b.bp.Rename(name) + if b.config.captureBuild { + b.config.modulesForTests.Rename(b.Module().base().commonProperties.DebugName, name) + } b.Module().base().commonProperties.DebugName = name } diff --git a/android/namespace.go b/android/namespace.go index 9ba502514..485dea829 100644 --- a/android/namespace.go +++ b/android/namespace.go @@ -220,6 +220,7 @@ func (r *NameResolver) NewModule(ctx blueprint.NamespaceContext, moduleGroup blu // inform the module whether its namespace is one that we want to export to Make amod.base().commonProperties.NamespaceExportedToMake = ns.exportToKati amod.base().commonProperties.DebugName = module.Name() + amod.base().commonProperties.DebugNamespace = ns.Path } return ns, nil diff --git a/android/test_config.go b/android/test_config.go index 5d79df099..88eb5ceb1 100644 --- a/android/test_config.go +++ b/android/test_config.go @@ -56,8 +56,11 @@ func initTestConfig(buildDir string, env map[string]string) *config { outDir: buildDir, soongOutDir: filepath.Join(buildDir, "soong"), captureBuild: true, - env: envCopy, - OncePer: &OncePer{}, + modulesForTests: &modulesForTests{ + moduleGroups: make(map[string]*moduleGroupForTests), + }, + env: envCopy, + OncePer: &OncePer{}, // Set testAllowNonExistentPaths so that test contexts don't need to specify every path // passed to PathForSource or PathForModuleSrc. diff --git a/android/testing.go b/android/testing.go index 1efa02421..25e0a53e5 100644 --- a/android/testing.go +++ b/android/testing.go @@ -17,9 +17,12 @@ package android import ( "bytes" "fmt" + "iter" + "maps" "path/filepath" "regexp" "runtime" + "slices" "sort" "strings" "sync" @@ -284,11 +287,11 @@ func (ctx *TestContext) OtherModulePropertyErrorf(module ModuleOrProxy, property panic(fmt.Sprintf(fmt_, args...)) } -// VisitAllModules wraps blueprint.Context.VisitAllModules, converting blueprint.Module to android.Module. +// VisitAllModules iterates over all modules tracked through the test config. func (ctx *TestContext) VisitAllModules(visit func(Module)) { - ctx.Context.VisitAllModules(func(module blueprint.Module) { - visit(module.(Module)) - }) + for module := range ctx.config.modulesForTests.Iter() { + visit(module) + } } // VisitAllModulesProxies wraps blueprint.Context.VisitAllModulesProxies, converting blueprint.ModuleProxy to @@ -299,10 +302,17 @@ func (ctx *TestContext) VisitAllModulesProxies(visit func(ModuleProxy)) { }) } -// VisitDirectDeps wraps blueprint.Context.VisitDirectDeps, converting blueprint.Module to android.Module. +// VisitDirectDeps wraps blueprint.Context.VisitDirectDepsProxies, converting blueprint.ModuleProxy to android.Module +// using the list of modules in the test config. func (ctx *TestContext) VisitDirectDeps(module Module, visit func(Module)) { - ctx.Context.VisitDirectDeps(module, func(module blueprint.Module) { - visit(module.(Module)) + allModules := slices.Collect(ctx.config.modulesForTests.Iter()) + ctx.VisitDirectDepsProxies(module, func(dep ModuleProxy) { + i := slices.IndexFunc(allModules, func(m Module) bool { return EqualModules(m, dep) }) + if i < 0 { + panic(fmt.Errorf("failed to find Module for ModuleProxy %s", dep)) + } else { + visit(allModules[i]) + } }) } @@ -1446,6 +1456,86 @@ func PanickingConfigAndErrorContext(ctx *TestContext) ConfigurableEvaluatorConte } } +// modulesForTests stores the list of modules that exist for use during tests. +type modulesForTests struct { + moduleGroups map[string]*moduleGroupForTests + lock sync.Mutex +} + +// moduleGroupForTests stores the list of variants that exist for a single module name. +type moduleGroupForTests struct { + modules []Module + // nextInsertIndex is the position in modules where the last module is inserted. + // It is used when inserting new variants to place them after the variant they + // were created from. + nextInsertIndex int +} + +// Insert inserts a module into modulesForTests. If the Module matches and existing +// Module in the list (either by being the same pointer or by being a clone with +// identical name, namespace and variations) then it replaces the entry currently +// in the list. Otherwise, it is inserted after the most recently updated entry in +// the list. +func (m *modulesForTests) Insert(name string, module Module) { + m.lock.Lock() + defer m.lock.Unlock() + if existing, ok := m.moduleGroups[name]; ok { + // A name that is already present + if i := slices.IndexFunc(existing.modules, func(old Module) bool { + return old == module || + (old.base().commonProperties.DebugName == module.base().commonProperties.DebugName && + old.base().commonProperties.DebugNamespace == module.base().commonProperties.DebugNamespace && + slices.Equal(old.base().commonProperties.DebugVariations, module.base().commonProperties.DebugVariations) && + slices.Equal(old.base().commonProperties.DebugMutators, module.base().commonProperties.DebugMutators)) + }); i >= 0 { + // The module matches an existing module, either by being the same Module or by being a clone. + // Replace the current entry, and set the insertion point to after the current entry. + // This path is reached when TransitionMutator is creating new variants, and relies on the + // Blueprint optimization that the existing variant is reused as the first new variant so that + // the list doesn't collect old obsolete variants. + existing.modules[i] = module + existing.nextInsertIndex = i + 1 + } else { + // The module doesn't match an existing module, insert it at the insertion point and update the + // insertion point to point after it. + existing.modules = slices.Concat(existing.modules[:existing.nextInsertIndex], + []Module{module}, + existing.modules[existing.nextInsertIndex:]) + existing.nextInsertIndex += 1 + } + } else { + // The name is not present, add a new entry for it. + m.moduleGroups[name] = &moduleGroupForTests{ + modules: []Module{module}, + nextInsertIndex: 0, + } + } +} + +// Rename updates the name of a module group. +func (m *modulesForTests) Rename(from, to string) { + m.lock.Lock() + defer m.lock.Unlock() + m.moduleGroups[to] = m.moduleGroups[from] + delete(m.moduleGroups, from) +} + +// Iter returns a Seq of all the modules in a deterministic order (alphabetically by module name, +// and then in variant order). +func (m *modulesForTests) Iter() iter.Seq[Module] { + return func(yield func(Module) bool) { + groups := slices.Collect(maps.Keys(m.moduleGroups)) + slices.Sort(groups) + for _, group := range groups { + for _, module := range m.moduleGroups[group].modules { + if !yield(module) { + return + } + } + } + } +} + type visitDirectDepsInterface interface { VisitDirectDepsProxies(ModuleOrProxy, func(dep ModuleProxy)) } diff --git a/android/transition.go b/android/transition.go index 0677ca1dd..56d26b478 100644 --- a/android/transition.go +++ b/android/transition.go @@ -228,6 +228,9 @@ func (a *androidTransitionMutatorAdapter) Mutate(ctx blueprint.BottomUpMutatorCo base.commonProperties.DebugMutators = append(base.commonProperties.DebugMutators, a.name) base.commonProperties.DebugVariations = append(base.commonProperties.DebugVariations, variation) } + if config := ctx.Config().(Config); config.captureBuild { + config.modulesForTests.Insert(ctx.ModuleName(), am) + } mctx := bottomUpMutatorContextFactory(ctx, am, a.finalPhase) defer bottomUpMutatorContextPool.Put(mctx) -- cgit v1.2.3 From 90a4e5831c1b5f0be2dbc2235dd8e185d4d49dde Mon Sep 17 00:00:00 2001 From: Charisee Date: Wed, 9 Apr 2025 18:59:04 +0000 Subject: Change cgu to 16 for "eng" builds For faster Rust build times bug: http://b/409133473 Test: m Change-Id: Ifd7fe2a3303a1dd20c7de47fcabcb019af8e36f9 --- rust/builder.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rust/builder.go b/rust/builder.go index 4e19bf79d..108cd9fe4 100644 --- a/rust/builder.go +++ b/rust/builder.go @@ -375,6 +375,8 @@ func transformSrctoCrate(ctx android.ModuleContext, main android.Path, deps Path incrementalPath := android.PathForOutput(ctx, "rustc").String() rustcFlags = append(rustcFlags, "-C incremental="+incrementalPath) + } else if ctx.Config().Eng() { + rustcFlags = append(rustcFlags, "-C codegen-units=16") } else { rustcFlags = append(rustcFlags, "-C codegen-units=1") } -- cgit v1.2.3 From 967584d82fb8e7b7f6f0a4a45f90e94a3677d9a6 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Wed, 9 Apr 2025 22:17:09 +0000 Subject: Add native bridge deps to autogenerated partitions Native bridge variants have a .native_bridge suffix in their `LOCAL_MODULE` name, due to which they are currently missing from devices like cf_x86_64_phone. This CL updates fsgen to handle these deps Details - Add a NativeBridgeSupport map to depCandidateProps. This map will be used to store information on whether the main or nativebridge variant or both variants should be added - In collectDepsMutator, append ".native_bridge" suffix to the moduleName for lookup - In setDepsMutator, use NativeBridgeSupport map to partition the deps. NativeBridgeDisabled will be added to the main deps like before. NativeBridgeEnabled will be added to `Multilib.Native_bridge.deps` Bug: 376873507 Test: lunch cf_x86_64_phone-trunk_staging-userdebug Test: m soong_generated_system_filesystem_test Test: There are still a lot of diffs, but lib/arm/*.so and lib64/arm64/*.so diffs are gone Change-Id: I47fd8115029e0dedbdf90a040eb981ad5482cae5 --- fsgen/filesystem_creator.go | 18 +++++----- fsgen/fsgen_mutators.go | 81 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 71 insertions(+), 28 deletions(-) diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go index 14aa062fc..1e9037862 100644 --- a/fsgen/filesystem_creator.go +++ b/fsgen/filesystem_creator.go @@ -643,7 +643,7 @@ func (f *filesystemCreator) createPartition(ctx android.LoadHookContext, partiti return } - baseProps := generateBaseProps(proptools.StringPtr(partition.moduleName)) + baseProps := generateBaseProps(proptools.StringPtr(partition.moduleName), ctx.Config()) fsProps, supported := generateFsProps(ctx, partitions, partition.partitionType) if !supported { @@ -962,15 +962,17 @@ func (f *filesystemCreator) createLinkerConfigSourceFilegroups(ctx android.LoadH } type filesystemBaseProperty struct { - Name *string - Compile_multilib *string - Visibility []string + Name *string + Compile_multilib *string + Native_bridge_supported *bool + Visibility []string } -func generateBaseProps(namePtr *string) *filesystemBaseProperty { +func generateBaseProps(namePtr *string, config android.Config) *filesystemBaseProperty { return &filesystemBaseProperty{ - Name: namePtr, - Compile_multilib: proptools.StringPtr("both"), + Name: namePtr, + Compile_multilib: proptools.StringPtr("both"), + Native_bridge_supported: proptools.BoolPtr(config.ProductVariables().NativeBridgeArch != nil), // The vbmeta modules are currently in the root directory and depend on the partitions Visibility: []string{"//.", "//build/soong:__subpackages__"}, } @@ -1278,7 +1280,7 @@ func generateBpContent(ctx android.EarlyModuleContext, partitionType string) str return "" } - baseProps := generateBaseProps(proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), partitionType))) + baseProps := generateBaseProps(proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), partitionType)), ctx.Config()) deps := fsGenState.fsDeps[partitionType] highPriorityDeps := fsGenState.generatedPrebuiltEtcModuleNames depProps := generateDepStruct(*deps, highPriorityDeps) diff --git a/fsgen/fsgen_mutators.go b/fsgen/fsgen_mutators.go index bef37121a..e945c0cdc 100644 --- a/fsgen/fsgen_mutators.go +++ b/fsgen/fsgen_mutators.go @@ -16,7 +16,6 @@ package fsgen import ( "fmt" - "slices" "strings" "sync" @@ -45,9 +44,10 @@ func getAllSoongGeneratedPartitionNames(config android.Config, partitions []stri } type depCandidateProps struct { - Namespace string - Multilib string - Arch []android.ArchType + Namespace string + Multilib string + Arch []android.ArchType + NativeBridgeSupport map[android.NativeBridgeSupport]bool } // Map of module name to depCandidateProps @@ -57,7 +57,8 @@ type multilibDeps map[string]*depCandidateProps // dependencies type FsGenState struct { // List of modules in `PRODUCT_PACKAGES` and `PRODUCT_PACKAGES_DEBUG` - depCandidates []string + depCandidates []string + depCandidatesMap map[string]bool // Map of names of partition to the information of modules to be added as deps fsDeps map[string]*multilibDeps // Information about the main soong-generated partitions @@ -79,8 +80,9 @@ type installationProperties struct { func defaultDepCandidateProps(config android.Config) *depCandidateProps { return &depCandidateProps{ - Namespace: ".", - Arch: []android.ArchType{config.BuildArch}, + Namespace: ".", + Arch: []android.ArchType{config.BuildArch}, + NativeBridgeSupport: map[android.NativeBridgeSupport]bool{android.NativeBridgeDisabled: true}, } } @@ -89,9 +91,13 @@ func createFsGenState(ctx android.LoadHookContext, generatedPrebuiltEtcModuleNam partitionVars := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse candidates := android.FirstUniqueStrings(android.Concat(partitionVars.ProductPackages, partitionVars.ProductPackagesDebug)) candidates = android.Concat(candidates, generatedPrebuiltEtcModuleNames) - + candidatesMap := map[string]bool{} + for _, candidate := range candidates { + candidatesMap[candidate] = true + } fsGenState := FsGenState{ - depCandidates: candidates, + depCandidates: candidates, + depCandidatesMap: candidatesMap, fsDeps: map[string]*multilibDeps{ // These additional deps are added according to the cuttlefish system image bp. "system": { @@ -207,7 +213,7 @@ func checkDepModuleInMultipleNamespaces(mctx android.BottomUpMutatorContext, fou } } -func appendDepIfAppropriate(mctx android.BottomUpMutatorContext, deps *multilibDeps, installPartition string) { +func appendDepIfAppropriate(mctx android.BottomUpMutatorContext, deps *multilibDeps, installPartition string, nbs android.NativeBridgeSupport) { moduleName := mctx.ModuleName() checkDepModuleInMultipleNamespaces(mctx, *deps, moduleName, installPartition) if _, ok := (*deps)[moduleName]; ok { @@ -216,12 +222,14 @@ func appendDepIfAppropriate(mctx android.BottomUpMutatorContext, deps *multilibD (*deps)[moduleName].Namespace = mctx.Namespace().Path } (*deps)[moduleName].Arch = append((*deps)[moduleName].Arch, mctx.Module().Target().Arch.ArchType) + (*deps)[moduleName].NativeBridgeSupport[nbs] = true } else { multilib, _ := mctx.Module().DecodeMultilib(mctx) (*deps)[moduleName] = &depCandidateProps{ - Namespace: mctx.Namespace().Path, - Multilib: multilib, - Arch: []android.ArchType{mctx.Module().Target().Arch.ArchType}, + Namespace: mctx.Namespace().Path, + Multilib: multilib, + Arch: []android.ArchType{mctx.Module().Target().Arch.ArchType}, + NativeBridgeSupport: map[android.NativeBridgeSupport]bool{nbs: true}, } } } @@ -236,15 +244,28 @@ func collectDepsMutator(mctx android.BottomUpMutatorContext) { fsGenState.fsDepsMutex.Lock() defer fsGenState.fsDepsMutex.Unlock() - if slices.Contains(fsGenState.depCandidates, mctx.ModuleName()) { + if _, ok := fsGenState.depCandidatesMap[mctx.ModuleName()]; ok { installPartition := m.PartitionTag(mctx.DeviceConfig()) // Only add the module as dependency when: // - its enabled // - its namespace is included in PRODUCT_SOONG_NAMESPACES if m.Enabled(mctx) && m.ExportedToMake() { - appendDepIfAppropriate(mctx, fsGenState.fsDeps[installPartition], installPartition) + appendDepIfAppropriate(mctx, fsGenState.fsDeps[installPartition], installPartition, android.NativeBridgeDisabled) + } + } + + if _, ok := fsGenState.depCandidatesMap[mctx.ModuleName()+".native_bridge"]; ok { + installPartition := m.PartitionTag(mctx.DeviceConfig()) + if m.Enabled(mctx) && m.ExportedToMake() { + appendDepIfAppropriate(mctx, fsGenState.fsDeps[installPartition], installPartition, android.NativeBridgeEnabled) + } + } else if _, ok := fsGenState.depCandidatesMap[mctx.ModuleName()+".bootstrap.native_bridge"]; ok { + installPartition := m.PartitionTag(mctx.DeviceConfig()) + if m.Enabled(mctx) && m.ExportedToMake() { + appendDepIfAppropriate(mctx, fsGenState.fsDeps[installPartition], installPartition, android.NativeBridgeEnabled) } } + // store the map of module to (required,overrides) even if the module is not in PRODUCT_PACKAGES. // the module might be installed transitively. if m.Enabled(mctx) && m.ExportedToMake() { @@ -260,11 +281,12 @@ type depsStruct struct { } type multilibDepsStruct struct { - Common depsStruct - Lib32 depsStruct - Lib64 depsStruct - Both depsStruct - Prefer32 depsStruct + Common depsStruct + Lib32 depsStruct + Lib64 depsStruct + Both depsStruct + Prefer32 depsStruct + Native_bridge depsStruct } type packagingPropsStruct struct { @@ -363,6 +385,11 @@ func isHighPriorityDep(depName string) bool { func generateDepStruct(deps map[string]*depCandidateProps, highPriorityDeps []string) *packagingPropsStruct { depsStruct := packagingPropsStruct{} for depName, depProps := range deps { + if _, ok := depProps.NativeBridgeSupport[android.NativeBridgeDisabled]; !ok { + // Only the native bridge variant of this dep should be added. + // This will be done separately. + continue + } bitness := getBitness(depProps.Arch) fullyQualifiedDepName := fullyQualifiedModuleName(depName, depProps.Namespace) if android.InList(depName, highPriorityDeps) { @@ -394,12 +421,26 @@ func generateDepStruct(deps map[string]*depCandidateProps, highPriorityDeps []st depsStruct.Multilib.Common.Deps = append(depsStruct.Multilib.Common.Deps, fullyQualifiedDepName) } } + // Add the native bridge deps + var nativeBridgeDeps []string + for depName, depProps := range deps { + if _, ok := depProps.NativeBridgeSupport[android.NativeBridgeEnabled]; !ok { + continue + } + if depProps.Namespace != "." { // Add the fully qualified name + nativeBridgeDeps = append(nativeBridgeDeps, "//"+depProps.Namespace+":"+depName) + } else { + nativeBridgeDeps = append(nativeBridgeDeps, depName) + } + } + depsStruct.Deps = android.SortedUniqueStrings(depsStruct.Deps) depsStruct.Multilib.Lib32.Deps = android.SortedUniqueStrings(depsStruct.Multilib.Lib32.Deps) depsStruct.Multilib.Lib64.Deps = android.SortedUniqueStrings(depsStruct.Multilib.Lib64.Deps) depsStruct.Multilib.Prefer32.Deps = android.SortedUniqueStrings(depsStruct.Multilib.Prefer32.Deps) depsStruct.Multilib.Both.Deps = android.SortedUniqueStrings(depsStruct.Multilib.Both.Deps) depsStruct.Multilib.Common.Deps = android.SortedUniqueStrings(depsStruct.Multilib.Common.Deps) + depsStruct.Multilib.Native_bridge.Deps = android.SortedUniqueStrings(nativeBridgeDeps) depsStruct.High_priority_deps = android.SortedUniqueStrings(depsStruct.High_priority_deps) return &depsStruct -- cgit v1.2.3 From 8c96806c6add46c420d152d4f484350ce6eb2ace Mon Sep 17 00:00:00 2001 From: Yu Liu Date: Tue, 8 Apr 2025 23:28:01 +0000 Subject: Add PostGenerateAndroidBuildActionsHook. Bug: 358427516 Test: Unit tests and compare the generated ninja and mk files. Change-Id: Ife6e96195b06698588ab091d85321d59bb17fbc7 --- android/hooks.go | 22 +++++++++++++++++++++- android/module.go | 2 ++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/android/hooks.go b/android/hooks.go index 5d509a43e..5a07a4ee3 100644 --- a/android/hooks.go +++ b/android/hooks.go @@ -243,6 +243,26 @@ func (x *hooks) runInstallHooks(ctx ModuleContext, srcPath Path, path InstallPat } } +// AddPostGenerateAndroidBuildActionsHook adds a hook that runs immediately after +// the module's GenerateAndroidBuildActions method is called, allowing modules +// to inject custom logic when sharing that method. +func AddPostGenerateAndroidBuildActionsHook(m blueprint.Module, hook func(ctx ModuleContext)) { + h := &m.(Module).base().hooks + h.postGenerateAndroidBuildActions = append(h.postGenerateAndroidBuildActions, hook) +} + +func (x *hooks) runPostGenerateAndroidBuildActionsHooks(ctx ModuleContext) { + if len(x.postGenerateAndroidBuildActions) > 0 { + for _, x := range x.postGenerateAndroidBuildActions { + x(ctx) + if ctx.Failed() { + return + } + } + } +} + type hooks struct { - install []func(InstallHookContext) + install []func(InstallHookContext) + postGenerateAndroidBuildActions []func(ModuleContext) } diff --git a/android/module.go b/android/module.go index 3f3d5b401..3d72588f5 100644 --- a/android/module.go +++ b/android/module.go @@ -2153,6 +2153,8 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) return } + m.module.base().hooks.runPostGenerateAndroidBuildActionsHooks(ctx) + if x, ok := m.module.(IDEInfo); ok { var result IdeInfo x.IDEInfo(ctx, &result) -- cgit v1.2.3 From 87fe5acecfba5458e7fbed1b1f4848a78053ea93 Mon Sep 17 00:00:00 2001 From: Yu Liu Date: Thu, 10 Apr 2025 00:01:23 +0000 Subject: Don't remove raw_ files for incremental analysis build, otherwise ninja will complain about missing files for restored modules because they don't run GenerateAndroidBuildActions therefore won't have these raw- files written. Bug: 358427516 Test: Unit tests and compare the generated ninja and mk files. Change-Id: I0ab6c637dfb030690c8d2af9501c606991ea4e70 --- android/raw_files.go | 2 +- android/singleton.go | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/android/raw_files.go b/android/raw_files.go index ebba4d145..128b6feb0 100644 --- a/android/raw_files.go +++ b/android/raw_files.go @@ -271,7 +271,7 @@ func (rawFilesSingleton) GenerateBuildActions(ctx SingletonContext) { // Checking that the path matches allows changing the structure of the raw directory, for example to increase // the sharding. rawFileInfo, written := rawFileSet.Load(key) - if !written || rawFileInfo.relPath != relPath { + if !ctx.GetIncrementalAnalysis() && (!written || rawFileInfo.relPath != relPath) { os.Remove(path) } return nil diff --git a/android/singleton.go b/android/singleton.go index e5f26842a..872c5f315 100644 --- a/android/singleton.go +++ b/android/singleton.go @@ -121,6 +121,8 @@ type SingletonContext interface { // directory on the build server with the given filename when any of the // specified goals are built. DistForGoalsWithFilename(goals []string, path Path, filename string) + + GetIncrementalAnalysis() bool } type singletonAdaptor struct { @@ -410,3 +412,7 @@ func (s *singletonContextAdaptor) DistForGoalsWithFilename(goals []string, path paths: distCopies{{from: path, dest: filename}}, }) } + +func (s *singletonContextAdaptor) GetIncrementalAnalysis() bool { + return s.SingletonContext.GetIncrementalAnalysis() +} -- cgit v1.2.3 From 7ff2fcd945ba603f3c344d1c546d3cf283b5db71 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Wed, 9 Apr 2025 16:25:54 -0700 Subject: Use coverage deps in test_package When coverage is enabled, non-coverage variants don't install/package any files, and the coverage variants do. Our test package was always depending on the non-coverage variants, so when coverage was enabled they weren't installing anything and the test package was mostly empty. The coverage mutator supports modules implementing IsNativeCoverageNeeded() to indicate that they want the coverage variants of their dep, so use that. Bug: 408492405 Test: CLANG_COVERAGE=true m continuous_instrumentation_tests_soong, check that it has the same files in it as the non-coverage variant Change-Id: I01d068d9630518c4bcf62c0362fbfa42e0f71311 --- ci_tests/Android.bp | 1 + ci_tests/ci_test_package_zip.go | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/ci_tests/Android.bp b/ci_tests/Android.bp index 181ded46d..27edc585c 100644 --- a/ci_tests/Android.bp +++ b/ci_tests/Android.bp @@ -10,6 +10,7 @@ bootstrap_go_package { "blueprint-proptools", "soong", "soong-android", + "soong-cc", ], srcs: [ "ci_test_package_zip.go", diff --git a/ci_tests/ci_test_package_zip.go b/ci_tests/ci_test_package_zip.go index 46edebb4b..1c457b3d9 100644 --- a/ci_tests/ci_test_package_zip.go +++ b/ci_tests/ci_test_package_zip.go @@ -22,6 +22,7 @@ import ( "strings" "android/soong/android" + "android/soong/cc" "github.com/google/blueprint" "github.com/google/blueprint/proptools" @@ -156,6 +157,15 @@ func TestPackageZipFactory() android.Module { return module } +// We need to implement IsNativeCoverageNeeded so that in coverage builds we depend on the coverage +// variants of the tests. The non-coverage variants will have PreventInstall called on them, +// so they won't be able to be packaged into this test zip. +func (p *testPackageZip) IsNativeCoverageNeeded(ctx cc.IsNativeCoverageNeededContext) bool { + return ctx.DeviceConfig().NativeCoverageEnabled() +} + +var _ cc.UseCoverage = (*testPackageZip)(nil) + func (p *testPackageZip) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Never install this test package, it's for disting only p.SkipInstall() -- cgit v1.2.3 From 1e50981fd0231227b18a3964ccf2bfc3c26cd185 Mon Sep 17 00:00:00 2001 From: Ivan Lozano Date: Wed, 2 Apr 2025 17:17:01 +0000 Subject: rust: Windows Support Add support for the windows host to Rust. This adds a rust_object module which is required for building the Windows crt (which is defined as a .rs file and expected as a .o). Bug: 331798788 Test: Basic windows module builds. Change-Id: I22e7b9c0196e4415e44abcc38a95e99264161f4e --- rust/binary.go | 25 ++++-- rust/builder.go | 28 ++++-- rust/compiler.go | 8 ++ rust/config/Android.bp | 1 + rust/config/global.go | 7 +- rust/config/x86_windows_host.go | 188 ++++++++++++++++++++++++++++++++++++++++ rust/library.go | 17 +++- rust/rust.go | 8 +- rust/test.go | 23 +++++ scripts/rustc_linker.py | 29 +++++-- 10 files changed, 309 insertions(+), 25 deletions(-) create mode 100644 rust/config/x86_windows_host.go diff --git a/rust/binary.go b/rust/binary.go index 4a4fb6fb8..b413a40cc 100644 --- a/rust/binary.go +++ b/rust/binary.go @@ -15,9 +15,10 @@ package rust import ( - "android/soong/android" - + "github.com/google/blueprint/pathtools" "github.com/google/blueprint/proptools" + + "android/soong/android" ) func init() { @@ -83,8 +84,8 @@ func (binary *binaryDecorator) begin(ctx BaseModuleContext) { } } - if ctx.Darwin() || (ctx.Os().Linux() && ctx.Host() && ctx.toolchain().Glibc()) { - // Static executables are not supported on Darwin + if ctx.Darwin() || ctx.Windows() || (ctx.Os().Linux() && ctx.Host() && ctx.toolchain().Glibc()) { + // Static executables are not supported on Darwin, Linux glibc, or Windows binary.Properties.Static_executable = nil } } @@ -129,8 +130,10 @@ func (binary *binaryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps { deps.CrtBegin = []string{"libc_musl_crtbegin_dynamic"} } deps.CrtEnd = []string{"libc_musl_crtend"} + } else if ctx.Os() == android.Windows { + deps.CrtBegin = []string{"rsbegin.rust_sysroot"} + deps.CrtEnd = []string{"rsend.rust_sysroot"} } - return deps } @@ -160,10 +163,20 @@ func (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps Path flags.RustFlags = append(flags.RustFlags, deps.depFlags...) flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...) flags.LinkFlags = append(flags.LinkFlags, deps.rustLibObjects...) - flags.LinkFlags = append(flags.LinkFlags, deps.sharedLibObjects...) flags.LinkFlags = append(flags.LinkFlags, deps.staticLibObjects...) flags.LinkFlags = append(flags.LinkFlags, deps.wholeStaticLibObjects...) + if ctx.Windows() { + for _, lib := range deps.sharedLibObjects { + // Windows uses the .lib import library at link-time and at runtime + // uses the .dll library, so we need to make sure we're passing the + // import library to the linker. + flags.LinkFlags = append(flags.LinkFlags, pathtools.ReplaceExtension(lib, "lib")) + } + } else { + flags.LinkFlags = append(flags.LinkFlags, deps.sharedLibObjects...) + } + if binary.stripper.NeedsStrip(ctx) { strippedOutputFile := outputFile outputFile = android.PathForModuleOut(ctx, "unstripped", fileName) diff --git a/rust/builder.go b/rust/builder.go index 2519830b0..8d4192afe 100644 --- a/rust/builder.go +++ b/rust/builder.go @@ -463,6 +463,21 @@ func transformSrctoCrate(ctx android.ModuleContext, main android.Path, deps Path implicits = append(implicits, outputs.Paths()...) } } + var implicitOutputs android.WritablePaths + mod := ctx.Module().(cc.LinkableInterface) + if ctx.Windows() && mod.Shared() { + // On windows, an additional .lib file is produced for shared libraries. + importLibraryPath := android.PathForModuleOut(ctx, outputFile.ReplaceExtension(ctx, "lib").Base()) + linkFlags = append(linkFlags, "-Wl,--out-implib="+importLibraryPath.String()) + implicitOutputs = append(implicitOutputs, importLibraryPath) + + // On Windows, we always generate a PDB file + // --strip-debug is needed to also keep COFF symbols which are needed when + // we patch binaries with symbol_inject. + pdb := outputFile.ReplaceExtension(ctx, "pdb") + linkFlags = append(linkFlags, " -Wl,--strip-debug -Wl,--pdb="+pdb.String()+" ") + implicitOutputs = append(implicitOutputs, pdb) + } if !t.synthetic { // Only worry about clippy for actual Rust modules. @@ -490,12 +505,13 @@ func transformSrctoCrate(ctx android.ModuleContext, main android.Path, deps Path } ctx.Build(pctx, android.BuildParams{ - Rule: rustc, - Description: "rustc " + main.Rel(), - Output: outputFile, - Inputs: inputs, - Implicits: implicits, - OrderOnly: orderOnly, + Rule: rustc, + Description: "rustc " + main.Rel(), + Output: outputFile, + Inputs: inputs, + Implicits: implicits, + ImplicitOutputs: implicitOutputs, + OrderOnly: orderOnly, Args: map[string]string{ "rustcFlags": strings.Join(rustcFlags, " "), "earlyLinkFlags": earlyLinkFlags, diff --git a/rust/compiler.go b/rust/compiler.go index d5ad4e733..b5f20fbef 100644 --- a/rust/compiler.go +++ b/rust/compiler.go @@ -442,6 +442,7 @@ func CommonDefaultFlags(ctx android.ModuleContext, toolchain config.Toolchain, f if ctx.Os() == android.Linux { // Add -lc, -lrt, -ldl, -lpthread, -lm and -lgcc_s to glibc builds to match // the default behavior of device builds. + flags.RustFlags = append(flags.RustFlags, config.LinuxHostGlobalRustFlags...) flags.LinkFlags = append(flags.LinkFlags, config.LinuxHostGlobalLinkFlags...) } else if ctx.Os() == android.Darwin { // Add -lc, -ldl, -lpthread and -lm to glibc darwin builds to match the default @@ -550,6 +551,13 @@ func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps { deps.Stdlibs = append(deps.Stdlibs, stdlib) } } + + if ctx.Windows() { + if ctx.ModuleName() != "libwinpthread" { + deps.StaticLibs = append(deps.StaticLibs, "libwinpthread") + } + } + return deps } diff --git a/rust/config/Android.bp b/rust/config/Android.bp index 25f7580d0..a52719a2c 100644 --- a/rust/config/Android.bp +++ b/rust/config/Android.bp @@ -22,6 +22,7 @@ bootstrap_go_package { "x86_linux_host.go", "x86_device.go", "x86_64_device.go", + "x86_windows_host.go", "arm64_linux_host.go", ], visibility: [ diff --git a/rust/config/global.go b/rust/config/global.go index 907316fab..75d3f38a4 100644 --- a/rust/config/global.go +++ b/rust/config/global.go @@ -48,7 +48,6 @@ var ( "-Z remap-cwd-prefix=.", "-C debuginfo=2", "-C opt-level=3", - "-C relocation-model=pic", "-C overflow-checks=on", "-C force-unwind-tables=yes", // Use v0 mangling to distinguish from C++ symbols @@ -60,7 +59,9 @@ var ( // cfg flag to indicate that we are building in AOSP with Soong "--cfg soong", } - + LinuxHostGlobalRustFlags = []string{ + "-C relocation-model=pic", + } LinuxHostGlobalLinkFlags = []string{ "-lc", "-lrt", @@ -77,6 +78,7 @@ var ( "-Z debug-info-for-profiling", // Android has ELF TLS on platform "-Z tls-model=global-dynamic", + "-C relocation-model=pic", } deviceGlobalLinkFlags = []string{ @@ -130,6 +132,7 @@ func init() { pctx.StaticVariable("RUST_DEFAULT_VERSION", RustDefaultVersion) pctx.StaticVariable("GLOBAL_RUSTC_FLAGS", strings.Join(GlobalRustFlags, " ")) pctx.StaticVariable("LINUX_HOST_GLOBAL_LINK_FLAGS", strings.Join(LinuxHostGlobalLinkFlags, " ")) + pctx.StaticVariable("LINUX_HOST_GLOBAL_RUST_FLAGS", strings.Join(LinuxHostGlobalRustFlags, " ")) pctx.StaticVariable("DEVICE_GLOBAL_RUSTC_FLAGS", strings.Join(deviceGlobalRustFlags, " ")) pctx.StaticVariable("DEVICE_GLOBAL_LINK_FLAGS", diff --git a/rust/config/x86_windows_host.go b/rust/config/x86_windows_host.go new file mode 100644 index 000000000..f69a0ee58 --- /dev/null +++ b/rust/config/x86_windows_host.go @@ -0,0 +1,188 @@ +// 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 config + +import ( + "strings" + + "android/soong/android" +) + +var ( + // Common Windows Rust flags + windowsRustFlags = []string{ + "-C dlltool=${cc_config.ClangBin}/llvm-dlltool", + "-C split-debuginfo=packed", + "-C link-self-contained=no", + "-C panic=abort", + } + // Common Windows linker flags for Rust + windowsRustLinkFlags = []string{ + "--sysroot ${cc_config.WindowsGccRoot}/${cc_config.WindowsGccTriple}", + "-fuse-ld=lld", + "-lssp", + "-lgcc_s", + "-ladvapi32", + } + + // x86 specific flags + windowsX86RustFlags = []string{} + windowsX8664RustFlags = []string{} + + // x86_64 specific flags + windowsX86RustLinkFlags = []string{} + windowsX8664RustLinkFlags = []string{} +) + +func init() { + registerToolchainFactory(android.Windows, android.X86, windowsX86ToolchainFactory) + registerToolchainFactory(android.Windows, android.X86_64, windowsX8664ToolchainFactory) + + pctx.StaticVariable("WindowsToolchainRustFlags", strings.Join(windowsRustFlags, " ")) + pctx.StaticVariable("WindowsToolchainRustLinkFlags", strings.Join(windowsRustLinkFlags, " ")) + + pctx.StaticVariable("WindowsX86ToolchainRustFlags", strings.Join(windowsX86RustFlags, " ")) + pctx.StaticVariable("WindowsX86ToolchainRustLinkFlags", strings.Join(windowsX86RustLinkFlags, " ")) + pctx.StaticVariable("WindowsX8664ToolchainRustFlags", strings.Join(windowsX8664RustFlags, " ")) + pctx.StaticVariable("WindowsX8664ToolchainRustLinkFlags", strings.Join(windowsX8664RustLinkFlags, " ")) +} + +type toolchainWindowsX86 struct { + toolchainBase +} + +func (t *toolchainWindowsX86) Is64Bit() bool { + return false +} + +func (t *toolchainWindowsX86) LibclangRuntimeLibraryArch() string { + return "i686" +} + +func (t *toolchainWindowsX86) RlibSuffix() string { + return ".rlib" +} + +// Windows x86 +func (t *toolchainWindowsX86) Name() string { + return "x86" +} + +func (t *toolchainWindowsX86) ToolchainLinkFlags() string { + // Prepend the lld flags from cc_config so we stay in sync with cc + return "${cc_config.WindowsLldflags} ${cc_config.WindowsX86Ldflags} ${cc_config.WindowsAvailableLibraries} " + + "${config.WindowsToolchainRustLinkFlags} ${config.WindowsX86ToolchainRustLinkFlags}" +} + +func (t *toolchainWindowsX86) ToolchainRustFlags() string { + return "${config.WindowsToolchainRustFlags} ${config.WindowsX86ToolchainRustFlags}" +} + +func (t *toolchainWindowsX86) RustTriple() string { + return "i686-pc-windows-gnu" +} + +func windowsX86ToolchainFactory(arch android.Arch) Toolchain { + return toolchainWindowsX86Singleton +} + +func (toolchainWindowsX86) Supported() bool { + return true +} + +func (toolchainWindowsX86) StaticLibSuffix() string { + return ".a" +} + +func (toolchainWindowsX86) SharedLibSuffix() string { + return ".dll" +} + +func (toolchainWindowsX86) ExecutableSuffix() string { + return ".exe" +} + +func (toolchainWindowsX86) DylibSuffix() string { + return ".dylib.dll" +} + +func (toolchainWindowsX86) ProcMacroSuffix() string { + return ".dylib.dll" +} + +// Windows x86_64 +type toolchainWindowsX8664 struct { + toolchainBase +} + +func (t *toolchainWindowsX8664) Is64Bit() bool { + return true +} + +func (t *toolchainWindowsX8664) LibclangRuntimeLibraryArch() string { + return "x86_64" +} + +func (t *toolchainWindowsX8664) RlibSuffix() string { + return ".rlib" +} + +func (t *toolchainWindowsX8664) Name() string { + return "x86_64" +} + +func (t *toolchainWindowsX8664) ToolchainLinkFlags() string { + // Prepend the lld flags from cc_config so we stay in sync with cc + return "${cc_config.WindowsLldflags} ${cc_config.WindowsX8664Ldflags} ${cc_config.WindowsAvailableLibraries} " + + "${config.WindowsToolchainRustLinkFlags} ${config.WindowsX8664ToolchainRustLinkFlags}" +} + +func (t *toolchainWindowsX8664) ToolchainRustFlags() string { + return "${config.WindowsToolchainRustFlags} ${config.WindowsX8664ToolchainRustFlags}" +} + +func (t *toolchainWindowsX8664) RustTriple() string { + return "x86_64-pc-windows-gnu" +} +func windowsX8664ToolchainFactory(arch android.Arch) Toolchain { + return toolchainWindowsX8664Singleton +} + +func (toolchainWindowsX8664) Supported() bool { + return true +} + +func (toolchainWindowsX8664) StaticLibSuffix() string { + return ".a" +} + +func (toolchainWindowsX8664) SharedLibSuffix() string { + return ".dll" +} + +func (toolchainWindowsX8664) ExecutableSuffix() string { + return ".exe" +} + +func (toolchainWindowsX8664) DylibSuffix() string { + return ".dylib.dll" +} + +func (toolchainWindowsX8664) ProcMacroSuffix() string { + return ".dylib.dll" +} + +var toolchainWindowsX8664Singleton Toolchain = &toolchainWindowsX8664{} +var toolchainWindowsX86Singleton Toolchain = &toolchainWindowsX86{} diff --git a/rust/library.go b/rust/library.go index 3e11b60c8..df83122b0 100644 --- a/rust/library.go +++ b/rust/library.go @@ -22,6 +22,7 @@ import ( "github.com/google/blueprint" "github.com/google/blueprint/depset" + "github.com/google/blueprint/pathtools" "android/soong/android" "android/soong/cc" @@ -626,7 +627,9 @@ func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags) F "-install_name @rpath/"+library.sharedLibFilename(ctx), ) } else { - flags.LinkFlags = append(flags.LinkFlags, "-Wl,-soname="+library.sharedLibFilename(ctx)) + if !ctx.Windows() { + flags.LinkFlags = append(flags.LinkFlags, "-Wl,-soname="+library.sharedLibFilename(ctx)) + } } } @@ -677,10 +680,20 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa flags.RustFlags = append(flags.RustFlags, deps.depFlags...) flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...) flags.LinkFlags = append(flags.LinkFlags, deps.rustLibObjects...) - flags.LinkFlags = append(flags.LinkFlags, deps.sharedLibObjects...) flags.LinkFlags = append(flags.LinkFlags, deps.staticLibObjects...) flags.LinkFlags = append(flags.LinkFlags, deps.wholeStaticLibObjects...) + if ctx.Windows() { + for _, lib := range deps.sharedLibObjects { + // Windows uses the .lib import library at link-time and at runtime + // uses the .dll library, so we need to make sure we're passing the + // import library to the linker. + flags.LinkFlags = append(flags.LinkFlags, pathtools.ReplaceExtension(lib, "lib")) + } + } else { + flags.LinkFlags = append(flags.LinkFlags, deps.sharedLibObjects...) + } + if String(library.Properties.Version_script) != "" { if String(library.Properties.Extra_exported_symbols) != "" { ctx.ModuleErrorf("version_script and extra_exported_symbols cannot both be set.") diff --git a/rust/rust.go b/rust/rust.go index c67a9cd85..7e0193711 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -1125,7 +1125,13 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { if buildOutput.kytheFile != nil { mod.kytheFiles = append(mod.kytheFiles, buildOutput.kytheFile) } - bloaty.MeasureSizeForPaths(ctx, mod.compiler.strippedOutputFilePath(), android.OptionalPathForPath(mod.compiler.unstrippedOutputFilePath())) + if _, ok := mod.compiler.(*objectDecorator); !ok && !ctx.Windows() { + // Bloaty doesn't recognize Windows object files. + // Since objects are inputs to other binaries, if there's bloat + // in one it should be reflected in the outputs which take them + // as inputs, so skipping this check for them should be fine. + bloaty.MeasureSizeForPaths(ctx, mod.compiler.strippedOutputFilePath(), android.OptionalPathForPath(mod.compiler.unstrippedOutputFilePath())) + } mod.docTimestampFile = mod.compiler.rustdoc(ctx, flags, deps) diff --git a/rust/test.go b/rust/test.go index 72eaaae81..9ca295b25 100644 --- a/rust/test.go +++ b/rust/test.go @@ -255,12 +255,22 @@ func RustTestFactory() android.Module { // rustTestHostMultilib load hook to set MultilibFirst for the // host target. android.AddLoadHook(module, rustTestHostMultilib) + + // Windows tests are currently unsupported, so disable them. + // To support Windows test modules, we likely need to switch + // to panic=unwind. + android.AddLoadHook(module, rustTestDisableWindows) module.testModule = true return module.Init() } func RustTestHostFactory() android.Module { module, _ := NewRustTest(android.HostSupported) + + // Windows tests are unsupported, so disable them. + // To support Windows test modules, we likely need to switch + // to panic=unwind. + android.AddLoadHook(module, rustTestDisableWindows) module.testModule = true return module.Init() } @@ -322,3 +332,16 @@ func rustTestHostMultilib(ctx android.LoadHookContext) { p.Target.Host.Compile_multilib = proptools.StringPtr("first") ctx.AppendProperties(p) } + +func rustTestDisableWindows(ctx android.LoadHookContext) { + type props struct { + Target struct { + Windows struct { + Enabled bool + } + } + } + p := &props{} + p.Target.Windows.Enabled = false + ctx.AppendProperties(p) +} diff --git a/scripts/rustc_linker.py b/scripts/rustc_linker.py index 3f60708e2..c9c4a1515 100755 --- a/scripts/rustc_linker.py +++ b/scripts/rustc_linker.py @@ -31,27 +31,40 @@ replacementVersionScript = None argparser = argparse.ArgumentParser() argparser.add_argument('--android-clang-bin', required=True) args = argparser.parse_known_args() -clang_args = [args[0].android_clang_bin] + args[1] +old_clang_args = [args[0].android_clang_bin] + args[1] +new_clang_args = list() -for i, arg in enumerate(clang_args): +# Add/remove args +for i, arg in enumerate(old_clang_args): + # Record and remove the custom android-version-script arg if arg.startswith('-Wl,--android-version-script='): replacementVersionScript = arg.split("=")[1] - del clang_args[i] - break + continue + # Remove object files rustc emits for Windows target + # We provide these as an rlib. + if arg == "rsend.o": + continue + if arg == "rsbegin.o": + continue + + # Keep the arg + new_clang_args.append(old_clang_args[i]) + +# Modify args if replacementVersionScript: versionScriptFound = False - for i, arg in enumerate(clang_args): + for i, arg in enumerate(new_clang_args): if arg.startswith('-Wl,--version-script='): - clang_args[i] ='-Wl,--version-script=' + replacementVersionScript + new_clang_args[i] ='-Wl,--version-script=' + replacementVersionScript versionScriptFound = True break if not versionScriptFound: # If rustc did not emit a version script, just append the arg - clang_args.append('-Wl,--version-script=' + replacementVersionScript) + new_clang_args.append('-Wl,--version-script=' + replacementVersionScript) try: - subprocess.run(clang_args, encoding='utf-8', check=True) + subprocess.run(new_clang_args, encoding='utf-8', check=True) except subprocess.CalledProcessError as e: sys.exit(-1) -- cgit v1.2.3 From bd72a7209d684806d76638b79233b54fa93833a2 Mon Sep 17 00:00:00 2001 From: Yu Liu Date: Thu, 10 Apr 2025 17:51:08 +0000 Subject: Compare the PropertyName fields of the SdkMemberTypes in IsInstance instead of the pointers, otherwise a restored module will fail the comparison because of having different SdkMemberType pointer. Bug: 358427516 Test: Unit tests and compare the generated ninja and mk files. Change-Id: I8d6d942634c808d628cf0369b3e90d090c468202 --- cc/binary_sdk_member.go | 2 +- cc/library_sdk_member.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cc/binary_sdk_member.go b/cc/binary_sdk_member.go index bd15cab73..4d5e3cbea 100644 --- a/cc/binary_sdk_member.go +++ b/cc/binary_sdk_member.go @@ -60,7 +60,7 @@ func (mt *binarySdkMemberType) IsInstance(ctx android.ModuleContext, module andr // Check the module to see if it can be used with this module type. if m, ok := android.OtherModuleProvider(ctx, module, CcInfoProvider); ok { for _, allowableMemberType := range m.SdkMemberTypes { - if allowableMemberType == mt { + if allowableMemberType.SdkPropertyName() == mt.SdkPropertyName() { return true } } diff --git a/cc/library_sdk_member.go b/cc/library_sdk_member.go index 03103f7bf..847436c2a 100644 --- a/cc/library_sdk_member.go +++ b/cc/library_sdk_member.go @@ -191,7 +191,7 @@ func (mt *librarySdkMemberType) IsInstance(ctx android.ModuleContext, module and // Check the module to see if it can be used with this module type. if m, ok := android.OtherModuleProvider(ctx, module, CcInfoProvider); ok { for _, allowableMemberType := range m.SdkMemberTypes { - if allowableMemberType == mt { + if allowableMemberType.SdkPropertyName() == mt.SdkPropertyName() { return true } } -- cgit v1.2.3 From 072ea6398e18e000e232de1a3dbe2772def41dc2 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Thu, 10 Apr 2025 14:01:46 -0700 Subject: Dist target files and update package on droidcore-unbundled These were not being disted properly in the command used on CI. Add them to the droidcore-unbundled dist target. Bug: 385383524 Bug: 383902856 Test: m droid dist Change-Id: Ie5704a18055a32e4bfcd8e21761d98aed5c440c8 --- filesystem/android_device.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/filesystem/android_device.go b/filesystem/android_device.go index 2d027ed7f..b11f23cbf 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -447,11 +447,12 @@ func (a *androidDevice) distFiles(ctx android.ModuleContext) { } if a.targetFilesZip != nil { ctx.DistForGoalWithFilenameTag("target-files-package", a.targetFilesZip, namePrefix+a.targetFilesZip.Base()) + ctx.DistForGoalWithFilenameTag("droidcore-unbundled", a.targetFilesZip, namePrefix+a.targetFilesZip.Base()) } if a.updatePackage != nil { ctx.DistForGoalWithFilenameTag("updatepackage", a.updatePackage, namePrefix+a.updatePackage.Base()) + ctx.DistForGoalWithFilenameTag("droidcore-unbundled", a.updatePackage, namePrefix+a.updatePackage.Base()) } - } } -- cgit v1.2.3 From 2f972bbf9470d2d174a9d920b4973c3d20195198 Mon Sep 17 00:00:00 2001 From: LaMont Jones Date: Wed, 9 Apr 2025 11:39:39 -0700 Subject: Add SOONG_PARTIAL_COMPILE to banner This adds SOONG_PARTIAL_COMPILE to the banner when the user has requested that it be used with `SOONG_USE_PARTIAL_COMPILE=true`. Additionally, disable partial compile for some targets (including `droid` and `sync`) since some of the partial compile speed optimizations cause the image to become too large for many devices. If we are not dumping variables (such as during `lunch`) and we have temporarily disabled partial compile, say that in the banner. Bug: b/374975543 Bug: b/409810224 Test: manual, TH Change-Id: Id1a485df1b01a624d6e870d039e5a1b1f0017228 --- cmd/soong_ui/main.go | 9 ++------- ui/build/config.go | 46 ++++++++++++++++++++++++++++++++++++++++++++++ ui/build/config_test.go | 28 ++++++++++++++++++++++++++++ ui/build/dumpvars.go | 12 ++++++++++++ 4 files changed, 88 insertions(+), 7 deletions(-) diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go index 584cc042d..f9e223a1e 100644 --- a/cmd/soong_ui/main.go +++ b/cmd/soong_ui/main.go @@ -74,7 +74,7 @@ var commands = []command{ description: "print the value of the legacy make variable VAR to stdout", simpleOutput: true, logsPrefix: "dumpvars-", - config: dumpVarConfig, + config: build.NewDumpVarConfig, stdio: customStdio, run: dumpVar, }, { @@ -82,7 +82,7 @@ var commands = []command{ description: "dump the values of one or more legacy make variables, in shell syntax", simpleOutput: true, logsPrefix: "dumpvars-", - config: dumpVarConfig, + config: build.NewDumpVarConfig, stdio: customStdio, run: dumpVars, }, { @@ -442,11 +442,6 @@ func customStdio() terminal.StdioInterface { return terminal.NewCustomStdio(os.Stdin, os.Stderr, os.Stderr) } -// dumpVarConfig does not require any arguments to be parsed by the NewConfig. -func dumpVarConfig(ctx build.Context, args ...string) build.Config { - return build.NewConfig(ctx) -} - func buildActionConfig(ctx build.Context, args ...string) build.Config { flags := flag.NewFlagSet("build-mode", flag.ContinueOnError) flags.SetOutput(ctx.Writer) diff --git a/ui/build/config.go b/ui/build/config.go index e9b32b9fd..d31a0958a 100644 --- a/ui/build/config.go +++ b/ui/build/config.go @@ -77,6 +77,9 @@ type configImpl struct { buildDateTime string logsPrefix string + // Whether this config was generated by NewDumpVarConfig(). + isDumpVar bool + // From the arguments parallel int keepGoing int @@ -143,6 +146,28 @@ type configImpl struct { // Which builder are we using ninjaCommand ninjaCommandType + + // Whether this build has a target that needs to disable SOONG_USE_PARTIAL_COMPILE. + disableUsePartialCompile bool + + // Whether the user requested partial compile. + partialCompileRequested bool +} + +// Some of the speed optimizations (such as using d8 instead of r8) used in partial +// compile cause the size of image to become too large. To avoid this, some ninja +// targets force SOONG_USE_PARTIAL_COMPILE=false. +// This list is missing a great many targets which could cause the image to be too +// large. Rather than try to be complete, it only includes targets which we know +// are commonly used by Java/Kotlin developers. +// +// Without this automation, the developer would do an initial build -- which would +// fail -- and then need to run `SOONG_USE_PARTIAL_COMPILE=false m ...` to rebuild +// before beginning their inner loop work. See also b/409810224. +var disableUsePartialCompileArgs = map[string]bool{ + "droid": true, + "sync": true, + "systemimage": true, } type NinjaWeightListSource uint @@ -226,11 +251,21 @@ func loadEnvConfig(ctx Context, config *configImpl, bc string) error { return nil } +// NewDumpVarConfig does not parse any arguments. +func NewDumpVarConfig(ctx Context, args ...string) Config { + return newConfig(ctx, true) +} + func NewConfig(ctx Context, args ...string) Config { + return newConfig(ctx, false, args...) +} + +func newConfig(ctx Context, isDumpVar bool, args ...string) Config { ret := &configImpl{ environ: OsEnvironment(), sandboxConfig: &SandboxConfig{}, ninjaWeightListSource: DEFAULT, + isDumpVar: isDumpVar, } wd, err := os.Getwd() if err != nil { @@ -334,7 +369,11 @@ func NewConfig(ctx Context, args ...string) Config { // This simplifies the generated Ninja rules, so that they only need to check for the empty string. if value, ok := ret.environ.Get("SOONG_USE_PARTIAL_COMPILE"); ok { if value == "true" || value == "1" || value == "y" || value == "yes" { + ret.partialCompileRequested = true value = "true" + if ret.disableUsePartialCompile { + value = "" + } } else { value = "" } @@ -989,9 +1028,16 @@ func (c *configImpl) parseArgs(ctx Context, args []string) { if arg == "checkbuild" { c.checkbuild = true } + if disableUsePartialCompileArgs[arg] { + c.disableUsePartialCompile = true + } c.arguments = append(c.arguments, arg) } } + // The default target needs disableUsePartialCompile. + if len(args) == 0 { + c.disableUsePartialCompile = true + } } func validateNinjaWeightList(weightListFilePath string) (err error) { diff --git a/ui/build/config_test.go b/ui/build/config_test.go index 10de1ad96..977825b6e 100644 --- a/ui/build/config_test.go +++ b/ui/build/config_test.go @@ -1047,6 +1047,34 @@ func TestBuildConfig(t *testing.T) { NinjaWeightListSource: smpb.BuildConfig_NOT_USED.Enum(), }, }, + { + name: "partial compile not used", + environ: Environment{"SOONG_USE_PARTIAL_COMPILE=", "SOONG_PARTIAL_COMPILE=true"}, + expectedBuildConfig: &smpb.BuildConfig{ + ForceUseGoma: proto.Bool(false), + UseGoma: proto.Bool(false), + UseRbe: proto.Bool(false), + SoongEnvVars: &smpb.SoongEnvVars{ + PartialCompile: proto.String("true"), + UsePartialCompile: proto.String("false"), + }, + NinjaWeightListSource: smpb.BuildConfig_NOT_USED.Enum(), + }, + }, + { + name: "partial compile", + environ: Environment{"SOONG_USE_PARTIAL_COMPILE=true", "SOONG_PARTIAL_COMPILE=true"}, + expectedBuildConfig: &smpb.BuildConfig{ + ForceUseGoma: proto.Bool(false), + UseGoma: proto.Bool(false), + UseRbe: proto.Bool(false), + SoongEnvVars: &smpb.SoongEnvVars{ + PartialCompile: proto.String("true"), + UsePartialCompile: proto.String("true"), + }, + NinjaWeightListSource: smpb.BuildConfig_NOT_USED.Enum(), + }, + }, { // RBE is only supported on linux. name: "use rbe", diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go index 710be8407..f9a7246f1 100644 --- a/ui/build/dumpvars.go +++ b/ui/build/dumpvars.go @@ -181,6 +181,18 @@ func Banner(config Config, make_vars map[string]string) string { fmt.Fprintf(b, "%s=%s\n", name, make_vars[name]) } } + if config.partialCompileRequested { + if partialCompile, ok := config.environ.Get("SOONG_PARTIAL_COMPILE"); ok { + // If we are only dumping variables, do not say that partial compile is disabled. + if config.disableUsePartialCompile && !config.isDumpVar { + fmt.Fprintf(b, + "SOONG_PARTIAL_COMPILE=%s # Inactive because of build arguments\n", + partialCompile) + } else { + fmt.Fprintf(b, "SOONG_PARTIAL_COMPILE=%s\n", partialCompile) + } + } + } if config.skipKatiControlledByFlags { fmt.Fprintf(b, "SOONG_ONLY=%t\n", config.soongOnlyRequested) } else { // default for this product -- cgit v1.2.3 From c12d2f5c53789a2913628516b011d585518ca81a Mon Sep 17 00:00:00 2001 From: Wei Li Date: Thu, 10 Apr 2025 15:54:06 -0700 Subject: Add more compliance metadata for the following cases 1) kernel modules and related files 2) abvpubkey 3) bpf related files 4) android_sdk_library related files Bug: 406020450 Bug: 406023231 Test: presubmits Change-Id: I2ce36bd47ff7df65aaee0b4a6bea0bb161e82ddc --- android/compliance_metadata.go | 32 ++++++++++++++++++++++++ android/provider_keys.go | 8 ++++++ filesystem/filesystem.go | 10 ++++++++ kernel/prebuilt_kernel_modules.go | 51 +++++++++++++++++++++++++++++---------- 4 files changed, 88 insertions(+), 13 deletions(-) diff --git a/android/compliance_metadata.go b/android/compliance_metadata.go index 83f072166..032161b22 100644 --- a/android/compliance_metadata.go +++ b/android/compliance_metadata.go @@ -133,6 +133,7 @@ type ComplianceMetadataInfo struct { filesContained []string prebuiltFilesCopied []string platformGeneratedFiles []string + kernelModuleCopyFiles []string } type complianceMetadataInfoGob struct { @@ -140,6 +141,7 @@ type complianceMetadataInfoGob struct { FilesContained []string PrebuiltFilesCopied []string PlatformGeneratedFiles []string + KernelModuleCopyFiles []string } func NewComplianceMetadataInfo() *ComplianceMetadataInfo { @@ -148,6 +150,7 @@ func NewComplianceMetadataInfo() *ComplianceMetadataInfo { filesContained: make([]string, 0), prebuiltFilesCopied: make([]string, 0), platformGeneratedFiles: make([]string, 0), + kernelModuleCopyFiles: make([]string, 0), } } @@ -157,6 +160,7 @@ func (m *ComplianceMetadataInfo) ToGob() *complianceMetadataInfoGob { FilesContained: m.filesContained, PrebuiltFilesCopied: m.prebuiltFilesCopied, PlatformGeneratedFiles: m.platformGeneratedFiles, + KernelModuleCopyFiles: m.kernelModuleCopyFiles, } } @@ -165,6 +169,7 @@ func (m *ComplianceMetadataInfo) FromGob(data *complianceMetadataInfoGob) { m.filesContained = data.FilesContained m.prebuiltFilesCopied = data.PrebuiltFilesCopied m.platformGeneratedFiles = data.PlatformGeneratedFiles + m.kernelModuleCopyFiles = data.KernelModuleCopyFiles } func (c *ComplianceMetadataInfo) GobEncode() ([]byte, error) { @@ -210,6 +215,14 @@ func (c *ComplianceMetadataInfo) GetPlatformGeneratedFiles() []string { return c.platformGeneratedFiles } +func (c *ComplianceMetadataInfo) SetKernelModuleCopyFiles(files []string) { + c.kernelModuleCopyFiles = files +} + +func (c *ComplianceMetadataInfo) GetKernelModuleCopyFiles() []string { + return c.kernelModuleCopyFiles +} + func (c *ComplianceMetadataInfo) getStringValue(propertyName string) string { if !slices.Contains(COMPLIANCE_METADATA_PROPS, propertyName) { panic(fmt.Errorf("Unknown metadata property: %s.", propertyName)) @@ -259,6 +272,17 @@ func buildComplianceMetadataProvider(ctx *moduleContext, m *ModuleBase) { installed = append(installed, ctx.katiSymlinks.InstallPaths()...) installed = append(installed, ctx.katiInitRcInstalls.InstallPaths()...) installed = append(installed, ctx.katiVintfInstalls.InstallPaths()...) + // The following module types use PackageFiles instead of InstallFiles so here we need to + // collect the fullInstallPaths from the packagingSpecs. + // TODO: b/409854522 + if strings.HasPrefix(ctx.ModuleType(), "sdk_library_internal") || + ctx.ModuleType() == "bpf" || + ctx.ModuleType() == "libbpf_prog" || + ctx.ModuleType() == "avbpubkey__loadHookModule" { + for _, s := range ctx.packagingSpecs { + installed = append(installed, s.fullInstallPath) + } + } complianceMetadataInfo.SetListValue(ComplianceMetadataProp.INSTALLED_FILES, FirstUniqueStrings(installed.Strings())) } ctx.setProvider(ComplianceMetadataProvider, complianceMetadataInfo) @@ -374,6 +398,12 @@ func (c *complianceMetadataSingleton) GenerateBuildActions(ctx SingletonContext) } sort.Strings(allFiles) + destToKernelModuleMap := make(map[string]string) + for _, p := range metadataInfo.GetKernelModuleCopyFiles() { + pair := strings.Split(p, "::") + destToKernelModuleMap[pair[1]] = p + } + csvHeaders := "installed_file,module_path,is_soong_module,is_prebuilt_make_module,product_copy_files,kernel_module_copy_files,is_platform_generated,static_libs,whole_static_libs,license_text" csvContent := make([]string, 0, len(allFiles)+1) csvContent = append(csvContent, csvHeaders) @@ -383,6 +413,8 @@ func (c *complianceMetadataSingleton) GenerateBuildActions(ctx SingletonContext) csvContent = append(csvContent, file+",,,,"+srcDestPair+",,,,,") } else if slices.Contains(metadataInfo.platformGeneratedFiles, file) { csvContent = append(csvContent, file+",,,,,,Y,,,build/soong/licenses/LICENSE") + } else if km, ok := destToKernelModuleMap[file]; ok { + csvContent = append(csvContent, file+",,,,,"+km+",,,,") } else { csvContent = append(csvContent, file+",,Y,,,,,,,") } diff --git a/android/provider_keys.go b/android/provider_keys.go index 60b383f53..1f99414c2 100644 --- a/android/provider_keys.go +++ b/android/provider_keys.go @@ -22,3 +22,11 @@ type AndroidDeviceInfo struct { } var AndroidDeviceInfoProvider = blueprint.NewProvider[AndroidDeviceInfo]() + +// Providers of prebuilt_kernel_modules +type PrebuiltKernelModulesComplianceMetadata struct { + Srcs []string + Dests []string +} + +var PrebuiltKernelModulesComplianceMetadataProvider = blueprint.NewProvider[PrebuiltKernelModulesComplianceMetadata]() diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index 31ab4deaa..64bf139b0 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -799,6 +799,16 @@ func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) { } complianceMetadataInfo.SetFilesContained(filesContained) complianceMetadataInfo.SetPlatformGeneratedFiles(platformGeneratedFiles) + + kernelModuleSrcDestPairs := []string{} + ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) { + if pkmi, ok := android.OtherModuleProvider(ctx, dep, android.PrebuiltKernelModulesComplianceMetadataProvider); ok { + for i, _ := range pkmi.Srcs { + kernelModuleSrcDestPairs = append(kernelModuleSrcDestPairs, pkmi.Srcs[i]+"::"+pkmi.Dests[i]) + } + } + }) + complianceMetadataInfo.SetKernelModuleCopyFiles(kernelModuleSrcDestPairs) } func (f *filesystem) fileystemStagingDirTimestamp(ctx android.ModuleContext) android.WritablePath { diff --git a/kernel/prebuilt_kernel_modules.go b/kernel/prebuilt_kernel_modules.go index 1225da0f2..716ba75a1 100644 --- a/kernel/prebuilt_kernel_modules.go +++ b/kernel/prebuilt_kernel_modules.go @@ -120,45 +120,70 @@ func (pkm *prebuiltKernelModules) GenerateAndroidBuildActions(ctx android.Module installDir = installDir.Join(ctx, pkm.KernelVersion()) } + dests := []string{} for _, m := range modules { - ctx.InstallFile(installDir, filepath.Base(m.String()), m) + installPath := ctx.InstallFile(installDir, filepath.Base(m.String()), m) + dests = append(dests, installPath.String()) } - ctx.InstallFile(installDir, "modules.load", depmodOut.modulesLoad) - ctx.InstallFile(installDir, "modules.dep", depmodOut.modulesDep) - ctx.InstallFile(installDir, "modules.softdep", depmodOut.modulesSoftdep) - ctx.InstallFile(installDir, "modules.alias", depmodOut.modulesAlias) - pkm.installBlocklistFile(ctx, installDir) - pkm.installOptionsFile(ctx, installDir) + srcs := android.PathsForModuleSrc(ctx, pkm.properties.Srcs).Strings() + // Use ANDROID-GEN to identify the source of module.* files which are generated in the build process. + // See the use of ANDROID-GEN in build/make/core/Makefile + androidGen := "ANDROID-GEN" + // Add ANDROID-GEN four time to match the number of "modules.*" files installed below. + srcs = append(srcs, androidGen, androidGen, androidGen, androidGen) + installPath := ctx.InstallFile(installDir, "modules.load", depmodOut.modulesLoad) + dests = append(dests, installPath.String()) + installPath = ctx.InstallFile(installDir, "modules.dep", depmodOut.modulesDep) + dests = append(dests, installPath.String()) + installPath = ctx.InstallFile(installDir, "modules.softdep", depmodOut.modulesSoftdep) + dests = append(dests, installPath.String()) + installPath = ctx.InstallFile(installDir, "modules.alias", depmodOut.modulesAlias) + dests = append(dests, installPath.String()) + + pkm.installBlocklistFile(ctx, installDir, &srcs, &dests) + pkm.installOptionsFile(ctx, installDir, &srcs, &dests) ctx.SetOutputFiles(modules, ".modules") + + android.SetProvider(ctx, android.PrebuiltKernelModulesComplianceMetadataProvider, + android.PrebuiltKernelModulesComplianceMetadata{ + Srcs: srcs, + Dests: dests, + }) } -func (pkm *prebuiltKernelModules) installBlocklistFile(ctx android.ModuleContext, installDir android.InstallPath) { +func (pkm *prebuiltKernelModules) installBlocklistFile(ctx android.ModuleContext, installDir android.InstallPath, srcs *[]string, dests *[]string) { if pkm.properties.Blocklist_file == nil { return } blocklistOut := android.PathForModuleOut(ctx, "modules.blocklist") + src := android.PathForModuleSrc(ctx, proptools.String(pkm.properties.Blocklist_file)) + *srcs = append(*srcs, src.String()) ctx.Build(pctx, android.BuildParams{ Rule: processBlocklistFile, - Input: android.PathForModuleSrc(ctx, proptools.String(pkm.properties.Blocklist_file)), + Input: src, Output: blocklistOut, }) - ctx.InstallFile(installDir, "modules.blocklist", blocklistOut) + installPath := ctx.InstallFile(installDir, "modules.blocklist", blocklistOut) + *dests = append(*dests, installPath.String()) } -func (pkm *prebuiltKernelModules) installOptionsFile(ctx android.ModuleContext, installDir android.InstallPath) { +func (pkm *prebuiltKernelModules) installOptionsFile(ctx android.ModuleContext, installDir android.InstallPath, srcs *[]string, dests *[]string) { if pkm.properties.Options_file == nil { return } optionsOut := android.PathForModuleOut(ctx, "modules.options") + src := android.PathForModuleSrc(ctx, proptools.String(pkm.properties.Options_file)) + *srcs = append(*srcs, src.String()) ctx.Build(pctx, android.BuildParams{ Rule: processOptionsFile, - Input: android.PathForModuleSrc(ctx, proptools.String(pkm.properties.Options_file)), + Input: src, Output: optionsOut, }) - ctx.InstallFile(installDir, "modules.options", optionsOut) + installPath := ctx.InstallFile(installDir, "modules.options", optionsOut) + *dests = append(*dests, installPath.String()) } var ( -- cgit v1.2.3 From bab06a316e92c494b9ac5b03a85037364102ae54 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Thu, 10 Apr 2025 16:08:54 -0700 Subject: Remove _soong suffixes No need for these to be suffixed with _soong. It makes it confusing because the target to build with `m` is different from the dist target. Test: Presubmits Change-Id: I363fb00607552b9433694306f97aae5f90df8767 --- ci_tests/ci_test_package_zip.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ci_tests/ci_test_package_zip.go b/ci_tests/ci_test_package_zip.go index 1c457b3d9..94963ffb7 100644 --- a/ci_tests/ci_test_package_zip.go +++ b/ci_tests/ci_test_package_zip.go @@ -74,8 +74,13 @@ 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_instrumentation_tests_soong", "continuous_instrumentation_metric_tests_soong", "continuous_native_tests_soong", "continuous_native_metric_tests_soong", "platform_tests"} + moduleNamesAllowed = []string{ + "continuous_instrumentation_tests", + "continuous_instrumentation_metric_tests", + "continuous_native_tests", + "continuous_native_metric_tests", + "platform_tests", + } ) func (p *testPackageZip) DepsMutator(ctx android.BottomUpMutatorContext) { @@ -171,7 +176,7 @@ func (p *testPackageZip) GenerateAndroidBuildActions(ctx android.ModuleContext) p.SkipInstall() if !android.InList(ctx.ModuleName(), moduleNamesAllowed) { - ctx.ModuleErrorf("%s is not allowed to use module type test_package") + ctx.ModuleErrorf("%s is not allowed to use module type test_package", ctx.ModuleName()) } p.output = createOutput(ctx, pctx) -- cgit v1.2.3 From 8e48e2e9e111882edb43048a612fbad20bab17b6 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Thu, 10 Apr 2025 22:55:04 +0000 Subject: Delete an unused variable depCandidates (list) was replaced with depCandidatesMap (map) for faster lookup in ag/32978552 Test: go build ./fsgen Test: lunch aosp_cf_x86_64_phone-trunk_staging-userdebug Test: m soong_generated_system_filesystem_test --no-soong-only Change-Id: If1c389e92ed06dcc7e49f19b8154b150a55ee02e --- fsgen/fsgen_mutators.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/fsgen/fsgen_mutators.go b/fsgen/fsgen_mutators.go index e945c0cdc..e5f245b1d 100644 --- a/fsgen/fsgen_mutators.go +++ b/fsgen/fsgen_mutators.go @@ -57,7 +57,6 @@ type multilibDeps map[string]*depCandidateProps // dependencies type FsGenState struct { // List of modules in `PRODUCT_PACKAGES` and `PRODUCT_PACKAGES_DEBUG` - depCandidates []string depCandidatesMap map[string]bool // Map of names of partition to the information of modules to be added as deps fsDeps map[string]*multilibDeps @@ -89,14 +88,17 @@ func defaultDepCandidateProps(config android.Config) *depCandidateProps { func createFsGenState(ctx android.LoadHookContext, generatedPrebuiltEtcModuleNames []string, avbpubkeyGenerated bool) *FsGenState { return ctx.Config().Once(fsGenStateOnceKey, func() interface{} { partitionVars := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse - candidates := android.FirstUniqueStrings(android.Concat(partitionVars.ProductPackages, partitionVars.ProductPackagesDebug)) - candidates = android.Concat(candidates, generatedPrebuiltEtcModuleNames) candidatesMap := map[string]bool{} - for _, candidate := range candidates { + for _, candidate := range partitionVars.ProductPackages { + candidatesMap[candidate] = true + } + for _, candidate := range partitionVars.ProductPackagesDebug { + candidatesMap[candidate] = true + } + for _, candidate := range generatedPrebuiltEtcModuleNames { candidatesMap[candidate] = true } fsGenState := FsGenState{ - depCandidates: candidates, depCandidatesMap: candidatesMap, fsDeps: map[string]*multilibDeps{ // These additional deps are added according to the cuttlefish system image bp. -- cgit v1.2.3 From d898d846439e46edde04ac0bab58c29f51c093a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kosi=C5=84ski?= Date: Fri, 11 Apr 2025 00:19:13 +0000 Subject: Do not use SVE in Rust. There is a fairly large amount of Rust code that runs in VMs where SVE is not supported, including a few crates. Disable it for now until we can apply a solution similar to the one used for C++ (cc_baremetal_defaults). Bug: 409810708 Test: See bug Flag: build.RELEASE_RUST_USE_ARM_TARGET_ARCH_VARIANT Change-Id: Iecfecf77636f7114c65694cd4b8883f08024e1cf --- rust/config/arm64_device.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rust/config/arm64_device.go b/rust/config/arm64_device.go index 1f4e6ce9e..9dd414cc0 100644 --- a/rust/config/arm64_device.go +++ b/rust/config/arm64_device.go @@ -66,30 +66,30 @@ var ( armv85aFeatures, armv87aFeatures, }, + + // All of the Armv9 entries below should have "-C target-feature=+sve2", + // but a large subset of Rust code runs in VMs that are incompatible with SVE. + // TODO: b/409859765 - apply a solution similar to cc_baremetal_defaults. "armv9-a": { armv82aFeatures, armv85aFeatures, - "-C target-feature=+sve2", }, "armv9-2a": { armv82aFeatures, armv85aFeatures, armv87aFeatures, - "-C target-feature=+sve2", }, // ARMv9.3-A adds +hbc,+mops but they're both unstable "armv9-3a": { armv82aFeatures, armv85aFeatures, armv87aFeatures, - "-C target-feature=+sve2", }, // ARMv9.4-A adds +cssc but it's unstable "armv9-4a": { armv82aFeatures, armv85aFeatures, armv87aFeatures, - "-C target-feature=+sve2", }, } ) -- cgit v1.2.3 From 1caaa1bdfd583c37c0fe373313f8f15a11af6986 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Thu, 10 Apr 2025 22:13:49 +0000 Subject: Build and dist ota.zip files using Soong These use the target_files_dir as input. To prevent incremental build issues, these will be built in the same rule that builds target_files.zip. Bug: 395988453 Test: Built the files locally. Test: Files are not bit-identical between make and soong. e.g. ota_metadata https://paste.googleplex.com/5757988046110720 Change-Id: I7b09eb9446f831e810dc4a4406ba289412f69d52 --- filesystem/android_device.go | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/filesystem/android_device.go b/filesystem/android_device.go index b11f23cbf..57b75f4e3 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -122,6 +122,9 @@ type androidDevice struct { apkCertsInfo android.Path targetFilesZip android.Path updatePackage android.Path + otaFilesZip android.Path + otaMetadata android.Path + partialOtaFilesZip android.Path symbolsZipFile android.ModuleOutPath symbolsMappingFile android.ModuleOutPath @@ -453,6 +456,15 @@ func (a *androidDevice) distFiles(ctx android.ModuleContext) { ctx.DistForGoalWithFilenameTag("updatepackage", a.updatePackage, namePrefix+a.updatePackage.Base()) ctx.DistForGoalWithFilenameTag("droidcore-unbundled", a.updatePackage, namePrefix+a.updatePackage.Base()) } + if a.otaFilesZip != nil { + ctx.Phony("otapackage", a.otaFilesZip) + ctx.DistForGoalWithFilenameTag("droidcore-unbundled", a.otaFilesZip, namePrefix+a.otaFilesZip.Base()) + ctx.DistForGoalWithFilenameTag("droidcore-unbundled", a.otaMetadata, namePrefix+a.otaMetadata.Base()) + } + if a.partialOtaFilesZip != nil { + ctx.Phony("partialotapackage", a.partialOtaFilesZip) + ctx.DistForGoalWithFilenameTag("droidcore-unbundled", a.partialOtaFilesZip, namePrefix+a.partialOtaFilesZip.Base()) + } } } @@ -527,6 +539,9 @@ type targetFilesystemZipCopy struct { func (a *androidDevice) buildTargetFilesZip(ctx android.ModuleContext, allInstalledModules []android.ModuleProxy) { targetFilesDir := android.PathForModuleOut(ctx, "target_files_dir") targetFilesZip := android.PathForModuleOut(ctx, "target_files.zip") + otaFilesZip := android.PathForModuleOut(ctx, "ota.zip") + otaMetadata := android.PathForModuleOut(ctx, "ota_metadata") + partialOtaFilesZip := android.PathForModuleOut(ctx, "partial-ota.zip") builder := android.NewRuleBuilder(pctx, ctx) builder.Command().Textf("rm -rf %s", targetFilesDir.String()) @@ -649,6 +664,31 @@ func (a *androidDevice) buildTargetFilesZip(ctx android.ModuleContext, allInstal FlagWithArg("-C ", targetFilesDir.String()). FlagWithArg("-D ", targetFilesDir.String()). Text("-sha256") + + pem, _ := ctx.Config().DefaultAppCertificate(ctx) + pemWithoutFileExt := strings.TrimSuffix(pem.String(), ".x509.pem") + builder.Command(). + BuiltTool("ota_from_target_files"). + Flag("--verbose"). + FlagWithArg("-k ", pemWithoutFileExt). + FlagWithOutput("--output_metadata_path ", otaMetadata). + Text(targetFilesDir.String()). + Output(otaFilesZip) + a.otaFilesZip = otaFilesZip + a.otaMetadata = otaMetadata + + // Partial ota + if len(a.deviceProps.Partial_ota_update_partitions) > 0 { + builder.Command(). + BuiltTool("ota_from_target_files"). + Flag("--verbose"). + FlagWithArg("-k ", pemWithoutFileExt). + FlagForEachArg("--partial ", a.deviceProps.Partial_ota_update_partitions). + Text(targetFilesDir.String()). + Output(partialOtaFilesZip) + a.partialOtaFilesZip = partialOtaFilesZip + } + builder.Build("target_files_"+ctx.ModuleName(), "Build target_files.zip") } -- cgit v1.2.3 From e49d8fd4d3548211241c6129f90c4a8d2e069ce2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kosi=C5=84ski?= Date: Fri, 11 Apr 2025 00:37:32 +0000 Subject: Add rust_baremetal_defaults. Mirrors cc_baremetal_defaults and disables SVE in Rust code that runs in environments where SVE is not supported. Bug: 409810708 Test: presubmit Flag: EXEMPT no-op build system change Change-Id: I2e7dd9eab1f5ff7cea4a3774ff92222a9809e07f --- Android.bp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Android.bp b/Android.bp index 713459112..4882be3db 100644 --- a/Android.bp +++ b/Android.bp @@ -161,6 +161,22 @@ cc_defaults { defaults_visibility: ["//visibility:public"], } +rust_defaults { + name: "rust_baremetal_defaults", + arch: { + arm64: { + flags: [ + // There is no Rust flag that says "use baseline instruction set", + // so we disable SVE specifically. This can be extended with more + // problematic target features from rust/config/arm64_device.go + // as needed. + "-C target-feature=-sve2", + ], + }, + }, + defaults_visibility: ["//visibility:public"], +} + product_config { name: "product_config", visibility: [ -- cgit v1.2.3 From ab955c2b608c1d83b86ba6e82997a566ebf5c85e Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Thu, 10 Apr 2025 14:41:01 -0700 Subject: Replace line_endings with dos2unix. Bug: http://b/215533109 Change-Id: Ic0f41145ced09dcd04b477ffb49b7f9ddcde00ed --- android_sdk/sdk_repo_host.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/android_sdk/sdk_repo_host.go b/android_sdk/sdk_repo_host.go index a2486fdf5..ed4465716 100644 --- a/android_sdk/sdk_repo_host.go +++ b/android_sdk/sdk_repo_host.go @@ -189,9 +189,7 @@ func (s *sdkRepoHost) GenerateAndroidBuildActions(ctx android.ModuleContext) { Flag("-o -name '*.txt' -o -name '*.windows' -o -name '*.xml' -print0"). // Using -n 500 for xargs to limit the max number of arguments per call to line_endings // to 500. This avoids line_endings failing with "arguments too long". - Text("| xargs -0 -n 500 "). - BuiltTool("line_endings"). - Flag("unix") + Text("| xargs -0 -n 500 dos2unix") // Exclude some file types (roughly matching sdk.exclude.atree) builder.Command(). -- cgit v1.2.3 From 284b9ddf35f10d0455919ff067698d1d7d887037 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Fri, 11 Apr 2025 21:02:14 +0000 Subject: Do not allow nativebridge variant to override "main" variant Make packaging does not allow a native bridge variant to override a native bridge disabled variant variant. It does so indirectly by appending .native_bridge suffix to each entry in overrides (`makeOverrideModuleNames` in build/soong/cc/androidmk.go) This CL ports this logic in Soong packaging by splitting `overriden` map to two maps, one for nativeBridgeDisabled and another for nativeBridgeEnabled. Bug: 376873507 Test: lunch cf_x86_64_phone-trunk_staging-userdebug Test: m soong_generated_system_filesystem_test Test: before and after diffs https://diff.googleplex.com/#key=7kBozIg4Cv6v Change-Id: I8b0c1fa49d69293de47a3a8617888e08ebff2eb8 --- android/packaging.go | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/android/packaging.go b/android/packaging.go index 689340ee9..d1ea5aa9e 100644 --- a/android/packaging.go +++ b/android/packaging.go @@ -523,6 +523,7 @@ func (p *PackagingBase) GatherPackagingSpecsWithFilterAndModifier(ctx ModuleCont // list of module names overridden overridden := make(map[string]bool) + nativeBridgeOverridden := make(map[string]bool) // all installed modules which are not overridden. modulesToInstall := make(map[string]bool) @@ -542,6 +543,11 @@ func (p *PackagingBase) GatherPackagingSpecsWithFilterAndModifier(ctx ModuleCont return false } + isNativeBridgeVariant := func(m ModuleOrProxy) bool { + commonInfo := OtherModulePointerProviderOrDefault(ctx, m, CommonModuleInfoProvider) + return commonInfo.Target.NativeBridge == NativeBridgeEnabled + } + // find all overridden modules and packaging specs ctx.VisitDirectDepsProxy(func(child ModuleProxy) { depTag := ctx.OtherModuleDependencyTag(child) @@ -571,7 +577,11 @@ func (p *PackagingBase) GatherPackagingSpecsWithFilterAndModifier(ctx ModuleCont } for o := range ps.overrides.Iter() { - overridden[o] = true + if !isNativeBridgeVariant(child) { + overridden[o] = true + } else { + nativeBridgeOverridden[o] = true + } } } }) @@ -584,8 +594,14 @@ func (p *PackagingBase) GatherPackagingSpecsWithFilterAndModifier(ctx ModuleCont owner = overriddenBy } } - if overridden[owner] { - return false + if !isNativeBridgeVariant(child) { + if overridden[owner] { + return false + } + } else { + if nativeBridgeOverridden[owner] { + return false + } } modulesToInstall[owner] = true return true -- cgit v1.2.3 From 2bea1ef4dc0557cdae8d5db012c3b65928db7904 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Fri, 11 Apr 2025 22:34:59 +0000 Subject: Skip overrides removal of native bridge modules in fsgen fsgen's `removeOverriddenDeps` automatically removes all entries in `overrides` from the autogenerated partitions to handle scenarios where a module in one partition overrides a module in another partition. This automatic removal runs into issues for some native bridge cc modules that override the native bridge variant of another module, but not the "main" variant. ``` cc_binary { name: "foo", native_bridge_supported: true, overrides: "bar" <-- LOCAL_OVERRIDES_MODULE bar.native_bridge } cc_binary { name: "bar", } ``` In the above example, both native bridge variant of foo and the "main" bar variant will be installed, even though the latter is listed in overrides. This CL assumes that all native bridge modules are installed in system (no interpartition communication), and skips processing native bridge variants in `removeOverriddenDeps` Test: lunch cf_x86_64_phone-trunk_staging-userdebug Test: m soong_generated_system_filesystem_test Before and after diffs https://diff.googleplex.com/#key=0ZrQcQmklDVR Bug: 376873507 Bug: 375035189 Change-Id: I280c550a7e10593c1e74c3ebf379161ec5c57e00 --- fsgen/fsgen_mutators.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/fsgen/fsgen_mutators.go b/fsgen/fsgen_mutators.go index e5f245b1d..2565b009b 100644 --- a/fsgen/fsgen_mutators.go +++ b/fsgen/fsgen_mutators.go @@ -70,6 +70,8 @@ type FsGenState struct { generatedPrebuiltEtcModuleNames []string // Mapping from a path to an avb key to the name of a filegroup module that contains it avbKeyFilegroups map[string]string + // Name of all native bridge modules + nativeBridgeModules map[string]bool } type installationProperties struct { @@ -189,6 +191,7 @@ func createFsGenState(ctx android.LoadHookContext, generatedPrebuiltEtcModuleNam moduleToInstallationProps: map[string]installationProperties{}, generatedPrebuiltEtcModuleNames: generatedPrebuiltEtcModuleNames, avbKeyFilegroups: map[string]string{}, + nativeBridgeModules: map[string]bool{}, } if avbpubkeyGenerated { @@ -276,6 +279,10 @@ func collectDepsMutator(mctx android.BottomUpMutatorContext) { Overrides: m.Overrides(), } } + + if mctx.Target().NativeBridge == android.NativeBridgeEnabled { + fsGenState.nativeBridgeModules[mctx.ModuleName()] = true + } } type depsStruct struct { @@ -356,6 +363,14 @@ func removeOverriddenDeps(mctx android.BottomUpMutatorContext) { } depName := allDeps[i] for _, overrides := range fsGenState.moduleToInstallationProps[depName].Overrides { + if _, ok := fsGenState.nativeBridgeModules[depName]; ok { + // Do not remove automatically remove overrides of native bridge modules + // Some native_bridge_supported modules override the native_bridge variant + // of another module, but not the "main" variant. + // Determining this in fsgen requires additional information. Defer this to + // android_filesystem. + continue + } overridden[overrides] = true } // add required dep to the queue. -- cgit v1.2.3 From dbd8e7da39f44d1ad9672b4becb0e129cfaab0e2 Mon Sep 17 00:00:00 2001 From: kellyhung Date: Thu, 10 Apr 2025 01:06:17 +0000 Subject: Convert android_library module-info to Soong - android_library - android_library_import Bug: 389720048 Bug: 409426688 Test: m out/target/product/vsoc_x86_64/module-info.json Test: Inspect module-info.json diff, CI Change-Id: I2e6d5c38cde83a78419f21ae1bad36a1cf4cb928 --- java/aar.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/java/aar.go b/java/aar.go index f608d4e0f..9c8fd7798 100644 --- a/java/aar.go +++ b/java/aar.go @@ -1070,6 +1070,11 @@ func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) a.setOutputFiles(ctx) buildComplianceMetadata(ctx) + + moduleInfoJSON := ctx.ModuleInfoJSON() + moduleInfoJSON.Class = []string{"JAVA_LIBRARIES"} + moduleInfoJSON.ClassesJar = []string{a.Library.implementationAndResourcesJar.String()} + moduleInfoJSON.SystemSharedLibs = []string{"none"} } func (a *AndroidLibrary) setOutputFiles(ctx android.ModuleContext) { @@ -1582,6 +1587,11 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.SetOutputFiles([]android.Path{a.aarPath}, ".aar") buildComplianceMetadata(ctx) + + moduleInfoJSON := ctx.ModuleInfoJSON() + moduleInfoJSON.Class = []string{"JAVA_LIBRARIES"} + moduleInfoJSON.ClassesJar = []string{a.implementationAndResourcesJarFile.String()} + moduleInfoJSON.SystemSharedLibs = []string{"none"} } func (a *AARImport) HeaderJars() android.Paths { -- cgit v1.2.3 From 35cf8bfbe06149937aca34e58aae9e48d85aaae2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Kongstad?= Date: Mon, 14 Apr 2025 11:47:55 +0200 Subject: Rename aconfig cache intermediate files The aconfig cache file is named intermediate.pb. This is too generic to be helpful when searching through soongs intermediate files. Rename intermediate.pb -> aconfig-cache.pb. Also update intermediate.txt -> aconfig-flags.txt. Bug: N/A Test: croot build/soong && go test ./apex ./aconfig ./java Test: treehugger Change-Id: Ib288b9e744628f9ca8e834c3a6bed9c347d4bfb7 --- aconfig/aconfig_declarations.go | 4 ++-- aconfig/aconfig_declarations_test.go | 8 ++++---- aconfig/codegen/cc_aconfig_library_test.go | 2 +- aconfig/codegen/java_aconfig_library_test.go | 2 +- apex/apex_test.go | 30 ++++++++++++++-------------- java/aar_test.go | 2 +- java/app_test.go | 8 ++++---- java/rro_test.go | 2 +- 8 files changed, 29 insertions(+), 29 deletions(-) diff --git a/aconfig/aconfig_declarations.go b/aconfig/aconfig_declarations.go index b06839831..9589bf1fa 100644 --- a/aconfig/aconfig_declarations.go +++ b/aconfig/aconfig_declarations.go @@ -170,7 +170,7 @@ func (module *DeclarationsModule) GenerateAndroidBuildActions(ctx android.Module // Intermediate format declarationFiles := android.PathsForModuleSrc(ctx, module.properties.Srcs) - intermediateCacheFilePath := android.PathForModuleOut(ctx, assembleFileName(config, "intermediate.pb")) + intermediateCacheFilePath := android.PathForModuleOut(ctx, assembleFileName(config, "aconfig-cache.pb")) var defaultPermission string defaultPermission = ctx.Config().ReleaseAconfigFlagDefaultPermission() if config != "" { @@ -207,7 +207,7 @@ func (module *DeclarationsModule) GenerateAndroidBuildActions(ctx android.Module Args: args, }) - intermediateDumpFilePath := android.PathForModuleOut(ctx, assembleFileName(config, "intermediate.txt")) + intermediateDumpFilePath := android.PathForModuleOut(ctx, assembleFileName(config, "aconfig-flags.txt")) ctx.Build(pctx, android.BuildParams{ Rule: aconfigTextRule, Output: intermediateDumpFilePath, diff --git a/aconfig/aconfig_declarations_test.go b/aconfig/aconfig_declarations_test.go index c39008b74..76ea82271 100644 --- a/aconfig/aconfig_declarations_test.go +++ b/aconfig/aconfig_declarations_test.go @@ -44,10 +44,10 @@ func TestAconfigDeclarations(t *testing.T) { android.AssertStringEquals(t, "package", depData.Package, "com.example.package") android.AssertStringEquals(t, "container", depData.Container, "com.android.foo") android.AssertBoolEquals(t, "exportable", depData.Exportable, true) - if !strings.HasSuffix(depData.IntermediateCacheOutputPath.String(), "/intermediate.pb") { + if !strings.HasSuffix(depData.IntermediateCacheOutputPath.String(), "/aconfig-cache.pb") { t.Errorf("Missing intermediates proto path in provider: %s", depData.IntermediateCacheOutputPath.String()) } - if !strings.HasSuffix(depData.IntermediateDumpOutputPath.String(), "/intermediate.txt") { + if !strings.HasSuffix(depData.IntermediateDumpOutputPath.String(), "/aconfig-flags.txt") { t.Errorf("Missing intermediates text path in provider: %s", depData.IntermediateDumpOutputPath.String()) } } @@ -218,10 +218,10 @@ func TestGenerateAndroidBuildActions(t *testing.T) { slices.Sort(actualKeys) android.AssertStringEquals(t, "provider keys", strings.Join(expectedKeys, " "), strings.Join(actualKeys, " ")) for _, rc := range actualKeys { - if !strings.HasSuffix(depData[rc].IntermediateCacheOutputPath.String(), assembleFileName(rc, "/intermediate.pb")) { + if !strings.HasSuffix(depData[rc].IntermediateCacheOutputPath.String(), assembleFileName(rc, "/aconfig-cache.pb")) { t.Errorf("Incorrect intermediates proto path in provider for release config %s: %s", rc, depData[rc].IntermediateCacheOutputPath.String()) } - if !strings.HasSuffix(depData[rc].IntermediateDumpOutputPath.String(), assembleFileName(rc, "/intermediate.txt")) { + if !strings.HasSuffix(depData[rc].IntermediateDumpOutputPath.String(), assembleFileName(rc, "/aconfig-flags.txt")) { t.Errorf("Incorrect intermediates text path in provider for release config %s: %s", rc, depData[rc].IntermediateDumpOutputPath.String()) } } diff --git a/aconfig/codegen/cc_aconfig_library_test.go b/aconfig/codegen/cc_aconfig_library_test.go index 17abf1e07..3ea77394a 100644 --- a/aconfig/codegen/cc_aconfig_library_test.go +++ b/aconfig/codegen/cc_aconfig_library_test.go @@ -212,7 +212,7 @@ func TestAndroidMkCcLibrary(t *testing.T) { entry := android.AndroidMkInfoForTest(t, result.TestContext, module).PrimaryInfo makeVar := entry.EntryMap["LOCAL_ACONFIG_FILES"] - android.EnsureListContainsSuffix(t, makeVar, "my_aconfig_declarations_foo/intermediate.pb") + android.EnsureListContainsSuffix(t, makeVar, "my_aconfig_declarations_foo/aconfig-cache.pb") } func TestForceReadOnly(t *testing.T) { diff --git a/aconfig/codegen/java_aconfig_library_test.go b/aconfig/codegen/java_aconfig_library_test.go index b9455f77d..e8ce7c76b 100644 --- a/aconfig/codegen/java_aconfig_library_test.go +++ b/aconfig/codegen/java_aconfig_library_test.go @@ -285,5 +285,5 @@ func TestMkEntriesMatchedContainer(t *testing.T) { module := result.ModuleForTests(t, "my_module", "android_common").Module() entry := android.AndroidMkEntriesForTest(t, result.TestContext, module)[0] makeVar := entry.EntryMap["LOCAL_ACONFIG_FILES"] - android.EnsureListContainsSuffix(t, makeVar, "my_aconfig_declarations_foo/intermediate.pb") + android.EnsureListContainsSuffix(t, makeVar, "my_aconfig_declarations_foo/aconfig-cache.pb") } diff --git a/apex/apex_test.go b/apex/apex_test.go index 880d0014a..667c535bf 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -10671,8 +10671,8 @@ func TestAconfigFilesJavaDeps(t *testing.T) { ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.info.*/image.apex/etc/flag.info") inputs := []string{ - "my_aconfig_declarations_foo/intermediate.pb", - "my_aconfig_declarations_bar/intermediate.pb", + "my_aconfig_declarations_foo/aconfig-cache.pb", + "my_aconfig_declarations_bar/aconfig-cache.pb", } VerifyAconfigRule(t, &mod, "combine_aconfig_declarations", inputs, "android_common_myapex/aconfig_flags.pb", "", "") VerifyAconfigRule(t, &mod, "create_aconfig_package_map_file", inputs, "android_common_myapex/package.map", "myapex", "package_map") @@ -10810,9 +10810,9 @@ func TestAconfigFilesJavaAndCcDeps(t *testing.T) { ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.info .*/image.apex/etc/flag.info") inputs := []string{ - "my_aconfig_declarations_foo/intermediate.pb", + "my_aconfig_declarations_foo/aconfig-cache.pb", "my_cc_library_bar/android_arm64_armv8-a_shared_apex10000/myapex/aconfig_merged.pb", - "my_aconfig_declarations_baz/intermediate.pb", + "my_aconfig_declarations_baz/aconfig-cache.pb", } VerifyAconfigRule(t, &mod, "combine_aconfig_declarations", inputs, "android_common_myapex/aconfig_flags.pb", "", "") VerifyAconfigRule(t, &mod, "create_aconfig_package_map_file", inputs, "android_common_myapex/package.map", "myapex", "package_map") @@ -10972,9 +10972,9 @@ func TestAconfigFilesRustDeps(t *testing.T) { ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.info .*/image.apex/etc/flag.info") inputs := []string{ - "my_aconfig_declarations_foo/intermediate.pb", - "my_aconfig_declarations_bar/intermediate.pb", - "my_aconfig_declarations_baz/intermediate.pb", + "my_aconfig_declarations_foo/aconfig-cache.pb", + "my_aconfig_declarations_bar/aconfig-cache.pb", + "my_aconfig_declarations_baz/aconfig-cache.pb", "my_rust_binary/android_arm64_armv8-a_apex10000/myapex/aconfig_merged.pb", } VerifyAconfigRule(t, &mod, "combine_aconfig_declarations", inputs, "android_common_myapex/aconfig_flags.pb", "", "") @@ -11081,13 +11081,13 @@ func TestAconfigFilesOnlyMatchCurrentApex(t *testing.T) { if len(aconfigArgs) != 1 { t.Fatalf("Expected 1 commands, got %d in:\n%s", len(aconfigArgs), s) } - android.EnsureListContainsSuffix(t, aconfigArgs, "my_aconfig_declarations_foo/intermediate.pb") + android.EnsureListContainsSuffix(t, aconfigArgs, "my_aconfig_declarations_foo/aconfig-cache.pb") buildParams := combineAconfigRule.BuildParams if len(buildParams.Inputs) != 1 { t.Fatalf("Expected 1 input, got %d", len(buildParams.Inputs)) } - android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_aconfig_declarations_foo/intermediate.pb") + android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_aconfig_declarations_foo/aconfig-cache.pb") ensureContains(t, buildParams.Output.String(), "android_common_myapex/aconfig_flags.pb") } @@ -11161,13 +11161,13 @@ func TestAconfigFilesRemoveDuplicates(t *testing.T) { if len(aconfigArgs) != 1 { t.Fatalf("Expected 1 commands, got %d in:\n%s", len(aconfigArgs), s) } - android.EnsureListContainsSuffix(t, aconfigArgs, "my_aconfig_declarations_foo/intermediate.pb") + android.EnsureListContainsSuffix(t, aconfigArgs, "my_aconfig_declarations_foo/aconfig-cache.pb") buildParams := combineAconfigRule.BuildParams if len(buildParams.Inputs) != 1 { t.Fatalf("Expected 1 input, got %d", len(buildParams.Inputs)) } - android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_aconfig_declarations_foo/intermediate.pb") + android.EnsureListContainsSuffix(t, buildParams.Inputs.Strings(), "my_aconfig_declarations_foo/aconfig-cache.pb") ensureContains(t, buildParams.Output.String(), "android_common_myapex/aconfig_flags.pb") } @@ -11720,27 +11720,27 @@ func TestAconfifDeclarationsValidation(t *testing.T) { // to aconfig. android.AssertStringDoesContain(t, "cache file of a java_aconfig_library static_lib "+ "passed as an input", - aconfigFlagArgs, fmt.Sprintf("%s/%s/intermediate.pb", outDir, "bar")) + aconfigFlagArgs, fmt.Sprintf("%s/%s/aconfig-cache.pb", outDir, "bar")) // "baz-java-lib", which statically depends on "baz-lib", is a lib of "foo" and is passed // to metalava as classpath. Thus the cache file provided by the associated // aconfig_declarations module "baz" should be passed to aconfig. android.AssertStringDoesContain(t, "cache file of a lib that statically depends on "+ "java_aconfig_library passed as an input", - aconfigFlagArgs, fmt.Sprintf("%s/%s/intermediate.pb", outDir, "baz")) + aconfigFlagArgs, fmt.Sprintf("%s/%s/aconfig-cache.pb", outDir, "baz")) // "qux-lib" is passed to metalava as src via the filegroup, thus the cache file provided by // the associated aconfig_declarations module "qux" should be passed to aconfig. android.AssertStringDoesContain(t, "cache file of srcs java_aconfig_library passed as an "+ "input", - aconfigFlagArgs, fmt.Sprintf("%s/%s/intermediate.pb", outDir, "qux")) + aconfigFlagArgs, fmt.Sprintf("%s/%s/aconfig-cache.pb", outDir, "qux")) // "quux-java-lib" is a lib of "foo" and is passed to metalava as classpath, but does not // statically depend on "quux-lib". Therefore, the cache file provided by the associated // aconfig_declarations module "quux" should not be passed to aconfig. android.AssertStringDoesNotContain(t, "cache file of a lib that does not statically "+ "depend on java_aconfig_library not passed as an input", - aconfigFlagArgs, fmt.Sprintf("%s/%s/intermediate.pb", outDir, "quux")) + aconfigFlagArgs, fmt.Sprintf("%s/%s/aconfig-cache.pb", outDir, "quux")) } func TestMultiplePrebuiltsWithSameBase(t *testing.T) { diff --git a/java/aar_test.go b/java/aar_test.go index 088ad6c92..e385e52d1 100644 --- a/java/aar_test.go +++ b/java/aar_test.go @@ -131,7 +131,7 @@ func TestLibraryFlagsPackages(t *testing.T) { android.AssertStringDoesContain(t, "aapt2 link command expected to pass feature flags arguments", linkInFlags, - "--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt", + "--feature-flags @out/soong/.intermediates/bar/aconfig-flags.txt --feature-flags @out/soong/.intermediates/baz/aconfig-flags.txt", ) } diff --git a/java/app_test.go b/java/app_test.go index 7abde7839..fcaf69feb 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -4575,7 +4575,7 @@ func TestAppFlagsPackages(t *testing.T) { android.AssertStringDoesContain(t, "aapt2 link command expected to pass feature flags arguments", linkInFlags, - "--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt", + "--feature-flags @out/soong/.intermediates/bar/aconfig-flags.txt --feature-flags @out/soong/.intermediates/baz/aconfig-flags.txt", ) aapt2CompileRule := foo.Rule("android/soong/java.aapt2Compile") @@ -4583,7 +4583,7 @@ func TestAppFlagsPackages(t *testing.T) { android.AssertStringDoesContain(t, "aapt2 compile command expected to pass feature flags arguments", compileFlags, - "--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt", + "--feature-flags @out/soong/.intermediates/bar/aconfig-flags.txt --feature-flags @out/soong/.intermediates/baz/aconfig-flags.txt", ) } @@ -4655,12 +4655,12 @@ func TestAppFlagsPackagesPropagation(t *testing.T) { android.AssertStringDoesContain(t, "aapt2 link command expected to pass feature flags arguments of flags_packages and that of its static libs", linkInFlags, - "--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt", + "--feature-flags @out/soong/.intermediates/bar/aconfig-flags.txt --feature-flags @out/soong/.intermediates/baz/aconfig-flags.txt", ) android.AssertStringDoesNotContain(t, "aapt2 link command expected to not pass feature flags arguments of flags_packages of its libs", linkInFlags, - "--feature-flags @out/soong/.intermediates/foo/intermediate.txt", + "--feature-flags @out/soong/.intermediates/foo/aconfig-flags.txt", ) } diff --git a/java/rro_test.go b/java/rro_test.go index 3e4fed51e..faf82af84 100644 --- a/java/rro_test.go +++ b/java/rro_test.go @@ -355,7 +355,7 @@ func TestRuntimeResourceOverlayFlagsPackages(t *testing.T) { android.AssertStringDoesContain(t, "aapt2 link command expected to pass feature flags arguments", linkInFlags, - "--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt", + "--feature-flags @out/soong/.intermediates/bar/aconfig-flags.txt --feature-flags @out/soong/.intermediates/baz/aconfig-flags.txt", ) } -- cgit v1.2.3 From 5bda0ea8e3900791dd788d73ffaaa977d115b560 Mon Sep 17 00:00:00 2001 From: Luca Stefani Date: Fri, 11 Apr 2025 13:57:17 +0200 Subject: install_symlink: Make symlink target configurable Can be useful on trees supporting multiple QCOM families where firmware may have different mount points and there's a generic installed symlink pointing to the correct path. Test: m Change-Id: Id2c5c62e8e6f7cc8326ba213ddaacb5e4e2c13e6 --- etc/install_symlink.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/etc/install_symlink.go b/etc/install_symlink.go index aa33445e1..31da3f653 100644 --- a/etc/install_symlink.go +++ b/etc/install_symlink.go @@ -18,6 +18,8 @@ import ( "android/soong/android" "path/filepath" "strings" + + "github.com/google/blueprint/proptools" ) func init() { @@ -52,7 +54,7 @@ type InstallSymlinkProperties struct { // properties. Installed_location string // The target of the symlink, aka where the symlink points. - Symlink_target string + Symlink_target proptools.Configurable[string] } type InstallSymlink struct { @@ -64,7 +66,8 @@ type InstallSymlink struct { } func (m *InstallSymlink) GenerateAndroidBuildActions(ctx android.ModuleContext) { - if filepath.Clean(m.properties.Symlink_target) != m.properties.Symlink_target { + symlink_target := m.properties.Symlink_target.GetOrDefault(ctx, "") + if filepath.Clean(symlink_target) != symlink_target { ctx.PropertyErrorf("symlink_target", "Should be a clean filepath") return } @@ -83,7 +86,7 @@ func (m *InstallSymlink) GenerateAndroidBuildActions(ctx android.ModuleContext) name := filepath.Base(m.properties.Installed_location) installDir := android.PathForModuleInstall(ctx, filepath.Dir(m.properties.Installed_location)) - m.installedPath = ctx.InstallAbsoluteSymlink(installDir, name, m.properties.Symlink_target) + m.installedPath = ctx.InstallAbsoluteSymlink(installDir, name, symlink_target) } func (m *InstallSymlink) AndroidMkEntries() []android.AndroidMkEntries { -- cgit v1.2.3 From 62c119b09bd43ab82a1d8f310b7c9e296ed4ef23 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Mon, 14 Apr 2025 12:10:37 -0700 Subject: Remove -mllvm -jump-is-expensive=false from riscv64_device.go (part 2) Latest toolchain has this by default, and we removed this from the cflags already, but missed the ldflags. Related: https://github.com/google/android-riscv64/issues/124 Bug: 330200010 Change-Id: I330c901ec583bc409a3167bcec0a8c67dd0b9bca --- cc/config/riscv64_device.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/cc/config/riscv64_device.go b/cc/config/riscv64_device.go index 6a5293f4c..b0ab30d79 100644 --- a/cc/config/riscv64_device.go +++ b/cc/config/riscv64_device.go @@ -41,8 +41,6 @@ var ( // This is already the driver's Android default, but duplicated here (and // above) for ease of experimentation with additional extensions. "-march=rv64gcv_zba_zbb_zbs", - // TODO: remove when clang default changed (https://github.com/google/android-riscv64/issues/124) - "-Wl,-mllvm -Wl,-jump-is-expensive=false", } riscv64Lldflags = append(riscv64Ldflags, -- cgit v1.2.3 From a5493f9572339be6e2853f9e1d52894c3045eac6 Mon Sep 17 00:00:00 2001 From: LaMont Jones Date: Mon, 14 Apr 2025 12:41:58 -0700 Subject: Sort apiScopes in sdk_library_import dependencies This change makes it easier to confirm that a change does not affect analysis. Bug: none Test: soong-debug-info does not change on rerun. Change-Id: I507767976091781b42300f35a898df2eddcf22e0 --- java/sdk_library.go | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/java/sdk_library.go b/java/sdk_library.go index 28d141640..32a476732 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -17,9 +17,11 @@ package java import ( "errors" "fmt" + "maps" "path" "path/filepath" "reflect" + "slices" "sort" "strings" "sync" @@ -2134,6 +2136,12 @@ func (module *SdkLibraryImport) BaseModuleName() string { return proptools.StringDefault(module.properties.Source_module_name, module.ModuleBase.Name()) } +func (module *SdkLibraryImport) sortedApiScopes() []*apiScope { + return slices.SortedFunc(maps.Keys(module.scopeProperties), func(a, b *apiScope) int { + return strings.Compare(a.name, b.name) + }) +} + func (module *SdkLibraryImport) createInternalModules(mctx android.DefaultableHookContext) { // If the build is configured to use prebuilts then force this to be preferred. @@ -2141,7 +2149,8 @@ func (module *SdkLibraryImport) createInternalModules(mctx android.DefaultableHo module.prebuilt.ForcePrefer() } - for apiScope, scopeProperties := range module.scopeProperties { + for _, apiScope := range module.sortedApiScopes() { + scopeProperties := module.scopeProperties[apiScope] if len(scopeProperties.Jars) == 0 { continue } @@ -2166,7 +2175,8 @@ func (module *SdkLibraryImport) createInternalModules(mctx android.DefaultableHo // Add the dependencies on the child module in the component deps mutator so that it // creates references to the prebuilt and not the source modules. func (module *SdkLibraryImport) ComponentDepsMutator(ctx android.BottomUpMutatorContext) { - for apiScope, scopeProperties := range module.scopeProperties { + for _, apiScope := range module.sortedApiScopes() { + scopeProperties := module.scopeProperties[apiScope] if len(scopeProperties.Jars) == 0 { continue } @@ -2260,7 +2270,8 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo sdkLibInfo := module.generateCommonBuildActions(ctx) // Populate the scope paths with information from the properties. - for apiScope, scopeProperties := range module.scopeProperties { + for _, apiScope := range module.sortedApiScopes() { + scopeProperties := module.scopeProperties[apiScope] if len(scopeProperties.Jars) == 0 { continue } -- cgit v1.2.3 From 4561beee262739220aa51f598c20edba780c6ecf Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Mon, 14 Apr 2025 13:55:04 -0700 Subject: Introduce DISABLE_NOTICE_XML_GENERATION env var `DISABLE_NOTICE_XML_GENERATION` is used to disable NOTICE.xml file generation, for soong only build artifacts testing purpose. Test: m nothing Bug: 410609073 Change-Id: Iba8fe7793eddf9bc8fa4f26a970c570e5474f8c3 --- android/config.go | 4 ++++ compliance/notice.go | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/android/config.go b/android/config.go index 75f540452..ba8412357 100644 --- a/android/config.go +++ b/android/config.go @@ -1662,6 +1662,10 @@ func (c *config) katiPackageMkDir() string { return filepath.Join(c.soongOutDir, "kati_packaging"+c.katiSuffix) } +func (c *config) DisableNoticeXmlGeneration() bool { + return c.IsEnvTrue("DISABLE_NOTICE_XML_GENERATION") +} + func (c *deviceConfig) Arches() []Arch { var arches []Arch for _, target := range c.config.Targets[Android] { diff --git a/compliance/notice.go b/compliance/notice.go index c5b0fbebe..7bf9f090a 100644 --- a/compliance/notice.go +++ b/compliance/notice.go @@ -63,6 +63,8 @@ type NoticeXmlModule struct { props noticeXmlProperties + disabled bool + outputFile android.OutputPath } @@ -71,6 +73,12 @@ type noticeXmlProperties struct { } func (nx *NoticeXmlModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { + // No build action needs to be done in notice_xml module type if notice xml generation is disabled + if ctx.Config().DisableNoticeXmlGeneration() { + nx.disabled = true + return + } + prodVars := ctx.Config().ProductVariables() buildFingerprintFile := android.PathForArbitraryOutput(ctx, "target", "product", android.String(prodVars.DeviceName), "build_fingerprint.txt") implicits := []android.Path{buildFingerprintFile} @@ -101,5 +109,6 @@ func (nx *NoticeXmlModule) AndroidMkEntries() []android.AndroidMkEntries { return []android.AndroidMkEntries{{ Class: "ETC", OutputFile: android.OptionalPathForPath(nx.outputFile), + Disabled: nx.disabled, }} } -- cgit v1.2.3 From 5b4d78d316e5f5c80507de169bb08783aa97f169 Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Mon, 14 Apr 2025 13:49:23 -0700 Subject: Remove some img files from the soong only diff test allowlist This change utilizes the newly introduced `DISABLE_NOTICE_XML_GENERATION` environment variable to disable the notice xml file generation and make some img files bit identical between soong only build and soong plus make build. Test: build/soong/scripts/soong_only_diff_test.py aosp_cf_x86_64_phone Bug: 410609073 Change-Id: Ib0cb5e16d1c1e503c4970bb1109ad0827cd9cb87 --- scripts/soong_only_diff_test.py | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/scripts/soong_only_diff_test.py b/scripts/soong_only_diff_test.py index 67313fd40..cb255e3a8 100755 --- a/scripts/soong_only_diff_test.py +++ b/scripts/soong_only_diff_test.py @@ -37,6 +37,7 @@ def run_build_target_files_zip(product: Product, soong_only: bool) -> bool: 'USE_RBE=true', 'BUILD_DATETIME=1', 'USE_FIXED_TIMESTAMP_IMG_FILES=true', + 'DISABLE_NOTICE_XML_GENERATION=true', f'TARGET_PRODUCT={product.product}', f'TARGET_RELEASE={product.release}', f'TARGET_BUILD_VARIANT={product.variant}', @@ -106,14 +107,7 @@ def find_build_id() -> str | None: SHA_DIFF_ALLOWLIST = { "IMAGES/init_boot.img", - "IMAGES/odm_dlkm.img", - "IMAGES/odm.img", - "IMAGES/product.img", - "IMAGES/product.map", - "IMAGES/system_dlkm.img", - "IMAGES/system_ext.img", "IMAGES/system.img", - "IMAGES/system.map", "IMAGES/system_other.img", "IMAGES/userdata.img", "IMAGES/vbmeta.img", @@ -121,22 +115,10 @@ SHA_DIFF_ALLOWLIST = { "IMAGES/vbmeta_system.img", "IMAGES/vbmeta_vendor_dlkm.img", "IMAGES/vendor_boot.img", - "IMAGES/vendor_dlkm.img", - "IMAGES/vendor.img", - "IMAGES/vendor.map", - "META/care_map.pb", "META/file_contexts.bin", "META/kernel_version.txt", "META/misc_info.txt", "META/vbmeta_digest.txt", - "ODM_DLKM/etc/NOTICE.xml.gz", - "ODM/etc/NOTICE.xml.gz", - "PRODUCT/etc/NOTICE.xml.gz", - "SYSTEM_DLKM/etc/NOTICE.xml.gz", - "SYSTEM/etc/NOTICE.xml.gz", - "SYSTEM_EXT/etc/NOTICE.xml.gz", - "VENDOR_DLKM/etc/NOTICE.xml.gz", - "VENDOR/etc/NOTICE.xml.gz", "SYSTEM_EXT/etc/vm/trusty_vm/trusty_security_vm.elf", # TODO: Make this hermetic } @@ -151,10 +133,10 @@ def compare_sha_maps(soong_only_map: dict[str, bytes], soong_plus_make_map: dict if key not in soong_only_map: print(f'{key} not found in soong only build target_files.zip', file=sys.stderr) all_identical = False - if key not in soong_plus_make_map: + elif key not in soong_plus_make_map: print(f'{key} not found in soong plus make build target_files.zip', file=sys.stderr) all_identical = False - if soong_only_map[key] != soong_plus_make_map[key]: + elif soong_only_map[key] != soong_plus_make_map[key]: print(f'{key} sha value differ between soong only build and soong plus make build', file=sys.stderr) all_identical = False -- cgit v1.2.3 From 33cc07a83c81a04b63a017b53aa6e8fc4817157f Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Mon, 14 Apr 2025 14:23:42 -0700 Subject: Specify the correct tracking bug for an allowlisted entry Non-hermetic behavior of the allowlisted entry `trusty_security_vm.elf` is a known issue and is tracked in a separate bug. The entry can be removed from the allowlist once the tracking bug is marked fixed. Test: n/a Change-Id: Icc0fb9a307f5efd4d50e974538fc438bba2cdabc --- scripts/soong_only_diff_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/soong_only_diff_test.py b/scripts/soong_only_diff_test.py index cb255e3a8..e2a1b322a 100755 --- a/scripts/soong_only_diff_test.py +++ b/scripts/soong_only_diff_test.py @@ -119,7 +119,7 @@ SHA_DIFF_ALLOWLIST = { "META/kernel_version.txt", "META/misc_info.txt", "META/vbmeta_digest.txt", - "SYSTEM_EXT/etc/vm/trusty_vm/trusty_security_vm.elf", # TODO: Make this hermetic + "SYSTEM_EXT/etc/vm/trusty_vm/trusty_security_vm.elf", # TODO: b/406045340 - Remove from the allowlist once it's fixed } def compare_sha_maps(soong_only_map: dict[str, bytes], soong_plus_make_map: dict[str, bytes]) -> bool: -- cgit v1.2.3 From 065dc402d471142eb08dffdc6f4707e9f0a55b7a Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Mon, 14 Apr 2025 15:29:02 -0700 Subject: Additional dist goals for build flags singleton artifacts This change adds additional dist goals for the artifacts of the build flags singleton, to account for products that are built with phony targets other than `droid dist`. Test: CI Bug: 408047854 Change-Id: Id72be152e38a7a8e10a5d77c655560d0edf80ae4 --- aconfig/build_flags/build_flags_singleton.go | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/aconfig/build_flags/build_flags_singleton.go b/aconfig/build_flags/build_flags_singleton.go index 3a06e72d6..2eb86e3d1 100644 --- a/aconfig/build_flags/build_flags_singleton.go +++ b/aconfig/build_flags/build_flags_singleton.go @@ -38,6 +38,10 @@ type allBuildFlagDeclarationsSingleton struct { configsTextProtoPath android.OutputPath } +var buildFlagArtifactsDistGoals = []string{ + "docs", "droid", "sdk", "release_config_metadata", "gms", +} + func (this *allBuildFlagDeclarationsSingleton) GenerateBuildActions(ctx android.SingletonContext) { // Find all of the build_flag_declarations modules var flagsFiles android.Paths @@ -114,20 +118,19 @@ func (this *allBuildFlagDeclarationsSingleton) GenerateBuildActions(ctx android. ) ctx.DistForGoal("droid", this.flagsBinaryProtoPath) - for _, goal := range []string{"docs", "droid", "sdk", "release_config_metadata"} { - ctx.DistForGoalWithFilename(goal, this.flagsBinaryProtoPath, "build_flags/all_flags.pb") - ctx.DistForGoalWithFilename(goal, this.flagsTextProtoPath, "build_flags/all_flags.textproto") - ctx.DistForGoalWithFilename(goal, this.configsBinaryProtoPath, "build_flags/all_release_config_contributions.pb") - ctx.DistForGoalWithFilename(goal, this.configsTextProtoPath, "build_flags/all_release_config_contributions.textproto") - } + + ctx.DistForGoalsWithFilename(buildFlagArtifactsDistGoals, this.flagsBinaryProtoPath, "build_flags/all_flags.pb") + ctx.DistForGoalsWithFilename(buildFlagArtifactsDistGoals, this.flagsTextProtoPath, "build_flags/all_flags.textproto") + ctx.DistForGoalsWithFilename(buildFlagArtifactsDistGoals, this.configsBinaryProtoPath, "build_flags/all_release_config_contributions.pb") + ctx.DistForGoalsWithFilename(buildFlagArtifactsDistGoals, this.configsTextProtoPath, "build_flags/all_release_config_contributions.textproto") if ctx.Config().HasDeviceProduct() { flagsDir := android.PathForOutput(ctx, "release-config") baseAllRelease := fmt.Sprintf("all_release_configs-%s", ctx.Config().DeviceProduct()) distAllReleaseConfigsArtifact := func(ext string) { - ctx.DistForGoalWithFilename( - "droid", + ctx.DistForGoalsWithFilename( + buildFlagArtifactsDistGoals, flagsDir.Join(ctx, fmt.Sprintf("%s.%s", baseAllRelease, ext)), fmt.Sprintf("build_flags/all_release_configs.%s", ext), ) -- cgit v1.2.3 From 2b7ecb36a91e881942dee332344e7d525a3abff0 Mon Sep 17 00:00:00 2001 From: LaMont Jones Date: Fri, 11 Apr 2025 14:58:47 -0700 Subject: Add android_library.package_name If the only reason that an android_library needs a manifest file is to specify the package name, that can be specified in the Android.bp file. Bug: b/307962763 Test: Manual, TH Change-Id: Ifa778b77be8e86c963f0dd854f83b5768326eef6 --- java/aar.go | 26 ++++++++++++++++++++++++++ java/aar_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/java/aar.go b/java/aar.go index f608d4e0f..33d96db8a 100644 --- a/java/aar.go +++ b/java/aar.go @@ -108,6 +108,9 @@ type aaptProperties struct { // Names of aconfig_declarations modules that specify aconfig flags that the module depends on. Flags_packages []string + + // The package name of this app. May not be used if `manifest` or `additional_manifests` are provided. + Package_name proptools.Configurable[string] } type aapt struct { @@ -452,9 +455,21 @@ func (a *aapt) buildActions(ctx android.ModuleContext, opts aaptBuildActionOptio opts.classLoaderContexts = opts.classLoaderContexts.ExcludeLibs(opts.excludedLibs) // App manifest file + packageNameProp := a.aaptProperties.Package_name.Get(ctx) var manifestFilePath android.Path if opts.manifestForAapt != nil { manifestFilePath = opts.manifestForAapt + } else if a.isLibrary && packageNameProp.IsPresent() && a.aaptProperties.Manifest == nil && a.aaptProperties.Additional_manifests == nil { + // If the only reason that a library needs a manifest file is to give the package name, allow them to do that in + // the module declaration. If they are already supplying a manifest, then do not autogenerate a manifest file. + generatedManifestPath := android.PathForModuleOut(ctx, "GeneratedManifest.xml") + manifestString := ` + + +` + android.WriteFileRule(ctx, generatedManifestPath, manifestString) + ctx.SetOutputFiles([]android.Path{generatedManifestPath}, ".gen_xml") + manifestFilePath = generatedManifestPath } else { manifestFile := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml") manifestFilePath = android.PathForModuleSrc(ctx, manifestFile) @@ -975,6 +990,17 @@ func (a *AndroidLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { } func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { + packageNameProp := a.aaptProperties.Package_name.Get(ctx) + if packageNameProp.IsPresent() { + if a.aaptProperties.Manifest != nil { + ctx.PropertyErrorf("package_name", "cannot be used with `manifest`") + return + } + if a.aaptProperties.Additional_manifests != nil { + ctx.PropertyErrorf("package_name", "cannot be used with `additional_manifests`") + return + } + } a.aapt.isLibrary = true a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx) if a.usesLibrary.shouldDisableDexpreopt { diff --git a/java/aar_test.go b/java/aar_test.go index 088ad6c92..9c1524d46 100644 --- a/java/aar_test.go +++ b/java/aar_test.go @@ -181,3 +181,29 @@ func TestAndroidLibraryOutputFilesRel(t *testing.T) { android.AssertStringEquals(t, "baz relative output path", "baz.jar", bazOutputPaths[0].Rel()) } + +func TestAndroidLibraryManifests(t *testing.T) { + t.Parallel() + result := android.GroupFixturePreparers( + PrepareForTestWithJavaDefaultModules, + ).RunTestWithBp(t, ` + android_library { + name: "foo", + package_name: "com.android.foo", + java_resources: ["foo.txt"], + } + `) + + foo := result.ModuleForTests(t, "foo", "android_common") + + fooOutputPaths := foo.OutputFiles(result.TestContext, t, "") + + android.AssertPathsRelativeToTopEquals(t, "foo manifest path", + []string{"out/soong/.intermediates/foo/android_common/GeneratedManifest.xml"}, + foo.OutputFiles(result.TestContext, t, ".gen_xml")) + android.AssertPathsRelativeToTopEquals(t, "foo output path", + []string{"out/soong/.intermediates/foo/android_common/withres/foo.jar"}, fooOutputPaths) + + android.AssertStringEquals(t, "foo relative output path", + "foo.jar", fooOutputPaths[0].Rel()) +} -- cgit v1.2.3 From 41ec881fd45bc6f3720ba82f42c33ff52c12c932 Mon Sep 17 00:00:00 2001 From: LaMont Jones Date: Thu, 27 Mar 2025 12:55:30 -0700 Subject: Enable header_jar_override on all release configs Bug: 396137333 Test: manual, TH Change-Id: I2c10808ecee62dd87c66c7e6143c9f2f43d66345 --- java/java.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java.go b/java/java.go index f0ecc435f..7bce1b614 100644 --- a/java/java.go +++ b/java/java.go @@ -1297,7 +1297,7 @@ func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) { j.usesLibrary.deps(ctx, false) j.deps(ctx) - if ctx.Config().GetBuildFlagBool("RELEASE_JAVA_HEADER_JAR_OVERRIDE") && j.properties.Header_jar_override != "" { + if j.properties.Header_jar_override != "" { ctx.AddVariationDependencies(nil, headerJarOverrideTag, j.properties.Header_jar_override) } if j.SdkLibraryName() != nil && strings.HasSuffix(j.Name(), ".impl") { -- cgit v1.2.3 From 107ae4efa2e82c6f718e1a011a6439bd9269868a Mon Sep 17 00:00:00 2001 From: Justin Yun Date: Mon, 14 Apr 2025 13:15:03 +0900 Subject: Set product_config and notice_xml non-generic product_config generates /out/soong/soong..[extra.]variables files. This file cannot be generic. notice_xml gathers information from /out/soong/compliance-metadata/ directory that includes the compliance metadata information for all modules. So the notice_xml cannot be generic. Set these two module types non-genetic by default. Bug: 406409033 Bug: 406411118 Test: build with use_generic_config: true Change-Id: I43f220a82b0d8435968a753271c76f8486f16b3f --- android/early_module_context.go | 2 +- android/product_config.go | 16 ++++++++-------- compliance/notice.go | 7 +++++-- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/android/early_module_context.go b/android/early_module_context.go index 75c8b1eb6..f48723ff8 100644 --- a/android/early_module_context.go +++ b/android/early_module_context.go @@ -150,7 +150,7 @@ func (e *earlyModuleContext) Config() Config { // If a module builds multiple image variations, provide the generic config only for the core // variant which is installed in the system partition. Other image variant may still read the // original configurations. - if e.Module().base().UseGenericConfig() && e.Module().base().commonProperties.ImageVariation == "" { + if e.Module().UseGenericConfig() && e.Module().base().commonProperties.ImageVariation == "" { return e.EarlyModuleContext.Config().(Config).genericConfig() } return e.EarlyModuleContext.Config().(Config) diff --git a/android/product_config.go b/android/product_config.go index 850f00334..2549f7967 100644 --- a/android/product_config.go +++ b/android/product_config.go @@ -14,10 +14,6 @@ package android -import ( - "github.com/google/blueprint/proptools" -) - func init() { ctx := InitRegistrationContext ctx.RegisterModuleType("product_config", productConfigFactory) @@ -27,6 +23,10 @@ type productConfigModule struct { ModuleBase } +func (p *productConfigModule) UseGenericConfig() bool { + return false +} + func (p *productConfigModule) GenerateAndroidBuildActions(ctx ModuleContext) { if ctx.ModuleName() != "product_config" || ctx.ModuleDir() != "build/soong" { ctx.ModuleErrorf("There can only be one product_config module in build/soong") @@ -34,10 +34,10 @@ func (p *productConfigModule) GenerateAndroidBuildActions(ctx ModuleContext) { } outputFilePath := PathForModuleOut(ctx, p.Name()+".json") - // DeviceProduct can be null so calling ctx.Config().DeviceProduct() may cause null dereference - targetProduct := proptools.String(ctx.Config().config.productVariables.DeviceProduct) - if targetProduct != "" { - targetProduct += "." + // DeviceProduct can be null, so check before calling ctx.Config().DeviceProduct() + targetProduct := "" + if ctx.Config().HasDeviceProduct() { + targetProduct = ctx.Config().DeviceProduct() + "." } coverageSuffix := ctx.Config().CoverageSuffix() diff --git a/compliance/notice.go b/compliance/notice.go index 7bf9f090a..ff6f5b6ab 100644 --- a/compliance/notice.go +++ b/compliance/notice.go @@ -72,6 +72,10 @@ type noticeXmlProperties struct { Partition_name string } +func (nx *NoticeXmlModule) UseGenericConfig() bool { + return false +} + func (nx *NoticeXmlModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { // No build action needs to be done in notice_xml module type if notice xml generation is disabled if ctx.Config().DisableNoticeXmlGeneration() { @@ -79,8 +83,7 @@ func (nx *NoticeXmlModule) GenerateAndroidBuildActions(ctx android.ModuleContext return } - prodVars := ctx.Config().ProductVariables() - buildFingerprintFile := android.PathForArbitraryOutput(ctx, "target", "product", android.String(prodVars.DeviceName), "build_fingerprint.txt") + buildFingerprintFile := ctx.Config().BuildFingerprintFile(ctx) implicits := []android.Path{buildFingerprintFile} output := android.PathForModuleOut(ctx, "NOTICE.xml.gz") -- cgit v1.2.3 From 759f9f7c474b20832ce3477dd9e1668eaa878b26 Mon Sep 17 00:00:00 2001 From: Jooyung Han Date: Tue, 15 Apr 2025 19:47:24 +0900 Subject: Revert "apex: Do not compress EROFS APEX" To compress or not is controlled by PRODUCT_COMPRESSED_APEX. Special casing is confusing. Bug: 380786910 Test: m --no-skip-soong-tests This reverts commit a8fb73be3258237caaa226df2aef6f4fea20d004. Change-Id: I8428bc8f78c07c06f5f53c9da4501d13d80554e1 --- apex/apex.go | 8 +------- apex/apex_test.go | 28 ---------------------------- 2 files changed, 1 insertion(+), 35 deletions(-) diff --git a/apex/apex.go b/apex/apex.go index 17c2884bc..0634b69e6 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -1733,13 +1733,7 @@ func (a *apexBundle) setPayloadFsType(ctx android.ModuleContext) { } func (a *apexBundle) isCompressable() bool { - if a.testApex { - return false - } - if a.payloadFsType == erofs { - return false - } - return proptools.Bool(a.overridableProperties.Compressible) + return proptools.BoolDefault(a.overridableProperties.Compressible, false) && !a.testApex } func (a *apexBundle) commonBuildActions(ctx android.ModuleContext) bool { diff --git a/apex/apex_test.go b/apex/apex_test.go index 880d0014a..41de1a460 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -9325,34 +9325,6 @@ func TestCompressedApex_NonUpdatable(t *testing.T) { `) } -func TestCompressedApexIsDisabledWhenUsingErofs(t *testing.T) { - t.Parallel() - ctx := testApex(t, ` - apex { - name: "myapex", - key: "myapex.key", - compressible: true, - updatable: true, - min_sdk_version: "29", - payload_fs_type: "erofs", - } - apex_key { - name: "myapex.key", - public_key: "testkey.avbpubkey", - private_key: "testkey.pem", - } - `, - android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { - variables.CompressedApex = proptools.BoolPtr(true) - }), - ) - - compressRule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").MaybeRule("compressRule") - if compressRule.Rule != nil { - t.Error("erofs apex should not be compressed") - } -} - func TestApexSet_ShouldRespectCompressedApexFlag(t *testing.T) { t.Parallel() for _, compressionEnabled := range []bool{true, false} { -- cgit v1.2.3 From eef2c8df11367778ab6c0f84473b78b3ef0fb2a1 Mon Sep 17 00:00:00 2001 From: Jared Duke Date: Fri, 11 Apr 2025 23:09:08 +0000 Subject: Add PRODUCT_COPY_FILES support to java_system_features_srcs Add a new property that allows routing of XML permission feature files from PRODUCT_COPY_FILES to inputs for systemfeatures-gen-tool. This is not yet used on any production targets. That will land in a follow-up CL guarded by a trunk stable build flag. Bug: 203143243 Flag: EXEMPT tool only change Test: go test systemfeatures/. Change-Id: Ie694138236e3f156c63662698cd76e029eb23cbe --- systemfeatures/system_features.go | 59 +++++++++++++++++++++++-- systemfeatures/system_features_test.go | 80 ++++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+), 4 deletions(-) diff --git a/systemfeatures/system_features.go b/systemfeatures/system_features.go index b8dacfb1f..1e6182b27 100644 --- a/systemfeatures/system_features.go +++ b/systemfeatures/system_features.go @@ -15,6 +15,7 @@ package systemfeatures import ( "fmt" + "path/filepath" "sort" "strings" @@ -44,8 +45,10 @@ type javaSystemFeaturesSrcs struct { // Whether to generate only a simple metadata class with details about the full API surface. // This is useful for tools that rely on the mapping from feature names to their generated // method names, but don't want the fully generated API class (e.g., for linting). - Metadata_only *bool + // Whether to parse feature definitions from feature XML files for the + // target's PRODUCT_COPY_FILES. Defaults to false. + Use_product_copy_files *bool } outputFiles android.WritablePaths } @@ -74,13 +77,18 @@ func (m *javaSystemFeaturesSrcs) GenerateAndroidBuildActions(ctx android.ModuleC rule := android.NewRuleBuilder(pctx, ctx) rule.Command().Text("rm -rf").Text(outputDir.String()) rule.Command().Text("mkdir -p").Text(outputDir.String()) - rule.Command(). + ruleCmd := rule.Command(). BuiltTool("systemfeatures-gen-tool"). Flag(m.properties.Full_class_name). FlagForEachArg("--feature=", features). FlagWithArg("--readonly=", fmt.Sprint(ctx.Config().ReleaseUseSystemFeatureBuildFlags())). - FlagWithArg("--metadata-only=", fmt.Sprint(proptools.Bool(m.properties.Metadata_only))). - FlagWithOutput(" > ", outputFile) + FlagWithArg("--metadata-only=", fmt.Sprint(proptools.Bool(m.properties.Metadata_only))) + if proptools.Bool(m.properties.Use_product_copy_files) { + if featureXmlFiles := uniquePossibleFeatureXmlPaths(ctx); len(featureXmlFiles) > 0 { + ruleCmd.FlagWithInputList("--feature-xml-files=", featureXmlFiles, ",") + } + } + ruleCmd.FlagWithOutput(" > ", outputFile) rule.Build(ctx.ModuleName(), "Generating systemfeatures srcs filegroup") m.outputFiles = append(m.outputFiles, outputFile) @@ -106,6 +114,49 @@ func JavaSystemFeaturesSrcsFactory() android.Module { module := &javaSystemFeaturesSrcs{} module.AddProperties(&module.properties) module.properties.Metadata_only = proptools.BoolPtr(false) + module.properties.Use_product_copy_files = proptools.BoolPtr(false) android.InitAndroidModule(module) return module } + +// Generates a list of unique, existent src paths for potential feature XML +// files, as contained in the configured PRODUCT_COPY_FILES listing. +func uniquePossibleFeatureXmlPaths(ctx android.ModuleContext) android.Paths { + dstPathSeen := make(map[string]bool) + var possibleSrcPaths []android.Path + for _, copyFilePair := range ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.ProductCopyFiles { + srcDstList := strings.Split(copyFilePair, ":") + // The length may be >2 (e.g., "$src:$dst:$owner"), but we only care + // that it has at least "$src:$dst". + if len(srcDstList) < 2 { + ctx.ModuleErrorf("PRODUCT_COPY_FILES must follow the format \"src:dest\", got: %s", copyFilePair) + continue + } + src, dst := srcDstList[0], srcDstList[1] + + // We're only interested in `.xml` files (case-insensitive). + if !strings.EqualFold(filepath.Ext(dst), ".xml") { + continue + } + + // We only care about files directly in `*/etc/permissions/` or + // `*/etc/sysconfig` dirs, not any nested subdirs. + normalizedDstDir := filepath.ToSlash(filepath.Dir(filepath.Clean(dst))) + if !strings.HasSuffix(normalizedDstDir, "/etc/permissions") && + !strings.HasSuffix(normalizedDstDir, "/etc/sysconfig") { + continue + } + + // The first `dst` entry in the PRODUCT_COPY_FILES `src:dst` pairings + // always takes precedence over latter entries. + if _, ok := dstPathSeen[dst]; !ok { + relSrc := android.ToRelativeSourcePath(ctx, src) + if optionalPath := android.ExistentPathForSource(ctx, relSrc); optionalPath.Valid() { + dstPathSeen[dst] = true + possibleSrcPaths = append(possibleSrcPaths, optionalPath.Path()) + } + } + } + // A sorted, unique list ensures stability of ninja build command outputs. + return android.SortedUniquePaths(possibleSrcPaths) +} diff --git a/systemfeatures/system_features_test.go b/systemfeatures/system_features_test.go index 58e6a0660..e0210731f 100644 --- a/systemfeatures/system_features_test.go +++ b/systemfeatures/system_features_test.go @@ -44,8 +44,88 @@ java_system_features_srcs { android.AssertStringDoesContain(t, "Expected TELEVISION feature flag", cmd, "--feature=TELEVISION:UNAVAILABLE ") android.AssertStringDoesContain(t, "Expected WATCH feature flag", cmd, "--feature=WATCH: ") android.AssertStringDoesNotContain(t, "Unexpected FOO arg from non-system feature flag", cmd, "FOO") + android.AssertStringDoesNotContain(t, "Unexpected feature xml files flag", cmd, "--feature-xml-files") systemFeaturesModule := module.Module().(*javaSystemFeaturesSrcs) expectedOutputPath := "out/soong/.intermediates/system-features-srcs/gen/RoSystemFeatures.java" android.AssertPathsRelativeToTopEquals(t, "Expected output file", []string{expectedOutputPath}, systemFeaturesModule.Srcs()) } + +func TestJavaSystemFeaturesSrcsFromProductFiles(t *testing.T) { + bp := ` +java_system_features_srcs { + name: "system-features-srcs", + full_class_name: "com.android.test.RoSystemFeatures", + use_product_copy_files: true, +} +` + + res := android.GroupFixturePreparers( + android.FixtureRegisterWithContext(registerSystemFeaturesComponents), + android.PrepareForTestWithBuildFlag("RELEASE_USE_SYSTEM_FEATURE_BUILD_FLAGS", "true"), + android.PrepareForTestWithBuildFlag("RELEASE_SYSTEM_FEATURE_AUTOMOTIVE", "0"), + android.FixtureModifyConfig(func(config android.Config) { + config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.ProductCopyFiles = []string{ + "frameworks/features.xml:system/etc/permissions/features.xml", + "frameworks/features.xml:system/etc/permissions/featurescopy.xml", + "frameworks/features2.xml:system/etc/sysconfig/features2.xml", + "frameworks/featureswithowner.xml:vendor/etc/permissions/featureswithowner.xml:customowner", + "frameworks/dstalreadyexists.xml:system/etc/permissions/features.xml", + "frameworks/wrongsuffix.notxml:system/etc/permissions/wrongsuffix.notxml", + "frameworks/wrongsubdir.xml:system/notsysconfig/wrongsubdir.xml", + "frameworks/wrongsubdir.xml:system/notpermissions/wrongsubdir.xml", + "frameworks/wrongsubdir.xml:system/etc/permissions/nested/wrongsubdir.xml", + "frameworks/wrongsubdir.xml:system/notetc/permissions/wrongsubdir.xml", + "frameworks/nonexistent.xml:system/etc/permissions/nonexistent.xml", + } + }), + android.FixtureMergeMockFs(android.MockFS{ + "frameworks/features.xml": nil, + "frameworks/features2.xml": nil, + "frameworks/featureswithowner.xml": nil, + "frameworks/wrongsuffix.notxml": nil, + "frameworks/wrongsubdir.xml": nil, + "frameworks/dstalreadyexists.xml": nil, + // Note that we explicitly omit frameworks/nonexistent.xml. + }), + ).RunTestWithBp(t, bp) + + module := res.ModuleForTests(t, "system-features-srcs", "") + cmd := module.Rule("system-features-srcs").RuleParams.Command + android.AssertStringDoesContain(t, "Expected fully class name", cmd, " com.android.test.RoSystemFeatures ") + android.AssertStringDoesContain(t, "Expected readonly flag", cmd, "--readonly=true") + android.AssertStringDoesContain(t, "Expected AUTOMOTIVE feature flag", cmd, "--feature=AUTOMOTIVE:0 ") + android.AssertStringDoesContain(t, "Expected feature xml files flag", cmd, "--feature-xml-files=frameworks/features.xml,frameworks/features2.xml,frameworks/featureswithowner.xml") + android.AssertStringDoesNotContain(t, "Unexpected feature xml file", cmd, "dstalreadyexists.xml") + android.AssertStringDoesNotContain(t, "Unexpected feature xml file", cmd, "nonexistent.xml") + android.AssertStringDoesNotContain(t, "Unexpected feature xml file", cmd, "wrongsubdir.xml") + android.AssertStringDoesNotContain(t, "Unexpected feature xml file", cmd, "wrongsuffix.notxml") + + systemFeaturesModule := module.Module().(*javaSystemFeaturesSrcs) + expectedOutputPath := "out/soong/.intermediates/system-features-srcs/gen/RoSystemFeatures.java" + android.AssertPathsRelativeToTopEquals(t, "Expected output file", []string{expectedOutputPath}, systemFeaturesModule.Srcs()) +} + +func TestJavaSystemFeaturesSrcsFromInvalidProductFiles(t *testing.T) { + bp := ` +java_system_features_srcs { + name: "system-features-srcs", + full_class_name: "com.android.test.RoSystemFeatures", + use_product_copy_files: true, +} +` + + android.GroupFixturePreparers( + android.FixtureRegisterWithContext(registerSystemFeaturesComponents), + android.FixtureModifyConfig(func(config android.Config) { + config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.ProductCopyFiles = []string{ + "frameworks/dstmissing.xml", + } + }), + android.FixtureMergeMockFs(android.MockFS{ + "frameworks/dstmissing.xml": nil, + }), + ).ExtendWithErrorHandler( + android.FixtureExpectsAtLeastOneErrorMatchingPattern("PRODUCT_COPY_FILES must follow the format \"src:dest\", got: frameworks/dstmissing.xml"), + ).RunTestWithBp(t, bp) +} -- cgit v1.2.3 From e93689b205a4253e4cf12e77db3fceb1d84700f7 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Fri, 28 Mar 2025 21:51:13 -0700 Subject: Don't glob genrule dir_srcs The trusty dir_srcs do a lot of very large globs, leading to extra Soong reanalysis when any files are added to large parts of the tree. Soong doesn't need to know the list of files during analysis, it only needs the list of files as dependencies to rerun the genrule. This can be handled with a depsfile instead. Add a new dir_to_depfile tool that produces a list of all of the subdirectories and files in a directory in depfile format, and add it to the command line when using nsjail + dir_srcs. Bug: 375551969 Test: builds Change-Id: I9b2830919b5325f700cc27d9c602b45f9fed3707 --- android/paths.go | 8 +++ android/rule_builder.go | 95 ++++++++++++++++++++++++------------ cmd/dir_to_depfile/Android.bp | 23 +++++++++ cmd/dir_to_depfile/dir_to_depfile.go | 80 ++++++++++++++++++++++++++++++ genrule/genrule.go | 15 ++---- 5 files changed, 179 insertions(+), 42 deletions(-) create mode 100644 cmd/dir_to_depfile/Android.bp create mode 100644 cmd/dir_to_depfile/dir_to_depfile.go diff --git a/android/paths.go b/android/paths.go index 45a1e76fb..5dfaa8602 100644 --- a/android/paths.go +++ b/android/paths.go @@ -600,6 +600,14 @@ var _ DirectoryPath = (*directoryPath)(nil) type DirectoryPaths []DirectoryPath +func (paths DirectoryPaths) Strings() []string { + ret := make([]string, 0, len(paths)) + for _, path := range paths { + ret = append(ret, path.String()) + } + return ret +} + // DirectoryPathsForModuleSrcExcludes returns a Paths{} containing the resolved references in // directory paths. Elements of paths are resolved as: // - filepath, relative to local module directory, resolves as a filepath relative to the local diff --git a/android/rule_builder.go b/android/rule_builder.go index 01fe6d8ea..3b6189ae3 100644 --- a/android/rule_builder.go +++ b/android/rule_builder.go @@ -22,11 +22,12 @@ import ( "strings" "testing" - "github.com/google/blueprint" - "github.com/google/blueprint/proptools" "google.golang.org/protobuf/encoding/prototext" "google.golang.org/protobuf/proto" + "github.com/google/blueprint" + "github.com/google/blueprint/proptools" + "android/soong/cmd/sbox/sbox_proto" "android/soong/remoteexec" "android/soong/response" @@ -47,25 +48,26 @@ type RuleBuilder struct { pctx PackageContext ctx BuilderContext - commands []*RuleBuilderCommand - installs RuleBuilderInstalls - temporariesSet map[WritablePath]bool - restat bool - sbox bool - highmem bool - remoteable RemoteRuleSupports - rbeParams *remoteexec.REParams - outDir WritablePath - sboxOutSubDir string - sboxTools bool - sboxInputs bool - sboxManifestPath WritablePath - missingDeps []string - args map[string]string - nsjail bool - nsjailKeepGendir bool - nsjailBasePath WritablePath - nsjailImplicits Paths + commands []*RuleBuilderCommand + installs RuleBuilderInstalls + temporariesSet map[WritablePath]bool + restat bool + sbox bool + highmem bool + remoteable RemoteRuleSupports + rbeParams *remoteexec.REParams + outDir WritablePath + sboxOutSubDir string + sboxTools bool + sboxInputs bool + sboxManifestPath WritablePath + missingDeps []string + args map[string]string + nsjail bool + nsjailKeepGendir bool + nsjailBasePath WritablePath + nsjailDirDepsFile WritablePath + nsjailImplicits Paths } // NewRuleBuilder returns a newly created RuleBuilder. @@ -185,7 +187,7 @@ func (r *RuleBuilder) Sbox(outputDir WritablePath, manifestPath WritablePath) *R // output directory that nsjail will mount to out/. It should not be written to by any other rule. // baseDir should point to a location where nsjail will mount to /nsjail_build_sandbox, which will // be the working directory of the command. -func (r *RuleBuilder) Nsjail(outputDir WritablePath, baseDir WritablePath) *RuleBuilder { +func (r *RuleBuilder) Nsjail(outputDir WritablePath, baseDir WritablePath, dirDepsFile WritablePath) *RuleBuilder { if len(r.commands) > 0 { panic("Nsjail() may not be called after Command()") } @@ -195,6 +197,7 @@ func (r *RuleBuilder) Nsjail(outputDir WritablePath, baseDir WritablePath) *Rule r.nsjail = true r.outDir = outputDir r.nsjailBasePath = baseDir + r.nsjailDirDepsFile = dirDepsFile return r } @@ -476,6 +479,21 @@ func (r *RuleBuilder) rspFiles() []rspFileAndPaths { return rspFiles } +// implicitDirectories returns the list of paths that were passed to the RuleBuilderCommand.ImplicitDirectory method. +// The list is sorted and duplicates removed. +func (r *RuleBuilder) implicitDirectories() DirectoryPaths { + var dirsList DirectoryPaths + for _, c := range r.commands { + dirsList = append(dirsList, c.implicitDirectories...) + } + + sort.Slice(dirsList, func(i, j int) bool { + return dirsList[i].String() < dirsList[j].String() + }) + + return dirsList +} + // Commands returns a slice containing the built command line for each call to RuleBuilder.Command. func (r *RuleBuilder) Commands() []string { var commands []string @@ -501,6 +519,14 @@ func (r *RuleBuilder) depFileMergerCmd(depFiles WritablePaths) *RuleBuilderComma Inputs(depFiles.Paths()) } +func (r *RuleBuilder) dirsToDepFileCmd(dirs DirectoryPaths, target WritablePath) *RuleBuilderCommand { + return r.Command(). + builtToolWithoutDeps("dir_to_depfile"). + FlagWithDepFile("-o ", r.nsjailDirDepsFile). + FlagWithArg("-t ", target.String()). + Text(strings.Join(dirs.Strings(), " ")) +} + // Build adds the built command line to the build graph, with dependencies on Inputs and Tools, and output files for // Outputs. func (r *RuleBuilder) Build(name string, desc string) { @@ -524,22 +550,29 @@ func (r *RuleBuilder) build(name string, desc string) { return } + if dirs := r.implicitDirectories(); len(dirs) > 0 { + if !r.nsjail { + panic(fmt.Errorf("ImplicitDirectories are only supported for nsjail")) + } + r.dirsToDepFileCmd(dirs, r.Outputs()[0]) + } + var depFile WritablePath var depFormat blueprint.Deps if depFiles := r.DepFiles(); len(depFiles) > 0 { + if r.sbox || r.nsjail { + // Check for Rel() errors, as all depfiles should be in the output dir. Errors + // will be reported to the ctx. + for _, path := range depFiles { + Rel(r.ctx, r.outDir.String(), path.String()) + } + } + depFile = depFiles[0] depFormat = blueprint.DepsGCC if len(depFiles) > 1 { // Add a command locally that merges all depfiles together into the first depfile. r.depFileMergerCmd(depFiles) - - if r.sbox { - // Check for Rel() errors, as all depfiles should be in the output dir. Errors - // will be reported to the ctx. - for _, path := range depFiles[1:] { - Rel(r.ctx, r.outDir.String(), path.String()) - } - } } } @@ -608,8 +641,6 @@ func (r *RuleBuilder) build(name string, desc string) { for _, c := range r.commands { for _, directory := range c.implicitDirectories { addBindMount(directory.String(), directory.String()) - // TODO(b/375551969): Add implicitDirectories to BuildParams, rather than relying on implicits - inputs = append(inputs, SourcePath{basePath: directory.base()}) } for _, tool := range c.packagedTools { addBindMount(tool.srcPath.String(), nsjailPathForPackagedToolRel(tool)) diff --git a/cmd/dir_to_depfile/Android.bp b/cmd/dir_to_depfile/Android.bp new file mode 100644 index 000000000..a70216e22 --- /dev/null +++ b/cmd/dir_to_depfile/Android.bp @@ -0,0 +1,23 @@ +// Copyright 2018 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 { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +blueprint_go_binary { + name: "dir_to_depfile", + deps: ["soong-makedeps"], + srcs: ["dir_to_depfile.go"], +} diff --git a/cmd/dir_to_depfile/dir_to_depfile.go b/cmd/dir_to_depfile/dir_to_depfile.go new file mode 100644 index 000000000..bd7834bec --- /dev/null +++ b/cmd/dir_to_depfile/dir_to_depfile.go @@ -0,0 +1,80 @@ +// 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. + +// This tool finds all subdirectories and files in a list of directories and +// produces a dependency file for use by ninja. +package main + +import ( + "flag" + "fmt" + "io/fs" + "log" + "os" + "path/filepath" + + "android/soong/makedeps" +) + +func main() { + flag.Usage = func() { + fmt.Fprintf(os.Stderr, "Usage: %s -o -t [...]", os.Args[0]) + flag.PrintDefaults() + } + output := flag.String("o", "", "Output file") + target := flag.String("t", "", "Target name to write into depfile") + + flag.Parse() + + if flag.NArg() < 1 { + log.Fatal("Expected at least one directory as an argument") + } + + if *output == "" { + log.Fatal("Expected -o argument") + } + + if *target == "" { + log.Fatal("Expected -t argument") + } + + depsFile := makedeps.Deps{ + Output: *output, + } + + for _, arg := range flag.Args() { + deps, err := collectDirectoryDeps(arg) + if err != nil { + log.Fatalf("Error collecting deps from %q: %v", arg, err) + } + + depsFile.Inputs = append(depsFile.Inputs, deps...) + } + + err := os.WriteFile(*output, depsFile.Print(), 0666) + if err != nil { + log.Fatalf("Failed to write output file %q: %v", *output, err) + } +} + +func collectDirectoryDeps(dir string) (deps []string, err error) { + err = filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + deps = append(deps, path) + return nil + }) + return deps, err +} diff --git a/genrule/genrule.go b/genrule/genrule.go index bad0ed713..8f527dd99 100644 --- a/genrule/genrule.go +++ b/genrule/genrule.go @@ -21,7 +21,6 @@ package genrule import ( "fmt" "io" - "path/filepath" "strconv" "strings" @@ -222,7 +221,7 @@ type generateTask struct { in android.Paths out android.WritablePaths copyTo android.WritablePaths // For gensrcs to set on gensrcsMerge rule. - genDir android.WritablePath + genDir android.ModuleGenPath extraInputs map[string][]string cmd string @@ -457,7 +456,7 @@ func (g *Module) generateCommonBuildActions(ctx android.ModuleContext) { srcFiles = append(srcFiles, addLabelsForInputs("device_first_srcs", g.properties.Device_first_srcs.GetOrDefault(ctx, nil), nil)...) srcFiles = append(srcFiles, addLabelsForInputs("device_common_srcs", g.properties.Device_common_srcs.GetOrDefault(ctx, nil), nil)...) srcFiles = append(srcFiles, addLabelsForInputs("common_os_srcs", g.properties.Common_os_srcs.GetOrDefault(ctx, nil), nil)...) - srcFiles = append(srcFiles, addLabelsForInputs("host_first_src", g.properties.Host_first_src.GetOrDefault(ctx, nil), nil)...) + srcFiles = append(srcFiles, addLabelsForInputs("host_first_src", g.properties.Host_first_src.GetOrDefault(ctx, nil), nil)...) var copyFrom android.Paths var outputFiles android.WritablePaths @@ -489,7 +488,9 @@ func (g *Module) generateCommonBuildActions(ctx android.ModuleContext) { desc := "generate" name := "generator" if task.useNsjail { - rule = android.NewRuleBuilder(pctx, ctx).Nsjail(task.genDir, android.PathForModuleOut(ctx, "nsjail_build_sandbox")) + rule = android.NewRuleBuilder(pctx, ctx). + Nsjail(task.genDir, android.PathForModuleOut(ctx, "nsjail_build_sandbox"), + task.genDir.Join(ctx, "nsjail_dir_deps.d")) if task.keepGendir { rule.NsjailKeepGendir() } @@ -611,12 +612,6 @@ func (g *Module) generateCommonBuildActions(ctx android.ModuleContext) { if task.useNsjail { for _, input := range task.dirSrcs { cmd.ImplicitDirectory(input) - // TODO(b/375551969): remove glob - if paths, err := ctx.GlobWithDeps(filepath.Join(input.String(), "**/*"), nil); err == nil { - rule.NsjailImplicits(android.PathsForSource(ctx, paths)) - } else { - ctx.PropertyErrorf("dir_srcs", "can't glob %q", input.String()) - } } } -- cgit v1.2.3 From 1864b1513690586cbea0c327653dd75094747c4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kosi=C5=84ski?= Date: Sat, 12 Apr 2025 03:26:37 +0000 Subject: Don't allow arch and CPU variant specific properties. Arch variant specific and CPU variant specific properties seem like a bad idea, because they are forward-incompatible. When the code is compiled for a new product that has a new CPU or arch variant, all places that define these types of properties need to be updated. Feature properties do not suffer from this issue. There are currently no uses of CPU variant properties and only one use of arch variant properties, so let's remove them. Replace the one use of arch variant properties with a feature property. Bug: 406629772 Test: presubmit Flag: EXEMPT unused build system feature removal Change-Id: I560c00361d0fc4cb2e7b05c15960d482dae435f5 --- android/arch.go | 34 ---------------------------------- android/arch_list.go | 12 ++++++++++++ 2 files changed, 12 insertions(+), 34 deletions(-) diff --git a/android/arch.go b/android/arch.go index d6b297119..19f25269f 100644 --- a/android/arch.go +++ b/android/arch.go @@ -1371,40 +1371,6 @@ func getArchProperties(ctx BaseModuleContext, archProperties interface{}, arch A if ok { result = append(result, archStruct) - // Handle arch-variant-specific properties in the form: - // arch: { - // arm: { - // variant: { - // key: value, - // }, - // }, - // }, - v := variantReplacer.Replace(arch.ArchVariant) - if v != "" { - prefix := "arch." + archType.Name + "." + v - if variantProperties, ok := getChildPropertyStruct(ctx, archStruct, v, prefix); ok { - result = append(result, variantProperties) - } - } - - // Handle cpu-variant-specific properties in the form: - // arch: { - // arm: { - // variant: { - // key: value, - // }, - // }, - // }, - if arch.CpuVariant != arch.ArchVariant { - c := variantReplacer.Replace(arch.CpuVariant) - if c != "" { - prefix := "arch." + archType.Name + "." + c - if cpuVariantProperties, ok := getChildPropertyStruct(ctx, archStruct, c, prefix); ok { - result = append(result, cpuVariantProperties) - } - } - } - // Handle arch-feature-specific properties in the form: // arch: { // arm: { diff --git a/android/arch_list.go b/android/arch_list.go index 4ef8e7319..c0b5bfcf8 100644 --- a/android/arch_list.go +++ b/android/arch_list.go @@ -115,7 +115,12 @@ var cpuVariants = map[ArchType][]string{ X86_64: {}, } +// Lists all possible optional features for each architecture. var archFeatures = map[ArchType][]string{ + Arm: { + // Software implementation of ceil/floor is needed in libm + "soft_ceil_floor", + }, Arm64: { "branchprot", "dotprod", @@ -145,7 +150,14 @@ var archFeatures = map[ArchType][]string{ }, } +// Lists which optional features are automatically enabled +// for each value of TARGET_ARCH_VARIANT. var androidArchFeatureMap = map[ArchType]map[string][]string{ + Arm: { + "armv7-a-neon": { + "soft_ceil_floor", + }, + }, Arm64: { "armv8-a-branchprot": { "branchprot", -- cgit v1.2.3 From f016ed6def707f570d88f1e0284bceaf822a1f46 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Tue, 15 Apr 2025 20:00:52 +0000 Subject: Handle fsgen partitions of override apps fsgen uses `PartitionTag` to determine which autogenerated android_filesystem should be used to partition PRODUCT_PACKAGES. For most override modules, the *_specific properties are not set on the override modules, due to which such modules are currently listed in deps of the autogenerated sytem partition. This CL updates fsgen to move the override apps to the same partition as their base apps. Bug: 410570903 Test: m nothing --no-skip-soong-tests Test: lunch cf_x86_64_phone-trunk_staging-userdebug Test: m soong_generated_vendor_filesystem_test Before and after diffs https://diff.googleplex.com/#key=4C2OszgAl660 Change-Id: I57ff65a91b7ab85a46de8c3d146a14a9cfafd446 --- android/override_module.go | 2 ++ fsgen/filesystem_creator_test.go | 35 +++++++++++++++++++++++++++++++++++ fsgen/fsgen_mutators.go | 34 ++++++++++++++++++++++++++++------ 3 files changed, 65 insertions(+), 6 deletions(-) diff --git a/android/override_module.go b/android/override_module.go index 7552a57a6..8b0836e00 100644 --- a/android/override_module.go +++ b/android/override_module.go @@ -40,6 +40,8 @@ import ( type OverrideModule interface { Module + GetOverriddenModuleName() string + getOverridingProperties() []interface{} setOverridingProperties(properties []interface{}) diff --git a/fsgen/filesystem_creator_test.go b/fsgen/filesystem_creator_test.go index 06a8599d5..f8b81020e 100644 --- a/fsgen/filesystem_creator_test.go +++ b/fsgen/filesystem_creator_test.go @@ -669,3 +669,38 @@ func TestPrebuiltEtcModuleGen(t *testing.T) { }), ) } + +func TestPartitionOfOverrideModules(t *testing.T) { + result := android.GroupFixturePreparers( + android.PrepareForIntegrationTestWithAndroid, + android.PrepareForTestWithAndroidBuildComponents, + android.PrepareForTestWithAllowMissingDependencies, + prepareForTestWithFsgenBuildComponents, + java.PrepareForTestWithJavaBuildComponents, + prepareMockRamdiksNodeList, + android.FixtureMergeMockFs(android.MockFS{ + "external/avb/test/data/testkey_rsa4096.pem": nil, + "build/soong/fsgen/Android.bp": []byte(` + soong_filesystem_creator { + name: "foo", + } + `), + }), + android.FixtureModifyConfig(func(config android.Config) { + config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.ProductPackages = []string{"system_ext_app", "system_ext_override_app"} + }), + ).RunTestWithBp(t, ` +android_app { + name: "system_ext_app", + system_ext_specific: true, + platform_apis: true, +} +override_android_app { + name: "system_ext_override_app", + base: "system_ext_app", +} +`) + resolvedDeps := result.TestContext.Config().Get(fsGenStateOnceKey).(*FsGenState).fsDeps["system_ext"] + _, overrideAppInSystemExt := (*resolvedDeps)["system_ext_override_app"] + android.AssertBoolEquals(t, "Override app should be added to the same partition as the `base`", true, overrideAppInSystemExt) +} diff --git a/fsgen/fsgen_mutators.go b/fsgen/fsgen_mutators.go index 2565b009b..f45b8c5b3 100644 --- a/fsgen/fsgen_mutators.go +++ b/fsgen/fsgen_mutators.go @@ -26,7 +26,7 @@ import ( func RegisterCollectFileSystemDepsMutators(ctx android.RegisterMutatorsContext) { ctx.BottomUp("fs_collect_deps", collectDepsMutator).MutatesGlobalState() - ctx.BottomUp("fs_set_deps", setDepsMutator) + ctx.BottomUp("fs_set_deps", setDepsMutator).MutatesDependencies() } var fsGenStateOnceKey = android.NewOnceKey("FsGenState") @@ -218,8 +218,7 @@ func checkDepModuleInMultipleNamespaces(mctx android.BottomUpMutatorContext, fou } } -func appendDepIfAppropriate(mctx android.BottomUpMutatorContext, deps *multilibDeps, installPartition string, nbs android.NativeBridgeSupport) { - moduleName := mctx.ModuleName() +func appendDepIfAppropriate(mctx android.BottomUpMutatorContext, deps *multilibDeps, installPartition string, nbs android.NativeBridgeSupport, moduleName string) { checkDepModuleInMultipleNamespaces(mctx, *deps, moduleName, installPartition) if _, ok := (*deps)[moduleName]; ok { // Prefer the namespace-specific module over the platform module @@ -255,19 +254,19 @@ func collectDepsMutator(mctx android.BottomUpMutatorContext) { // - its enabled // - its namespace is included in PRODUCT_SOONG_NAMESPACES if m.Enabled(mctx) && m.ExportedToMake() { - appendDepIfAppropriate(mctx, fsGenState.fsDeps[installPartition], installPartition, android.NativeBridgeDisabled) + appendDepIfAppropriate(mctx, fsGenState.fsDeps[installPartition], installPartition, android.NativeBridgeDisabled, mctx.ModuleName()) } } if _, ok := fsGenState.depCandidatesMap[mctx.ModuleName()+".native_bridge"]; ok { installPartition := m.PartitionTag(mctx.DeviceConfig()) if m.Enabled(mctx) && m.ExportedToMake() { - appendDepIfAppropriate(mctx, fsGenState.fsDeps[installPartition], installPartition, android.NativeBridgeEnabled) + appendDepIfAppropriate(mctx, fsGenState.fsDeps[installPartition], installPartition, android.NativeBridgeEnabled, mctx.ModuleName()) } } else if _, ok := fsGenState.depCandidatesMap[mctx.ModuleName()+".bootstrap.native_bridge"]; ok { installPartition := m.PartitionTag(mctx.DeviceConfig()) if m.Enabled(mctx) && m.ExportedToMake() { - appendDepIfAppropriate(mctx, fsGenState.fsDeps[installPartition], installPartition, android.NativeBridgeEnabled) + appendDepIfAppropriate(mctx, fsGenState.fsDeps[installPartition], installPartition, android.NativeBridgeEnabled, mctx.ModuleName()) } } @@ -324,6 +323,7 @@ func getBitness(archTypes []android.ArchType) (ret []string) { func setDepsMutator(mctx android.BottomUpMutatorContext) { removeOverriddenDeps(mctx) + updatePartitionsOfOverrideModules(mctx) fsGenState := mctx.Config().Get(fsGenStateOnceKey).(*FsGenState) fsDeps := fsGenState.fsDeps m := mctx.Module() @@ -339,6 +339,28 @@ func setDepsMutator(mctx android.BottomUpMutatorContext) { } } +// Adds override apps (override_android_app, override_apex, ...) to the partition of their `base` apps. +func updatePartitionsOfOverrideModules(mctx android.BottomUpMutatorContext) { + fsGenState := mctx.Config().Get(fsGenStateOnceKey).(*FsGenState) + fsGenState.fsDepsMutex.Lock() + defer fsGenState.fsDepsMutex.Unlock() + if override, ok := mctx.Module().(android.OverrideModule); ok { + fsDeps := mctx.Config().Get(fsGenStateOnceKey).(*FsGenState).fsDeps + overridePartition := mctx.Module().PartitionTag(mctx.DeviceConfig()) + if _, ok := (*fsDeps[overridePartition])[mctx.Module().Name()]; !ok { + // The override module is not in PRODUCT_PACKAGES + return + } + base := override.GetOverriddenModuleName() + for partition, _ := range fsDeps { + if _, ok := (*fsDeps[partition])[base]; ok { + appendDepIfAppropriate(mctx, fsDeps[partition], partition, android.NativeBridgeDisabled, mctx.Module().Name()) + break + } + } + } +} + // removeOverriddenDeps collects PRODUCT_PACKAGES and (transitive) required deps. // it then removes any modules which appear in `overrides` of the above list. func removeOverriddenDeps(mctx android.BottomUpMutatorContext) { -- cgit v1.2.3 From 946a1df5f03186cfecdfb5e56f361bc887355743 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Tue, 15 Apr 2025 14:03:42 -0700 Subject: --include_descriptors_from_img uses same order as make Make always passes these flags in a certain order, and that order then gets encoded into the output file. Make soong-built vbmeta partitions match the order so that they're easier to compare against make-built vbmeta partitions. Bug: 390204058 Test: Compare ninja commands for make and soong built vbmeta.img Change-Id: Ic6b0810d8c9589a64ac1fae1492e381be4644fd8 --- filesystem/bootimg.go | 6 +++++ filesystem/vbmeta.go | 73 +++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 71 insertions(+), 8 deletions(-) diff --git a/filesystem/bootimg.go b/filesystem/bootimg.go index 485eae47c..06d493e75 100644 --- a/filesystem/bootimg.go +++ b/filesystem/bootimg.go @@ -227,6 +227,8 @@ func (b *bootimg) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Set the Filesystem info of the ramdisk dependency. // `android_device` will use this info to package `target_files.zip` + // TODO: Move this under BootimgInfo, as is, it's easy to confuse the bootImg module for + // the underlying ramdisk module. if ramdisk := proptools.String(b.properties.Ramdisk_module); ramdisk != "" { ramdiskModule := ctx.GetDirectDepWithTag(ramdisk, bootimgRamdiskDep) fsInfo, _ := android.OtherModuleProvider(ctx, ramdiskModule, FilesystemProvider) @@ -238,11 +240,13 @@ func (b *bootimg) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Set BootimgInfo for building target_files.zip dtbPath := b.getDtbPath(ctx) android.SetProvider(ctx, BootimgInfoProvider, BootimgInfo{ + Type: b.bootImageType, Cmdline: b.properties.Cmdline, Kernel: kernelPath, Dtb: dtbPath, Bootconfig: b.getBootconfigPath(ctx), Output: output, + SignedOutput: b.SignedOutputPath(), PropFileForMiscInfo: b.buildPropFileForMiscInfo(ctx), HeaderVersion: proptools.String(b.properties.Header_version), }) @@ -287,11 +291,13 @@ func (b *bootimg) GenerateAndroidBuildActions(ctx android.ModuleContext) { var BootimgInfoProvider = blueprint.NewProvider[BootimgInfo]() type BootimgInfo struct { + Type bootImageType Cmdline []string Kernel android.Path Dtb android.Path Bootconfig android.Path Output android.Path + SignedOutput android.Path PropFileForMiscInfo android.Path HeaderVersion string } diff --git a/filesystem/vbmeta.go b/filesystem/vbmeta.go index e7a39bef7..ac95988b5 100644 --- a/filesystem/vbmeta.go +++ b/filesystem/vbmeta.go @@ -16,6 +16,7 @@ package filesystem import ( "fmt" + "slices" "sort" "strconv" "strings" @@ -177,6 +178,30 @@ func (v *vbmeta) partitionName() string { // See external/avb/libavb/avb_slot_verify.c#VBMETA_MAX_SIZE const vbmetaMaxSize = 64 * 1024 +// This is the order that make listed the partitions in. The order is important because +// it ends up being encoded in the output file. Maintain the order so that the resultant +// files are easier to compare. +// https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile;l=4833;drc=a951ebf0198006f7fd38073a05c442d0eb92f97b +var includeDescriptorsFromImgOrder = []string{ + "boot", + "init_boot", + "vendor_boot", + "vendor_kernel_boot", + "system", + "vendor", + "product", + "system_ext", + "odm", + "vendor_dlkm", + "odm_dlkm", + "system_dlkm", + "dtbo", + "pvmfw", + "recovery", + "vbmeta_system", + "vbmeta_vendor", +} + func (v *vbmeta) GenerateAndroidBuildActions(ctx android.ModuleContext) { builder := android.NewRuleBuilder(pctx, ctx) cmd := builder.Command().BuiltTool("avbtool").Text("make_vbmeta_image") @@ -210,20 +235,52 @@ func (v *vbmeta) GenerateAndroidBuildActions(ctx android.ModuleContext) { cmd.FlagWithArg("--prop ", key+":"+value) } + type partitionWithName struct { + Name string + Output android.Path + } + var includeDescriptorsFromImages []partitionWithName for _, p := range ctx.GetDirectDepsWithTag(vbmetaPartitionDep) { - f, ok := p.(Filesystem) - if !ok { - ctx.PropertyErrorf("partitions", "%q(type: %s) is not supported", - p.Name(), ctx.OtherModuleType(p)) + bootImgInfo, ok := android.OtherModuleProvider(ctx, p, BootimgInfoProvider) + if ok { + includeDescriptorsFromImages = append(includeDescriptorsFromImages, partitionWithName{ + Name: bootImgInfo.Type.String(), + Output: bootImgInfo.SignedOutput, + }) continue } - signedImage := f.SignedOutputPath() - if signedImage == nil { - ctx.PropertyErrorf("partitions", "%q(type: %s) is not signed. Use `use_avb: true`", + + fsInfo, ok := android.OtherModuleProvider(ctx, p, FilesystemProvider) + if !ok { + ctx.PropertyErrorf("partitions", "%q(type: %s) is not supported, must be a filesystem", p.Name(), ctx.OtherModuleType(p)) continue } - cmd.FlagWithInput("--include_descriptors_from_image ", signedImage) + includeDescriptorsFromImages = append(includeDescriptorsFromImages, partitionWithName{ + Name: fsInfo.PartitionName, + Output: fsInfo.SignedOutputPath, + }) + } + + sort.SliceStable(includeDescriptorsFromImages, func(i, j int) bool { + iName := includeDescriptorsFromImages[i].Name + jName := includeDescriptorsFromImages[j].Name + iIndex := slices.Index(includeDescriptorsFromImgOrder, iName) + jIndex := slices.Index(includeDescriptorsFromImgOrder, jName) + if iIndex < 0 && jIndex < 0 { + return iName < jName + } + if iIndex < 0 { + return false + } + if jIndex < 0 { + return true + } + return iIndex < jIndex + }) + + for _, partition := range includeDescriptorsFromImages { + cmd.FlagWithInput("--include_descriptors_from_image ", partition.Output) } seenRils := make(map[int]bool) -- cgit v1.2.3 From b357849f8d9e7bb483b1548a68e495678441ca56 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Tue, 15 Apr 2025 16:11:07 -0700 Subject: Revert "Handle fsgen partitions of override apps" This reverts commit f016ed6def707f570d88f1e0284bceaf822a1f46. Reason for revert: Race condition deteced Change-Id: I90ecbdeede4eb1b66bfde56b08c1e69f0b536a17 --- android/override_module.go | 2 -- fsgen/filesystem_creator_test.go | 35 ----------------------------------- fsgen/fsgen_mutators.go | 34 ++++++---------------------------- 3 files changed, 6 insertions(+), 65 deletions(-) diff --git a/android/override_module.go b/android/override_module.go index 8b0836e00..7552a57a6 100644 --- a/android/override_module.go +++ b/android/override_module.go @@ -40,8 +40,6 @@ import ( type OverrideModule interface { Module - GetOverriddenModuleName() string - getOverridingProperties() []interface{} setOverridingProperties(properties []interface{}) diff --git a/fsgen/filesystem_creator_test.go b/fsgen/filesystem_creator_test.go index f8b81020e..06a8599d5 100644 --- a/fsgen/filesystem_creator_test.go +++ b/fsgen/filesystem_creator_test.go @@ -669,38 +669,3 @@ func TestPrebuiltEtcModuleGen(t *testing.T) { }), ) } - -func TestPartitionOfOverrideModules(t *testing.T) { - result := android.GroupFixturePreparers( - android.PrepareForIntegrationTestWithAndroid, - android.PrepareForTestWithAndroidBuildComponents, - android.PrepareForTestWithAllowMissingDependencies, - prepareForTestWithFsgenBuildComponents, - java.PrepareForTestWithJavaBuildComponents, - prepareMockRamdiksNodeList, - android.FixtureMergeMockFs(android.MockFS{ - "external/avb/test/data/testkey_rsa4096.pem": nil, - "build/soong/fsgen/Android.bp": []byte(` - soong_filesystem_creator { - name: "foo", - } - `), - }), - android.FixtureModifyConfig(func(config android.Config) { - config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.ProductPackages = []string{"system_ext_app", "system_ext_override_app"} - }), - ).RunTestWithBp(t, ` -android_app { - name: "system_ext_app", - system_ext_specific: true, - platform_apis: true, -} -override_android_app { - name: "system_ext_override_app", - base: "system_ext_app", -} -`) - resolvedDeps := result.TestContext.Config().Get(fsGenStateOnceKey).(*FsGenState).fsDeps["system_ext"] - _, overrideAppInSystemExt := (*resolvedDeps)["system_ext_override_app"] - android.AssertBoolEquals(t, "Override app should be added to the same partition as the `base`", true, overrideAppInSystemExt) -} diff --git a/fsgen/fsgen_mutators.go b/fsgen/fsgen_mutators.go index f45b8c5b3..2565b009b 100644 --- a/fsgen/fsgen_mutators.go +++ b/fsgen/fsgen_mutators.go @@ -26,7 +26,7 @@ import ( func RegisterCollectFileSystemDepsMutators(ctx android.RegisterMutatorsContext) { ctx.BottomUp("fs_collect_deps", collectDepsMutator).MutatesGlobalState() - ctx.BottomUp("fs_set_deps", setDepsMutator).MutatesDependencies() + ctx.BottomUp("fs_set_deps", setDepsMutator) } var fsGenStateOnceKey = android.NewOnceKey("FsGenState") @@ -218,7 +218,8 @@ func checkDepModuleInMultipleNamespaces(mctx android.BottomUpMutatorContext, fou } } -func appendDepIfAppropriate(mctx android.BottomUpMutatorContext, deps *multilibDeps, installPartition string, nbs android.NativeBridgeSupport, moduleName string) { +func appendDepIfAppropriate(mctx android.BottomUpMutatorContext, deps *multilibDeps, installPartition string, nbs android.NativeBridgeSupport) { + moduleName := mctx.ModuleName() checkDepModuleInMultipleNamespaces(mctx, *deps, moduleName, installPartition) if _, ok := (*deps)[moduleName]; ok { // Prefer the namespace-specific module over the platform module @@ -254,19 +255,19 @@ func collectDepsMutator(mctx android.BottomUpMutatorContext) { // - its enabled // - its namespace is included in PRODUCT_SOONG_NAMESPACES if m.Enabled(mctx) && m.ExportedToMake() { - appendDepIfAppropriate(mctx, fsGenState.fsDeps[installPartition], installPartition, android.NativeBridgeDisabled, mctx.ModuleName()) + appendDepIfAppropriate(mctx, fsGenState.fsDeps[installPartition], installPartition, android.NativeBridgeDisabled) } } if _, ok := fsGenState.depCandidatesMap[mctx.ModuleName()+".native_bridge"]; ok { installPartition := m.PartitionTag(mctx.DeviceConfig()) if m.Enabled(mctx) && m.ExportedToMake() { - appendDepIfAppropriate(mctx, fsGenState.fsDeps[installPartition], installPartition, android.NativeBridgeEnabled, mctx.ModuleName()) + appendDepIfAppropriate(mctx, fsGenState.fsDeps[installPartition], installPartition, android.NativeBridgeEnabled) } } else if _, ok := fsGenState.depCandidatesMap[mctx.ModuleName()+".bootstrap.native_bridge"]; ok { installPartition := m.PartitionTag(mctx.DeviceConfig()) if m.Enabled(mctx) && m.ExportedToMake() { - appendDepIfAppropriate(mctx, fsGenState.fsDeps[installPartition], installPartition, android.NativeBridgeEnabled, mctx.ModuleName()) + appendDepIfAppropriate(mctx, fsGenState.fsDeps[installPartition], installPartition, android.NativeBridgeEnabled) } } @@ -323,7 +324,6 @@ func getBitness(archTypes []android.ArchType) (ret []string) { func setDepsMutator(mctx android.BottomUpMutatorContext) { removeOverriddenDeps(mctx) - updatePartitionsOfOverrideModules(mctx) fsGenState := mctx.Config().Get(fsGenStateOnceKey).(*FsGenState) fsDeps := fsGenState.fsDeps m := mctx.Module() @@ -339,28 +339,6 @@ func setDepsMutator(mctx android.BottomUpMutatorContext) { } } -// Adds override apps (override_android_app, override_apex, ...) to the partition of their `base` apps. -func updatePartitionsOfOverrideModules(mctx android.BottomUpMutatorContext) { - fsGenState := mctx.Config().Get(fsGenStateOnceKey).(*FsGenState) - fsGenState.fsDepsMutex.Lock() - defer fsGenState.fsDepsMutex.Unlock() - if override, ok := mctx.Module().(android.OverrideModule); ok { - fsDeps := mctx.Config().Get(fsGenStateOnceKey).(*FsGenState).fsDeps - overridePartition := mctx.Module().PartitionTag(mctx.DeviceConfig()) - if _, ok := (*fsDeps[overridePartition])[mctx.Module().Name()]; !ok { - // The override module is not in PRODUCT_PACKAGES - return - } - base := override.GetOverriddenModuleName() - for partition, _ := range fsDeps { - if _, ok := (*fsDeps[partition])[base]; ok { - appendDepIfAppropriate(mctx, fsDeps[partition], partition, android.NativeBridgeDisabled, mctx.Module().Name()) - break - } - } - } -} - // removeOverriddenDeps collects PRODUCT_PACKAGES and (transitive) required deps. // it then removes any modules which appear in `overrides` of the above list. func removeOverriddenDeps(mctx android.BottomUpMutatorContext) { -- cgit v1.2.3 From c905ff60c2d5528c95acc61cb8687a0804e6ce4a Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Tue, 15 Apr 2025 17:28:00 -0700 Subject: Don't copy images to target-files.zip add_img_to_target_files will build the images again from the files that are already in target-files.zip. When it does so, it sets a fixed timestamp for the file mtimes so that they're hermetic. We were also doing that in the filesystem modules, but we weren't doing it for the vbmeta modules, causing a mismatch and a boot failure. Bug: 376727180 Test: ./verify_img_zip.sh out/soong/.intermediates/build/soong/fsgen/aosp_cf_x86_64_only_phone_generated_device/android_x86_64_silvermont/img.zip where verify_img_zip.sh is: ``` tempdir=$(mktemp -d) unzip $1 -d ${tempdir} ( cd ${tempdir} simg2img super.img super_unsparse.img lpunpack super_unsparse.img for i in *_a.img; do cp ${i} ${i/_a.img/.img} done avbtool verify_image --image vbmeta.img --follow_chain_partitions ) ``` Change-Id: I80c45f16fddc4f737bb95164214014235faf3da7 --- filesystem/android_device.go | 55 ++++++++------------------------------------ 1 file changed, 9 insertions(+), 46 deletions(-) diff --git a/filesystem/android_device.go b/filesystem/android_device.go index 57b75f4e3..939efa873 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -633,7 +633,10 @@ func (a *androidDevice) buildTargetFilesZip(ctx android.ModuleContext, allInstal } if a.partitionProps.Boot_partition_name != nil { bootImg := ctx.GetDirectDepProxyWithTag(proptools.String(a.partitionProps.Boot_partition_name), filesystemDepTag) - bootImgInfo, _ := android.OtherModuleProvider(ctx, bootImg, BootimgInfoProvider) + bootImgInfo, ok := android.OtherModuleProvider(ctx, bootImg, BootimgInfoProvider) + if !ok { + ctx.PropertyErrorf("boot_partition_name", "Expected a BootimgInfoProvider") + } builder.Command().Textf("echo %s > %s/BOOT/cmdline", proptools.ShellEscape(strings.Join(bootImgInfo.Cmdline, " ")), targetFilesDir) if bootImgInfo.Dtb != nil { builder.Command().Textf("cp ").Input(bootImgInfo.Dtb).Textf(" %s/BOOT/dtb", targetFilesDir) @@ -653,7 +656,11 @@ func (a *androidDevice) buildTargetFilesZip(ctx android.ModuleContext, allInstal builder.Command().Textf("cp ").Input(android.PathForModuleSrc(ctx, *a.deviceProps.Android_info)).Textf(" %s/OTA/android-info.txt", targetFilesDir) } - a.copyImagesToTargetZip(ctx, builder, targetFilesDir) + builder.Command().Textf("mkdir -p %s/IMAGES", targetFilesDir.String()) + if a.deviceProps.Bootloader != nil { + builder.Command().Textf("cp ").Input(android.PathForModuleSrc(ctx, proptools.String(a.deviceProps.Bootloader))).Textf(" %s/IMAGES/bootloader", targetFilesDir.String()) + } + a.copyMetadataToTargetZip(ctx, builder, targetFilesDir, allInstalledModules) a.targetFilesZip = targetFilesZip @@ -692,50 +699,6 @@ func (a *androidDevice) buildTargetFilesZip(ctx android.ModuleContext, allInstal builder.Build("target_files_"+ctx.ModuleName(), "Build target_files.zip") } -func (a *androidDevice) copyImagesToTargetZip(ctx android.ModuleContext, builder *android.RuleBuilder, targetFilesDir android.WritablePath) { - // Create an IMAGES/ subdirectory - builder.Command().Textf("mkdir -p %s/IMAGES", targetFilesDir.String()) - if a.deviceProps.Bootloader != nil { - builder.Command().Textf("cp ").Input(android.PathForModuleSrc(ctx, proptools.String(a.deviceProps.Bootloader))).Textf(" %s/IMAGES/bootloader", targetFilesDir.String()) - } - // Copy the filesystem ,boot and vbmeta img files to IMAGES/ - ctx.VisitDirectDepsProxyWithTag(filesystemDepTag, func(child android.ModuleProxy) { - if strings.Contains(child.Name(), "recovery") { - return // skip recovery.img to match the make packaging behavior - } - if info, ok := android.OtherModuleProvider(ctx, child, BootimgInfoProvider); ok { - // Check Boot img first so that the boot.img is copied and not its dep ramdisk.img - builder.Command().Textf("cp ").Input(info.Output).Textf(" %s/IMAGES/", targetFilesDir.String()) - } else if info, ok := android.OtherModuleProvider(ctx, child, FilesystemProvider); ok { - builder.Command().Textf("cp ").Input(info.Output).Textf(" %s/IMAGES/", targetFilesDir.String()) - } else if info, ok := android.OtherModuleProvider(ctx, child, vbmetaPartitionProvider); ok { - builder.Command().Textf("cp ").Input(info.Output).Textf(" %s/IMAGES/", targetFilesDir.String()) - } else { - ctx.ModuleErrorf("Module %s does not provide an .img file output for target_files.zip", child.Name()) - } - }) - - 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.SortedKeys(info.SubImageInfo) { - if info.SubImageInfo[partition].OutputHermetic != nil { - builder.Command().Textf("cp ").Input(info.SubImageInfo[partition].OutputHermetic).Textf(" %s/IMAGES/", targetFilesDir.String()) - } - if info.SubImageInfo[partition].MapFile != nil { - builder.Command().Textf("cp ").Input(info.SubImageInfo[partition].MapFile).Textf(" %s/IMAGES/", targetFilesDir.String()) - } - } - // super_empty.img - if info.SuperEmptyImage != nil { - builder.Command().Textf("cp ").Input(info.SuperEmptyImage).Textf(" %s/IMAGES/", targetFilesDir.String()) - } - } else { - ctx.ModuleErrorf("Super partition %s does set SuperImageProvider\n", superPartition.Name()) - } - } -} - func writeFileWithNewLines(ctx android.ModuleContext, path android.WritablePath, contents []string) { builder := &strings.Builder{} for i, content := range contents { -- cgit v1.2.3 From 634ea6e97f61093b7c9227f61cf06f8ba37313fa Mon Sep 17 00:00:00 2001 From: Yi Kong Date: Fri, 7 Mar 2025 13:28:20 -0800 Subject: Upgrade clang to clang-r563880 Two new warnings suppressed. With llvm commit c6f3b7bcd0, _LIBCPP_HAS_THREAD_API_WIN32 is now defined. Updated the macro to the same value. The default mcpu option for BPF was bumped to v3 in upstream. Explicitly set the version to v1. MLGO inliner model is updated to a mixed v3 model. Add flags to select the model trained for ARM64. Test: presubmit Bug: 401330760 Bug: 395154089 Change-Id: I23eb9e3f98403593a050aa708115317b644f5914 --- bpf/bpf.go | 2 +- cc/compiler.go | 5 ++++- cc/config/global.go | 7 +++++-- cc/stl.go | 2 +- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/bpf/bpf.go b/bpf/bpf.go index deb465dd6..b0be3e788 100644 --- a/bpf/bpf.go +++ b/bpf/bpf.go @@ -41,7 +41,7 @@ var ( blueprint.RuleParams{ Depfile: "${out}.d", Deps: blueprint.DepsGCC, - Command: "$relPwd $ccCmd --target=bpf -c $cFlags -MD -MF ${out}.d -o $out $in", + Command: "$relPwd $ccCmd --target=bpf -mcpu=v1 -c $cFlags -MD -MF ${out}.d -o $out $in", CommandDeps: []string{"$ccCmd"}, }, "ccCmd", "cFlags") diff --git a/cc/compiler.go b/cc/compiler.go index 949603e40..316cd9e1d 100644 --- a/cc/compiler.go +++ b/cc/compiler.go @@ -711,7 +711,10 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps if ctx.optimizeForSize() { flags.Local.CFlags = append(flags.Local.CFlags, "-Oz") if !ctx.Config().IsEnvFalse("THINLTO_USE_MLGO") { - flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-mllvm,-enable-ml-inliner=release") + if ctx.Arch().ArchType == android.Arm64 { + flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-mllvm,-enable-ml-inliner=release") + flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-mllvm,-ml-inliner-model-selector=arm64-mixed") + } } } diff --git a/cc/config/global.go b/cc/config/global.go index e81ac0d47..b91697ded 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -292,6 +292,9 @@ var ( "-Wno-error=deprecated", // in external/googletest/googletest // New warnings to be fixed after clang-r522817 "-Wno-error=invalid-offsetof", + // New warnings to be fixed after clang-r563880 + "-Wno-nontrivial-memcall", + "-Wno-invalid-specialization", // Allow using VLA CXX extension. "-Wno-vla-cxx-extension", @@ -385,8 +388,8 @@ var ( // prebuilts/clang default settings. ClangDefaultBase = "prebuilts/clang/host" - ClangDefaultVersion = "clang-r547379" - ClangDefaultShortVersion = "20" + ClangDefaultVersion = "clang-r563880" + ClangDefaultShortVersion = "21" // Directories with warnings from Android.bp files. WarningAllowedProjects = []string{ diff --git a/cc/stl.go b/cc/stl.go index 8c4ef0b4a..b91a1f1f5 100644 --- a/cc/stl.go +++ b/cc/stl.go @@ -212,7 +212,7 @@ func (stl *stl) flags(ctx ModuleContext, flags Flags) Flags { "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS=", "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS=", // Use Win32 threads in libc++. - "-D_LIBCPP_HAS_THREAD_API_WIN32=") + "-D_LIBCPP_HAS_THREAD_API_WIN32=1") } } case "libstdc++": -- cgit v1.2.3 From a52b89f8abfbc00d0c952caab8d4fdf5a0483121 Mon Sep 17 00:00:00 2001 From: "Chaitanya Cheemala (xWF)" Date: Wed, 16 Apr 2025 03:08:48 -0700 Subject: Revert^2 "apex: Do not compress EROFS APEX" 759f9f7c474b20832ce3477dd9e1668eaa878b26 Change-Id: Ibc462f18dc9b88f36db4c69c1d7d159ceb65049f --- apex/apex.go | 8 +++++++- apex/apex_test.go | 28 ++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/apex/apex.go b/apex/apex.go index 0634b69e6..17c2884bc 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -1733,7 +1733,13 @@ func (a *apexBundle) setPayloadFsType(ctx android.ModuleContext) { } func (a *apexBundle) isCompressable() bool { - return proptools.BoolDefault(a.overridableProperties.Compressible, false) && !a.testApex + if a.testApex { + return false + } + if a.payloadFsType == erofs { + return false + } + return proptools.Bool(a.overridableProperties.Compressible) } func (a *apexBundle) commonBuildActions(ctx android.ModuleContext) bool { diff --git a/apex/apex_test.go b/apex/apex_test.go index 41de1a460..880d0014a 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -9325,6 +9325,34 @@ func TestCompressedApex_NonUpdatable(t *testing.T) { `) } +func TestCompressedApexIsDisabledWhenUsingErofs(t *testing.T) { + t.Parallel() + ctx := testApex(t, ` + apex { + name: "myapex", + key: "myapex.key", + compressible: true, + updatable: true, + min_sdk_version: "29", + payload_fs_type: "erofs", + } + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + `, + android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.CompressedApex = proptools.BoolPtr(true) + }), + ) + + compressRule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").MaybeRule("compressRule") + if compressRule.Rule != nil { + t.Error("erofs apex should not be compressed") + } +} + func TestApexSet_ShouldRespectCompressedApexFlag(t *testing.T) { t.Parallel() for _, compressionEnabled := range []bool{true, false} { -- cgit v1.2.3 From 94bfe5f6b929ba53be5a51d286d3170bbaec003b Mon Sep 17 00:00:00 2001 From: Jan Chmura Date: Wed, 16 Apr 2025 09:38:27 -0700 Subject: Fix rust_protobuf grpc_protos build Issue being protobuf::well_known_types::wrappers is not available in gRPC generated code, thus it failed to compile `grpc_protos` To solve this I added it as public module to `source_stem` file. Buganizer: 406463925 (cherry picked from https://partner-android-review.googlesource.com/q/commit:2dfaf7c2f94e64b34a773c20a8bf2b8694b6de1a) Merged-In: Ia9b0c1d88dc4bf22fc512a44b5ee9a008f8ddfb1 Change-Id: Ia9b0c1d88dc4bf22fc512a44b5ee9a008f8ddfb1 --- rust/protobuf.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rust/protobuf.go b/rust/protobuf.go index fab5259a5..b2ce4d867 100644 --- a/rust/protobuf.go +++ b/rust/protobuf.go @@ -227,6 +227,9 @@ func (proto *protobufDecorator) genModFileContents() string { lines, "pub mod empty {", " pub use protobuf::well_known_types::empty::Empty;", + "}", + "pub mod wrappers {", + " pub use protobuf::well_known_types::wrappers::*;", "}") } -- cgit v1.2.3 From 8706404dd1020abb9df2e3abb541ea2f17dd2b50 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Wed, 16 Apr 2025 01:16:20 +0000 Subject: Reapply "Handle fsgen partitions of override apps" This reverts commit b357849f8d9e7bb483b1548a68e495678441ca56. To avoid race conditions, a new mutator has been added. - It will run after collect_deps, allowing the override module to know the partition of its base module from fsGenState - It will run before set_deps, ensuring that the override modules have been added to fsGenState before the appendDeps operation on the autogenerated partitions Test: go clean -cache Test: go test ./fsgen -race Change-Id: Ia8e7b7c8b40ee4dffd2984bc79e4612a59db3e53 --- android/override_module.go | 2 ++ fsgen/filesystem_creator_test.go | 35 +++++++++++++++++++++++++++++++++++ fsgen/fsgen_mutators.go | 36 +++++++++++++++++++++++++++++++----- 3 files changed, 68 insertions(+), 5 deletions(-) diff --git a/android/override_module.go b/android/override_module.go index 7552a57a6..8b0836e00 100644 --- a/android/override_module.go +++ b/android/override_module.go @@ -40,6 +40,8 @@ import ( type OverrideModule interface { Module + GetOverriddenModuleName() string + getOverridingProperties() []interface{} setOverridingProperties(properties []interface{}) diff --git a/fsgen/filesystem_creator_test.go b/fsgen/filesystem_creator_test.go index 06a8599d5..f8b81020e 100644 --- a/fsgen/filesystem_creator_test.go +++ b/fsgen/filesystem_creator_test.go @@ -669,3 +669,38 @@ func TestPrebuiltEtcModuleGen(t *testing.T) { }), ) } + +func TestPartitionOfOverrideModules(t *testing.T) { + result := android.GroupFixturePreparers( + android.PrepareForIntegrationTestWithAndroid, + android.PrepareForTestWithAndroidBuildComponents, + android.PrepareForTestWithAllowMissingDependencies, + prepareForTestWithFsgenBuildComponents, + java.PrepareForTestWithJavaBuildComponents, + prepareMockRamdiksNodeList, + android.FixtureMergeMockFs(android.MockFS{ + "external/avb/test/data/testkey_rsa4096.pem": nil, + "build/soong/fsgen/Android.bp": []byte(` + soong_filesystem_creator { + name: "foo", + } + `), + }), + android.FixtureModifyConfig(func(config android.Config) { + config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.ProductPackages = []string{"system_ext_app", "system_ext_override_app"} + }), + ).RunTestWithBp(t, ` +android_app { + name: "system_ext_app", + system_ext_specific: true, + platform_apis: true, +} +override_android_app { + name: "system_ext_override_app", + base: "system_ext_app", +} +`) + resolvedDeps := result.TestContext.Config().Get(fsGenStateOnceKey).(*FsGenState).fsDeps["system_ext"] + _, overrideAppInSystemExt := (*resolvedDeps)["system_ext_override_app"] + android.AssertBoolEquals(t, "Override app should be added to the same partition as the `base`", true, overrideAppInSystemExt) +} diff --git a/fsgen/fsgen_mutators.go b/fsgen/fsgen_mutators.go index 2565b009b..67f0cd78c 100644 --- a/fsgen/fsgen_mutators.go +++ b/fsgen/fsgen_mutators.go @@ -26,6 +26,7 @@ import ( func RegisterCollectFileSystemDepsMutators(ctx android.RegisterMutatorsContext) { ctx.BottomUp("fs_collect_deps", collectDepsMutator).MutatesGlobalState() + ctx.BottomUp("fs_remove_deps", removeDepsMutator).MutatesGlobalState() ctx.BottomUp("fs_set_deps", setDepsMutator) } @@ -218,8 +219,7 @@ func checkDepModuleInMultipleNamespaces(mctx android.BottomUpMutatorContext, fou } } -func appendDepIfAppropriate(mctx android.BottomUpMutatorContext, deps *multilibDeps, installPartition string, nbs android.NativeBridgeSupport) { - moduleName := mctx.ModuleName() +func appendDepIfAppropriate(mctx android.BottomUpMutatorContext, deps *multilibDeps, installPartition string, nbs android.NativeBridgeSupport, moduleName string) { checkDepModuleInMultipleNamespaces(mctx, *deps, moduleName, installPartition) if _, ok := (*deps)[moduleName]; ok { // Prefer the namespace-specific module over the platform module @@ -255,19 +255,19 @@ func collectDepsMutator(mctx android.BottomUpMutatorContext) { // - its enabled // - its namespace is included in PRODUCT_SOONG_NAMESPACES if m.Enabled(mctx) && m.ExportedToMake() { - appendDepIfAppropriate(mctx, fsGenState.fsDeps[installPartition], installPartition, android.NativeBridgeDisabled) + appendDepIfAppropriate(mctx, fsGenState.fsDeps[installPartition], installPartition, android.NativeBridgeDisabled, mctx.ModuleName()) } } if _, ok := fsGenState.depCandidatesMap[mctx.ModuleName()+".native_bridge"]; ok { installPartition := m.PartitionTag(mctx.DeviceConfig()) if m.Enabled(mctx) && m.ExportedToMake() { - appendDepIfAppropriate(mctx, fsGenState.fsDeps[installPartition], installPartition, android.NativeBridgeEnabled) + appendDepIfAppropriate(mctx, fsGenState.fsDeps[installPartition], installPartition, android.NativeBridgeEnabled, mctx.ModuleName()) } } else if _, ok := fsGenState.depCandidatesMap[mctx.ModuleName()+".bootstrap.native_bridge"]; ok { installPartition := m.PartitionTag(mctx.DeviceConfig()) if m.Enabled(mctx) && m.ExportedToMake() { - appendDepIfAppropriate(mctx, fsGenState.fsDeps[installPartition], installPartition, android.NativeBridgeEnabled) + appendDepIfAppropriate(mctx, fsGenState.fsDeps[installPartition], installPartition, android.NativeBridgeEnabled, mctx.ModuleName()) } } @@ -322,6 +322,13 @@ func getBitness(archTypes []android.ArchType) (ret []string) { return ret } +func removeDepsMutator(mctx android.BottomUpMutatorContext) { + fsGenState := mctx.Config().Get(fsGenStateOnceKey).(*FsGenState) + fsGenState.fsDepsMutex.Lock() + defer fsGenState.fsDepsMutex.Unlock() + updatePartitionsOfOverrideModules(mctx) +} + func setDepsMutator(mctx android.BottomUpMutatorContext) { removeOverriddenDeps(mctx) fsGenState := mctx.Config().Get(fsGenStateOnceKey).(*FsGenState) @@ -339,6 +346,25 @@ func setDepsMutator(mctx android.BottomUpMutatorContext) { } } +// Adds override apps (override_android_app, override_apex, ...) to the partition of their `base` apps. +func updatePartitionsOfOverrideModules(mctx android.BottomUpMutatorContext) { + if override, ok := mctx.Module().(android.OverrideModule); ok { + fsDeps := mctx.Config().Get(fsGenStateOnceKey).(*FsGenState).fsDeps + overridePartition := mctx.Module().PartitionTag(mctx.DeviceConfig()) + if _, ok := (*fsDeps[overridePartition])[mctx.Module().Name()]; !ok { + // The override module is not in PRODUCT_PACKAGES + return + } + base := override.GetOverriddenModuleName() + for partition, _ := range fsDeps { + if _, ok := (*fsDeps[partition])[base]; ok { + appendDepIfAppropriate(mctx, fsDeps[partition], partition, android.NativeBridgeDisabled, mctx.Module().Name()) + break + } + } + } +} + // removeOverriddenDeps collects PRODUCT_PACKAGES and (transitive) required deps. // it then removes any modules which appear in `overrides` of the above list. func removeOverriddenDeps(mctx android.BottomUpMutatorContext) { -- cgit v1.2.3 From ca21c78ea4b8dba9c066b361e127047d3eb9eb22 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Wed, 16 Apr 2025 09:58:16 -0700 Subject: Remove test suite phonies These were added so CI wouldn't error out in soong-only builds when the test suites didn't exist yet in soong-only, but now they do. Bug: 376727180 Test: Presubmits Change-Id: Ia111801c05db869f60defb6bbc169e9d2b43ba1e --- filesystem/android_device_product_out.go | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/filesystem/android_device_product_out.go b/filesystem/android_device_product_out.go index aa06337ca..15c547350 100644 --- a/filesystem/android_device_product_out.go +++ b/filesystem/android_device_product_out.go @@ -183,17 +183,6 @@ func (a *androidDevice) copyFilesToProductOutForSoongOnly(ctx android.ModuleCont Implicits: deps, }) - emptyFile := android.PathForModuleOut(ctx, "empty_file") - android.WriteFileRule(ctx, emptyFile, "") - - // TODO: We don't have these tests building in soong yet. Add phonies for them so that CI builds - // that try to build them don't error out. - ctx.Phony("continuous_instrumentation_tests", emptyFile) - ctx.Phony("continuous_native_tests", emptyFile) - ctx.Phony("device-tests", emptyFile) - ctx.Phony("device-platinum-tests", emptyFile) - ctx.Phony("platform_tests", emptyFile) - return copyToProductOutTimestamp } -- cgit v1.2.3 From 3e1cb65c6d5df618ead29cf53163dd340c2833ea Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Tue, 15 Apr 2025 22:52:39 +0000 Subject: Add impl and header jars to checkbuild of DeviceForHost/HostForDevice The impl and header jars of java_device_for_host and java_host_for_device are in the transitive closure of the phony $(module_name) target in Make builds. soong_java_prebuilt.mk adds them to deps of LOCAL_BUILT_MODULE which is itself added to deps of the phony (host|target)_$(module_name)_all_targets. These jars are currently not in the transitive closure of $(module_name) in soong only builds due to which building such modules in `m --soong-only` mode does not build anything. This CL fixes it by adding these jars to checkbuild. Bug: 410693901 Test: lunch aosp_cf_x86_64_phone-trunk_staging-userdebug (soong-only turned on by default) Test: m nothing Test: aninja -t path robolectric_android-all-device-deps out/soong/.intermediates/external/robolectric/robolectric_android-all-device-deps/linux_glibc_common/combined/robolectric_android-all-device-deps.jar (verified path exists) Change-Id: If4152070eb3399d34734abd5ac4d888ee9a3beff --- java/device_host_converter.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/java/device_host_converter.go b/java/device_host_converter.go index 04def3e28..2c2ef4cc1 100644 --- a/java/device_host_converter.go +++ b/java/device_host_converter.go @@ -158,6 +158,14 @@ func (d *DeviceHostConverter) GenerateAndroidBuildActions(ctx android.ModuleCont setExtraJavaInfo(ctx, d, javaInfo) android.SetProvider(ctx, JavaInfoProvider, javaInfo) + if ctx.Os() != android.Windows { // Make does not support Windows Java modules + if d.combinedImplementationJar != nil { + ctx.CheckbuildFile(d.combinedImplementationJar) + } + if d.combinedHeaderJar != nil { + ctx.CheckbuildFile(d.combinedHeaderJar) + } + } } func (d *DeviceHostConverter) HeaderJars() android.Paths { -- cgit v1.2.3 From 0df459ed243cc19786cbd6aee9c459773e5a7d88 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Wed, 16 Apr 2025 10:53:22 -0700 Subject: Remove "hermetic" filesystem builds As of ag/33085781, these are now built by the add_img_to_target_files script. Soong doesn't need to build them anymore. Bug: 376727180 Test: Presubmits Change-Id: Iaac2c081e6679e2781518dc7a4c3d7a146369085 --- filesystem/filesystem.go | 31 ------------------------------- filesystem/system_other.go | 25 ------------------------- 2 files changed, 56 deletions(-) diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index 64bf139b0..44e562a53 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -417,10 +417,6 @@ type FilesystemInfo struct { // 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 - OutputHermetic android.Path // A text file containing the list of paths installed on the partition. FileListFile android.Path // The root staging directory used to build the output filesystem. If consuming this, make sure @@ -435,9 +431,6 @@ type FilesystemInfo struct { // in ninja. In many cases this is the same as RootDir, only in the system partition is it // different. There, it points to the "system" sub-directory of RootDir. RebasedDir android.Path - // A text file with block data of the .img file - // This is an implicit output of `build_image` - MapFile android.Path // Name of the module that produced this FilesystemInfo origionally. (though it may be // re-exported by super images or boot images) ModuleName string @@ -658,8 +651,6 @@ func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Create a new rule builder for build_image builder = android.NewRuleBuilder(pctx, ctx) - var mapFile android.Path - var outputHermetic android.WritablePath var buildImagePropFile android.Path var buildImagePropFileDeps android.Paths var extraRootDirs android.Paths @@ -671,12 +662,6 @@ func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) { output := android.PathForModuleOut(ctx, f.installFileName()) f.buildImageUsingBuildImage(ctx, builder, buildImageParams{rootDir, buildImagePropFile, buildImagePropFileDeps, output}) f.output = output - // Create the hermetic img file using a separate rule builder so that it can be built independently - hermeticBuilder := android.NewRuleBuilder(pctx, ctx) - outputHermetic = android.PathForModuleOut(ctx, "for_target_files", f.installFileName()) - propFileHermetic := f.propFileForHermeticImg(ctx, hermeticBuilder, buildImagePropFile) - f.buildImageUsingBuildImage(ctx, hermeticBuilder, buildImageParams{rootDir, propFileHermetic, buildImagePropFileDeps, outputHermetic}) - mapFile = f.getMapFile(ctx) case compressedCpioType: f.output, extraRootDirs = f.buildCpioImage(ctx, builder, rootDir, true) case cpioType: @@ -737,12 +722,10 @@ func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) { fsInfo := FilesystemInfo{ Output: f.OutputPath(), SignedOutputPath: f.SignedOutputPath(), - OutputHermetic: outputHermetic, FileListFile: fileListFile, RootDir: rootDir, ExtraRootDirs: extraRootDirs, RebasedDir: rebasedDir, - MapFile: mapFile, ModuleName: ctx.ModuleName(), BuildImagePropFile: buildImagePropFile, BuildImagePropFileDeps: buildImagePropFileDeps, @@ -864,11 +847,6 @@ func (f *filesystem) setVbmetaPartitionProvider(ctx android.ModuleContext) { }) } -func (f *filesystem) getMapFile(ctx android.ModuleContext) android.WritablePath { - // create the filepath by replacing the extension of the corresponding img file - return android.PathForModuleOut(ctx, f.installFileName()).ReplaceExtension(ctx, "map") -} - func (f *filesystem) validateVintfFragments(ctx android.ModuleContext) { visitedModule := map[string]bool{} packagingSpecs := f.gatherFilteredPackagingSpecs(ctx) @@ -1096,15 +1074,6 @@ func (f *filesystem) buildImageUsingBuildImage( builder.Build("build_"+params.output.String(), fmt.Sprintf("Creating filesystem %s", f.BaseModuleName())) } -func (f *filesystem) propFileForHermeticImg(ctx android.ModuleContext, builder *android.RuleBuilder, inputPropFile android.Path) android.Path { - propFilePinnedTimestamp := android.PathForModuleOut(ctx, "for_target_files", "prop") - builder.Command().Textf("cat").Input(inputPropFile).Flag(">").Output(propFilePinnedTimestamp). - Textf(" && echo use_fixed_timestamp=true >> %s", propFilePinnedTimestamp). - Textf(" && echo block_list=%s >> %s", f.getMapFile(ctx).String(), propFilePinnedTimestamp) // mapfile will be an implicit output - builder.Command().Text("touch").Output(f.getMapFile(ctx)) - return propFilePinnedTimestamp -} - func (f *filesystem) buildFileContexts(ctx android.ModuleContext) android.Path { builder := android.NewRuleBuilder(pctx, ctx) fcBin := android.PathForModuleOut(ctx, "file_contexts.bin") diff --git a/filesystem/system_other.go b/filesystem/system_other.go index 5451b10e7..044211150 100644 --- a/filesystem/system_other.go +++ b/filesystem/system_other.go @@ -161,26 +161,8 @@ func (m *systemOtherImage) GenerateAndroidBuildActions(ctx android.ModuleContext builder.Build("build_system_other", "build system other") - // 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, propFile) - builder.Command(). - Textf("PATH=%s:$PATH", strings.Join(pathToolDirs, ":")). - BuiltTool("build_image"). - Text(stagingDir.String()). // input directory - Input(outputHermeticPropFile). - Implicits(systemInfo.BuildImagePropFileDeps). - Implicit(fec). - Implicit(stagingDirTimestamp). - Output(outputHermetic). - Text(stagingDir.String()) - - builder.Build("build_system_other_hermetic", "build system other") - fsInfo := FilesystemInfo{ Output: output, - OutputHermetic: outputHermetic, RootDir: stagingDir, FilesystemConfig: m.generateFilesystemConfig(ctx, stagingDir, stagingDirTimestamp), PropFileForMiscInfo: m.buildPropFileForMiscInfo(ctx), @@ -216,13 +198,6 @@ func (s *systemOtherImage) generateFilesystemConfig(ctx android.ModuleContext, s return out } -func (f *systemOtherImage) propFileForHermeticImg(ctx android.ModuleContext, builder *android.RuleBuilder, inputPropFile android.Path) android.Path { - propFilePinnedTimestamp := android.PathForModuleOut(ctx, "for_target_files", "prop") - builder.Command().Textf("cat").Input(inputPropFile).Flag(">").Output(propFilePinnedTimestamp). - Textf(" && echo use_fixed_timestamp=true >> %s", propFilePinnedTimestamp) - return propFilePinnedTimestamp -} - func (f *systemOtherImage) buildPropFileForMiscInfo(ctx android.ModuleContext) android.Path { var lines []string addStr := func(name string, value string) { -- cgit v1.2.3 From bd25acbe1ed72f02d028de2e750bf7cf3ed1245c Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Wed, 16 Apr 2025 20:47:54 +0000 Subject: Move some required-like properties to baseProperties This ensures that autogenerated modules (e.g. autogenerated RROs) do not inherit these properties from the parent module by default. If inheritence is desired, module factories can explicitly list them in craete load hook. Bug: 410570903 Test: lunch cf_x86_64_phone-trunk_staging-userdebug Test: m soong_generated_vendor_filesystem_test ``` Before Soong only installed file(s): etc/init/init.repair_mode.rc After (empty) ``` Change-Id: I782cd27a55a3b0cddabc855331b18cfd21d8f95a --- android/module.go | 36 ++++++++++++++++++------------------ android/module_context.go | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/android/module.go b/android/module.go index b0b6f89e9..40fa835f5 100644 --- a/android/module.go +++ b/android/module.go @@ -424,12 +424,6 @@ type commonProperties struct { // Whether this module is built for non-native architectures (also known as native bridge binary) Native_bridge_supported *bool `android:"arch_variant"` - // init.rc files to be installed if this module is installed - Init_rc proptools.Configurable[[]string] `android:"arch_variant,path"` - - // VINTF manifest fragments to be installed if this module is installed - Vintf_fragments proptools.Configurable[[]string] `android:"path"` - // The OsType of artifacts that this module variant is responsible for creating. // // Set by osMutator @@ -523,13 +517,6 @@ type commonProperties struct { // The team (defined by the owner/vendor) who owns the property. Team *string `android:"path"` - // vintf_fragment Modules required from this module. - Vintf_fragment_modules proptools.Configurable[[]string] `android:"path"` - - // List of module names that are prevented from being installed when this module gets - // installed. - Overrides []string - // Set to true if this module must be generic and does not require product-specific information. // To be included in the system image, this property must be set to true. Use_generic_config *bool @@ -551,6 +538,19 @@ type baseProperties struct { // module type. This is used by neverallow to ensure you can't bypass a ModuleType() matcher // just by creating a soong config module type. Soong_config_base_module_type *string `blueprint:"mutated"` + + // init.rc files to be installed if this module is installed + Init_rc proptools.Configurable[[]string] `android:"arch_variant,path"` + + // VINTF manifest fragments to be installed if this module is installed + Vintf_fragments proptools.Configurable[[]string] `android:"path"` + + // vintf_fragment Modules required from this module. + Vintf_fragment_modules proptools.Configurable[[]string] `android:"path"` + + // List of module names that are prevented from being installed when this module gets + // installed. + Overrides []string } type distProperties struct { @@ -1677,11 +1677,11 @@ func (m *ModuleBase) TargetRequiredModuleNames() []string { } func (m *ModuleBase) VintfFragmentModuleNames(ctx ConfigurableEvaluatorContext) []string { - return m.base().commonProperties.Vintf_fragment_modules.GetOrDefault(m.ConfigurableEvaluator(ctx), nil) + return m.base().baseProperties.Vintf_fragment_modules.GetOrDefault(m.ConfigurableEvaluator(ctx), nil) } func (m *ModuleBase) VintfFragments(ctx ConfigurableEvaluatorContext) []string { - return m.base().commonProperties.Vintf_fragments.GetOrDefault(m.ConfigurableEvaluator(ctx), nil) + return m.base().baseProperties.Vintf_fragments.GetOrDefault(m.ConfigurableEvaluator(ctx), nil) } func (m *ModuleBase) generateVariantTarget(ctx *moduleContext) { @@ -2102,7 +2102,7 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) // so only a single rule is created for each init.rc or vintf fragment file. if !m.InVendorRamdisk() { - ctx.initRcPaths = PathsForModuleSrc(ctx, m.commonProperties.Init_rc.GetOrDefault(ctx, nil)) + ctx.initRcPaths = PathsForModuleSrc(ctx, m.baseProperties.Init_rc.GetOrDefault(ctx, nil)) rcDir := PathForModuleInstall(ctx, "etc", "init") for _, src := range ctx.initRcPaths { installedInitRc := rcDir.Join(ctx, src.Base()) @@ -2118,7 +2118,7 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) installFiles.InstalledInitRcPaths = ctx.installedInitRcPaths } - ctx.vintfFragmentsPaths = PathsForModuleSrc(ctx, m.commonProperties.Vintf_fragments.GetOrDefault(ctx, nil)) + ctx.vintfFragmentsPaths = PathsForModuleSrc(ctx, m.baseProperties.Vintf_fragments.GetOrDefault(ctx, nil)) vintfDir := PathForModuleInstall(ctx, "etc", "vintf", "manifest") for _, src := range ctx.vintfFragmentsPaths { installedVintfFragment := vintfDir.Join(ctx, src.Base()) @@ -2821,7 +2821,7 @@ func (m *ModuleBase) DecodeMultilib(ctx ConfigContext) (string, string) { } func (m *ModuleBase) Overrides() []string { - return m.commonProperties.Overrides + return m.baseProperties.Overrides } func (m *ModuleBase) UseGenericConfig() bool { diff --git a/android/module_context.go b/android/module_context.go index 516cc4cd9..8ee7f621b 100644 --- a/android/module_context.go +++ b/android/module_context.go @@ -649,7 +649,7 @@ func (m *moduleContext) setAconfigPaths(paths Paths) { func (m *moduleContext) getOwnerAndOverrides() (string, []string) { owner := m.ModuleName() - overrides := slices.Clone(m.Module().base().commonProperties.Overrides) + overrides := slices.Clone(m.Module().base().baseProperties.Overrides) if b, ok := m.Module().(OverridableModule); ok { if b.GetOverriddenBy() != "" { // overriding variant of base module -- cgit v1.2.3 From f9391e00974d87438a01b8644fd8253ed40503de Mon Sep 17 00:00:00 2001 From: Pirama Arumuga Nainar Date: Wed, 16 Apr 2025 13:24:59 -0700 Subject: Disable global-merge optimization for coverage builds Bug: http://b/408093589 Bug: http://b/396515430 LLVM commit http://github.com/llvm/llvm-project/commit/4089763883 to global merge regressed code coverage, marking previously covered lines as uncovered. Disable global merge until the regression is fixed. -Wunused-command-line-argument needs to be disabled because -mno-global-merge is reported as unused in LTO mode. Test: verify coverage for liblyric.core_multicam_activation_resolver_test in b/408093589 Change-Id: I98e60c4a7bb524e3019cbfe2176a2b8dee43c20e --- cc/coverage.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cc/coverage.go b/cc/coverage.go index 757641cba..878dc2ab2 100644 --- a/cc/coverage.go +++ b/cc/coverage.go @@ -38,6 +38,14 @@ var ( "-fcoverage-mapping", "-Wno-pass-failed", "-D__ANDROID_CLANG_COVERAGE__", + + // Bug: http://b/408093589, http://b/396515430: LLVM change 4089763883 to + // global merge regressed code coverage, marking previously covered lines + // as uncovered. Disable global merge until the regression is fixed. + // -Wunused-command-line-argument needs to be disabled because + // -mno-global-merge is reported as unused in LTO mode. + "-mno-global-merge", + "-Wno-unused-command-line-argument", } clangCoverageHWASanFlags = []string{ "-mllvm", -- cgit v1.2.3 From 3fb5c06a89d2839b2921f5f2aa5f1298afbbd530 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 10 Apr 2025 10:38:44 -0700 Subject: Rename PrebuiltInfo to PrebuiltJsonInfo The name PrebuiltInfo will be used for a generic PrebuiltInfoProvider, rename the existing PrebuiltInfo to PrebuiltJsonInfo. Test: builds Change-Id: I4bcd6b320b7d1b0d18dcc0afe467b5be1b70c775 --- android/apex.go | 4 ++-- apex/apex.go | 4 ++-- apex/apex_singleton.go | 4 ++-- apex/prebuilt.go | 4 ++-- java/app_set.go | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/android/apex.go b/android/apex.go index 90ece0c70..6a43713d0 100644 --- a/android/apex.go +++ b/android/apex.go @@ -796,10 +796,10 @@ type ApexExportsInfo struct { LibraryNameToDexJarPathOnHost map[string]Path } -var PrebuiltInfoProvider = blueprint.NewProvider[PrebuiltInfo]() +var PrebuiltJsonInfoProvider = blueprint.NewProvider[PrebuiltJsonInfo]() // contents of prebuilt_info.json -type PrebuiltInfo struct { +type PrebuiltJsonInfo struct { // Name of the apex, without the prebuilt_ prefix Name string diff --git a/apex/apex.go b/apex/apex.go index 17c2884bc..48b061383 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -2296,11 +2296,11 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Set prebuiltInfoProvider. This will be used by `apex_prebuiltinfo_singleton` to print out a metadata file // with information about whether source or prebuilt of an apex was used during the build. func (a *apexBundle) providePrebuiltInfo(ctx android.ModuleContext) { - info := android.PrebuiltInfo{ + info := android.PrebuiltJsonInfo{ Name: a.Name(), Is_prebuilt: false, } - android.SetProvider(ctx, android.PrebuiltInfoProvider, info) + android.SetProvider(ctx, android.PrebuiltJsonInfoProvider, info) } // Set a provider containing information about the jars and .prof provided by the apex diff --git a/apex/apex_singleton.go b/apex/apex_singleton.go index 797f47b09..e3363f4b6 100644 --- a/apex/apex_singleton.go +++ b/apex/apex_singleton.go @@ -158,10 +158,10 @@ type apexPrebuiltInfo struct { } func (a *apexPrebuiltInfo) GenerateBuildActions(ctx android.SingletonContext) { - prebuiltInfos := []android.PrebuiltInfo{} + prebuiltInfos := []android.PrebuiltJsonInfo{} ctx.VisitAllModuleProxies(func(m android.ModuleProxy) { - prebuiltInfo, exists := android.OtherModuleProvider(ctx, m, android.PrebuiltInfoProvider) + prebuiltInfo, exists := android.OtherModuleProvider(ctx, m, android.PrebuiltJsonInfoProvider) // Use prebuiltInfoProvider to filter out non apex soong modules. // Use HideFromMake to filter out the unselected variants of a specific apex. if exists && !android.OtherModulePointerProviderOrDefault(ctx, m, android.CommonModuleInfoProvider).HideFromMake { diff --git a/apex/prebuilt.go b/apex/prebuilt.go index 61ba6a5a2..4a68c61df 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -637,7 +637,7 @@ func (p *prebuiltCommon) provideApexExportsInfo(ctx android.ModuleContext, di *a // Set prebuiltInfoProvider. This will be used by `apex_prebuiltinfo_singleton` to print out a metadata file // with information about whether source or prebuilt of an apex was used during the build. func (p *prebuiltCommon) providePrebuiltInfo(ctx android.ModuleContext) { - info := android.PrebuiltInfo{ + info := android.PrebuiltJsonInfo{ Name: p.BaseModuleName(), Is_prebuilt: true, } @@ -645,7 +645,7 @@ func (p *prebuiltCommon) providePrebuiltInfo(ctx android.ModuleContext) { if p.prebuiltCommonProperties.Prebuilt_info != nil { info.Prebuilt_info_file_path = android.PathForModuleSrc(ctx, *p.prebuiltCommonProperties.Prebuilt_info).String() } - android.SetProvider(ctx, android.PrebuiltInfoProvider, info) + android.SetProvider(ctx, android.PrebuiltJsonInfoProvider, info) } // Uses an object provided by its deps to validate that the contents of bcpf have been added to the global diff --git a/java/app_set.go b/java/app_set.go index 6e61b9802..8c575df6d 100644 --- a/java/app_set.go +++ b/java/app_set.go @@ -131,7 +131,7 @@ type prebuiltInfoProps struct { // Set prebuiltInfoProvider. This will be used by `apex_prebuiltinfo_singleton` to print out a metadata file // with information about whether source or prebuilt of an apex was used during the build. func providePrebuiltInfo(ctx android.ModuleContext, p prebuiltInfoProps) { - info := android.PrebuiltInfo{ + info := android.PrebuiltJsonInfo{ Name: p.baseModuleName, Is_prebuilt: p.isPrebuilt, } @@ -140,7 +140,7 @@ func providePrebuiltInfo(ctx android.ModuleContext, p prebuiltInfoProps) { prebuiltInfoFile := android.PathForModuleSrc(ctx, *p.prebuiltInfo) info.Prebuilt_info_file_path = prebuiltInfoFile.String() } - android.SetProvider(ctx, android.PrebuiltInfoProvider, info) + android.SetProvider(ctx, android.PrebuiltJsonInfoProvider, info) } func (as *AndroidAppSet) GenerateAndroidBuildActions(ctx android.ModuleContext) { -- cgit v1.2.3 From cd57212751ae9e0774dbf9cb0c0ac2adf488a09c Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Tue, 8 Apr 2025 15:44:42 -0700 Subject: Convert androidmk to ModuleOrProxy When cc modules are marked with FreeModuleAfterGenerateBuildActions it will be an error to visit any cc module using VisitAllModules. Make androidmk use VisitAllModulesOrProxies, which will use a ModuleProxy for modules that called FreeModuleAfterGenerateBuildActions, and a Module for modules that did not. Test: all Soong tests pass Change-Id: Iea0145e72c8994c51ddc83e5bab404f20bb56bfc --- android/aconfig_providers.go | 4 ++-- android/androidmk.go | 43 ++++++++++++++++++++++--------------------- android/licenses.go | 2 +- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/android/aconfig_providers.go b/android/aconfig_providers.go index 758fe008c..94361740b 100644 --- a/android/aconfig_providers.go +++ b/android/aconfig_providers.go @@ -191,7 +191,7 @@ func aconfigUpdateAndroidMkEntries(ctx fillInEntriesContext, mod Module, entries // 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) { +func aconfigUpdateAndroidMkInfos(ctx fillInEntriesContext, mod ModuleOrProxy, infos *AndroidMkProviderInfo) { info, ok := OtherModuleProvider(ctx, mod, AconfigPropagatingProviderKey) if !ok || len(info.AconfigFiles) == 0 { return @@ -246,7 +246,7 @@ func getContainer(m Module) string { // 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 { +func getContainerUsingProviders(ctx OtherModuleProviderContext, m ModuleOrProxy) string { container := "system" commonInfo := OtherModulePointerProviderOrDefault(ctx, m, CommonModuleInfoProvider) if commonInfo.Vendor || commonInfo.Proprietary || commonInfo.SocSpecific { diff --git a/android/androidmk.go b/android/androidmk.go index a20b0d152..33a8af073 100644 --- a/android/androidmk.go +++ b/android/androidmk.go @@ -358,13 +358,14 @@ func (d *distCopies) Strings() (ret []string) { // This gets the dist contributuions from the given module that were specified in the Android.bp // file using the dist: property. It does not include contribututions that the module's // implementation may have defined with ctx.DistForGoals(), for that, see DistProvider. -func getDistContributions(ctx ConfigAndOtherModuleProviderContext, mod Module) *distContributions { - amod := mod.base() - name := amod.BaseModuleName() +func getDistContributions(ctx ConfigAndOtherModuleProviderContext, mod ModuleOrProxy) *distContributions { + name := mod.Name() info := OtherModuleProviderOrDefault(ctx, mod, InstallFilesProvider) availableTaggedDists := info.DistFiles + commonInfo := OtherModulePointerProviderOrDefault(ctx, mod, CommonModuleInfoProvider) + if len(availableTaggedDists) == 0 { // Nothing dist-able for this module. return nil @@ -378,7 +379,7 @@ func getDistContributions(ctx ConfigAndOtherModuleProviderContext, mod Module) * } // 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, " ") @@ -715,10 +716,10 @@ func AndroidMkSingleton() Singleton { type androidMkSingleton struct{} -func allModulesSorted(ctx SingletonContext) []Module { - var allModules []Module +func allModulesSorted(ctx SingletonContext) []ModuleOrProxy { + var allModules []ModuleOrProxy - ctx.VisitAllModules(func(module Module) { + ctx.VisitAllModulesOrProxies(func(module ModuleOrProxy) { allModules = append(allModules, module) }) @@ -775,7 +776,7 @@ func (so *soongOnlyAndroidMkSingleton) GenerateBuildActions(ctx SingletonContext // 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) { +func (so *soongOnlyAndroidMkSingleton) soongOnlyBuildActions(ctx SingletonContext, mods []ModuleOrProxy) { allDistContributions, moduleInfoJSONs := getSoongOnlyDataFromMods(ctx, mods) singletonDists := getSingletonDists(ctx.Config()) @@ -885,7 +886,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 []Module) ([]distContributions, []*ModuleInfoJSON) { +func getSoongOnlyDataFromMods(ctx fillInEntriesContext, mods []ModuleOrProxy) ([]distContributions, []*ModuleInfoJSON) { var allDistContributions []distContributions var moduleInfoJSONs []*ModuleInfoJSON for _, mod := range mods { @@ -920,28 +921,28 @@ func getSoongOnlyDataFromMods(ctx fillInEntriesContext, mods []Module) ([]distCo data.Include = "$(BUILD_PREBUILT)" } - data.fillInData(ctx, mod) + data.fillInData(ctx, mod.(Module)) if data.Entries.disabled() { continue } if moduleInfoJSON, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok { moduleInfoJSONs = append(moduleInfoJSONs, moduleInfoJSON...) } - if contribution := getDistContributions(ctx, mod); contribution != nil { + if contribution := getDistContributions(ctx, mod.(Module)); contribution != nil { allDistContributions = append(allDistContributions, *contribution) } } if x, ok := mod.(AndroidMkEntriesProvider); ok { entriesList := x.AndroidMkEntries() for _, entries := range entriesList { - entries.fillInEntries(ctx, mod) + entries.fillInEntries(ctx, mod.(Module)) if entries.disabled() { continue } if moduleInfoJSON, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok { moduleInfoJSONs = append(moduleInfoJSONs, moduleInfoJSON...) } - if contribution := getDistContributions(ctx, mod); contribution != nil { + if contribution := getDistContributions(ctx, mod.(Module)); contribution != nil { allDistContributions = append(allDistContributions, *contribution) } } @@ -951,7 +952,7 @@ func getSoongOnlyDataFromMods(ctx fillInEntriesContext, mods []Module) ([]distCo return allDistContributions, moduleInfoJSONs } -func translateAndroidMk(ctx SingletonContext, absMkFile string, moduleInfoJSONPath WritablePath, mods []Module) error { +func translateAndroidMk(ctx SingletonContext, absMkFile string, moduleInfoJSONPath WritablePath, mods []ModuleOrProxy) error { buf := &bytes.Buffer{} var moduleInfoJSONs []*ModuleInfoJSON @@ -966,7 +967,7 @@ func translateAndroidMk(ctx SingletonContext, absMkFile string, moduleInfoJSONPa return err } - if ctx.PrimaryModule(mod) == mod { + if ctx.IsPrimaryModule(mod) { typeStats[ctx.ModuleType(mod)] += 1 } } @@ -1011,7 +1012,7 @@ func writeModuleInfoJSON(ctx SingletonContext, moduleInfoJSONs []*ModuleInfoJSON return nil } -func translateAndroidMkModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON, mod Module) error { +func translateAndroidMkModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON, mod ModuleOrProxy) error { defer func() { if r := recover(); r != nil { panic(fmt.Errorf("%s in translateAndroidMkModule for module %s variant %s", @@ -1027,9 +1028,9 @@ func translateAndroidMkModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs } else { switch x := mod.(type) { case AndroidMkDataProvider: - err = translateAndroidModule(ctx, w, moduleInfoJSONs, mod, x) + err = translateAndroidModule(ctx, w, moduleInfoJSONs, mod.(Module), x) case AndroidMkEntriesProvider: - err = translateAndroidMkEntriesModule(ctx, w, moduleInfoJSONs, mod, x) + err = translateAndroidMkEntriesModule(ctx, w, moduleInfoJSONs, mod.(Module), x) default: // Not exported to make so no make variables to set. } @@ -1326,7 +1327,7 @@ 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 { + mod ModuleOrProxy, providerInfo *AndroidMkProviderInfo) error { commonInfo := OtherModulePointerProviderOrDefault(ctx, mod, CommonModuleInfoProvider) if commonInfo.SkipAndroidMkProcessing { return nil @@ -1473,7 +1474,7 @@ func (a *AndroidMkInfo) AddCompatibilityTestSuites(suites ...string) { // 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) { +func (a *AndroidMkInfo) fillInEntries(ctx fillInEntriesContext, mod ModuleOrProxy, commonInfo *CommonModuleInfo) { helperInfo := AndroidMkInfo{ EntryMap: make(map[string][]string), } @@ -1654,7 +1655,7 @@ func (a *AndroidMkInfo) write(w io.Writer) { // calls from the module's dist and dists properties. // 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 { +func (a *AndroidMkInfo) GetDistForGoals(ctx fillInEntriesContext, mod ModuleOrProxy, commonInfo *CommonModuleInfo) []string { distContributions := getDistContributions(ctx, mod) if distContributions == nil { return nil diff --git a/android/licenses.go b/android/licenses.go index f49b0fc18..3473e8fb2 100644 --- a/android/licenses.go +++ b/android/licenses.go @@ -340,7 +340,7 @@ func getLicenses(ctx BaseModuleContext, module Module) []string { } // Returns whether a module is an allowed list of modules that do not have or need applicable licenses. -func exemptFromRequiredApplicableLicensesProperty(module Module) bool { +func exemptFromRequiredApplicableLicensesProperty(module ModuleOrProxy) bool { switch reflect.TypeOf(module).String() { case "*android.licenseModule": // is a license, doesn't need one case "*android.licenseKindModule": // is a license, doesn't need one -- cgit v1.2.3 From 59753b1405c0499390f60ce5e28f0786733ea347 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 10 Apr 2025 11:30:45 -0700 Subject: Add TestingModule.ModuleProxy Tests may want to test methods that take a ModuleProxy. Add a TestingModule.ModuleProxy method that can convert a TestingModule returned by ModuleForTests into a ModuleProxy. Test: builds Change-Id: I8a93eecf16d8c9dc8bd3eb8762506af6bd60d2cf --- android/fixture.go | 5 +++++ android/namespace_test.go | 2 +- android/testing.go | 17 ++++++++++++++--- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/android/fixture.go b/android/fixture.go index ea52b95f5..b5a60aa63 100644 --- a/android/fixture.go +++ b/android/fixture.go @@ -1051,6 +1051,11 @@ func (r *TestResult) Module(name string, variant string) Module { return r.ModuleForTests(r.fixture.t, name, variant).Module() } +// ModuleProxy returns the module with the specific name and of the specified variant. +func (r *TestResult) ModuleProxy(name string, variant string) ModuleProxy { + return r.ModuleForTests(r.fixture.t, name, variant).ModuleProxy() +} + // CollateErrs adds additional errors to the result and returns true if there is more than one // error in the result. func (r *TestResult) CollateErrs(errs []error) bool { diff --git a/android/namespace_test.go b/android/namespace_test.go index f4f0b33ae..0026aa78c 100644 --- a/android/namespace_test.go +++ b/android/namespace_test.go @@ -691,7 +691,7 @@ func findModuleById(result *TestResult, id string) (module TestingModule) { testModule, ok := candidate.(*testModule) if ok { if testModule.properties.Id == id { - module = newTestingModule(result.fixture.t, result.config, testModule) + module = newTestingModule(result.fixture.t, result.config, testModule, result.ModuleToProxy(testModule)) } } } diff --git a/android/testing.go b/android/testing.go index 25e0a53e5..dfee70f37 100644 --- a/android/testing.go +++ b/android/testing.go @@ -324,6 +324,10 @@ func (ctx *TestContext) VisitDirectDepsProxies(module ModuleOrProxy, visit func( }) } +func (ctx *TestContext) ModuleToProxy(module ModuleOrProxy) ModuleProxy { + return ModuleProxy{ctx.Context.ModuleToProxy(module)} +} + // registeredComponentOrder defines the order in which a sortableComponent type is registered at // runtime and provides support for reordering the components registered for a test in the same // way. @@ -638,7 +642,7 @@ func (ctx *TestContext) ModuleVariantForTests(t *testing.T, name string, matchVa name, matchVariations, strings.Join(moduleStrings, "\n ")) } - return newTestingModule(t, ctx.config, modules[0]) + return newTestingModule(t, ctx.config, modules[0], ctx.ModuleToProxy(modules[0])) } func (ctx *TestContext) ModuleForTests(t *testing.T, name, variant string) TestingModule { @@ -671,7 +675,7 @@ func (ctx *TestContext) ModuleForTests(t *testing.T, name, variant string) Testi } } - return newTestingModule(t, ctx.config, module) + return newTestingModule(t, ctx.config, module, ctx.ModuleToProxy(module)) } func (ctx *TestContext) ModuleVariantsForTests(name string) []string { @@ -1109,12 +1113,14 @@ func (b baseTestingComponent) AllOutputs() []string { type TestingModule struct { baseTestingComponent module Module + proxy ModuleProxy } -func newTestingModule(t *testing.T, config Config, module Module) TestingModule { +func newTestingModule(t *testing.T, config Config, module Module, proxy ModuleProxy) TestingModule { return TestingModule{ newBaseTestingComponent(t, config, module), module, + proxy, } } @@ -1123,6 +1129,11 @@ func (m TestingModule) Module() Module { return m.module } +// ModuleProxy returns the ModuleProxy wrapped by the TestingModule. +func (m TestingModule) ModuleProxy() ModuleProxy { + return m.proxy +} + // VariablesForTestsRelativeToTop returns a copy of the Module.VariablesForTests() with every value // having any temporary build dir usages replaced with paths relative to a notional top. func (m TestingModule) VariablesForTestsRelativeToTop() map[string]string { -- cgit v1.2.3 From d0cb3b51fc621b6d08c1fb55e979400983e178b8 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 10 Apr 2025 15:18:25 -0700 Subject: Add SingletonContext.VisitDirectDepsProxies and OtherModuleDependencyTag Add methods to SingletonContext to allow converting more singletons to providers. Test: builds Change-Id: Ifa8a786492499d12b82840cc7bbcd9eb79f376dc --- android/singleton.go | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/android/singleton.go b/android/singleton.go index 535dd0fc9..139f606ea 100644 --- a/android/singleton.go +++ b/android/singleton.go @@ -76,11 +76,7 @@ type SingletonContext interface { VisitDirectDeps(module Module, visit func(Module)) VisitDirectDepsIf(module Module, pred func(Module) bool, visit func(Module)) - // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module - VisitDepsDepthFirst(module Module, visit func(Module)) - // Deprecated: use WalkDeps instead to support multiple dependency tags on the same module - VisitDepsDepthFirstIf(module Module, pred func(Module) bool, - visit func(Module)) + VisitDirectDepsProxies(module ModuleProxy, visit func(ModuleProxy)) VisitAllModuleVariants(module Module, visit func(Module)) @@ -131,6 +127,11 @@ type SingletonContext interface { // specified goals are built. DistForGoalsWithFilename(goals []string, path Path, filename string) + // OtherModuleDependencyTag returns the dependency tag used to depend on a module, or nil if there is no dependency + // on the module. When called inside a Visit* method with current module being visited, and there are multiple + // dependencies on the module being visited, it returns the dependency tag used for the current dependency. + OtherModuleDependencyTag(module ModuleOrProxy) blueprint.DependencyTag + GetIncrementalAnalysis() bool } @@ -337,12 +338,12 @@ func (s *singletonContextAdaptor) VisitDirectDepsIf(module Module, pred func(Mod s.SingletonContext.VisitDirectDepsIf(module, predAdaptor(pred), visitAdaptor(visit)) } -func (s *singletonContextAdaptor) VisitDepsDepthFirst(module Module, visit func(Module)) { - s.SingletonContext.VisitDepsDepthFirst(module, visitAdaptor(visit)) +func (s *singletonContextAdaptor) VisitDirectDepsProxies(module ModuleProxy, visit func(ModuleProxy)) { + s.SingletonContext.VisitDirectDepsProxies(module.ModuleProxy, visitProxyAdaptor(visit)) } -func (s *singletonContextAdaptor) VisitDepsDepthFirstIf(module Module, pred func(Module) bool, visit func(Module)) { - s.SingletonContext.VisitDepsDepthFirstIf(module, predAdaptor(pred), visitAdaptor(visit)) +func (s *singletonContextAdaptor) OtherModuleDependencyTag(module ModuleOrProxy) blueprint.DependencyTag { + return s.SingletonContext.OtherModuleDependencyTag(module) } func (s *singletonContextAdaptor) VisitAllModuleVariants(module Module, visit func(Module)) { -- cgit v1.2.3 From 36e826296b7dd0c6357e5140d6a41691eafcbc89 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 16 Apr 2025 11:53:09 -0700 Subject: Fix plugin allowlist after conversion to providers The plugin allowlist hasn't been working since Blueprint plugins were converted to providers. Use the newly exported PluginDepTag to identify plugin dependencies. Also add a test. Test: plugin_test.go Change-Id: I9be8d848b108e22b34cf96d39fb25c59b2e7d807 --- android/plugin.go | 51 ++++++++++++++++++++++++------------------------ golang/Android.bp | 1 + golang/plugin_test.go | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 26 deletions(-) create mode 100644 golang/plugin_test.go diff --git a/android/plugin.go b/android/plugin.go index 4348f1475..87545320f 100644 --- a/android/plugin.go +++ b/android/plugin.go @@ -19,7 +19,7 @@ import ( "os" "strings" - "github.com/google/blueprint" + "github.com/google/blueprint/bootstrap" ) func init() { @@ -59,6 +59,7 @@ var allowedPluginsByName = map[string]bool{ "soong-java-config-error_prone": true, "soong-libchrome": true, "soong-llvm": true, + "soong-noto-fonts": true, "soong-robolectric": true, "soong-rust-prebuilts": true, "soong-selinux": true, @@ -68,16 +69,13 @@ var allowedPluginsByName = map[string]bool{ "treble_report_module": true, "vintf-compatibility-matrix-soong-rules": true, "xsdc-soong-rules": true, + "xtensa": true, } var internalPluginsPaths = []string{ "vendor/google/build/soong/internal_plugins.json", } -type pluginProvider interface { - IsPluginFor(string) bool -} - func maybeAddInternalPluginsToAllowlist(ctx SingletonContext) { for _, internalPluginsPath := range internalPluginsPaths { if path := ExistentPathForSource(ctx, internalPluginsPath); path.Valid() { @@ -105,34 +103,35 @@ func (p *pluginSingleton) GenerateBuildActions(ctx SingletonContext) { maybeAddInternalPluginsToAllowlist(ctx) disallowedPlugins := map[string]bool{} - ctx.VisitAllModulesBlueprint(func(module blueprint.Module) { - if ctx.ModuleType(module) != "bootstrap_go_package" { + ctx.VisitAllModuleProxies(func(module ModuleProxy) { + if ctx.ModuleName(module) != "soong_build" { return } - p, ok := module.(pluginProvider) - if !ok || !p.IsPluginFor("soong_build") { - return - } + ctx.VisitDirectDepsProxies(module, func(module ModuleProxy) { + if ctx.OtherModuleDependencyTag(module) != bootstrap.PluginDepTag { + return + } - name := ctx.ModuleName(module) - if _, ok := allowedPluginsByName[name]; ok { - return - } + name := ctx.ModuleName(module) + if _, ok := allowedPluginsByName[name]; ok { + return + } - dir := ctx.ModuleDir(module) + dir := ctx.ModuleDir(module) - // allow use of plugins within Soong to not allowlist everything - if strings.HasPrefix(dir, "build/soong") { - return - } + // allow use of plugins within Soong to not allowlist everything + if strings.HasPrefix(dir, "build/soong") { + return + } - // allow third party users outside of external to create new plugins, i.e. non-google paths - // under vendor or hardware - if !strings.HasPrefix(dir, "external/") && IsThirdPartyPath(dir) { - return - } - disallowedPlugins[name] = true + // allow third party users outside of external to create new plugins, i.e. non-google paths + // under vendor or hardware + if !strings.HasPrefix(dir, "external/") && IsThirdPartyPath(dir) { + return + } + 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).", SortedKeys(disallowedPlugins)) diff --git a/golang/Android.bp b/golang/Android.bp index 3eae94fa2..d3bbd51ea 100644 --- a/golang/Android.bp +++ b/golang/Android.bp @@ -17,6 +17,7 @@ bootstrap_go_package { ], testSrcs: [ "golang_test.go", + "plugin_test.go", ], pluginFor: ["soong_build"], } diff --git a/golang/plugin_test.go b/golang/plugin_test.go new file mode 100644 index 000000000..54a91face --- /dev/null +++ b/golang/plugin_test.go @@ -0,0 +1,54 @@ +// 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 golang + +import ( + "testing" + + "android/soong/android" + "github.com/google/blueprint/bootstrap" +) + +func TestPluginAllowList(t *testing.T) { + bp := ` + bootstrap_go_package { + name: "bad_plugin", + pkgPath: "test/bad", + pluginFor: ["soong_build"], + } + + bootstrap_go_package { + name: "soong-llvm", + pkgPath: "test/llvm", + pluginFor: ["soong_build"], + } + + blueprint_go_binary { + name: "soong_build", + } + ` + + android.GroupFixturePreparers( + android.PrepareForTestWithArchMutator, + android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { + RegisterGoModuleTypes(ctx) + ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) { + ctx.BottomUpBlueprint("bootstrap_deps", bootstrap.BootstrapDeps).UsesReverseDependencies() + }) + android.RegisterPluginSingletonBuildComponents(ctx) + }), + ).ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(`New plugins are not supported; however \["bad_plugin"\] were found.`)). + RunTestWithBp(t, bp) +} -- cgit v1.2.3 From 564822cbb924b1eae3f100e364a4ad306e576b9d Mon Sep 17 00:00:00 2001 From: Jooyung Han Date: Wed, 16 Apr 2025 16:22:51 -0700 Subject: Revert^3 "apex: Do not compress EROFS APEX" a52b89f8abfbc00d0c952caab8d4fdf5a0483121 Change-Id: Ibe1c417fde2198b34853269657ba49edf682b98e --- apex/apex.go | 8 +------- apex/apex_test.go | 28 ---------------------------- 2 files changed, 1 insertion(+), 35 deletions(-) diff --git a/apex/apex.go b/apex/apex.go index 17c2884bc..0634b69e6 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -1733,13 +1733,7 @@ func (a *apexBundle) setPayloadFsType(ctx android.ModuleContext) { } func (a *apexBundle) isCompressable() bool { - if a.testApex { - return false - } - if a.payloadFsType == erofs { - return false - } - return proptools.Bool(a.overridableProperties.Compressible) + return proptools.BoolDefault(a.overridableProperties.Compressible, false) && !a.testApex } func (a *apexBundle) commonBuildActions(ctx android.ModuleContext) bool { diff --git a/apex/apex_test.go b/apex/apex_test.go index 880d0014a..41de1a460 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -9325,34 +9325,6 @@ func TestCompressedApex_NonUpdatable(t *testing.T) { `) } -func TestCompressedApexIsDisabledWhenUsingErofs(t *testing.T) { - t.Parallel() - ctx := testApex(t, ` - apex { - name: "myapex", - key: "myapex.key", - compressible: true, - updatable: true, - min_sdk_version: "29", - payload_fs_type: "erofs", - } - apex_key { - name: "myapex.key", - public_key: "testkey.avbpubkey", - private_key: "testkey.pem", - } - `, - android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { - variables.CompressedApex = proptools.BoolPtr(true) - }), - ) - - compressRule := ctx.ModuleForTests(t, "myapex", "android_common_myapex").MaybeRule("compressRule") - if compressRule.Rule != nil { - t.Error("erofs apex should not be compressed") - } -} - func TestApexSet_ShouldRespectCompressedApexFlag(t *testing.T) { t.Parallel() for _, compressionEnabled := range []bool{true, false} { -- cgit v1.2.3 From 4822f989b6e8db94b7f34d0d9900f012fa46b4e6 Mon Sep 17 00:00:00 2001 From: LaMont Jones Date: Wed, 16 Apr 2025 09:21:20 -0700 Subject: Improve errors from release-config - If there are multiple flag declaration errors, report all of them before exiting. - Add --declarations-only flag to build-flag, which only processes flag declarations. This simplifies verifying that there are no duplicate definitions in the workspace. - Add --maps-file flag to build-flag, which expects a file containing a list of --map arguments, one per line. Bug: b/408528314 Test: manual, TH Change-Id: Id31dac0e36be8bde7092505ea50695a599df9dee --- cmd/release_config/build_flag/main.go | 30 +++++++++++++- cmd/release_config/release_config/main.go | 2 +- .../release_config_lib/release_configs.go | 47 +++++++++++++--------- 3 files changed, 58 insertions(+), 21 deletions(-) diff --git a/cmd/release_config/build_flag/main.go b/cmd/release_config/build_flag/main.go index 5d103cc25..c63ff71ce 100644 --- a/cmd/release_config/build_flag/main.go +++ b/cmd/release_config/build_flag/main.go @@ -29,6 +29,10 @@ type Flags struct { // `PRODUCT_RELEASE_CONFIG_MAPS` are used. maps rc_lib.StringList + // File containing the list of maps to use, one file per line. + // Cannot be used with --map. + mapsFile string + // Output directory (relative to `top`). outDir string @@ -53,6 +57,10 @@ type Flags struct { // If true, and we cannot find the named release config, values for // `trunk_staging` will be used. allowMissing bool + + // Only load flag declarations, do not load values. The output + // will have only values provided in the declaration files. + declarationsOnly bool } type CommandFunc func(*rc_lib.ReleaseConfigs, Flags, string, []string) error @@ -323,7 +331,7 @@ func SetCommand(configs *rc_lib.ReleaseConfigs, commonFlags Flags, cmd string, a } // Reload the release configs. - configs, err = rc_lib.ReadReleaseConfigMaps(commonFlags.maps, commonFlags.targetReleases[0], commonFlags.useGetBuildVar, commonFlags.allowMissing) + configs, err = rc_lib.ReadReleaseConfigMaps(commonFlags.maps, commonFlags.targetReleases[0], commonFlags.useGetBuildVar, commonFlags.allowMissing, commonFlags.declarationsOnly) if err != nil { return err } @@ -345,12 +353,14 @@ func main() { flag.StringVar(&commonFlags.top, "top", topDir, "path to top of workspace") flag.BoolVar(&commonFlags.quiet, "quiet", false, "disable warning messages") flag.Var(&commonFlags.maps, "map", "path to a release_config_map.textproto. may be repeated") + flag.StringVar(&commonFlags.mapsFile, "maps-file", "", "path to a file containing a list of release_config_map.textproto paths, one per line") flag.StringVar(&commonFlags.outDir, "out-dir", rc_lib.GetDefaultOutDir(), "basepath for the output. Multiple formats are created") flag.Var(&commonFlags.targetReleases, "release", "TARGET_RELEASE for this build") flag.BoolVar(&commonFlags.allowMissing, "allow-missing", false, "Use trunk_staging values if release not found") flag.BoolVar(&commonFlags.allReleases, "all-releases", false, "operate on all releases. (Ignored for set command)") flag.BoolVar(&commonFlags.useGetBuildVar, "use-get-build-var", true, "use get_build_var PRODUCT_RELEASE_CONFIG_MAPS to get needed maps") flag.BoolVar(&commonFlags.debug, "debug", false, "turn on debugging output for errors") + flag.BoolVar(&commonFlags.declarationsOnly, "declarations-only", false, "only process flag declarations") flag.Parse() errorExit := func(err error) { @@ -365,6 +375,22 @@ func main() { rc_lib.DisableWarnings() } + if commonFlags.mapsFile != "" { + if len(commonFlags.maps) > 0 { + errorExit(fmt.Errorf("Cannot use both --map and --maps-file")) + } + data, err := os.ReadFile(commonFlags.mapsFile) + if err != nil { + errorExit(err) + } + // Add the list of maps to `maps`. + for _, m := range strings.Split(string(data), "\n") { + if len(m) > 0 { + commonFlags.maps.Set(m) + } + } + } + if len(commonFlags.targetReleases) == 0 { release, ok := os.LookupEnv("TARGET_RELEASE") if ok { @@ -383,7 +409,7 @@ func main() { if relName == "--all" || relName == "-all" { commonFlags.allReleases = true } - configs, err = rc_lib.ReadReleaseConfigMaps(commonFlags.maps, relName, commonFlags.useGetBuildVar, commonFlags.allowMissing) + configs, err = rc_lib.ReadReleaseConfigMaps(commonFlags.maps, relName, commonFlags.useGetBuildVar, commonFlags.allowMissing, commonFlags.declarationsOnly) if err != nil { errorExit(err) } diff --git a/cmd/release_config/release_config/main.go b/cmd/release_config/release_config/main.go index 7013d6bd4..f11147a2c 100644 --- a/cmd/release_config/release_config/main.go +++ b/cmd/release_config/release_config/main.go @@ -66,7 +66,7 @@ func main() { if err = os.Chdir(top); err != nil { panic(err) } - configs, err = rc_lib.ReadReleaseConfigMaps(releaseConfigMapPaths, targetRelease, useBuildVar, allowMissing) + configs, err = rc_lib.ReadReleaseConfigMaps(releaseConfigMapPaths, targetRelease, useBuildVar, allowMissing, false) if err != nil { panic(err) } diff --git a/cmd/release_config/release_config_lib/release_configs.go b/cmd/release_config/release_config_lib/release_configs.go index a32ea98f9..446821c2f 100644 --- a/cmd/release_config/release_config_lib/release_configs.go +++ b/cmd/release_config/release_config_lib/release_configs.go @@ -16,6 +16,7 @@ package release_config_lib import ( "cmp" + "errors" "fmt" "io/fs" "os" @@ -294,7 +295,7 @@ func EnumerateReleaseConfigs(dir string) ([]string, error) { return ret, err } -func (configs *ReleaseConfigs) LoadReleaseConfigMap(path string, ConfigDirIndex int) error { +func (configs *ReleaseConfigs) LoadReleaseConfigMap(path string, ConfigDirIndex int, declarationsOnly bool) error { if _, err := os.Stat(path); err != nil { return fmt.Errorf("%s does not exist\n", path) } @@ -327,6 +328,7 @@ func (configs *ReleaseConfigs) LoadReleaseConfigMap(path string, ConfigDirIndex DuplicateDeclarationAllowlist[flag] = true } } + var declarationErrors []error err = WalkTextprotoFiles(dir, "flag_declarations", func(path string, d fs.DirEntry, err error) error { flagDeclaration, err := FlagDeclarationFactory(path) if err != nil { @@ -342,7 +344,10 @@ func (configs *ReleaseConfigs) LoadReleaseConfigMap(path string, ConfigDirIndex if def, ok := configs.FlagArtifacts[name]; !ok { configs.FlagArtifacts[name] = &FlagArtifact{FlagDeclaration: flagDeclaration, DeclarationIndex: ConfigDirIndex} } else if !proto.Equal(def.FlagDeclaration, flagDeclaration) || !DuplicateDeclarationAllowlist[name] { - return fmt.Errorf("Duplicate definition of %s in %s", *flagDeclaration.Name, path) + err = fmt.Errorf("Duplicate definition of %s in %s", *flagDeclaration.Name, path) + declarationErrors = append(declarationErrors, err) + // We will gather up all of the errors after the walk is done. + return nil } // Set the initial value in the flag artifact. configs.FilesUsedMap[path] = true @@ -354,8 +359,8 @@ func (configs *ReleaseConfigs) LoadReleaseConfigMap(path string, ConfigDirIndex } return nil }) - if err != nil { - return err + if len(declarationErrors) > 0 { + return errors.Join(declarationErrors...) } subDirs := func(subdir string) (ret []string) { @@ -401,18 +406,20 @@ func (configs *ReleaseConfigs) LoadReleaseConfigMap(path string, ConfigDirIndex } } - // Only walk flag_values/{RELEASE} for defined releases. - err2 := WalkTextprotoFiles(dir, filepath.Join("flag_values", name), func(path string, d fs.DirEntry, err error) error { - flagValue, err := FlagValueFactory(path) - if err != nil { - return err + if !declarationsOnly { + // Only walk flag_values/{RELEASE} for defined releases. + err2 := WalkTextprotoFiles(dir, filepath.Join("flag_values", name), func(path string, d fs.DirEntry, err error) error { + flagValue, err := FlagValueFactory(path) + if err != nil { + return err + } + config.FilesUsedMap[path] = true + rcc.FlagValues = append(rcc.FlagValues, flagValue) + return nil + }) + if err2 != nil { + return err2 } - config.FilesUsedMap[path] = true - rcc.FlagValues = append(rcc.FlagValues, flagValue) - return nil - }) - if err2 != nil { - return err2 } if rcc.proto.GetAconfigFlagsOnly() { config.AconfigFlagsOnly = true @@ -537,7 +544,7 @@ func (configs *ReleaseConfigs) GenerateReleaseConfigs(targetRelease string) erro return nil } -func ReadReleaseConfigMaps(releaseConfigMapPaths StringList, targetRelease string, useBuildVar, allowMissing bool) (*ReleaseConfigs, error) { +func ReadReleaseConfigMaps(releaseConfigMapPaths StringList, targetRelease string, useBuildVar, allowMissing, declarationsOnly bool) (*ReleaseConfigs, error) { var err error if len(releaseConfigMapPaths) == 0 { @@ -557,6 +564,7 @@ func ReadReleaseConfigMaps(releaseConfigMapPaths StringList, targetRelease strin configs.allowMissing = allowMissing mapsRead := make(map[string]bool) var idx int + var loadErrors []error for _, releaseConfigMapPath := range releaseConfigMapPaths { // Maintain an ordered list of release config directories. configDir := filepath.Dir(releaseConfigMapPath) @@ -568,12 +576,15 @@ func ReadReleaseConfigMaps(releaseConfigMapPaths StringList, targetRelease strin configs.configDirs = append(configs.configDirs, configDir) // Force the path to be the textproto path, so that both the scl and textproto formats can coexist. releaseConfigMapPath = filepath.Join(configDir, "release_config_map.textproto") - err = configs.LoadReleaseConfigMap(releaseConfigMapPath, idx) + err = configs.LoadReleaseConfigMap(releaseConfigMapPath, idx, declarationsOnly) if err != nil { - return nil, err + loadErrors = append(loadErrors, err) } idx += 1 } + if len(loadErrors) > 0 { + return nil, errors.Join(loadErrors...) + } // Now that we have all of the release config maps, can meld them and generate the artifacts. err = configs.GenerateReleaseConfigs(targetRelease) -- cgit v1.2.3 From 49d07e27b72e48eb309ad31244a80c6e5da6de3d Mon Sep 17 00:00:00 2001 From: LaMont Jones Date: Wed, 16 Apr 2025 09:25:21 -0700 Subject: Add all_release_configs module This module provides the `all_release_configs.pb` for the current build, for use in test modules. Also add a validation that ensures there are no duplicate build flag declarations in the workspace. Bug: b/408528314 Test: manual, TH Change-Id: I05561faaf1961a5b727a8cae6653179a979771a9 --- aconfig/build_flags/Android.bp | 4 +++ aconfig/build_flags/build_flags_singleton.go | 39 ++++++++++++++++++--- aconfig/build_flags/init.go | 14 +++++--- aconfig/build_flags/release_configs.go | 52 ++++++++++++++++++++++++++++ ui/build/finder.go | 23 ++++++++++++ 5 files changed, 124 insertions(+), 8 deletions(-) diff --git a/aconfig/build_flags/Android.bp b/aconfig/build_flags/Android.bp index 139aeac3b..582eed854 100644 --- a/aconfig/build_flags/Android.bp +++ b/aconfig/build_flags/Android.bp @@ -23,3 +23,7 @@ bootstrap_go_package { ], pluginFor: ["soong_build"], } + +all_release_configs { + name: "all_release_configs", +} diff --git a/aconfig/build_flags/build_flags_singleton.go b/aconfig/build_flags/build_flags_singleton.go index 2eb86e3d1..68d8cda88 100644 --- a/aconfig/build_flags/build_flags_singleton.go +++ b/aconfig/build_flags/build_flags_singleton.go @@ -59,8 +59,10 @@ func (this *allBuildFlagDeclarationsSingleton) GenerateBuildActions(ctx android. } }) + basePath := android.PathForIntermediates(ctx, "release_configs") + // Generate build action for build_flag (binary proto output) - this.flagsBinaryProtoPath = android.PathForIntermediates(ctx, "all_build_flag_declarations.pb") + this.flagsBinaryProtoPath = basePath.Join(ctx, "all_build_flag_declarations.pb") ctx.Build(pctx, android.BuildParams{ Rule: allDeclarationsRule, Inputs: flagsFiles, @@ -73,7 +75,7 @@ func (this *allBuildFlagDeclarationsSingleton) GenerateBuildActions(ctx android. ctx.Phony("all_build_flag_declarations", this.flagsBinaryProtoPath) // Generate build action for build_flag (text proto output) - this.flagsTextProtoPath = android.PathForIntermediates(ctx, "all_build_flag_declarations.textproto") + this.flagsTextProtoPath = basePath.Join(ctx, "all_build_flag_declarations.textproto") ctx.Build(pctx, android.BuildParams{ Rule: allDeclarationsRuleTextProto, Input: this.flagsBinaryProtoPath, @@ -83,7 +85,7 @@ func (this *allBuildFlagDeclarationsSingleton) GenerateBuildActions(ctx android. ctx.Phony("all_build_flag_declarations_textproto", this.flagsTextProtoPath) // Generate build action for release_configs (binary proto output) - this.configsBinaryProtoPath = android.PathForIntermediates(ctx, "all_release_config_contributions.pb") + this.configsBinaryProtoPath = basePath.Join(ctx, "all_release_config_contributions.pb") ctx.Build(pctx, android.BuildParams{ Rule: allReleaseConfigContributionsRule, Inputs: contributionDirs, @@ -96,7 +98,7 @@ func (this *allBuildFlagDeclarationsSingleton) GenerateBuildActions(ctx android. }) ctx.Phony("all_release_config_contributions", this.configsBinaryProtoPath) - this.configsTextProtoPath = android.PathForIntermediates(ctx, "all_release_config_contributions.textproto") + this.configsTextProtoPath = basePath.Join(ctx, "all_release_config_contributions.textproto") ctx.Build(pctx, android.BuildParams{ Rule: allReleaseConfigContributionsRule, Inputs: contributionDirs, @@ -109,12 +111,41 @@ func (this *allBuildFlagDeclarationsSingleton) GenerateBuildActions(ctx android. }) ctx.Phony("all_release_config_contributions_textproto", this.configsTextProtoPath) + // Validator to ensure that there are no duplicate flag declarations. + // The Validator timestamp file. + mapsListPath := basePath.Join(ctx, "release_config_map.list") + duplicatesPath := basePath.Join(ctx, "duplicate_allowlist.list") + validatorPath := basePath.Join(ctx, "release_config_map.timestamp") + + // The file containing the list of all `release_config_map.textproto` files in the source tree. + ctx.Build(pctx, android.BuildParams{ + Rule: android.CpIfChanged, + Input: android.PathForArbitraryOutput(ctx, ".module_paths", "release_config_map.list"), + Output: mapsListPath, + Validation: validatorPath, + }) + ctx.Build(pctx, android.BuildParams{ + Rule: android.CpIfChanged, + Input: android.PathForArbitraryOutput(ctx, ".module_paths", "duplicate_allowlist.list"), + Output: duplicatesPath, + Validation: validatorPath, + }) + ctx.Build(pctx, android.BuildParams{ + Rule: flagDeclarationsValidationRule, + Input: mapsListPath, + Implicits: append(android.Paths{duplicatesPath}, flagsFiles...), + Output: validatorPath, + }) + // Make sure that this is at least built on CI machines. + ctx.Phony("droid", mapsListPath) + // Add a simple target for ci/build_metadata to use. ctx.Phony("release_config_metadata", this.flagsBinaryProtoPath, this.flagsTextProtoPath, this.configsBinaryProtoPath, this.configsTextProtoPath, + mapsListPath, ) ctx.DistForGoal("droid", this.flagsBinaryProtoPath) diff --git a/aconfig/build_flags/init.go b/aconfig/build_flags/init.go index a7575e86a..c4776fbae 100644 --- a/aconfig/build_flags/init.go +++ b/aconfig/build_flags/init.go @@ -72,19 +72,24 @@ var ( CommandDeps: []string{ "${releaseConfigContributions}", }, + Restat: true, }, "dirs", "format") - allReleaseConfigContributionsRuleText = pctx.AndroidStaticRule("all-release-config-contributions-dumptext", + + flagDeclarationsValidationRule = pctx.AndroidStaticRule("flagDeclarationsValidation", blueprint.RuleParams{ - Command: `${releaseConfigContributions} ${dirs} --format ${format} --output ${out}`, + // Get no flags, so that we have no output. + Command: `${buildFlag} --maps-file ${in} --quiet --declarations-only get && date > ${out}`, CommandDeps: []string{ - "${releaseConfigContributions}", + "${buildFlag}", }, - }, "dirs", "format") + Restat: true, + }) ) func init() { RegisterBuildComponents(android.InitRegistrationContext) pctx.Import("android/soong/android") + pctx.HostBinToolVariable("buildFlag", "build-flag") pctx.HostBinToolVariable("buildFlagDeclarations", "build-flag-declarations") pctx.HostBinToolVariable("releaseConfigContributions", "release-config-contributions") } @@ -92,5 +97,6 @@ func init() { func RegisterBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("build_flag_declarations", DeclarationsFactory) ctx.RegisterModuleType("release_config_contributions", ReleaseConfigContributionsFactory) + ctx.RegisterModuleType("all_release_configs", AllReleaseConfigsFactory) ctx.RegisterParallelSingletonType("all_build_flag_declarations", AllBuildFlagDeclarationsFactory) } diff --git a/aconfig/build_flags/release_configs.go b/aconfig/build_flags/release_configs.go index 3fa8a7c02..966939e0f 100644 --- a/aconfig/build_flags/release_configs.go +++ b/aconfig/build_flags/release_configs.go @@ -15,6 +15,7 @@ package build_flags import ( + "fmt" "path/filepath" "android/soong/android" @@ -28,6 +29,12 @@ type ReleaseConfigContributionsProviderData struct { var ReleaseConfigContributionsProviderKey = blueprint.NewProvider[ReleaseConfigContributionsProviderData]() +type AllReleaseConfigsProviderData struct { + AllReleaseConfigsPath android.Path +} + +var AllReleaseConfigsProviderKey = blueprint.NewProvider[AllReleaseConfigsProviderData]() + // Soong uses `release_config_contributions` modules to produce the // `build_flags/all_release_config_contributions.*` artifacts, listing *all* of // the directories in the source tree that contribute to each release config, @@ -76,3 +83,48 @@ func (module *ReleaseConfigContributionsModule) GenerateAndroidBuildActions(ctx }) } + +// Soong provides release config informamtion via an `all_release_configs` module. +// +// This module can be used by test modules that need to inspect release configs. +type AllReleaseConfigsModule struct { + android.ModuleBase + android.DefaultableModuleBase + + // There are no extra properties for "all_release_configs". + properties struct{} +} + +func AllReleaseConfigsFactory() android.Module { + module := &AllReleaseConfigsModule{} + + android.InitAndroidModule(module) + android.InitDefaultableModule(module) + module.AddProperties(&module.properties) + + return module +} + +func (module *AllReleaseConfigsModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { + if !ctx.Config().HasDeviceProduct() { + return + } + // The 'release-config' command is called for every build, and generates the + // all_release_configs-${TARGET_PRODUCT}.pb file. + srcPath := android.PathForOutput(ctx, "release-config", fmt.Sprintf("all_release_configs-%s.pb", ctx.Config().DeviceProduct())) + outputPath := android.PathForModuleOut(ctx, "all_release_configs.pb") + + ctx.Phony("droid", outputPath) + ctx.Phony("all_release_configs", outputPath) + + // Update the output file only if the source file is changed. + ctx.Build(pctx, android.BuildParams{ + Rule: android.CpIfChanged, + Input: srcPath, + Output: outputPath, + }) + + android.SetProvider(ctx, AllReleaseConfigsProviderKey, AllReleaseConfigsProviderData{ + AllReleaseConfigsPath: outputPath, + }) +} diff --git a/ui/build/finder.go b/ui/build/finder.go index ff8908b29..a4834f6f3 100644 --- a/ui/build/finder.go +++ b/ui/build/finder.go @@ -83,6 +83,10 @@ func NewSourceFinder(ctx Context, config Config) (f *finder.Finder) { "TEST_MAPPING", // METADATA file of packages "METADATA", + // Release config contributions. + "release_config_map.textproto", + // Release config allowed duplicate flag declarations. + "duplicate_allowlist.txt", }, IncludeSuffixes: []string{ // .mk files for product/board configuration. @@ -195,6 +199,25 @@ func FindSources(ctx Context, config Config, f *finder.Finder) { ctx.Fatalf("Could not find METADATA: %v", err) } + // Recursively look for all release_config_map.textproto files. + releaseConfigMaps := f.FindNamedAt(".", "release_config_map.textproto") + err = dumpListToFile(ctx, config, releaseConfigMaps, filepath.Join(dumpDir, "release_config_map.list")) + if err != nil { + ctx.Fatalf("Could not find release_config_map.textproto: %v", err) + } + + // Recursively look for all duplicate_allowlist.txt files where we found release_config_map.textproto. + var duplicateAllowlists []string + for _, mapPath := range releaseConfigMaps { + // The only `duplicate_allowlist.txt` files we care about are in the same directory + // as `release_config_map.textproto`. + duplicateAllowlists = append(duplicateAllowlists, f.FindNamedAt(filepath.Dir(mapPath), "duplicate_allowlist.txt")...) + } + err = dumpListToFile(ctx, config, duplicateAllowlists, filepath.Join(dumpDir, "duplicate_allowlist.list")) + if err != nil { + ctx.Fatalf("Could not find duplicate_allowlist.txt: %v", err) + } + // Recursively look for all TEST_MAPPING files. testMappings := f.FindNamedAt(".", "TEST_MAPPING") err = dumpListToFile(ctx, config, testMappings, filepath.Join(dumpDir, "TEST_MAPPING.list")) -- cgit v1.2.3 From 9889bde3c6afe16fdf8bf38150f577121a8e497b Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Wed, 16 Apr 2025 15:52:58 -0700 Subject: Dist ninja files and target_files.zip in a subfolder in soong only diff test ...so that debugging the diffs between the soong only build and the soong plus make build is easier. Test: build/soong/scripts/soong_only_diff_test.py aosp_cf_x86_64_phone Bug: 409368614 Change-Id: Icae53c5bd4c7d37986222efc3094767010ce92ff --- scripts/soong_only_diff_test.py | 44 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/scripts/soong_only_diff_test.py b/scripts/soong_only_diff_test.py index e2a1b322a..1a4eea145 100755 --- a/scripts/soong_only_diff_test.py +++ b/scripts/soong_only_diff_test.py @@ -16,7 +16,9 @@ # import argparse +import glob import os +import shutil import struct import subprocess import sys @@ -105,6 +107,39 @@ def find_build_id() -> str | None: return build_id +def zip_ninja_files(subdistdir: str): + out_dir = os.getenv('OUT_DIR', 'out') + root_dir = os.path.dirname(out_dir) + files_to_zip = [ + *glob.glob(os.path.join(out_dir, "*.ninja"), recursive=False), # ninja files in out/ + *glob.glob(os.path.join(out_dir, "soong", "*.ninja"), recursive=False), # ninja files in out/soong/ + ] + + zip_filename = os.path.join(subdistdir, "ninja_files.zip") + with zipfile.ZipFile(zip_filename, 'w', compression=zipfile.ZIP_DEFLATED) as zipf: + for file in files_to_zip: + zipf.write(filename=file, arcname=os.path.relpath(file, root_dir)) + +def move_artifacts_to_subfolder(product: Product, soong_only: bool): + subdir = "soong_only" if soong_only else "soong_plus_make" + + out_dir = os.getenv('OUT_DIR', 'out') + dist_dir = os.getenv('DIST_DIR', os.path.join(out_dir, 'dist')) + subdistdir = os.path.join(dist_dir, subdir) + if os.path.exists(subdistdir): + shutil.rmtree(subdistdir) + os.makedirs(subdistdir) + zip_ninja_files(subdistdir) + + build_id = find_build_id() + + files_to_move = [ + os.path.join(dist_dir, f'{product.product}-target_files-{build_id}.zip'), # target_files.zip + ] + + for file in files_to_move: + shutil.move(file, subdistdir) + SHA_DIFF_ALLOWLIST = { "IMAGES/init_boot.img", "IMAGES/system.img", @@ -180,8 +215,13 @@ def main(): 'userdebug', ) - soong_only_zip_sha_map = get_zip_sha_map(product, True) - soong_plus_make_zip_sha_map = get_zip_sha_map(product, False) + soong_only = True + soong_only_zip_sha_map = get_zip_sha_map(product, soong_only) + move_artifacts_to_subfolder(product, soong_only) + + soong_only = False + soong_plus_make_zip_sha_map = get_zip_sha_map(product, soong_only) + move_artifacts_to_subfolder(product, soong_only) if not compare_sha_maps(soong_only_zip_sha_map, soong_plus_make_zip_sha_map): sys.exit("target_files.zip differ between soong only build and soong plus make build") -- cgit v1.2.3 From 7639a6f8f03a569b750b563bd970bc03424cefe6 Mon Sep 17 00:00:00 2001 From: Jooyung Han Date: Thu, 17 Apr 2025 12:50:20 +0900 Subject: Fix sbom_test 'deapexer list' doesn't support erofs apex. apex-ls can be used instead. Bug: 380961055 Flag: RELEASE_APEX_USE_EROFS_PREINSTALLED Test: sbom_test.sh with RELEASE_APEX_USE_EROFS_PREINSTALLED Change-Id: I82cdb29cff2c3ea5f35337fad9833fe3f2002552 --- tests/sbom_test.sh | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/sbom_test.sh b/tests/sbom_test.sh index 2ef9e374f..81da22e40 100755 --- a/tests/sbom_test.sh +++ b/tests/sbom_test.sh @@ -267,19 +267,17 @@ function test_sbom_unbundled_apex { out_dir="$(setup)" # run_soong to build com.android.adbd.apex - run_soong "${out_dir}" "sbom deapexer" "com.android.adbd" + run_soong "${out_dir}" "sbom apex-ls" "com.android.adbd" - deapexer=${out_dir}/host/linux-x86/bin/deapexer - debugfs=${out_dir}/host/linux-x86/bin/debugfs_static + apex_ls=${out_dir}/host/linux-x86/bin/apex-ls apex_file=${out_dir}/target/product/module_arm64/system/apex/com.android.adbd.apex echo "============ Diffing files in $apex_file and SBOM" set +e - # deapexer prints the list of all files and directories - # sed extracts the file/directory names + # apex-ls prints the list of all files and directories # grep removes directories # sed removes leading ./ in file names diff -I /system/apex/com.android.adbd.apex -I apex_manifest.pb \ - <($deapexer --debugfs_path=$debugfs list --extents ${apex_file} | sed -E 's#(.*) \[.*\]$#\1#' | grep -v "/$" | sed -E 's#^\./(.*)#\1#' | sort -n) \ + <(${apex_ls} ${apex_file} | grep -v "/$" | sed -E 's#^\./(.*)#\1#' | sort -n) \ <(grep '"fileName": ' ${apex_file}.spdx.json | sed -E 's/.*"fileName": "(.*)",/\1/' | sort -n ) if [ $? != "0" ]; then -- cgit v1.2.3 From 44484b4bf8863a4492c0c4050f1a31f01fd835ef Mon Sep 17 00:00:00 2001 From: Inseob Kim Date: Fri, 11 Apr 2025 18:10:15 +0900 Subject: Add skeleton code for Treble labeling test Treble labeling test is a SELinux test ensuring that platform partitions and vendor partitions are correctly split. The test uses the following as inputs: * preinstalled apps * seapp_contexts files * file_contexts files * A precompiled SEPolicy binary This change adds skeleton code for the Treble labeling test, and a phony target named check-selinux-treble-labeling to run the test manually. Bug: 406185315 Test: m check-selinux-treble-labeling Change-Id: I3bd63bed37d7c31849bc487c716c2a4481611160 --- android/config.go | 4 ++ android/variable.go | 2 + filesystem/android_device.go | 141 +++++++++++++++++++++++++++++++++++++++++++ fsgen/filesystem_creator.go | 21 ++++--- 4 files changed, 158 insertions(+), 10 deletions(-) diff --git a/android/config.go b/android/config.go index ba8412357..2be3270b0 100644 --- a/android/config.go +++ b/android/config.go @@ -2501,3 +2501,7 @@ func (c *config) DeviceManifestFiles() []string { func (c *config) OdmManifestFiles() []string { return c.productVariables.OdmManifestFiles } + +func (c *config) EnforceSELinuxTrebleLabeling() bool { + return Bool(c.productVariables.EnforceSELinuxTrebleLabeling) +} diff --git a/android/variable.go b/android/variable.go index bbb96e845..3da50a326 100644 --- a/android/variable.go +++ b/android/variable.go @@ -555,6 +555,8 @@ type ProductVariables struct { // Will be used to install host tools in soong only builds ProductHostPackages []string `json:",omitempty"` + + EnforceSELinuxTrebleLabeling *bool `json:",omitempty"` } type CompatibilityTestcaseJSON struct { diff --git a/filesystem/android_device.go b/filesystem/android_device.go index 57b75f4e3..36d61c382 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -18,6 +18,7 @@ import ( "cmp" "fmt" "path/filepath" + "regexp" "slices" "sort" "strings" @@ -100,6 +101,9 @@ type DeviceProperties struct { // when dexpreopting apps. So setting this doesn't really do anything except enforce that the // actual kernel version is as specified here. Kernel_version *string + + // Precompiled sepolicy only with system + system_ext + product. Used for SELinux tests. + Precompiled_sepolicy_without_vendor *string `android:"path"` } type androidDevice struct { @@ -281,6 +285,10 @@ func (a *androidDevice) GenerateAndroidBuildActions(ctx android.ModuleContext) { deps = append(deps, a.copyFilesToProductOutForSoongOnly(ctx)) } + trebleLabelingTestTimestamp := a.buildTrebleLabelingTest(ctx) + if ctx.Config().EnforceSELinuxTrebleLabeling() { + validations = append(validations, trebleLabelingTestTimestamp) + } ctx.Build(pctx, android.BuildParams{ Rule: android.Touch, @@ -1276,3 +1284,136 @@ type ApkCertsInfo struct { } var ApkCertsInfoProvider = blueprint.NewProvider[ApkCertsInfo]() + +func findAllPreinstalledApps(partitions []string, fsInfos map[string]FilesystemInfo) android.Paths { + var ret android.Paths + for _, partition := range partitions { + info, ok := fsInfos[partition] + if !ok { + continue + } + // use MustCompile, because if `partition` is invalid, then we already did something wrong + apkPattern := regexp.MustCompile(partition + `/(app|priv-app)/[^/]+/[^/]+\.apk$`) + for _, path := range info.FullInstallPaths { + if !path.IsDir && path.SymlinkTarget == "" && + apkPattern.FindString(path.FullInstallPath.String()) != "" { + ret = append(ret, path.SourcePath) + } + } + } + return android.SortedUniquePaths(ret) +} + +func findInstalledFile(rel string, info FilesystemInfo) android.Path { + for _, path := range info.FullInstallPaths { + if !path.IsDir && path.SymlinkTarget == "" && + strings.HasSuffix(path.FullInstallPath.String(), rel) { + return path.SourcePath + } + } + return nil +} + +func findFilesInPartitions(paths map[string]string, fsInfos map[string]FilesystemInfo) android.Paths { + var ret android.Paths + for partition, rel := range paths { + info, ok := fsInfos[partition] + if !ok { + continue + } + + if path := findInstalledFile(rel, info); path != nil { + ret = append(ret, path) + } + } + return android.SortedUniquePaths(ret) +} + +func (a *androidDevice) buildTrebleLabelingTest(ctx android.ModuleContext) android.Path { + platformPartitions := []string{ + "system", + "system_ext", + "product", + } + + vendorPartitions := []string{ + "vendor", + "odm", + } + + fsInfos := a.getFsInfos(ctx) + + platformApps := findAllPreinstalledApps(platformPartitions, fsInfos) + vendorApps := findAllPreinstalledApps(vendorPartitions, fsInfos) + + platformSeappContextsPaths := map[string]string{ + "system": "system/etc/selinux/plat_seapp_contexts", + "system_ext": "system_ext/etc/selinux/plat_seapp_contexts", + "product": "product/etc/selinux/plat_seapp_contexts", + } + platformSeappContexts := findFilesInPartitions(platformSeappContextsPaths, fsInfos) + + vendorSeappContextsPaths := map[string]string{ + "vendor": "vendor/etc/selinux/vendor_seapp_contexts", + "odm": "odm/etc/selinux/odm_seapp_contexts", + } + vendorSeappContexts := findFilesInPartitions(vendorSeappContextsPaths, fsInfos) + + vendorFileContextsPaths := map[string]string{ + "vendor": "vendor/etc/selinux/vendor_file_contexts", + "odm": "odm/etc/selinux/odm_file_contexts", + } + vendorFileContexts := findFilesInPartitions(vendorFileContextsPaths, fsInfos) + + precompiledSepolicyPaths := map[string]string{ + "odm": "odm/etc/selinux/precompiled_sepolicy", + "vendor": "vendor/etc/selinux/precompiled_sepolicy", + } + precompiledSepolicies := findFilesInPartitions(precompiledSepolicyPaths, fsInfos) + + testTimestamp := android.PathForModuleOut(ctx, "treble_labeling_test.timestamp") + + platformAppsList := android.PathForModuleOut(ctx, "platform_apps.txt") + android.WriteFileRule(ctx, platformAppsList, strings.Join(platformApps.Strings(), "\n")) + vendorAppsList := android.PathForModuleOut(ctx, "vendor_apps.txt") + android.WriteFileRule(ctx, vendorAppsList, strings.Join(vendorApps.Strings(), "\n")) + + rule := android.NewRuleBuilder(pctx, ctx) + + if len(precompiledSepolicies) != 1 { + errorMessage := fmt.Sprintf("number of precompiled_sepolicy must be one but was %q", precompiledSepolicies.Strings()) + rule.Command(). + Text("echo"). + Text(proptools.ShellEscape(errorMessage)). + Text(" && exit 1"). + ImplicitOutput(testTimestamp) + } else if proptools.String(a.deviceProps.Precompiled_sepolicy_without_vendor) == "" { + rule.Command(). + Text("echo"). + Text("cannot find precompiled_sepolicy_without_vendor"). + Text(" && exit 1"). + ImplicitOutput(testTimestamp) + } else { + precompiledSepolicyWithoutVendor := android.PathForModuleSrc(ctx, proptools.String(a.deviceProps.Precompiled_sepolicy_without_vendor)) + rule.Command().BuiltTool("treble_labeling_tests"). + FlagWithInput("--platform_apks ", platformAppsList). + FlagWithInput("--vendor_apks ", vendorAppsList). + FlagWithInput("--precompiled_sepolicy_without_vendor ", precompiledSepolicyWithoutVendor). + FlagWithInput("--precompiled_sepolicy ", precompiledSepolicies[0]). // len(precompiledSepolicies) == 1 + FlagWithInputList("--platform_seapp_contexts ", platformSeappContexts, " "). + FlagWithInputList("--vendor_seapp_contexts ", vendorSeappContexts, " "). + FlagWithInputList("--vendor_file_contexts ", vendorFileContexts, " "). + FlagWithInput("--aapt2_path ", ctx.Config().HostToolPath(ctx, "aapt2")). + Implicits(platformApps). + Implicits(vendorApps). + FlagWithOutput("> ", testTimestamp) + } + + rule.Build("treble_labeling_test", "SELinux Treble Labeling Test") + + if !ctx.Config().KatiEnabled() && proptools.Bool(a.deviceProps.Main_device) { + ctx.Phony("check-selinux-treble-labeling", testTimestamp) + } + + return testTimestamp +} diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go index 1e9037862..5e592059b 100644 --- a/fsgen/filesystem_creator.go +++ b/fsgen/filesystem_creator.go @@ -419,16 +419,17 @@ func (f *filesystemCreator) createDeviceModule( partitionProps.Vbmeta_partitions = vbmetaPartitions deviceProps := &filesystem.DeviceProperties{ - Main_device: proptools.BoolPtr(true), - Ab_ota_updater: proptools.BoolPtr(ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.AbOtaUpdater), - Ab_ota_partitions: ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.AbOtaPartitions, - Ab_ota_postinstall_config: ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.AbOtaPostInstallConfig, - Ramdisk_node_list: proptools.StringPtr(":ramdisk_node_list"), - Android_info: proptools.StringPtr(":" + generatedModuleName(ctx.Config(), "android_info.prop{.txt}")), - Kernel_version: ctx.Config().ProductVariables().BoardKernelVersion, - Partial_ota_update_partitions: ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.BoardPartialOtaUpdatePartitionsList, - Flash_block_size: proptools.StringPtr(ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.BoardFlashBlockSize), - Bootloader_in_update_package: proptools.BoolPtr(ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.BootloaderInUpdatePackage), + Main_device: proptools.BoolPtr(true), + Ab_ota_updater: proptools.BoolPtr(ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.AbOtaUpdater), + Ab_ota_partitions: ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.AbOtaPartitions, + Ab_ota_postinstall_config: ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.AbOtaPostInstallConfig, + Ramdisk_node_list: proptools.StringPtr(":ramdisk_node_list"), + Android_info: proptools.StringPtr(":" + generatedModuleName(ctx.Config(), "android_info.prop{.txt}")), + Kernel_version: ctx.Config().ProductVariables().BoardKernelVersion, + Partial_ota_update_partitions: ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.BoardPartialOtaUpdatePartitionsList, + Flash_block_size: proptools.StringPtr(ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.BoardFlashBlockSize), + Bootloader_in_update_package: proptools.BoolPtr(ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.BootloaderInUpdatePackage), + Precompiled_sepolicy_without_vendor: proptools.StringPtr(":precompiled_sepolicy_without_vendor"), } if bootloader, ok := f.createBootloaderFilegroup(ctx); ok { -- cgit v1.2.3 From 23ce75e3d5a8bcc56e56e736f2e920903232b282 Mon Sep 17 00:00:00 2001 From: kellyhung Date: Thu, 10 Apr 2025 01:06:17 +0000 Subject: Convert module-info under build/soong/java to Soong-only - android_app_import - bootclasspath_fragment - bootclasspath_fragment_test - prebuilt_bootclasspath_fragment - java_device_for_host - java_host_for_device - java_genrule_combiner - java_import - java_import_host - java_api_library - java_sdk_library Bug: 389720048 Bug: 410762216 Test: lunch aosp_cf_x86_64_phone; (SOONG_ONLY=true) Test: m out/target/product/vsoc_x86_64/module-info.json (or refreshmod) Test: Inspect module-info.json diff, CI Change-Id: Ib9df982645137c27883f456cc2d405efceb4b577 --- java/app_import.go | 4 ++++ java/bootclasspath_fragment.go | 4 ++++ java/device_host_converter.go | 7 +++++++ java/genrule_combiner.go | 6 ++++++ java/java.go | 14 ++++++++++++++ java/sdk_library.go | 7 +++++++ 6 files changed, 42 insertions(+) diff --git a/java/app_import.go b/java/app_import.go index 837ab529b..811f4b8e2 100644 --- a/java/app_import.go +++ b/java/app_import.go @@ -355,6 +355,10 @@ func (a *AndroidAppImport) stripEmbeddedJniLibsUnusedArch( func (a *AndroidAppImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.generateAndroidBuildActions(ctx) + moduleInfoJSON := ctx.ModuleInfoJSON() + moduleInfoJSON.Class = []string{"APPS"} + moduleInfoJSON.SystemSharedLibs = []string{"none"} + appInfo := &AppInfo{ Prebuilt: true, } diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go index 17fb8128b..ed3735bae 100644 --- a/java/bootclasspath_fragment.go +++ b/java/bootclasspath_fragment.go @@ -536,6 +536,10 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo // Generate classpaths.proto config b.generateClasspathProtoBuildActions(ctx) + moduleInfoJSON := ctx.ModuleInfoJSON() + moduleInfoJSON.Class = []string{"FAKE"} + moduleInfoJSON.SystemSharedLibs = []string{"none"} + // Gather the bootclasspath fragment's contents. var contents []android.Module ctx.VisitDirectDeps(func(module android.Module) { diff --git a/java/device_host_converter.go b/java/device_host_converter.go index 2c2ef4cc1..b2a3674d2 100644 --- a/java/device_host_converter.go +++ b/java/device_host_converter.go @@ -166,6 +166,13 @@ func (d *DeviceHostConverter) GenerateAndroidBuildActions(ctx android.ModuleCont ctx.CheckbuildFile(d.combinedHeaderJar) } } + + moduleInfoJSON := ctx.ModuleInfoJSON() + moduleInfoJSON.Class = []string{"JAVA_LIBRARIES"} + if d.combinedImplementationJar != nil { + moduleInfoJSON.ClassesJar = []string{d.combinedImplementationJar.String()} + } + moduleInfoJSON.SystemSharedLibs = []string{"none"} } func (d *DeviceHostConverter) HeaderJars() android.Paths { diff --git a/java/genrule_combiner.go b/java/genrule_combiner.go index 357dc2c76..feff60b7e 100644 --- a/java/genrule_combiner.go +++ b/java/genrule_combiner.go @@ -178,6 +178,12 @@ func (j *GenruleCombiner) GenerateAndroidBuildActions(ctx android.ModuleContext) ctx.SetOutputFiles(javaInfo.HeaderJars, ".hjar") android.SetProvider(ctx, JavaInfoProvider, javaInfo) + moduleInfoJSON := ctx.ModuleInfoJSON() + moduleInfoJSON.Class = []string{"JAVA_LIBRARIES"} + if j.combinedImplementationJar != nil { + moduleInfoJSON.ClassesJar = []string{j.combinedImplementationJar.String()} + } + moduleInfoJSON.SystemSharedLibs = []string{"none"} } func (j *GenruleCombiner) GeneratedSourceFiles() android.Paths { diff --git a/java/java.go b/java/java.go index 7bce1b614..7e510e845 100644 --- a/java/java.go +++ b/java/java.go @@ -2828,6 +2828,13 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { } setExtraJavaInfo(ctx, al, javaInfo) android.SetProvider(ctx, JavaInfoProvider, javaInfo) + + moduleInfoJSON := ctx.ModuleInfoJSON() + moduleInfoJSON.Class = []string{"JAVA_LIBRARIES"} + if al.stubsJar != nil { + moduleInfoJSON.ClassesJar = []string{al.stubsJar.String()} + } + moduleInfoJSON.SystemSharedLibs = []string{"none"} } func (al *ApiLibrary) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath { @@ -3315,6 +3322,13 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.SetOutputFiles(android.Paths{j.combinedImplementationFile}, ".jar") buildComplianceMetadata(ctx) + + moduleInfoJSON := ctx.ModuleInfoJSON() + moduleInfoJSON.Class = []string{"JAVA_LIBRARIES"} + if j.combinedImplementationFile != nil { + moduleInfoJSON.ClassesJar = []string{j.combinedImplementationFile.String()} + } + moduleInfoJSON.SystemSharedLibs = []string{"none"} } func (j *Import) maybeInstall(ctx android.ModuleContext, jarName string, outputFile android.Path) { diff --git a/java/sdk_library.go b/java/sdk_library.go index 32a476732..30569fec4 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -1644,6 +1644,13 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) android.SetProvider(ctx, JavaLibraryInfoProvider, JavaLibraryInfo{ PermittedPackages: module.PermittedPackagesForUpdatableBootJars(), }) + + moduleInfoJSON := ctx.ModuleInfoJSON() + moduleInfoJSON.Class = []string{"JAVA_LIBRARIES"} + if module.implementationAndResourcesJar != nil { + moduleInfoJSON.ClassesJar = []string{module.implementationAndResourcesJar.String()} + } + moduleInfoJSON.SystemSharedLibs = []string{"none"} } func setOutputFilesFromJavaInfo(ctx android.ModuleContext, info *JavaInfo) { -- cgit v1.2.3 From f4f7872660b70b71fa9b9928f5879a40a331c831 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Thu, 17 Apr 2025 12:51:41 -0700 Subject: Move merged aconfig files to a dedicated folder Currently, they're under a folder based on the container name, which can be a relatively simple value like "system". This has the potential to conflict with other things, so move them under a merged_aconfig_files folder to be more explicit. Bug: 411402140 Test: Presubmits Change-Id: I92c48cb584e2437cc4a867bcebbc1d3cba4c5feb --- aconfig/codegen/java_aconfig_library_test.go | 2 +- android/aconfig_providers.go | 2 +- apex/apex_test.go | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/aconfig/codegen/java_aconfig_library_test.go b/aconfig/codegen/java_aconfig_library_test.go index e8ce7c76b..a34f48c3c 100644 --- a/aconfig/codegen/java_aconfig_library_test.go +++ b/aconfig/codegen/java_aconfig_library_test.go @@ -62,7 +62,7 @@ func runJavaAndroidMkTest(t *testing.T, bp string) { entry := android.AndroidMkEntriesForTest(t, result.TestContext, module)[0] makeVar := entry.EntryMap["LOCAL_ACONFIG_FILES"] - android.EnsureListContainsSuffix(t, makeVar, "android_common/system/aconfig_merged.pb") + android.EnsureListContainsSuffix(t, makeVar, "android_common/merged_aconfig_files/system/aconfig_merged.pb") } func TestAndroidMkJavaLibrary(t *testing.T) { diff --git a/android/aconfig_providers.go b/android/aconfig_providers.go index 758fe008c..a6c857aa2 100644 --- a/android/aconfig_providers.go +++ b/android/aconfig_providers.go @@ -213,7 +213,7 @@ func mergeAconfigFiles(ctx ModuleContext, container string, inputs Paths, genera return Paths{inputs[0]} } - output := PathForModuleOut(ctx, container, "aconfig_merged.pb") + output := PathForModuleOut(ctx, "merged_aconfig_files", container, "aconfig_merged.pb") if generateRule { ctx.Build(pctx, BuildParams{ diff --git a/apex/apex_test.go b/apex/apex_test.go index 667c535bf..6a30d1328 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -10811,7 +10811,7 @@ func TestAconfigFilesJavaAndCcDeps(t *testing.T) { inputs := []string{ "my_aconfig_declarations_foo/aconfig-cache.pb", - "my_cc_library_bar/android_arm64_armv8-a_shared_apex10000/myapex/aconfig_merged.pb", + "my_cc_library_bar/android_arm64_armv8-a_shared_apex10000/merged_aconfig_files/myapex/aconfig_merged.pb", "my_aconfig_declarations_baz/aconfig-cache.pb", } VerifyAconfigRule(t, &mod, "combine_aconfig_declarations", inputs, "android_common_myapex/aconfig_flags.pb", "", "") @@ -10975,7 +10975,7 @@ func TestAconfigFilesRustDeps(t *testing.T) { "my_aconfig_declarations_foo/aconfig-cache.pb", "my_aconfig_declarations_bar/aconfig-cache.pb", "my_aconfig_declarations_baz/aconfig-cache.pb", - "my_rust_binary/android_arm64_armv8-a_apex10000/myapex/aconfig_merged.pb", + "my_rust_binary/android_arm64_armv8-a_apex10000/merged_aconfig_files/myapex/aconfig_merged.pb", } VerifyAconfigRule(t, &mod, "combine_aconfig_declarations", inputs, "android_common_myapex/aconfig_flags.pb", "", "") VerifyAconfigRule(t, &mod, "create_aconfig_package_map_file", inputs, "android_common_myapex/package.map", "myapex", "package_map") -- cgit v1.2.3 From 78892960db86a52147837a4c58724450631ad54d Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Thu, 17 Apr 2025 19:50:51 +0000 Subject: Handle fsgen partition of override apps If the base app is not listed in PRODUCT_PACKAGES. The previous implementation in ag/33086725 assumed that if an override app is in PRODUCT_PACKAGES, the base app is in PRODUCT_PACKAGES as well. This is not always true. To support this case, a new prop has been added to FsGenState that can be used to lookup partition of the base module. Test: go test ./fsgen Bug: 410570903 Change-Id: I9314b3e52db9e54be6bcae0ab556a1fa5a5a2ecf --- fsgen/filesystem_creator_test.go | 2 +- fsgen/fsgen_mutators.go | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/fsgen/filesystem_creator_test.go b/fsgen/filesystem_creator_test.go index f8b81020e..6fe0db58f 100644 --- a/fsgen/filesystem_creator_test.go +++ b/fsgen/filesystem_creator_test.go @@ -687,7 +687,7 @@ func TestPartitionOfOverrideModules(t *testing.T) { `), }), android.FixtureModifyConfig(func(config android.Config) { - config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.ProductPackages = []string{"system_ext_app", "system_ext_override_app"} + config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.ProductPackages = []string{"system_ext_override_app"} }), ).RunTestWithBp(t, ` android_app { diff --git a/fsgen/fsgen_mutators.go b/fsgen/fsgen_mutators.go index 67f0cd78c..c06df3f29 100644 --- a/fsgen/fsgen_mutators.go +++ b/fsgen/fsgen_mutators.go @@ -78,6 +78,7 @@ type FsGenState struct { type installationProperties struct { Required []string Overrides []string + Partition string } func defaultDepCandidateProps(config android.Config) *depCandidateProps { @@ -277,6 +278,7 @@ func collectDepsMutator(mctx android.BottomUpMutatorContext) { fsGenState.moduleToInstallationProps[mctx.ModuleName()] = installationProperties{ Required: m.RequiredModuleNames(mctx), Overrides: m.Overrides(), + Partition: m.PartitionTag(mctx.DeviceConfig()), } } @@ -349,18 +351,17 @@ func setDepsMutator(mctx android.BottomUpMutatorContext) { // Adds override apps (override_android_app, override_apex, ...) to the partition of their `base` apps. func updatePartitionsOfOverrideModules(mctx android.BottomUpMutatorContext) { if override, ok := mctx.Module().(android.OverrideModule); ok { - fsDeps := mctx.Config().Get(fsGenStateOnceKey).(*FsGenState).fsDeps + fsGenState := mctx.Config().Get(fsGenStateOnceKey).(*FsGenState) + fsDeps := fsGenState.fsDeps overridePartition := mctx.Module().PartitionTag(mctx.DeviceConfig()) if _, ok := (*fsDeps[overridePartition])[mctx.Module().Name()]; !ok { // The override module is not in PRODUCT_PACKAGES return } base := override.GetOverriddenModuleName() - for partition, _ := range fsDeps { - if _, ok := (*fsDeps[partition])[base]; ok { - appendDepIfAppropriate(mctx, fsDeps[partition], partition, android.NativeBridgeDisabled, mctx.Module().Name()) - break - } + if baseModuleProps, ok := fsGenState.moduleToInstallationProps[base]; ok { + partition := baseModuleProps.Partition + appendDepIfAppropriate(mctx, fsDeps[partition], partition, android.NativeBridgeDisabled, mctx.Module().Name()) } } } -- cgit v1.2.3 From e60fe7be0f4b0c2166a4ba5670a83ea1d1d2073a Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Thu, 17 Apr 2025 17:15:25 -0700 Subject: Always use file_contexts_bin_gen in target-files Previously we were using the system image's selinux context. When we autogenerate partitions, we always use file_contexts_bin_gen as the selinux context. But with the handwritten soong image, they use a different selinux context that only has the selinux information for the system image. file_contexts_bin_gen has information for all images. Just hardcode the usage of file_contexts_bin_gen for the target-files.zip package. This is the same as what make does. This selinux contexts file is later used to build the "hermetic" versions of the images in the target-files.zip package, so it's important it has info for all partitions. Bug: 376727180 Test: ./prebuilts/build-tools/linux-x86/bin/py3-cmd build/soong/scripts/soong_only_diff_test.py aosp_cf_x86_64_phone Change-Id: I75a82a035fd76ccd5c0621316a1735e504d50c29 --- filesystem/android_device.go | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/filesystem/android_device.go b/filesystem/android_device.go index 939efa873..fa360ef85 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -149,10 +149,14 @@ type superPartitionDepTagType struct { type targetFilesMetadataDepTagType struct { blueprint.BaseDependencyTag } +type fileContextsDepTagType struct { + blueprint.BaseDependencyTag +} var superPartitionDepTag superPartitionDepTagType var filesystemDepTag partitionDepTagType var targetFilesMetadataDepTag targetFilesMetadataDepTagType +var fileContextsDepTag fileContextsDepTagType func (a *androidDevice) DepsMutator(ctx android.BottomUpMutatorContext) { addDependencyIfDefined := func(dep *string) { @@ -185,6 +189,7 @@ func (a *androidDevice) DepsMutator(ctx android.BottomUpMutatorContext) { func (a *androidDevice) addDepsForTargetFilesMetadata(ctx android.BottomUpMutatorContext) { ctx.AddFarVariationDependencies(ctx.Config().BuildOSTarget.Variations(), targetFilesMetadataDepTag, "liblz4") // host variant + ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), fileContextsDepTag, "file_contexts_bin_gen") } func (a *androidDevice) GenerateAndroidBuildActions(ctx android.ModuleContext) { @@ -721,8 +726,9 @@ func (a *androidDevice) copyMetadataToTargetZip(ctx android.ModuleContext, build }) builder.Command().Textf("cp").Input(android.PathForSource(ctx, "external/zucchini/version_info.h")).Textf(" %s/META/zucchini_config.txt", targetFilesDir.String()) builder.Command().Textf("cp").Input(android.PathForSource(ctx, "system/update_engine/update_engine.conf")).Textf(" %s/META/update_engine_config.txt", targetFilesDir.String()) - if a.getFsInfos(ctx)["system"].ErofsCompressHints != nil { - builder.Command().Textf("cp").Input(a.getFsInfos(ctx)["system"].ErofsCompressHints).Textf(" %s/META/erofs_default_compress_hints.txt", targetFilesDir.String()) + systemFsInfo := a.getFsInfos(ctx)["system"] + if systemFsInfo.ErofsCompressHints != nil { + builder.Command().Textf("cp").Input(systemFsInfo.ErofsCompressHints).Textf(" %s/META/erofs_default_compress_hints.txt", targetFilesDir.String()) } // ab_partitions.txt abPartitionsSorted := android.SortedUniqueStrings(a.deviceProps.Ab_ota_partitions) @@ -739,8 +745,15 @@ func (a *androidDevice) copyMetadataToTargetZip(ctx android.ModuleContext, build writeFileWithNewLines(ctx, abOtaPostInstallConfigFilePath, a.deviceProps.Ab_ota_postinstall_config) builder.Command().Textf("cp").Input(abOtaPostInstallConfigFilePath).Textf(" %s/META/", targetFilesDir) // selinuxfc - if a.getFsInfos(ctx)["system"].SelinuxFc != nil { - builder.Command().Textf("cp").Input(a.getFsInfos(ctx)["system"].SelinuxFc).Textf(" %s/META/file_contexts.bin", targetFilesDir.String()) + fileContextsModule := ctx.GetDirectDepWithTag("file_contexts_bin_gen", fileContextsDepTag) + outputFiles, ok := android.OtherModuleProvider(ctx, fileContextsModule, android.OutputFilesProvider) + if !ok || len(outputFiles.DefaultOutputFiles) != 1 { + ctx.ModuleErrorf("Expected exactly 1 output file from file_contexts_bin_gen") + } else { + selinuxFc := outputFiles.DefaultOutputFiles[0] + if selinuxFc != nil { + builder.Command().Textf("cp").Input(selinuxFc).Textf(" %s/META/file_contexts.bin", targetFilesDir.String()) + } } } // Copy $partition_filesystem_config.txt -- cgit v1.2.3 From a5c9d9d99b96eebe865c143de3b11631d62870dd Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Thu, 17 Apr 2025 21:50:04 +0000 Subject: Fsgen partition of override apps with namespaces Some override modules list the base with their fully qualified soong namespace names. The override mutators run in postDeps while fsgen mutators run in preDeps. This means that the correct base module name cannot be determined by visiting direct deps. As an alternative, this CL uses string split to guess the base module name. Test: go test ./fsgen Bug: 410570903 Change-Id: Ie0b4900fe3d88a6c20c1bedcda4b8d4dedc75e37 --- fsgen/filesystem_creator_test.go | 19 +++++++++++++++++-- fsgen/fsgen_mutators.go | 5 ++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/fsgen/filesystem_creator_test.go b/fsgen/filesystem_creator_test.go index 6fe0db58f..2ccf1b601 100644 --- a/fsgen/filesystem_creator_test.go +++ b/fsgen/filesystem_creator_test.go @@ -678,16 +678,25 @@ func TestPartitionOfOverrideModules(t *testing.T) { prepareForTestWithFsgenBuildComponents, java.PrepareForTestWithJavaBuildComponents, prepareMockRamdiksNodeList, + android.PrepareForTestWithNamespace, android.FixtureMergeMockFs(android.MockFS{ "external/avb/test/data/testkey_rsa4096.pem": nil, "build/soong/fsgen/Android.bp": []byte(` soong_filesystem_creator { name: "foo", + }`), + "mynamespace/Android.bp": []byte(` + soong_namespace{ } - `), + android_app { + name: "system_ext_app_in_namespace", + system_ext_specific: true, + platform_apis: true, + }`), }), android.FixtureModifyConfig(func(config android.Config) { - config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.ProductPackages = []string{"system_ext_override_app"} + config.TestProductVariables.NamespacesToExport = []string{"mynamespace"} + config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.ProductPackages = []string{"system_ext_override_app", "system_ext_override_app_in_namespace"} }), ).RunTestWithBp(t, ` android_app { @@ -699,8 +708,14 @@ override_android_app { name: "system_ext_override_app", base: "system_ext_app", } +override_android_app { + name: "system_ext_override_app_in_namespace", + base: "//mynamespace:system_ext_app_in_namespace", +} `) resolvedDeps := result.TestContext.Config().Get(fsGenStateOnceKey).(*FsGenState).fsDeps["system_ext"] _, overrideAppInSystemExt := (*resolvedDeps)["system_ext_override_app"] android.AssertBoolEquals(t, "Override app should be added to the same partition as the `base`", true, overrideAppInSystemExt) + _, overrideAppInSystemExt = (*resolvedDeps)["system_ext_override_app_in_namespace"] + android.AssertBoolEquals(t, "Override app should be added to the same partition as the `base`", true, overrideAppInSystemExt) } diff --git a/fsgen/fsgen_mutators.go b/fsgen/fsgen_mutators.go index c06df3f29..f19f266a2 100644 --- a/fsgen/fsgen_mutators.go +++ b/fsgen/fsgen_mutators.go @@ -359,7 +359,10 @@ func updatePartitionsOfOverrideModules(mctx android.BottomUpMutatorContext) { return } base := override.GetOverriddenModuleName() - if baseModuleProps, ok := fsGenState.moduleToInstallationProps[base]; ok { + if strings.HasPrefix(base, "//") { // Inside a soong namespace + base = strings.Split(base, ":")[1] + } + if baseModuleProps, ok := fsGenState.moduleToInstallationProps[base]; ok && mctx.Module().Enabled(mctx) && mctx.Module().ExportedToMake() { partition := baseModuleProps.Partition appendDepIfAppropriate(mctx, fsDeps[partition], partition, android.NativeBridgeDisabled, mctx.Module().Name()) } -- cgit v1.2.3 From 5a2c68ac65226c8d20b82ce4e5d4e9c2bec3f814 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Thu, 17 Apr 2025 23:22:02 +0000 Subject: android_filesystem packages autogen rros of apps in soong namespace The autogenerated RROs of apps inside soong namespaces are currently missing in Soong filesystems. This CL introduces a `OtherModuleNamespace` function to use the fully qualified module name for such cases. Bug: 410570903 Test: lunch cf_x86_64_phone-trunk_staging-userdebug NOTICE.xml.gz is the only missing diff Change-Id: I211280d14f1f292ec8511751ab6701d772ae6a30 --- android/early_module_context.go | 5 +++++ filesystem/filesystem.go | 13 +++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/android/early_module_context.go b/android/early_module_context.go index f48723ff8..2c4f97149 100644 --- a/android/early_module_context.go +++ b/android/early_module_context.go @@ -98,6 +98,7 @@ type EarlyModuleContext interface { // Namespace returns the Namespace object provided by the NameInterface set by Context.SetNameInterface, or the // default SimpleNameInterface if Context.SetNameInterface was not called. Namespace() *Namespace + OtherModuleNamespace(ModuleOrProxy) *Namespace // HasMutatorFinished returns true if the given mutator has finished running. // It will panic if given an invalid mutator name. @@ -188,6 +189,10 @@ func (e *earlyModuleContext) Namespace() *Namespace { return e.EarlyModuleContext.Namespace().(*Namespace) } +func (e *earlyModuleContext) OtherModuleNamespace(m ModuleOrProxy) *Namespace { + return e.EarlyModuleContext.OtherModuleNamespace(m).(*Namespace) +} + func (e *earlyModuleContext) OtherModulePropertyErrorf(module ModuleOrProxy, property string, fmt string, args ...interface{}) { e.EarlyModuleContext.OtherModulePropertyErrorf(module, property, fmt, args...) } diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index 64bf139b0..9d8c6fbba 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -1724,6 +1724,15 @@ func assertMaxImageSize(builder *android.RuleBuilder, image android.Path, maxSiz // It visits apps installed in system and system_ext partitions, and adds the autogenerated // RRO modules to its own deps. func addAutogeneratedRroDeps(ctx android.BottomUpMutatorContext) { + overlayModuleName := func(child android.ModuleOrProxy, partition string) string { + ret := java.AutogeneratedRroModuleName(ctx, child.Name(), partition) + // Use the fully qualified name if the app is a soong namespace + if ctx.OtherModuleNamespace(child).Path != "." { + ret = "//" + ctx.OtherModuleNamespace(child).Path + ":" + ret + } + return ret + } + f, ok := ctx.Module().(*filesystem) if !ok { return @@ -1743,10 +1752,10 @@ func addAutogeneratedRroDeps(ctx android.BottomUpMutatorContext) { if parent.Name() == f.Name() && depTag != interPartitionDependencyTag { return false // This is a module listed in deps of vendor/product filesystem } - if vendorOverlay := java.AutogeneratedRroModuleName(ctx, child.Name(), "vendor"); ctx.OtherModuleExists(vendorOverlay) && thisPartition == "vendor" { + if vendorOverlay := overlayModuleName(child, "vendor"); ctx.OtherModuleExists(vendorOverlay) && thisPartition == "vendor" { ctx.AddFarVariationDependencies(nil, dependencyTagWithVisibilityEnforcementBypass, vendorOverlay) } - if productOverlay := java.AutogeneratedRroModuleName(ctx, child.Name(), "product"); ctx.OtherModuleExists(productOverlay) && thisPartition == "product" { + if productOverlay := overlayModuleName(child, "product"); ctx.OtherModuleExists(productOverlay) && thisPartition == "product" { ctx.AddFarVariationDependencies(nil, dependencyTagWithVisibilityEnforcementBypass, productOverlay) } return true -- cgit v1.2.3 From 05f0d57e8d7541301c12e405724837f82bc54a22 Mon Sep 17 00:00:00 2001 From: Satish Yalla Date: Thu, 17 Apr 2025 22:45:15 -0700 Subject: Revert "Upgrade clang to clang-r563880" This reverts commit 634ea6e97f61093b7c9227f61cf06f8ba37313fa. Reason for revert: Droid monitor: Likely culprit for b/411553971 verifying through ABTD before revert submission. This is part of the standard investigation process, and does not mean your CL will be reverted. Bug: 411553971 Change-Id: I7a28be9e812a6b895b8640ebfe2c85af514a13fa --- bpf/bpf.go | 2 +- cc/compiler.go | 5 +---- cc/config/global.go | 7 ++----- cc/stl.go | 2 +- 4 files changed, 5 insertions(+), 11 deletions(-) diff --git a/bpf/bpf.go b/bpf/bpf.go index b0be3e788..deb465dd6 100644 --- a/bpf/bpf.go +++ b/bpf/bpf.go @@ -41,7 +41,7 @@ var ( blueprint.RuleParams{ Depfile: "${out}.d", Deps: blueprint.DepsGCC, - Command: "$relPwd $ccCmd --target=bpf -mcpu=v1 -c $cFlags -MD -MF ${out}.d -o $out $in", + Command: "$relPwd $ccCmd --target=bpf -c $cFlags -MD -MF ${out}.d -o $out $in", CommandDeps: []string{"$ccCmd"}, }, "ccCmd", "cFlags") diff --git a/cc/compiler.go b/cc/compiler.go index 316cd9e1d..949603e40 100644 --- a/cc/compiler.go +++ b/cc/compiler.go @@ -711,10 +711,7 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps if ctx.optimizeForSize() { flags.Local.CFlags = append(flags.Local.CFlags, "-Oz") if !ctx.Config().IsEnvFalse("THINLTO_USE_MLGO") { - if ctx.Arch().ArchType == android.Arm64 { - flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-mllvm,-enable-ml-inliner=release") - flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-mllvm,-ml-inliner-model-selector=arm64-mixed") - } + flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-mllvm,-enable-ml-inliner=release") } } diff --git a/cc/config/global.go b/cc/config/global.go index b91697ded..e81ac0d47 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -292,9 +292,6 @@ var ( "-Wno-error=deprecated", // in external/googletest/googletest // New warnings to be fixed after clang-r522817 "-Wno-error=invalid-offsetof", - // New warnings to be fixed after clang-r563880 - "-Wno-nontrivial-memcall", - "-Wno-invalid-specialization", // Allow using VLA CXX extension. "-Wno-vla-cxx-extension", @@ -388,8 +385,8 @@ var ( // prebuilts/clang default settings. ClangDefaultBase = "prebuilts/clang/host" - ClangDefaultVersion = "clang-r563880" - ClangDefaultShortVersion = "21" + ClangDefaultVersion = "clang-r547379" + ClangDefaultShortVersion = "20" // Directories with warnings from Android.bp files. WarningAllowedProjects = []string{ diff --git a/cc/stl.go b/cc/stl.go index b91a1f1f5..8c4ef0b4a 100644 --- a/cc/stl.go +++ b/cc/stl.go @@ -212,7 +212,7 @@ func (stl *stl) flags(ctx ModuleContext, flags Flags) Flags { "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS=", "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS=", // Use Win32 threads in libc++. - "-D_LIBCPP_HAS_THREAD_API_WIN32=1") + "-D_LIBCPP_HAS_THREAD_API_WIN32=") } } case "libstdc++": -- cgit v1.2.3 From c4165f09aca8da49bdcfcf826219f6a550625715 Mon Sep 17 00:00:00 2001 From: Brian Ryner Date: Thu, 10 Apr 2025 18:23:28 +0000 Subject: Run the cipd proxy server at soong startup, if enabled by a flag. Bug: 400695406 Test: none Change-Id: I5a151869e802cadfab2661dbbe8a723472e086c6 --- ui/build/Android.bp | 1 + ui/build/build.go | 5 ++++ ui/build/cipd.go | 65 +++++++++++++++++++++++++++++++++++++++++++ ui/build/cipd_proxy_policy.pb | 5 ++++ ui/build/config.go | 7 +++++ ui/build/ninja.go | 3 ++ 6 files changed, 86 insertions(+) create mode 100644 ui/build/cipd.go create mode 100644 ui/build/cipd_proxy_policy.pb diff --git a/ui/build/Android.bp b/ui/build/Android.bp index a868d6acb..80fc6ab93 100644 --- a/ui/build/Android.bp +++ b/ui/build/Android.bp @@ -51,6 +51,7 @@ bootstrap_go_package { srcs: [ "androidmk_denylist.go", "build.go", + "cipd.go", "cleanbuild.go", "config.go", "context.go", diff --git a/ui/build/build.go b/ui/build/build.go index 781ca182f..79c461be0 100644 --- a/ui/build/build.go +++ b/ui/build/build.go @@ -329,6 +329,11 @@ func Build(ctx Context, config Config) { close(rbeCh) } + if config.RunCIPDProxyServer() { + cipdProxy := startCIPDProxyServer(ctx, config) + defer cipdProxy.Stop() + } + if what&RunProductConfig != 0 { runMakeProductConfig(ctx, config) diff --git a/ui/build/cipd.go b/ui/build/cipd.go new file mode 100644 index 000000000..da0936a67 --- /dev/null +++ b/ui/build/cipd.go @@ -0,0 +1,65 @@ +// 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 build + +import ( + "bufio" + "log" + "path/filepath" + "strings" +) + +const ( + cipdProxyPolicyPath = "build/soong/ui/build/cipd_proxy_policy.pb" + cipdProxyUrlKey = "CIPD_PROXY_URL" +) + +type cipdProxy struct { + cmd *Cmd +} + +func startCIPDProxyServer(ctx Context, config Config) cipdProxy { + ctx.Status.Status("Starting CIPD proxy server...") + + cipdPath := filepath.Join("prebuilts/cipd", config.HostPrebuiltTag(), "cipd") + cmd := Command(ctx, config, "cipd", cipdPath, "proxy", "-proxy-policy", cipdProxyPolicyPath) + stdout, err := cmd.StdoutPipe() + if err != nil { + log.Fatal(err) + } + + if err := cmd.Start(); err != nil { + log.Fatal(err) + } + + bufReader := bufio.NewReader(stdout) + for { + l, err := bufReader.ReadString('\n') + if err != nil { + log.Fatal(err) + } + if strings.HasPrefix(l, cipdProxyUrlKey) { + proxyUrl := l[len(cipdProxyUrlKey)+1:] + config.environ.Set(cipdProxyUrlKey, proxyUrl) + ctx.Printf("Started CIPD proxy listening on %s", proxyUrl) + break + } + } + return cipdProxy{cmd: cmd} +} + +func (c *cipdProxy) Stop() { + c.cmd.Process.Kill() +} diff --git a/ui/build/cipd_proxy_policy.pb b/ui/build/cipd_proxy_policy.pb new file mode 100644 index 000000000..aa767ba06 --- /dev/null +++ b/ui/build/cipd_proxy_policy.pb @@ -0,0 +1,5 @@ +allowed_remotes: "chrome-infra-packages.appspot.com" +resolve_version { + allow_tags: true + allow_refs: false +} diff --git a/ui/build/config.go b/ui/build/config.go index d31a0958a..92a88bbe5 100644 --- a/ui/build/config.go +++ b/ui/build/config.go @@ -106,6 +106,7 @@ type configImpl struct { buildFromSourceStub bool incrementalBuildActions bool ensureAllowlistIntegrity bool // For CI builds - make sure modules are mixed-built + runCIPDProxyServer bool // From the product config katiArgs []string @@ -988,6 +989,8 @@ func (c *configImpl) parseArgs(ctx Context, args []string) { } } else if arg == "--ensure-allowlist-integrity" { c.ensureAllowlistIntegrity = true + } else if arg == "--run-cipd-proxy-server" { + c.runCIPDProxyServer = true } else if len(arg) > 0 && arg[0] == '-' { parseArgNum := func(def int) int { if len(arg) > 2 { @@ -1904,6 +1907,10 @@ func (c *configImpl) EnsureAllowlistIntegrity() bool { return c.ensureAllowlistIntegrity } +func (c *configImpl) RunCIPDProxyServer() bool { + return c.runCIPDProxyServer +} + // Returns a Time object if one was passed via a command-line flag. // Otherwise returns the passed default. func (c *configImpl) BuildStartedTimeOrDefault(defaultTime time.Time) time.Time { diff --git a/ui/build/ninja.go b/ui/build/ninja.go index e2a568fad..47975d11f 100644 --- a/ui/build/ninja.go +++ b/ui/build/ninja.go @@ -256,6 +256,9 @@ func runNinja(ctx Context, config Config, ninjaArgs []string) { // Directory for ExecutionMetrics "SOONG_METRICS_AGGREGATION_DIR", + + // CIPD proxy + "CIPD_PROXY_URL", }, config.BuildBrokenNinjaUsesEnvVars()...)...) } -- cgit v1.2.3 From bdd5a0f899d79a2fb7ad5ea242bf755b247c452b Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Fri, 18 Apr 2025 17:52:54 +0000 Subject: Add the override variants to allInstalledModules The override variants are currently missed by allInstalledModules, due to which downstream build rules like apkcerts.txt and apekkeys.txt are missing information about override modules. This CL adds them by casting the visited module to OverridableModule. WalkDepsProxy has been updated to the non proxy implementation. Bug: 410570253 Test: lunch cf_x86_64_phone-trunk_staging-userdebug Test: m nothing --no-skip-soong-tests Test: Built make and soong target_files.zip and verified that META/apkcerts.txt and META/apexkeys.txt are identical Change-Id: I26161c04b7a2e2818b27f8b4f7c8bf6a791066f0 --- android/symbols.go | 2 +- android/test_suites.go | 4 ++-- ci_tests/ci_test_package_zip.go | 10 +++++----- filesystem/android_device.go | 24 ++++++++++++++---------- filesystem/filesystem_test.go | 40 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 62 insertions(+), 18 deletions(-) diff --git a/android/symbols.go b/android/symbols.go index 20022da4c..3810b2e9a 100644 --- a/android/symbols.go +++ b/android/symbols.go @@ -64,7 +64,7 @@ type symbolsContext interface { // Defines the build rules to generate the symbols.zip file and the merged elf mapping textproto // file. Modules in depModules that provide [SymbolInfosProvider] and are exported to make // will be listed in the symbols.zip and the merged proto file. -func BuildSymbolsZip(ctx symbolsContext, depModules []ModuleProxy, iden string, symbolsZipFile, mergedMappingProtoFile WritablePath) { +func BuildSymbolsZip(ctx symbolsContext, depModules []ModuleOrProxy, iden string, symbolsZipFile, mergedMappingProtoFile WritablePath) { var allSymbolicOutputPaths, allElfMappingProtoPaths Paths for _, mod := range depModules { if commonInfo, _ := OtherModuleProvider(ctx, mod, CommonModuleInfoProvider); commonInfo.SkipAndroidMkProcessing { diff --git a/android/test_suites.go b/android/test_suites.go index fc40429af..3ae3b1a3c 100644 --- a/android/test_suites.go +++ b/android/test_suites.go @@ -128,9 +128,9 @@ type testSuiteInstallsInfo struct { var testSuiteInstallsInfoProvider = blueprint.NewProvider[testSuiteInstallsInfo]() -type testModulesInstallsMap map[ModuleProxy]InstallPaths +type testModulesInstallsMap map[ModuleOrProxy]InstallPaths -func (t testModulesInstallsMap) testModules() []ModuleProxy { +func (t testModulesInstallsMap) testModules() []ModuleOrProxy { return slices.Collect(maps.Keys(t)) } diff --git a/ci_tests/ci_test_package_zip.go b/ci_tests/ci_test_package_zip.go index 94963ffb7..737cca376 100644 --- a/ci_tests/ci_test_package_zip.go +++ b/ci_tests/ci_test_package_zip.go @@ -184,9 +184,9 @@ func (p *testPackageZip) GenerateAndroidBuildActions(ctx android.ModuleContext) ctx.SetOutputFiles(android.Paths{p.output}, "") } -func getAllTestModules(ctx android.ModuleContext) []android.ModuleProxy { - var ret []android.ModuleProxy - ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool { +func getAllTestModules(ctx android.ModuleContext) []android.ModuleOrProxy { + var ret []android.ModuleOrProxy + ctx.WalkDeps(func(child, parent android.Module) bool { if info, ok := android.OtherModuleProvider(ctx, child, android.CommonModuleInfoProvider); !ok || !info.Enabled { return false } @@ -203,7 +203,7 @@ func getAllTestModules(ctx android.ModuleContext) []android.ModuleProxy { } }) ret = android.FirstUniqueInPlace(ret) - slices.SortFunc(ret, func(a, b android.ModuleProxy) int { + slices.SortFunc(ret, func(a, b android.ModuleOrProxy) int { return cmp.Compare(a.String(), b.String()) }) return ret @@ -239,7 +239,7 @@ func createOutput(ctx android.ModuleContext, pctx android.PackageContext) androi return output } -func createSymbolsZip(ctx android.ModuleContext, allModules []android.ModuleProxy) { +func createSymbolsZip(ctx android.ModuleContext, allModules []android.ModuleOrProxy) { symbolsZipFile := android.PathForModuleOut(ctx, "symbols.zip") symbolsMappingFile := android.PathForModuleOut(ctx, "symbols-mapping.textproto") android.BuildSymbolsZip(ctx, allModules, ctx.ModuleName(), symbolsZipFile, symbolsMappingFile) diff --git a/filesystem/android_device.go b/filesystem/android_device.go index bc065bc50..e7eaaaae6 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -358,7 +358,7 @@ type installedOwnerInfo struct { // 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.ModuleProxy { +func (a *androidDevice) allInstalledModules(ctx android.ModuleContext) []android.ModuleOrProxy { fsInfoMap := a.getFsInfos(ctx) allOwners := make(map[string][]installedOwnerInfo) @@ -372,13 +372,17 @@ func (a *androidDevice) allInstalledModules(ctx android.ModuleContext) []android } } - ret := []android.ModuleProxy{} - ctx.WalkDepsProxy(func(mod, _ android.ModuleProxy) bool { + ret := []android.ModuleOrProxy{} + ctx.WalkDeps(func(mod, _ android.Module) bool { commonInfo, ok := android.OtherModuleProvider(ctx, mod, android.CommonModuleInfoProvider) if !(ok && commonInfo.ExportedToMake) { return false } - if variations, ok := allOwners[ctx.OtherModuleName(mod)]; ok && + name := ctx.OtherModuleName(mod) + if o, ok := mod.(android.OverridableModule); ok && o.GetOverriddenBy() != "" { + name = o.GetOverriddenBy() + } + if variations, ok := allOwners[name]; ok && android.InList(installedOwnerInfo{ Variation: ctx.OtherModuleSubDir(mod), Prebuilt: commonInfo.IsPrebuilt, @@ -392,7 +396,7 @@ func (a *androidDevice) allInstalledModules(ctx android.ModuleContext) []android ret = android.FirstUniqueInPlace(ret) // Sort the modules by their names and variants - slices.SortFunc(ret, func(a, b android.ModuleProxy) int { + slices.SortFunc(ret, func(a, b android.ModuleOrProxy) int { return cmp.Compare(a.String(), b.String()) }) return ret @@ -403,7 +407,7 @@ type symbolicOutputInfo struct { symbolicOutputPath android.InstallPath } -func (a *androidDevice) buildSymbolsZip(ctx android.ModuleContext, allInstalledModules []android.ModuleProxy) { +func (a *androidDevice) buildSymbolsZip(ctx android.ModuleContext, allInstalledModules []android.ModuleOrProxy) { a.symbolsZipFile = android.PathForModuleOut(ctx, "symbols.zip") a.symbolsMappingFile = android.PathForModuleOut(ctx, "symbols-mapping.textproto") android.BuildSymbolsZip(ctx, allInstalledModules, ctx.ModuleName(), a.symbolsZipFile, a.symbolsMappingFile) @@ -483,7 +487,7 @@ func (a *androidDevice) MakeVars(_ android.MakeVarsModuleContext) []android.Modu return nil } -func (a *androidDevice) buildProguardZips(ctx android.ModuleContext, allInstalledModules []android.ModuleProxy) { +func (a *androidDevice) buildProguardZips(ctx android.ModuleContext, allInstalledModules []android.ModuleOrProxy) { dictZip := android.PathForModuleOut(ctx, "proguard-dict.zip") dictZipBuilder := android.NewRuleBuilder(pctx, ctx) dictZipCmd := dictZipBuilder.Command().BuiltTool("soong_zip").Flag("-d").FlagWithOutput("-o ", dictZip) @@ -544,7 +548,7 @@ type targetFilesystemZipCopy struct { destSubdir string } -func (a *androidDevice) buildTargetFilesZip(ctx android.ModuleContext, allInstalledModules []android.ModuleProxy) { +func (a *androidDevice) buildTargetFilesZip(ctx android.ModuleContext, allInstalledModules []android.ModuleOrProxy) { targetFilesDir := android.PathForModuleOut(ctx, "target_files_dir") targetFilesZip := android.PathForModuleOut(ctx, "target_files.zip") otaFilesZip := android.PathForModuleOut(ctx, "ota.zip") @@ -719,7 +723,7 @@ func writeFileWithNewLines(ctx android.ModuleContext, path android.WritablePath, android.WriteFileRule(ctx, path, builder.String()) } -func (a *androidDevice) copyMetadataToTargetZip(ctx android.ModuleContext, builder *android.RuleBuilder, targetFilesDir android.ModuleOutPath, allInstalledModules []android.ModuleProxy) { +func (a *androidDevice) copyMetadataToTargetZip(ctx android.ModuleContext, builder *android.RuleBuilder, targetFilesDir android.ModuleOutPath, allInstalledModules []android.ModuleOrProxy) { // Create a META/ subdirectory builder.Command().Textf("mkdir -p %s/META", targetFilesDir.String()) if proptools.Bool(a.deviceProps.Ab_ota_updater) { @@ -1180,7 +1184,7 @@ func (a *androidDevice) extractKernelVersionAndConfigs(ctx android.ModuleContext return extractedVersionFile, extractedConfigsFile } -func (a *androidDevice) buildApkCertsInfo(ctx android.ModuleContext, allInstalledModules []android.ModuleProxy) android.Path { +func (a *androidDevice) buildApkCertsInfo(ctx android.ModuleContext, allInstalledModules []android.ModuleOrProxy) android.Path { // TODO (spandandas): Add compressed formatLine := func(cert java.Certificate, name, partition string) string { pem := cert.AndroidMkString() diff --git a/filesystem/filesystem_test.go b/filesystem/filesystem_test.go index 2e7f478ff..b493b5e2f 100644 --- a/filesystem/filesystem_test.go +++ b/filesystem/filesystem_test.go @@ -865,3 +865,43 @@ func TestFileSystemWithNativeBridgeDeps(t *testing.T) { android.AssertStringListContains(t, "missing entry", fs.entries, e) } } + +func TestApkCertsOverrideApps(t *testing.T) { + result := android.GroupFixturePreparers( + fixture, + android.PrepareForNativeBridgeEnabled, + android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { + ctx.RegisterModuleType("android_device", AndroidDeviceFactory) + }), + ).RunTestWithBp(t, ` + android_device { + name: "mydevice", + system_partition_name: "myfilesystem", + } + android_filesystem { + name: "myfilesystem", + compile_multilib: "both", + deps: ["app", "override_app"], + } + android_app { + name: "app", + platform_apis: true, + } + override_android_app { + name: "override_app", + base: "app", + } + cc_library_host_shared { + name: "liblz4", + } + java_genrule { + name: "file_contexts_bin_gen", + out: ["file_contexts.bin"], + } + `) + + apkCerts := result.ModuleForTests(t, "mydevice", "android_x86_64_silvermont").Output("apkcerts_without_app_sets.txt") + content := android.ContentFromFileRuleForTests(t, result.TestContext, apkCerts) + expected := `name="override_app.apk" certificate="build/make/target/product/security/testkey.x509.pem" private_key="build/make/target/product/security/testkey.pk8" partition="system"` + "\n" + android.AssertStringEquals(t, "apkcerts.txt contains override apps info", expected, content) +} -- cgit v1.2.3 From 80260e2f68986270ae1a6f1aea00b4677304b7aa Mon Sep 17 00:00:00 2001 From: Marybeth Fair Date: Wed, 9 Apr 2025 13:59:40 -0400 Subject: Connect ACONFIG_STORAGE_VERSION to aconfig --version When build flag RELEASE_ACONFIG_STORAGE_VERSION, the aconfig build time binary will create aconfig storage files with the given version. Instead of having a new launch version for each change, we can update this value. Chose a default of 2 bc 2 already launched all the way. From now on, we'll use Gantry to release new versions without having to update the build system or declare a new flag or change the aconfig binary!! Bug: 377311211 Flag: Build.RELEASE_ACONFIG_STORAGE_VERSION Test: manual Change-Id: Ibb8e2795bb25cfbc43dce1413e5afd081706eb90 --- aconfig/all_aconfig_declarations.go | 14 +++++--------- android/config.go | 10 ++++++++++ apex/builder.go | 9 ++------- filesystem/aconfig_files.go | 10 ++-------- 4 files changed, 19 insertions(+), 24 deletions(-) diff --git a/aconfig/all_aconfig_declarations.go b/aconfig/all_aconfig_declarations.go index 174aea186..4165d2447 100644 --- a/aconfig/all_aconfig_declarations.go +++ b/aconfig/all_aconfig_declarations.go @@ -17,7 +17,6 @@ package aconfig import ( "fmt" "slices" - "strconv" "android/soong/android" @@ -237,10 +236,7 @@ func (this *allAconfigDeclarationsSingleton) GenerateSingletonBuildActions(ctx a }) ctx.Phony("all_aconfig_declarations_textproto", this.releaseMap[rcName].intermediateTextProtoPath) - storageFilesVersion := 1 - if ctx.Config().ReleaseFingerprintAconfigPackages() { - storageFilesVersion = 2 - } + storageFilesVersion := ctx.Config().ReleaseAconfigStorageVersion() const container = "all_aconfig_declarations" ctx.Build(pctx, android.BuildParams{ @@ -251,7 +247,7 @@ func (this *allAconfigDeclarationsSingleton) GenerateSingletonBuildActions(ctx a Args: map[string]string{ "container": container, "cache_files": android.JoinPathsWithPrefix(cacheFiles, "--cache "), - "version": strconv.Itoa(storageFilesVersion), + "version": storageFilesVersion, }, }) ctx.Phony(allAconfigDeclarationsStorage, this.releaseMap[rcName].intermediateStoragePackageMap) @@ -264,7 +260,7 @@ func (this *allAconfigDeclarationsSingleton) GenerateSingletonBuildActions(ctx a Args: map[string]string{ "container": container, "cache_files": android.JoinPathsWithPrefix(cacheFiles, "--cache "), - "version": strconv.Itoa(storageFilesVersion), + "version": storageFilesVersion, }, }) ctx.Phony(allAconfigDeclarationsStorage, this.releaseMap[rcName].intermediateStorageFlagMap) @@ -277,7 +273,7 @@ func (this *allAconfigDeclarationsSingleton) GenerateSingletonBuildActions(ctx a Args: map[string]string{ "container": container, "cache_files": android.JoinPathsWithPrefix(cacheFiles, "--cache "), - "version": strconv.Itoa(storageFilesVersion), + "version": storageFilesVersion, }, }) ctx.Phony(allAconfigDeclarationsStorage, this.releaseMap[rcName].intermediateStorageFlagInfo) @@ -290,7 +286,7 @@ func (this *allAconfigDeclarationsSingleton) GenerateSingletonBuildActions(ctx a Args: map[string]string{ "container": container, "cache_files": android.JoinPathsWithPrefix(cacheFiles, "--cache "), - "version": strconv.Itoa(storageFilesVersion), + "version": storageFilesVersion, }, }) ctx.Phony(allAconfigDeclarationsStorage, this.releaseMap[rcName].intermediateStorageFlagVal) diff --git a/android/config.go b/android/config.go index 75f540452..845093784 100644 --- a/android/config.go +++ b/android/config.go @@ -290,6 +290,7 @@ func (c Config) ReleaseUseSystemFeatureBuildFlags() bool { return c.config.productVariables.GetBuildFlagBool("RELEASE_USE_SYSTEM_FEATURE_BUILD_FLAGS") } +// TODO: b/409598478 - Remove FINGERPRINT build flag. func (c Config) ReleaseFingerprintAconfigPackages() bool { return c.config.productVariables.GetBuildFlagBool("RELEASE_FINGERPRINT_ACONFIG_PACKAGES") } @@ -302,6 +303,15 @@ func (c Config) ReleaseUseSparseEncoding() bool { return c.config.productVariables.GetBuildFlagBool("RELEASE_SOONG_SPARSE_ENCODING") } +func (c Config) ReleaseAconfigStorageVersion() string { + if val, exists := c.GetBuildFlag("RELEASE_ACONFIG_STORAGE_VERSION"); exists { + return val + } else { + // Default value is 2. + return "2" + } +} + // A DeviceConfig object represents the configuration for a particular device // being built. For now there will only be one of these, but in the future there // may be multiple devices being built. diff --git a/apex/builder.go b/apex/builder.go index 3fda3c5f4..308ce0fbf 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -278,12 +278,7 @@ func (a *apexBundle) buildAconfigFiles(ctx android.ModuleContext) []apexFile { }) files = append(files, newApexFile(ctx, apexAconfigFile, "aconfig_flags", "etc", etc, android.ModuleProxy{})) - // To enable fingerprint, we need to have v2 storage files. The default version is 1. - storageFilesVersion := 1 - if ctx.Config().ReleaseFingerprintAconfigPackages() { - storageFilesVersion = 2 - } - + storageFilesVersion := ctx.Config().ReleaseAconfigStorageVersion() for _, info := range createStorageInfo { outputFile := android.PathForModuleOut(ctx, info.Output_file) ctx.Build(pctx, android.BuildParams{ @@ -295,7 +290,7 @@ func (a *apexBundle) buildAconfigFiles(ctx android.ModuleContext) []apexFile { "container": ctx.ModuleName(), "file_type": info.File_type, "cache_files": android.JoinPathsWithPrefix(aconfigFiles, "--cache "), - "version": strconv.Itoa(storageFilesVersion), + "version": storageFilesVersion, }, }) files = append(files, newApexFile(ctx, outputFile, info.File_type, "etc", etc, android.ModuleProxy{})) diff --git a/filesystem/aconfig_files.go b/filesystem/aconfig_files.go index 66d883339..ac620876b 100644 --- a/filesystem/aconfig_files.go +++ b/filesystem/aconfig_files.go @@ -16,7 +16,6 @@ package filesystem import ( "android/soong/android" - "strconv" "strings" "github.com/google/blueprint" @@ -97,12 +96,7 @@ func (f *filesystem) buildAconfigFlagsFiles( f.appendToEntry(ctx, installAconfigFlagsPath) *platformGeneratedFiles = append(*platformGeneratedFiles, installPath.String()) - // To enable fingerprint, we need to have v2 storage files. The default version is 1. - storageFilesVersion := 1 - if ctx.Config().ReleaseFingerprintAconfigPackages() { - storageFilesVersion = 2 - } - + storageFilesVersion := ctx.Config().ReleaseAconfigStorageVersion() installAconfigStorageDir := installEtcDir.Join(ctx, "aconfig") builder.Command().Text("mkdir -p").Text(installAconfigStorageDir.String()) @@ -116,7 +110,7 @@ func (f *filesystem) buildAconfigFlagsFiles( Args: map[string]string{ "container": container, "fileType": fileType, - "version": strconv.Itoa(storageFilesVersion), + "version": storageFilesVersion, }, }) builder.Command(). -- cgit v1.2.3 From 3a69855992e55ac6b6b5cfa11b574cef63add9fe Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Fri, 18 Apr 2025 13:03:41 -0700 Subject: Don't add a namespace prefix if the namespace is exported to make Soong-only builds would always add the soong namespace as a prefix to the module target if the module was in a namespace. This doesn't match what make does. Make would never add a namespace prefix, but it would also only see / generate a phony target for the modules in namespaces that are listed in PRODUCT_SOONG_NAMESPACES. Replicate this functionality in soong. I've also kept the namespace-prefix targets regardless of if the namespace is in PRODUCT_SOONG_NAMESPACES or not. Bug: 411694367 Test: m libg3a.af_test Test: diffed the ninja files, the only differences are in the -packaging ninja file, as more phonies are created now. Change-Id: Ie9202ef753ffe34a2ed72dc89d08ca68a92750df --- android/androidmk.go | 12 +++++--- android/module.go | 86 +++++++++++++++++++++++++++------------------------- apex/apex.go | 4 +-- java/sdk_library.go | 6 ++-- 4 files changed, 57 insertions(+), 51 deletions(-) diff --git a/android/androidmk.go b/android/androidmk.go index a20b0d152..810aedc82 100644 --- a/android/androidmk.go +++ b/android/androidmk.go @@ -570,10 +570,12 @@ func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod Module) { a.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", proptools.Bool(base.commonProperties.No_full_install)) } + moduleBuildTargetsInfo := OtherModuleProviderOrDefault(ctx, mod, ModuleBuildTargetsProvider) + if info.UncheckedModule { a.SetBool("LOCAL_DONT_CHECK_MODULE", true) - } else if info.CheckbuildTarget != nil { - a.SetPath("LOCAL_CHECKED_MODULE", info.CheckbuildTarget) + } else if moduleBuildTargetsInfo.CheckbuildTarget != nil { + a.SetPath("LOCAL_CHECKED_MODULE", moduleBuildTargetsInfo.CheckbuildTarget) } else { a.SetOptionalPath("LOCAL_CHECKED_MODULE", a.OutputFile) } @@ -1528,10 +1530,12 @@ func (a *AndroidMkInfo) fillInEntries(ctx fillInEntriesContext, mod Module, comm helperInfo.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", commonInfo.NoFullInstall) } + moduleBuildTargetsInfo := OtherModuleProviderOrDefault(ctx, mod, ModuleBuildTargetsProvider) + if info.UncheckedModule { helperInfo.SetBool("LOCAL_DONT_CHECK_MODULE", true) - } else if info.CheckbuildTarget != nil { - helperInfo.SetPath("LOCAL_CHECKED_MODULE", info.CheckbuildTarget) + } else if moduleBuildTargetsInfo.CheckbuildTarget != nil { + helperInfo.SetPath("LOCAL_CHECKED_MODULE", moduleBuildTargetsInfo.CheckbuildTarget) } else { helperInfo.SetOptionalPath("LOCAL_CHECKED_MODULE", a.OutputFile) } diff --git a/android/module.go b/android/module.go index 40fa835f5..9561e422a 100644 --- a/android/module.go +++ b/android/module.go @@ -1684,20 +1684,6 @@ func (m *ModuleBase) VintfFragments(ctx ConfigurableEvaluatorContext) []string { return m.base().baseProperties.Vintf_fragments.GetOrDefault(m.ConfigurableEvaluator(ctx), nil) } -func (m *ModuleBase) generateVariantTarget(ctx *moduleContext) { - namespacePrefix := ctx.Namespace().id - if namespacePrefix != "" { - namespacePrefix = namespacePrefix + "-" - } - - if !ctx.uncheckedModule && !shouldSkipAndroidMkProcessing(ctx, m) { - name := namespacePrefix + ctx.module.base().BaseModuleName() + "-" + ctx.ModuleSubDir() + "-checkbuild" - ctx.Phony(name, ctx.checkbuildFiles...) - ctx.checkbuildTarget = PathForPhony(ctx, name) - } - -} - // generateModuleTarget generates phony targets so that you can do `m `. // It will be run on every variant of the module, so it relies on the fact that phony targets // are deduped to merge all the deps from different variants together. @@ -1707,15 +1693,38 @@ func (m *ModuleBase) generateModuleTarget(ctx *moduleContext, testSuiteInstalls if nameSpace != "." { namespacePrefix = strings.ReplaceAll(nameSpace, "/", ".") + "-" } + shouldSkipAndroidMk := shouldSkipAndroidMkProcessing(ctx, m) + + phony := func(suffix string, deps Paths) string { + if ctx.Config().KatiEnabled() { + suffix += "-soong" + } + var ret string + // Create a target without the namespace prefix if it's exported to make. One of the + // conditions for being exported to make is that the namespace is in + // PRODUCT_SOONG_NAMESPACES, so historically that would mean that make would create the + // phonies for those modules as if they weren't in any namespace. + if !shouldSkipAndroidMk { + ret = ctx.module.base().BaseModuleName() + suffix + ctx.Phony(ret, deps...) + } + // Create another phony for building with the namespace specified. This can be used + // regardless of if the namespace is in PRODUCT_SOONG_NAMESPACES or not. + if nameSpace != "." { + ctx.Phony(namespacePrefix+ctx.module.base().BaseModuleName()+suffix, deps...) + } + return ret + } var deps Paths var info ModuleBuildTargetsInfo - if len(ctx.installFiles) > 0 && !shouldSkipAndroidMkProcessing(ctx, m) { - name := namespacePrefix + ctx.module.base().BaseModuleName() + "-install" + if len(ctx.installFiles) > 0 && !shouldSkipAndroidMk { installFiles := ctx.installFiles.Paths() - ctx.Phony(name, installFiles...) - info.InstallTarget = PathForPhony(ctx, name) + name := phony("-install", installFiles) + if name != "" { + info.InstallTarget = PathForPhony(ctx, name) + } deps = append(deps, installFiles...) } @@ -1723,15 +1732,17 @@ func (m *ModuleBase) generateModuleTarget(ctx *moduleContext, testSuiteInstalls // not be created if the module is not exported to make. // Those could depend on the build target and fail to compile // for the current build target. - if (!ctx.Config().KatiEnabled() || !shouldSkipAndroidMkProcessing(ctx, m)) && !ctx.uncheckedModule && ctx.checkbuildTarget != nil { - name := namespacePrefix + ctx.module.base().BaseModuleName() + "-checkbuild" - ctx.Phony(name, ctx.checkbuildTarget) - deps = append(deps, ctx.checkbuildTarget) + if !shouldSkipAndroidMk && !ctx.uncheckedModule { + phony("-checkbuild", ctx.checkbuildFiles) + checkbuildTarget := phony("-"+ctx.ModuleSubDir()+"-checkbuild", ctx.checkbuildFiles) + if checkbuildTarget != "" { + info.CheckbuildTarget = PathForPhony(ctx, checkbuildTarget) + } + deps = append(deps, ctx.checkbuildFiles...) } - if outputFiles, err := outputFilesForModule(ctx, ctx.Module(), ""); err == nil && len(outputFiles) > 0 && !shouldSkipAndroidMkProcessing(ctx, m) { - name := namespacePrefix + ctx.module.base().BaseModuleName() + "-outputs" - ctx.Phony(name, outputFiles...) + if outputFiles, err := outputFilesForModule(ctx, ctx.Module(), ""); err == nil && len(outputFiles) > 0 && !shouldSkipAndroidMk { + phony("-outputs", outputFiles) deps = append(deps, outputFiles...) } @@ -1740,21 +1751,16 @@ func (m *ModuleBase) generateModuleTarget(ctx *moduleContext, testSuiteInstalls } if len(deps) > 0 { - suffix := "" - if ctx.Config().KatiEnabled() { - suffix = "-soong" - } - - ctx.Phony(namespacePrefix+ctx.module.base().BaseModuleName()+suffix, deps...) + phony("", deps) if ctx.Device() { // Generate a target suffix for use in atest etc. - ctx.Phony(namespacePrefix+ctx.module.base().BaseModuleName()+"-target"+suffix, deps...) + phony("-target", deps) } else { // Generate a host suffix for use in atest etc. - ctx.Phony(namespacePrefix+ctx.module.base().BaseModuleName()+"-host"+suffix, deps...) + phony("-host", deps) if ctx.Target().HostCross { // Generate a host-cross suffix for use in atest etc. - ctx.Phony(namespacePrefix+ctx.module.base().BaseModuleName()+"-host-cross"+suffix, deps...) + phony("-host-cross", deps) } } @@ -1877,11 +1883,10 @@ func (m *ModuleBase) archModuleContextFactory(ctx archModuleContextFactoryContex } type InstallFilesInfo struct { - InstallFiles InstallPaths - CheckbuildFiles Paths - CheckbuildTarget Path - UncheckedModule bool - PackagingSpecs []PackagingSpec + InstallFiles InstallPaths + CheckbuildFiles Paths + UncheckedModule bool + PackagingSpecs []PackagingSpec // katiInstalls tracks the install rules that were created by Soong but are being exported // to Make to convert to ninja rules so that Make can add additional dependencies. KatiInstalls katiInstalls @@ -2176,8 +2181,6 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) return } - m.generateVariantTarget(ctx) - testData := FirstUniqueFunc(ctx.testData, func(a, b DataPath) bool { return a == b }) @@ -2185,7 +2188,6 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) installFiles.LicenseMetadataFile = ctx.licenseMetadataFile installFiles.InstallFiles = ctx.installFiles installFiles.CheckbuildFiles = ctx.checkbuildFiles - installFiles.CheckbuildTarget = ctx.checkbuildTarget installFiles.UncheckedModule = ctx.uncheckedModule installFiles.PackagingSpecs = ctx.packagingSpecs installFiles.KatiInstalls = ctx.katiInstalls diff --git a/apex/apex.go b/apex/apex.go index 17c2884bc..22bb509d0 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -632,8 +632,8 @@ func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidM module: module, } if !module.IsNil() { - if installFilesInfo, ok := android.OtherModuleProvider(ctx, module, android.InstallFilesProvider); ok { - ret.checkbuildTarget = installFilesInfo.CheckbuildTarget + if buildTargetsInfo, ok := android.OtherModuleProvider(ctx, module, android.ModuleBuildTargetsProvider); ok { + ret.checkbuildTarget = buildTargetsInfo.CheckbuildTarget } ret.moduleDir = ctx.OtherModuleDir(module) commonInfo := android.OtherModulePointerProviderOrDefault(ctx, module, android.CommonModuleInfoProvider) diff --git a/java/sdk_library.go b/java/sdk_library.go index 32a476732..de8402d0e 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -1561,9 +1561,9 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) module.hostdexInstallFile = module.implLibraryInfo.HostdexInstallFile } - if installFilesInfo, ok := android.OtherModuleProvider(ctx, implLib, android.InstallFilesProvider); ok { - if installFilesInfo.CheckbuildTarget != nil { - ctx.CheckbuildFile(installFilesInfo.CheckbuildTarget) + if buildTargetsInfo, ok := android.OtherModuleProvider(ctx, implLib, android.ModuleBuildTargetsProvider); ok { + if buildTargetsInfo.CheckbuildTarget != nil { + ctx.CheckbuildFile(buildTargetsInfo.CheckbuildTarget) } } } -- cgit v1.2.3 From 4bd1eac2e48cb969aea8358fac129c11c5aacf58 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Fri, 18 Apr 2025 14:42:12 -0700 Subject: Update documentation on android.OtherModuleProvider For the behavior change where it accepts nil modules. Test: Presubmits Change-Id: If07e0bc2d716b128d940a4454dc67398dcfe88a5 --- android/provider.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/android/provider.go b/android/provider.go index 4f4a4a0e8..85fc08c0c 100644 --- a/android/provider.go +++ b/android/provider.go @@ -22,9 +22,10 @@ type ConfigAndOtherModuleProviderContext interface { ConfigContext } -// OtherModuleProvider reads the provider for the given module. If the provider has been set the value is -// returned and the boolean is true. If it has not been set the zero value of the provider's type is returned -// and the boolean is false. The value returned may be a deep copy of the value originally passed to SetProvider. +// OtherModuleProvider reads the provider for the given module. If the provider has been set the +// value is returned and the boolean is true. If it has not been set or the module is nil, the zero +// value of the provider's type is returned and the boolean is false. The value returned may be a +// deep copy of the value originally passed to SetProvider. // // OtherModuleProviderContext is a helper interface that accepts ModuleContext or BottomUpMutatorContext. func OtherModuleProvider[K any](ctx OtherModuleProviderContext, module ModuleOrProxy, provider blueprint.ProviderKey[K]) (K, bool) { -- cgit v1.2.3 From 3d616fe25826835d9a1a3dd0e211e9c2a9eca643 Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Fri, 18 Apr 2025 16:12:22 -0700 Subject: Update the allowlist in soong only diff test script Recent changes in Soong have fixed some diffs in the target_files.zip between soong only build and soong plus make build. This change reflects those changes and remove fixed entries from the allowlist. This change also adds the non-deterministic entry to the allowlist temporarily. Test: build/soong/scripts/soong_only_diff_test.py aosp_cf_x86_64_phone Bug: 409368614 Change-Id: I561290c4afb0f55f2fc0b958da0c66c8dd01b771 --- scripts/soong_only_diff_test.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/scripts/soong_only_diff_test.py b/scripts/soong_only_diff_test.py index 1a4eea145..ca73a381c 100755 --- a/scripts/soong_only_diff_test.py +++ b/scripts/soong_only_diff_test.py @@ -141,20 +141,14 @@ def move_artifacts_to_subfolder(product: Product, soong_only: bool): shutil.move(file, subdistdir) SHA_DIFF_ALLOWLIST = { - "IMAGES/init_boot.img", "IMAGES/system.img", - "IMAGES/system_other.img", "IMAGES/userdata.img", - "IMAGES/vbmeta.img", - "IMAGES/vbmeta_system_dlkm.img", "IMAGES/vbmeta_system.img", - "IMAGES/vbmeta_vendor_dlkm.img", - "IMAGES/vendor_boot.img", - "META/file_contexts.bin", "META/kernel_version.txt", "META/misc_info.txt", "META/vbmeta_digest.txt", "SYSTEM_EXT/etc/vm/trusty_vm/trusty_security_vm.elf", # TODO: b/406045340 - Remove from the allowlist once it's fixed + "SYSTEM/apex/com.android.resolv.capex", # TODO: b/411514418 - Remove once nondeterminism is fixed } def compare_sha_maps(soong_only_map: dict[str, bytes], soong_plus_make_map: dict[str, bytes]) -> bool: -- cgit v1.2.3 From 43b1864cec26bd0143cb84dd7b91e6418c8b7add Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Thu, 10 Apr 2025 13:18:58 -0700 Subject: Propagate aconfig proto files for src modules Aconfig proto files need to be propagated to its rdeps when the module is listed in `srcs` via `:module_name{.tag}` syntax. For java modules, this only happens for cases when the generated srcjar stubs of the droidstubs are listed under `srcs` property. Test: m out/soong/.intermediates/frameworks/base/api/api_versions_public/android_common/flags-config-exportable.xml Bug: 409316536 Change-Id: I7b04d657c5bd2fe3c8b5fad29872c6a3bce30e20 --- java/base.go | 2 ++ java/builder.go | 8 +++++--- java/droidstubs.go | 2 ++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/java/base.go b/java/base.go index a524b1db9..af3d493a1 100644 --- a/java/base.go +++ b/java/base.go @@ -2625,6 +2625,8 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { case staticLibTag: deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...) } + } else if dep, ok := android.OtherModuleProvider(ctx, module, DroidStubsInfoProvider); ok { + deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.AconfigProtoFiles...) } else { switch tag { case bootClasspathTag: diff --git a/java/builder.go b/java/builder.go index e468b1f04..6d4605ea9 100644 --- a/java/builder.go +++ b/java/builder.go @@ -399,10 +399,12 @@ var ( blueprint.RuleParams{ Command: `${aconfig} dump-cache --dedup --format=protobuf ` + `--out ${out} ` + - `${flags_path} ` + + `@$out.rsp ` + `${filter_args} `, - CommandDeps: []string{"${aconfig}"}, - Description: "aconfig_bool", + CommandDeps: []string{"${aconfig}"}, + Description: "aconfig_bool", + Rspfile: "$out.rsp", + RspfileContent: "${flags_path}", }, "flags_path", "filter_args") generateMetalavaRevertAnnotationsRule = pctx.AndroidStaticRule("generateMetalavaRevertAnnotationsRule", diff --git a/java/droidstubs.go b/java/droidstubs.go index 3498f30ff..4b0587be1 100644 --- a/java/droidstubs.go +++ b/java/droidstubs.go @@ -36,6 +36,7 @@ type StubsInfo struct { } type DroidStubsInfo struct { + AconfigProtoFiles android.Paths CurrentApiTimestamp android.Path EverythingStubsInfo StubsInfo ExportableStubsInfo StubsInfo @@ -1416,6 +1417,7 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { } droidInfo := DroidStubsInfo{ + AconfigProtoFiles: deps.aconfigProtoFiles, CurrentApiTimestamp: d.CurrentApiTimestamp(), EverythingStubsInfo: StubsInfo{}, ExportableStubsInfo: StubsInfo{}, -- cgit v1.2.3 From 588b5ee9c0627f21b5de178541f355e361f2b61e Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Fri, 18 Apr 2025 16:46:27 -0700 Subject: Soong unit test for aconfig proto propagation via srcs This change adds a unit test for propagating aconfig proto files via droidstubs modules listed in srcs. Test: m nothing --no-skip-soong-tests Bug: 409316536 Change-Id: Icb53ff53fa3b0d25df377eb771406bb952d74790 --- java/java_test.go | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/java/java_test.go b/java/java_test.go index 813b8e44f..6e80dcd34 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -2911,6 +2911,59 @@ func TestApiLibraryAconfigDeclarations(t *testing.T) { android.AssertStringDoesContain(t, "flagged api hide command not included", cmdline, "flags-config-exportable.xml") } +func TestDroidstubsAconfigPropagation(t *testing.T) { + result := android.GroupFixturePreparers( + prepareForJavaTest, + android.FixtureMergeMockFs(map[string][]byte{ + "a/A.java": nil, + "a/current.txt": nil, + "a/removed.txt": nil, + }), + ).RunTestWithBp(t, ` + aconfig_declarations { + name: "bar", + package: "com.example.package", + container: "com.android.foo", + srcs: [ + "bar.aconfig", + ], + } + droidstubs { + name: "foo", + srcs: ["a/A.java"], + api_surface: "public", + check_api: { + current: { + api_file: "a/current.txt", + removed_api_file: "a/removed.txt", + } + }, + aconfig_declarations: [ + "bar", + ], + } + + java_library { + name: "baz", + srcs: [ + ":foo", + ], + } + `) + + bazModule := result.ModuleForTests(t, "baz", "android_common").Module() + javaInfo, _ := android.OtherModuleProvider(result, bazModule, JavaInfoProvider) + aconfigProtos := javaInfo.AconfigIntermediateCacheOutputPaths + + android.AssertIntEquals(t, "Expected to provide one aconfig proto file", 1, len(aconfigProtos)) + android.AssertStringDoesContain( + t, + "Expected to provide bar/aconfig-cache.pb", + strings.Join(aconfigProtos.Strings(), " "), + "bar/aconfig-cache.pb", + ) +} + func TestTestOnly(t *testing.T) { t.Parallel() ctx := android.GroupFixturePreparers( -- cgit v1.2.3 From 82848b7688d71e1eb5460a0a35e7d890b02bfaee Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Fri, 18 Apr 2025 17:29:22 -0700 Subject: Support for .flat files in flagged directories right above xml file ag/32882619 did not construct the correct path that aapt2 generated in some cases, thus led to "missing output file after successful execution" error. This change fixes such behavior and more robustly supports the feature. Test: m nothing --no-skip-soong-tests Test: mkdir frameworks/base/packages/SystemUI/res/drawable/flag\(com.android.systemui.icon_refresh_2025\) && mv frameworks/base/packages/SystemUI/res/drawable/flag(com.android.systemui.icon_refresh_2025)/qs_flashlight_icon_off.xml frameworks/base/packages/SystemUI/res/drawable/flag\(com.android.systemui.icon_refresh_2025\) && mv frameworks/base/packages/SystemUI/res/drawable/flag(com.android.systemui.icon_refresh_2025)/qs_flashlight_icon_on.xml frameworks/base/packages/SystemUI/res/drawable/flag\(com.android.systemui.icon_refresh_2025\) && m SystemUIGoogle Bug: 374827548 Change-Id: I93f2ce40726fb0d0a2e5169a7cbf9776470c60e6 --- java/aapt2.go | 2 +- java/app_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java/aapt2.go b/java/aapt2.go index fb451b2a2..4efa6655a 100644 --- a/java/aapt2.go +++ b/java/aapt2.go @@ -55,7 +55,7 @@ func pathToAapt2Path(ctx android.ModuleContext, res android.Path) android.Writab var flag string if isFlagsPath(lastDir) { flag = "." + strings.TrimPrefix(lastDir, "flag") - subDir, lastDir = filepath.Split(subDir) + subDir, lastDir = filepath.Split(filepath.Dir(subDir)) } else if isFlagsPath(subDir) { subDir, flag = filepath.Split(filepath.Dir(subDir)) flag = "." + strings.TrimPrefix(flag, "flag") diff --git a/java/app_test.go b/java/app_test.go index fcaf69feb..ed6396a99 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -4942,7 +4942,7 @@ func TestResourcesWithFlagDirectories(t *testing.T) { t, "Expected to generate flag path when it is a subdirectory of resource type subdirectory", compileOutputPaths, - "out/soong/.intermediates/foo/android_common/aapt2/res/drawable/_qs_flashlight_icon_off.(test.package.flag1).xml.flat", + "out/soong/.intermediates/foo/android_common/aapt2/res/drawable_qs_flashlight_icon_off.(test.package.flag1).xml.flat", ) } -- cgit v1.2.3 From 36b2c499a4f11e5a424b9877443b781bf6415c60 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 10 Apr 2025 11:32:41 -0700 Subject: Move prebuilt info out of CommonModuleInfoProvider IsModulePrebuilt needs to access IsPrebuilt during mutators that run before GenerateAndroidBuildActions when CommonModuleInfoProvider gets set. Create a new PrebuiltInfoMutator that is set earlier during the prebuilt_provider mutator and use it in IsModulePrebuilt. Test: all Soong tests pass Change-Id: I775378083d4aa6c26b846b1eabbad0fb1c446211 --- android/module.go | 11 ------- android/module_context.go | 6 ++-- android/prebuilt.go | 65 ++++++++++++++++++++++++++++++++---------- apex/prebuilt.go | 4 +-- cc/fuzz.go | 6 ++-- dexpreopt/config.go | 10 +++---- filesystem/android_device.go | 3 +- genrule/genrule.go | 4 +-- java/bootclasspath_fragment.go | 4 +-- java/dexpreopt_bootjars.go | 2 +- java/hiddenapi_modular.go | 2 +- 11 files changed, 72 insertions(+), 45 deletions(-) diff --git a/android/module.go b/android/module.go index 9561e422a..4a1aeb249 100644 --- a/android/module.go +++ b/android/module.go @@ -1931,8 +1931,6 @@ var ModuleBuildTargetsProvider = blueprint.NewProvider[ModuleBuildTargetsInfo]() type CommonModuleInfo struct { Enabled bool - // Whether the module has been replaced by a prebuilt - ReplacedByPrebuilt bool // The Target of artifacts that this module variant is responsible for creating. Target Target SkipAndroidMkProcessing bool @@ -1981,9 +1979,6 @@ type CommonModuleInfo struct { ExportedToMake bool Team string PartitionTag string - IsPrebuilt bool - PrebuiltSourceExists bool - UsePrebuilt bool ApexAvailable []string // This field is different from the above one as it can have different values // for cc, java library and sdkLibraryXml. @@ -2336,7 +2331,6 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) commonData := CommonModuleInfo{ Enabled: m.Enabled(ctx), - ReplacedByPrebuilt: m.commonProperties.ReplacedByPrebuilt, Target: m.commonProperties.CompileTarget, SkipAndroidMkProcessing: shouldSkipAndroidMkProcessing(ctx, m), UninstallableApexPlatformVariant: m.commonProperties.UninstallableApexPlatformVariant, @@ -2411,11 +2405,6 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) if mm, ok := m.module.(interface{ BaseModuleName() string }); ok { commonData.BaseModuleName = mm.BaseModuleName() } - if p, ok := m.module.(PrebuiltInterface); ok && p.Prebuilt() != nil { - commonData.IsPrebuilt = true - commonData.PrebuiltSourceExists = p.Prebuilt().SourceExists() - commonData.UsePrebuilt = p.Prebuilt().UsePrebuilt() - } SetProvider(ctx, CommonModuleInfoProvider, &commonData) if h, ok := m.module.(HostToolProvider); ok { diff --git a/android/module_context.go b/android/module_context.go index 8ee7f621b..acfcd9b10 100644 --- a/android/module_context.go +++ b/android/module_context.go @@ -678,7 +678,7 @@ func (m *moduleContext) packageFile(fullInstallPath InstallPath, srcPath Path, e requiresFullInstall: requiresFullInstall, fullInstallPath: fullInstallPath, variation: m.ModuleSubDir(), - prebuilt: IsModulePrebuilt(m.Module()), + prebuilt: IsModulePrebuilt(m, m.Module()), } m.packagingSpecs = append(m.packagingSpecs, spec) return spec @@ -834,7 +834,7 @@ func (m *moduleContext) InstallSymlink(installPath InstallPath, name string, src requiresFullInstall: m.requiresFullInstall(), fullInstallPath: fullInstallPath, variation: m.ModuleSubDir(), - prebuilt: IsModulePrebuilt(m.Module()), + prebuilt: IsModulePrebuilt(m, m.Module()), }) return fullInstallPath @@ -886,7 +886,7 @@ func (m *moduleContext) InstallAbsoluteSymlink(installPath InstallPath, name str requiresFullInstall: m.requiresFullInstall(), fullInstallPath: fullInstallPath, variation: m.ModuleSubDir(), - prebuilt: IsModulePrebuilt(m.Module()), + prebuilt: IsModulePrebuilt(m, m.Module()), }) return fullInstallPath diff --git a/android/prebuilt.go b/android/prebuilt.go index 18517c306..7f4e5961d 100644 --- a/android/prebuilt.go +++ b/android/prebuilt.go @@ -357,13 +357,15 @@ func IsModulePreferred(module Module) bool { return true } -func IsModulePreferredProxy(ctx OtherModuleProviderContext, module ModuleProxy) bool { - if OtherModulePointerProviderOrDefault(ctx, module, CommonModuleInfoProvider).ReplacedByPrebuilt { - // A source module that has been replaced by a prebuilt counterpart. - return false - } - if commonInfo, ok := OtherModuleProvider(ctx, module, CommonModuleInfoProvider); ok && commonInfo.IsPrebuilt { - return commonInfo.UsePrebuilt +func IsModulePreferredProxy(ctx OtherModuleProviderContext, module ModuleOrProxy) bool { + if info, ok := OtherModuleProvider(ctx, module, PrebuiltInfoProvider); ok { + if info.ReplacedByPrebuilt { + // A source module that has been replaced by a prebuilt counterpart. + return false + } + if info.IsPrebuilt { + return info.UsePrebuilt + } } return true } @@ -371,8 +373,13 @@ func IsModulePreferredProxy(ctx OtherModuleProviderContext, module ModuleProxy) // 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. -func IsModulePrebuilt(module Module) bool { - return GetEmbeddedPrebuilt(module) != nil +func IsModulePrebuilt(ctx BaseModuleContext, module ModuleOrProxy) bool { + if EqualModules(ctx.Module(), module) { + return GetEmbeddedPrebuilt(ctx.Module()) != nil + } else { + info := OtherModuleProviderOrDefault(ctx, module, PrebuiltInfoProvider) + return info.IsPrebuilt + } } // GetEmbeddedPrebuilt returns a pointer to the embedded Prebuilt structure or @@ -397,12 +404,14 @@ func GetEmbeddedPrebuilt(module Module) *Prebuilt { // the right module. This function is only safe to call after all TransitionMutators // have run, e.g. in GenerateAndroidBuildActions. func PrebuiltGetPreferred(ctx BaseModuleContext, module ModuleProxy) ModuleProxy { - if !OtherModulePointerProviderOrDefault(ctx, module, CommonModuleInfoProvider).ReplacedByPrebuilt { - return module - } - if commonInfo, ok := OtherModuleProvider(ctx, module, CommonModuleInfoProvider); ok && commonInfo.IsPrebuilt { - // If we're given a prebuilt then assume there's no source module around. - return module + if info, ok := OtherModuleProvider(ctx, module, PrebuiltInfoProvider); ok { + if !info.ReplacedByPrebuilt { + return module + } + if info.IsPrebuilt { + // If we're given a prebuilt then assume there's no source module around. + return module + } } sourceModDepFound := false @@ -444,6 +453,7 @@ func RegisterPrebuiltsPreDepsMutators(ctx RegisterMutatorsContext) { } func RegisterPrebuiltsPostDepsMutators(ctx RegisterMutatorsContext) { + ctx.BottomUp("prebuilt_provider", prebuiltProviderMutator) ctx.BottomUp("prebuilt_postdeps", PrebuiltPostDepsMutator).UsesReplaceDependencies() } @@ -572,6 +582,31 @@ func PrebuiltSelectModuleMutator(ctx BottomUpMutatorContext) { } } +var PrebuiltInfoProvider = blueprint.NewMutatorProvider[PrebuiltInfo]("prebuilt_provider") + +type PrebuiltInfo struct { + IsPrebuilt bool + PrebuiltSourceExists bool + UsePrebuilt bool + // Whether the module has been replaced by a prebuilt + ReplacedByPrebuilt bool +} + +// prebuiltProviderMutator sets the PrebuiltInfoProvider. +func prebuiltProviderMutator(ctx BottomUpMutatorContext) { + m := ctx.Module() + + info := PrebuiltInfo{} + + if p, ok := m.(PrebuiltInterface); ok && p.Prebuilt() != nil { + info.IsPrebuilt = true + info.PrebuiltSourceExists = p.Prebuilt().SourceExists() + info.UsePrebuilt = p.Prebuilt().UsePrebuilt() + } + info.ReplacedByPrebuilt = m.IsReplacedByPrebuilt() + SetProvider(ctx, PrebuiltInfoProvider, info) +} + // If any module in this mainline module family has been flagged using apex_contributions, disable every other module in that family func hideUnflaggedModules(ctx BottomUpMutatorContext, psi PrebuiltSelectionInfoMap, allModulesInFamily []Module) { var selectedModuleInFamily Module diff --git a/apex/prebuilt.go b/apex/prebuilt.go index 4a68c61df..2568eda85 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -345,14 +345,14 @@ func (m ApexPrebuiltDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint. } func (p *prebuiltCommon) checkExportedDependenciesArePrebuilts(ctx android.ModuleContext) { - ctx.VisitDirectDeps(func(dep android.Module) { + ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) { tag := ctx.OtherModuleDependencyTag(dep) depName := ctx.OtherModuleName(dep) if exportedTag, ok := tag.(exportedDependencyTag); ok { propertyName := exportedTag.name // It is an error if the other module is not a prebuilt. - if !android.IsModulePrebuilt(dep) { + if !android.IsModulePrebuilt(ctx, dep) { ctx.PropertyErrorf(propertyName, "%q is not a prebuilt module", depName) } diff --git a/cc/fuzz.go b/cc/fuzz.go index 4a57cae87..675d4b210 100644 --- a/cc/fuzz.go +++ b/cc/fuzz.go @@ -257,8 +257,10 @@ func isValidSharedDependency(ctx android.ModuleContext, dependency android.Modul // If the same library is present both as source and a prebuilt we must pick // only one to avoid a conflict. Always prefer the source since the prebuilt // probably won't be built with sanitizers enabled. - if commonInfo, ok := android.OtherModuleProvider(ctx, dependency, android.CommonModuleInfoProvider); ok && commonInfo.IsPrebuilt && commonInfo.PrebuiltSourceExists { - return false + if info, ok := android.OtherModuleProvider(ctx, dependency, android.PrebuiltInfoProvider); ok { + if info.IsPrebuilt && info.PrebuiltSourceExists { + return false + } } return true diff --git a/dexpreopt/config.go b/dexpreopt/config.go index 692a97919..788aae48e 100644 --- a/dexpreopt/config.go +++ b/dexpreopt/config.go @@ -469,8 +469,8 @@ func (d dex2oatDependencyTag) AllowDisabledModuleDependency(target android.Modul func (d dex2oatDependencyTag) AllowDisabledModuleDependencyProxy( ctx android.OtherModuleProviderContext, target android.ModuleProxy) bool { - return android.OtherModulePointerProviderOrDefault( - ctx, target, android.CommonModuleInfoProvider).ReplacedByPrebuilt + return android.OtherModuleProviderOrDefault( + ctx, target, android.PrebuiltInfoProvider).ReplacedByPrebuilt } // Dex2oatDepTag represents the dependency onto the dex2oatd module. It is added to any module that @@ -515,9 +515,9 @@ func dex2oatPathFromDep(ctx android.ModuleContext) android.Path { var dex2oatModule android.ModuleProxy ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool { var isPrebuilt, usePrebuilt bool - if commonInfo, ok := android.OtherModuleProvider(ctx, child, android.CommonModuleInfoProvider); ok { - isPrebuilt = commonInfo.IsPrebuilt - usePrebuilt = commonInfo.UsePrebuilt + if prebuiltInfo, ok := android.OtherModuleProvider(ctx, child, android.PrebuiltInfoProvider); ok { + isPrebuilt = prebuiltInfo.IsPrebuilt + usePrebuilt = prebuiltInfo.UsePrebuilt } if android.EqualModules(parent, ctx.Module()) && ctx.OtherModuleDependencyTag(child) == Dex2oatDepTag { // Found the source module, or prebuilt module that has replaced the source. diff --git a/filesystem/android_device.go b/filesystem/android_device.go index 52076c031..1b5000c5b 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -383,6 +383,7 @@ func (a *androidDevice) allInstalledModules(ctx android.ModuleContext) []android if !(ok && commonInfo.ExportedToMake) { return false } + prebuiltInfo := android.OtherModuleProviderOrDefault(ctx, mod, android.PrebuiltInfoProvider) name := ctx.OtherModuleName(mod) if o, ok := mod.(android.OverridableModule); ok && o.GetOverriddenBy() != "" { name = o.GetOverriddenBy() @@ -390,7 +391,7 @@ func (a *androidDevice) allInstalledModules(ctx android.ModuleContext) []android if variations, ok := allOwners[name]; ok && android.InList(installedOwnerInfo{ Variation: ctx.OtherModuleSubDir(mod), - Prebuilt: commonInfo.IsPrebuilt, + Prebuilt: prebuiltInfo.IsPrebuilt, }, variations) { ret = append(ret, mod) } diff --git a/genrule/genrule.go b/genrule/genrule.go index 8f527dd99..c2e6ae87c 100644 --- a/genrule/genrule.go +++ b/genrule/genrule.go @@ -111,8 +111,8 @@ func (t hostToolDependencyTag) AllowDisabledModuleDependency(target android.Modu func (t hostToolDependencyTag) AllowDisabledModuleDependencyProxy( ctx android.OtherModuleProviderContext, target android.ModuleProxy) bool { - return android.OtherModulePointerProviderOrDefault( - ctx, target, android.CommonModuleInfoProvider).ReplacedByPrebuilt + return android.OtherModuleProviderOrDefault( + ctx, target, android.PrebuiltInfoProvider).ReplacedByPrebuilt } var _ android.AllowDisabledModuleDependency = (*hostToolDependencyTag)(nil) diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go index ed3735bae..e3ada4c44 100644 --- a/java/bootclasspath_fragment.go +++ b/java/bootclasspath_fragment.go @@ -554,7 +554,7 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo // Perform hidden API processing. hiddenAPIOutput := b.generateHiddenAPIBuildActions(ctx, contents, fragments) - if android.IsModulePrebuilt(ctx.Module()) { + if android.IsModulePrebuilt(ctx, ctx.Module()) { b.profilePath = ctx.Module().(*PrebuiltBootclasspathFragmentModule).produceBootImageProfile(ctx) } else { b.profilePath = b.produceBootImageProfileFromSource(ctx, contents, hiddenAPIOutput.EncodedBootDexFilesByModule) @@ -662,7 +662,7 @@ func (b *BootclasspathFragmentModule) configuredJars(ctx android.ModuleContext) // TODO(b/202896428): Add better way to handle this. _, unknown = android.RemoveFromList("android.car-module", unknown) if isApexVariant(ctx) && len(unknown) > 0 { - if android.IsModulePrebuilt(ctx.Module()) { + if android.IsModulePrebuilt(ctx, ctx.Module()) { // prebuilt bcpf. the validation of this will be done at the top-level apex providerClasspathFragmentValidationInfoProvider(ctx, unknown) } else if !disableSourceApexVariant(ctx) && android.IsModulePreferred(ctx.Module()) { diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index 30e208d0a..93aef0cae 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -938,7 +938,7 @@ func getDexJarForApex(ctx android.ModuleContext, pair apexJarModulePair, apexNam return dex } // TODO: b/308174306 - Remove the legacy mechanism - if android.IsConfiguredJarForPlatform(pair.apex) || android.IsModulePrebuilt(pair.jarModule) { + if android.IsConfiguredJarForPlatform(pair.apex) || android.IsModulePrebuilt(ctx, pair.jarModule) { // This gives us the dex jar with the hidden API flags encoded from the monolithic hidden API // files or the dex jar extracted from a prebuilt APEX. We can't use this for a boot jar for // a source APEX because there is no guarantee that it is the same as the jar packed into the diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go index 7c502a95c..4d723be4a 100644 --- a/java/hiddenapi_modular.go +++ b/java/hiddenapi_modular.go @@ -1423,7 +1423,7 @@ func deferReportingMissingBootDexJar(ctx android.ModuleContext, module android.M // a prebuilt modules that has other variants which are part of an APEX. // // TODO(b/187910671): Remove this once platform variants are no longer created unnecessarily. - if android.IsModulePrebuilt(module) { + if android.IsModulePrebuilt(ctx, module) { // An inactive source module can still contribute to the APEX but an inactive prebuilt module // should not contribute to anything. So, rather than have a missing dex jar cause a Soong // failure defer the error reporting to Ninja. Unless the prebuilt build target is explicitly -- cgit v1.2.3 From 34cb15cde03b5174ea0e61259ab36f38f4f73a20 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 16 Apr 2025 13:42:50 -0700 Subject: Add OverrideInfoProvider Add OverrideInfoProvider and use it when determining if another module is overridden. Test: TestOverrides Change-Id: I8ad670905e49b7bed86353f0fc81b916b2d6102a --- android/override_module.go | 9 +++++++++ android/packaging.go | 8 ++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/android/override_module.go b/android/override_module.go index 8b0836e00..a3d3a10d9 100644 --- a/android/override_module.go +++ b/android/override_module.go @@ -258,6 +258,12 @@ func overrideModuleDepsMutator(ctx BottomUpMutatorContext) { var overrideModuleDefaultInfoProvider = blueprint.NewMutatorProvider[overrideTransitionMutatorInfo]("override_deps") +var OverrideInfoProvider = blueprint.NewMutatorProvider[OverrideInfo]("override_mutate") + +type OverrideInfo struct { + OverriddenBy string +} + // Now, goes through all overridable modules, finds all modules overriding them, creates a local // variant for each of them, and performs the actual overriding operation by calling override(). type overrideTransitionMutator struct{} @@ -321,6 +327,9 @@ func (overrideTransitionMutator) Mutate(ctx BottomUpMutatorContext, info overrid checkPrebuiltReplacesOverride(ctx, b, info) } + SetProvider(ctx, OverrideInfoProvider, OverrideInfo{ + OverriddenBy: info.name, + }) } } diff --git a/android/packaging.go b/android/packaging.go index d1ea5aa9e..43a250343 100644 --- a/android/packaging.go +++ b/android/packaging.go @@ -587,11 +587,11 @@ func (p *PackagingBase) GatherPackagingSpecsWithFilterAndModifier(ctx ModuleCont }) // gather modules to install, skipping overridden modules - ctx.WalkDeps(func(child, parent Module) bool { + ctx.WalkDepsProxy(func(child, parent ModuleProxy) bool { owner := ctx.OtherModuleName(child) - if o, ok := child.(OverridableModule); ok { - if overriddenBy := o.GetOverriddenBy(); overriddenBy != "" { - owner = overriddenBy + if info, ok := OtherModuleProvider(ctx, child, OverrideInfoProvider); ok { + if info.OverriddenBy != "" { + owner = info.OverriddenBy } } if !isNativeBridgeVariant(child) { -- cgit v1.2.3 From efc6760db8c9ad72c662b5bd482c1734d3a46480 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 16 Apr 2025 13:53:10 -0700 Subject: Move ProvenanceMetadata to a provider Replace the ProvenanceMetadata interface with a provider. Test: TestProvenanceSingleton Change-Id: I7bf01c57f23fe080707fecec64362520067b5eec --- apex/apex_test.go | 4 +++- apex/prebuilt.go | 8 +------- java/app_import.go | 8 +------- provenance/provenance_singleton.go | 30 +++++++++++++++--------------- 4 files changed, 20 insertions(+), 30 deletions(-) diff --git a/apex/apex_test.go b/apex/apex_test.go index 9fafc9cdc..b35d8c995 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -26,6 +26,7 @@ import ( "testing" "android/soong/aconfig/codegen" + "android/soong/provenance" "github.com/google/blueprint/proptools" @@ -5196,8 +5197,9 @@ func TestPrebuilt(t *testing.T) { if prebuilt.inputApex.String() != expectedInput { t.Errorf("inputApex invalid. expected: %q, actual: %q", expectedInput, prebuilt.inputApex.String()) } + provenanceInfo, _ := android.OtherModuleProvider(ctx, prebuilt, provenance.ProvenanceMetadataInfoProvider) android.AssertStringDoesContain(t, "Invalid provenance metadata file", - prebuilt.ProvenanceMetaDataFile().String(), "soong/.intermediates/provenance_metadata/myapex/provenance_metadata.textproto") + provenanceInfo.ProvenanceMetaDataFile.String(), "soong/.intermediates/provenance_metadata/myapex/provenance_metadata.textproto") rule := testingModule.Rule("genProvenanceMetaData") android.AssertStringEquals(t, "Invalid input", "myapex-arm64.apex", rule.Inputs[0].String()) android.AssertStringEquals(t, "Invalid output", "out/soong/.intermediates/provenance_metadata/myapex/provenance_metadata.textproto", rule.Output.String()) diff --git a/apex/prebuilt.go b/apex/prebuilt.go index 2568eda85..91f5f997c 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -380,8 +380,6 @@ type Prebuilt struct { properties PrebuiltProperties inputApex android.Path - - provenanceMetaDataFile android.Path } type ApexFileProperties struct { @@ -711,7 +709,7 @@ func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) { p.installApexSystemServerFiles(ctx) installDeps := slices.Concat(p.compatSymlinks, p.extraInstalledFiles) p.installedFile = ctx.InstallFile(p.installDir, p.installFilename, p.inputApex, installDeps...) - p.provenanceMetaDataFile = provenance.GenerateArtifactProvenanceMetaData(ctx, p.inputApex, p.installedFile) + provenance.GenerateArtifactProvenanceMetaData(ctx, p.inputApex, p.installedFile) } p.addApkCertsInfo(ctx) @@ -796,10 +794,6 @@ func (p *Prebuilt) addApkCertsInfo(ctx android.ModuleContext) { android.SetProvider(ctx, filesystem.ApkCertsInfoProvider, filesystem.ApkCertsInfo{p.apkCertsFile}) } -func (p *Prebuilt) ProvenanceMetaDataFile() android.Path { - return p.provenanceMetaDataFile -} - // extract registers the build actions to extract an apex from .apks file // returns the path of the extracted apex func extract(ctx android.ModuleContext, apexSet android.Path, prerelease *bool) android.Path { diff --git a/java/app_import.go b/java/app_import.go index 811f4b8e2..9fd13a74f 100644 --- a/java/app_import.go +++ b/java/app_import.go @@ -105,8 +105,6 @@ type AndroidAppImport struct { installPath android.InstallPath hideApexVariantFromMake bool - - provenanceMetaDataFile android.Path } type AndroidAppImportProperties struct { @@ -528,7 +526,7 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext if apexInfo.IsForPlatform() { a.installPath = ctx.InstallFile(installDir, apkFilename, a.outputFile) artifactPath := android.PathForModuleSrc(ctx, a.properties.Apk.GetOrDefault(ctx, "")) - a.provenanceMetaDataFile = provenance.GenerateArtifactProvenanceMetaData(ctx, artifactPath, a.installPath) + provenance.GenerateArtifactProvenanceMetaData(ctx, artifactPath, a.installPath) } providePrebuiltInfo(ctx, @@ -593,10 +591,6 @@ func (a *AndroidAppImport) Certificate() Certificate { return a.certificate } -func (a *AndroidAppImport) ProvenanceMetaDataFile() android.Path { - return a.provenanceMetaDataFile -} - func (a *AndroidAppImport) PrivAppAllowlist() android.OptionalPath { return android.OptionalPath{} } diff --git a/provenance/provenance_singleton.go b/provenance/provenance_singleton.go index c1bc1c75c..ca42ebe38 100644 --- a/provenance/provenance_singleton.go +++ b/provenance/provenance_singleton.go @@ -45,10 +45,12 @@ var ( }) ) -type ProvenanceMetadata interface { - ProvenanceMetaDataFile() android.Path +type ProvenanceMetadataInfo struct { + ProvenanceMetaDataFile android.Path } +var ProvenanceMetadataInfoProvider = blueprint.NewProvider[ProvenanceMetadataInfo]() + func init() { RegisterProvenanceSingleton(android.InitRegistrationContext) } @@ -69,18 +71,14 @@ type provenanceInfoSingleton struct { func (p *provenanceInfoSingleton) GenerateBuildActions(context android.SingletonContext) { allMetaDataFiles := make([]android.Path, 0) - moduleFilter := func(module android.Module) bool { - if !module.Enabled(context) || module.IsSkipInstall() { - return false - } - if p, ok := module.(ProvenanceMetadata); ok { - return p.ProvenanceMetaDataFile() != nil + context.VisitAllModuleProxies(func(module android.ModuleProxy) { + commonInfo := android.OtherModulePointerProviderOrDefault(context, module, android.CommonModuleInfoProvider) + if !commonInfo.Enabled || commonInfo.SkipInstall { + return } - return false - } - context.VisitAllModulesIf(moduleFilter, func(module android.Module) { - if p, ok := module.(ProvenanceMetadata); ok { - allMetaDataFiles = append(allMetaDataFiles, p.ProvenanceMetaDataFile()) + + if p, ok := android.OtherModuleProvider(context, module, ProvenanceMetadataInfoProvider); ok { + allMetaDataFiles = append(allMetaDataFiles, p.ProvenanceMetaDataFile) } }) p.mergedMetaDataFile = android.PathForOutput(context, "provenance_metadata.textproto") @@ -102,7 +100,7 @@ func (p *provenanceInfoSingleton) GenerateBuildActions(context android.Singleton context.DistForGoal("droidcore", p.mergedMetaDataFile) } -func GenerateArtifactProvenanceMetaData(ctx android.ModuleContext, artifactPath android.Path, installedFile android.InstallPath) android.Path { +func GenerateArtifactProvenanceMetaData(ctx android.ModuleContext, artifactPath android.Path, installedFile android.InstallPath) { onDevicePathOfInstalledFile := android.InstallPathToOnDevicePath(ctx, installedFile) artifactMetaDataFile := android.PathForIntermediates(ctx, "provenance_metadata", ctx.ModuleDir(), ctx.ModuleName(), "provenance_metadata.textproto") ctx.Build(pctx, android.BuildParams{ @@ -115,5 +113,7 @@ func GenerateArtifactProvenanceMetaData(ctx android.ModuleContext, artifactPath "install_path": onDevicePathOfInstalledFile, }}) - return artifactMetaDataFile + android.SetProvider(ctx, ProvenanceMetadataInfoProvider, ProvenanceMetadataInfo{ + ProvenanceMetaDataFile: artifactMetaDataFile, + }) } -- cgit v1.2.3 From fac80253fb0716dcc21cde9f4169fc2f482d5ed1 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 16 Apr 2025 14:03:27 -0700 Subject: Convert getDeapexerPropertiesIfNeeded to ModuleProxy Add RequiredFilesFromPrebuiltApexInfoProvider and make ModuleStemForDeapexing use CommonModuleInfoProvider so that getDeapexerPropertiesIfNeeded can use WalkDepsProxy. Test: all Soong tests pass Change-Id: Ibe37ee82db309f9fd49e2387db2fc461f513bccf --- android/deapexer.go | 14 ++++++++++++++ android/module.go | 8 ++++++++ apex/prebuilt.go | 11 +++++------ java/classpath_fragment.go | 2 +- java/dexpreopt_bootjars.go | 8 ++++---- 5 files changed, 32 insertions(+), 11 deletions(-) diff --git a/android/deapexer.go b/android/deapexer.go index 6d00dcd72..9d93427af 100644 --- a/android/deapexer.go +++ b/android/deapexer.go @@ -153,6 +153,20 @@ type RequiredFilesFromPrebuiltApex interface { UseProfileGuidedDexpreopt() bool } +type RequiredFilesFromPrebuiltApexInfo struct { + // RequiredFilesFromPrebuiltApex contains a list of the file paths (relative to the root of the + // APEX's contents) that the implementing module requires from within a prebuilt .apex file. + // + // For each file path this will cause the file to be extracted out of the prebuilt .apex file, and + // the path to the extracted file will be stored in the DeapexerInfo using the APEX relative file + // path as the key, The path can then be retrieved using the PrebuiltExportPath(key) method. + RequiredFilesFromPrebuiltApex []string + // UseProfileGuidedDexpreopt is true if a transitive dependency of an apex should use a .prof file to guide dexpreopt + UseProfileGuidedDexpreopt bool +} + +var RequiredFilesFromPrebuiltApexInfoProvider = blueprint.NewProvider[RequiredFilesFromPrebuiltApexInfo]() + // Marker interface that identifies dependencies on modules that may require files from a prebuilt // apex. type RequiresFilesFromPrebuiltApexTag interface { diff --git a/android/module.go b/android/module.go index 4a1aeb249..929b0a0f4 100644 --- a/android/module.go +++ b/android/module.go @@ -2435,6 +2435,14 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) }) } } + + if mm, ok := m.module.(RequiredFilesFromPrebuiltApex); ok { + SetProvider(ctx, RequiredFilesFromPrebuiltApexInfoProvider, RequiredFilesFromPrebuiltApexInfo{ + RequiredFilesFromPrebuiltApex: mm.RequiredFilesFromPrebuiltApex(ctx), + UseProfileGuidedDexpreopt: mm.UseProfileGuidedDexpreopt(), + }) + } + m.module.CleanupAfterBuildActions() } diff --git a/apex/prebuilt.go b/apex/prebuilt.go index 91f5f997c..341e65302 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -491,7 +491,7 @@ func (p *prebuiltCommon) getDeapexerPropertiesIfNeeded(ctx android.ModuleContext commonModules := []string{} dexpreoptProfileGuidedModules := []string{} exportedFiles := []string{} - ctx.WalkDeps(func(child, parent android.Module) bool { + ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool { tag := ctx.OtherModuleDependencyTag(child) // If the child is not in the same apex as the parent then ignore it and all its children. @@ -499,15 +499,14 @@ func (p *prebuiltCommon) getDeapexerPropertiesIfNeeded(ctx android.ModuleContext return false } - name := java.ModuleStemForDeapexing(child) + name := java.ModuleStemForDeapexing(ctx, child) if _, ok := tag.(android.RequiresFilesFromPrebuiltApexTag); ok { commonModules = append(commonModules, name) - extract := child.(android.RequiredFilesFromPrebuiltApex) - requiredFiles := extract.RequiredFilesFromPrebuiltApex(ctx) - exportedFiles = append(exportedFiles, requiredFiles...) + info := android.OtherModuleProviderOrDefault(ctx, child, android.RequiredFilesFromPrebuiltApexInfoProvider) + exportedFiles = append(exportedFiles, info.RequiredFilesFromPrebuiltApex...) - if extract.UseProfileGuidedDexpreopt() { + if info.UseProfileGuidedDexpreopt { dexpreoptProfileGuidedModules = append(dexpreoptProfileGuidedModules, name) } diff --git a/java/classpath_fragment.go b/java/classpath_fragment.go index 88a8fb80a..85dd38bae 100644 --- a/java/classpath_fragment.go +++ b/java/classpath_fragment.go @@ -109,7 +109,7 @@ func gatherPossibleApexModuleNamesAndStems(ctx android.ModuleContext, contents [ // Ignore apex boot jars from dexpreopt if it does not exist, and missing deps are allowed. continue } - set[ModuleStemForDeapexing(dep)] = struct{}{} + set[ModuleStemForDeapexing(ctx, dep)] = struct{}{} if m, ok := dep.(ModuleWithStem); ok { set[m.Stem()] = struct{}{} } else { diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index 93aef0cae..4af7227b1 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -923,9 +923,9 @@ func (m *apexNameToApexExportsInfoMap) javaLibraryDexPathOnHost(ctx android.Modu } // Returns the stem of an artifact inside a prebuilt apex -func ModuleStemForDeapexing(m android.Module) string { - bmn, _ := m.(interface{ BaseModuleName() string }) - return bmn.BaseModuleName() +func ModuleStemForDeapexing(ctx android.OtherModuleProviderContext, m android.ModuleOrProxy) string { + info := android.OtherModuleProviderOrDefault(ctx, m, android.CommonModuleInfoProvider) + return info.BaseModuleName } // Returns the java libraries exported by the apex for hiddenapi and dexpreopt @@ -934,7 +934,7 @@ func ModuleStemForDeapexing(m android.Module) string { // 2. Legacy: An edge to java_library or java_import (java_sdk_library) module. For prebuilt apexes, this serves as a hook and is populated by deapexers of prebuilt apxes // TODO: b/308174306 - Once all mainline modules have been flagged, drop (2) func getDexJarForApex(ctx android.ModuleContext, pair apexJarModulePair, apexNameToApexExportsInfoMap apexNameToApexExportsInfoMap) android.Path { - if dex, found := apexNameToApexExportsInfoMap.javaLibraryDexPathOnHost(ctx, pair.apex, ModuleStemForDeapexing(pair.jarModule)); found { + if dex, found := apexNameToApexExportsInfoMap.javaLibraryDexPathOnHost(ctx, pair.apex, ModuleStemForDeapexing(ctx, pair.jarModule)); found { return dex } // TODO: b/308174306 - Remove the legacy mechanism -- cgit v1.2.3 From 53f7408a85eeefd1a467d006604dd4ab3eaad46f Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 16 Apr 2025 14:07:50 -0700 Subject: Convert singletons to ModuleProxy Convert miscellaneous singletons to use ModuleProxy. Test: all Soong tests pass Change-Id: I64bc0eaedb6291d7bdb38efc91f20d41fc8022ad --- android/module.go | 7 ++++--- cc/cc.go | 4 ++++ cc/cmakelists.go | 49 +++++++++++++++++++++++++------------------------ cc/compdb.go | 36 ++++++++++++++++++------------------ cc/makevars.go | 10 +++++----- cc/misc_disted_files.go | 5 +++-- phony/phony.go | 2 +- 7 files changed, 60 insertions(+), 53 deletions(-) diff --git a/android/module.go b/android/module.go index 929b0a0f4..8ef7a44d6 100644 --- a/android/module.go +++ b/android/module.go @@ -3384,9 +3384,10 @@ func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) { hostCross bool } osDeps := map[osAndCross]Paths{} - ctx.VisitAllModules(func(module Module) { - if module.Enabled(ctx) { - key := osAndCross{os: module.Target().Os, hostCross: module.Target().HostCross} + ctx.VisitAllModuleProxies(func(module ModuleProxy) { + info := OtherModuleProviderOrDefault(ctx, module, CommonModuleInfoProvider) + if info.Enabled { + key := osAndCross{os: info.Target.Os, hostCross: info.Target.HostCross} osDeps[key] = append(osDeps[key], OtherModuleProviderOrDefault(ctx, module, InstallFilesProvider).CheckbuildFiles...) } }) diff --git a/cc/cc.go b/cc/cc.go index 3e28db3ae..d616978c0 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -173,11 +173,13 @@ type CcInfo struct { VendorAvailable bool OdmAvailable bool ProductAvailable bool + IsVendorPublicLibrary bool // Allowable SdkMemberTypes of this module type. SdkMemberTypes []android.SdkMemberType LocalFlags LocalOrGlobalFlagsInfo GlobalFlags LocalOrGlobalFlagsInfo SystemIncludeFlags []string + NoOverrideFlags []string CompilerInfo *CompilerInfo LinkerInfo *LinkerInfo SnapshotInfo *SnapshotInfo @@ -2582,6 +2584,7 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { OdmAvailable: c.OdmAvailable(), ProductAvailable: c.ProductAvailable(), SdkMemberTypes: c.sdkMemberTypes, + IsVendorPublicLibrary: c.IsVendorPublicLibrary(), LocalFlags: LocalOrGlobalFlagsInfo{ CommonFlags: c.flags.Local.CommonFlags, CFlags: c.flags.Local.CFlags, @@ -2595,6 +2598,7 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { CppFlags: c.flags.Global.CppFlags, }, SystemIncludeFlags: c.flags.SystemIncludeFlags, + NoOverrideFlags: c.flags.NoOverrideFlags, } if c.compiler != nil { cflags := c.compiler.baseCompilerProps().Cflags diff --git a/cc/cmakelists.go b/cc/cmakelists.go index 0f3f02da5..c2bd17ad9 100644 --- a/cc/cmakelists.go +++ b/cc/cmakelists.go @@ -16,12 +16,12 @@ package cc import ( "fmt" - - "android/soong/android" "os" "path" "path/filepath" "strings" + + "android/soong/android" ) // This singleton generates CMakeLists.txt files. It does so for each blueprint Android.bp resulting in a cc.Module @@ -65,10 +65,10 @@ func (c *cmakelistsGeneratorSingleton) GenerateBuildActions(ctx android.Singleto // variant for each project. seenProjects := map[string]bool{} - ctx.VisitAllModules(func(module android.Module) { - if ccModule, ok := module.(*Module); ok { - if compiledModule, ok := ccModule.compiler.(CompiledInterface); ok { - generateCLionProject(compiledModule, ctx, ccModule, seenProjects) + ctx.VisitAllModuleProxies(func(module android.ModuleProxy) { + if ccModule, ok := android.OtherModuleProvider(ctx, module, CcInfoProvider); ok { + if ccModule.CompilerInfo != nil { + generateCLionProject(ctx, module, ccModule, seenProjects) } } }) @@ -117,15 +117,15 @@ func linkAggregateCMakeListsFiles(path string, info os.FileInfo, err error) erro return nil } -func generateCLionProject(compiledModule CompiledInterface, ctx android.SingletonContext, ccModule *Module, +func generateCLionProject(ctx android.SingletonContext, module android.ModuleProxy, ccModule *CcInfo, seenProjects map[string]bool) { - srcs := compiledModule.Srcs() + srcs := ccModule.CompilerInfo.Srcs if len(srcs) == 0 { return } // Only write CMakeLists.txt for the first variant of each architecture of each module - clionprojectLocation := getCMakeListsForModule(ccModule, ctx) + clionprojectLocation := getCMakeListsForModule(ctx, module) if seenProjects[clionprojectLocation] { return } @@ -146,7 +146,7 @@ func generateCLionProject(compiledModule CompiledInterface, ctx android.Singleto f.WriteString("# To improve project view in Clion :\n") f.WriteString("# Tools > CMake > Change Project Root \n\n") f.WriteString(fmt.Sprintf("cmake_minimum_required(VERSION %s)\n", minimumCMakeVersionSupported)) - f.WriteString(fmt.Sprintf("project(%s)\n", ccModule.ModuleBase.Name())) + f.WriteString(fmt.Sprintf("project(%s)\n", module.Name())) f.WriteString(fmt.Sprintf("set(ANDROID_ROOT %s)\n\n", android.AbsSrcDirForExistingUseCases())) pathToCC, _ := evalVariable(ctx, "${config.ClangBin}/") @@ -163,44 +163,44 @@ func generateCLionProject(compiledModule CompiledInterface, ctx android.Singleto // Add all header search path and compiler parameters (-D, -W, -f, -XXXX) f.WriteString("\n# GLOBAL ALL FLAGS:\n") - globalAllParameters := parseCompilerParameters(ccModule.flags.Global.CommonFlags, ctx, f) + globalAllParameters := parseCompilerParameters(ccModule.GlobalFlags.CommonFlags, ctx, f) translateToCMake(globalAllParameters, f, true, true) f.WriteString("\n# LOCAL ALL FLAGS:\n") - localAllParameters := parseCompilerParameters(ccModule.flags.Local.CommonFlags, ctx, f) + localAllParameters := parseCompilerParameters(ccModule.LocalFlags.CommonFlags, ctx, f) translateToCMake(localAllParameters, f, true, true) f.WriteString("\n# GLOBAL CFLAGS:\n") - globalCParameters := parseCompilerParameters(ccModule.flags.Global.CFlags, ctx, f) + globalCParameters := parseCompilerParameters(ccModule.GlobalFlags.CFlags, ctx, f) translateToCMake(globalCParameters, f, true, true) f.WriteString("\n# LOCAL CFLAGS:\n") - localCParameters := parseCompilerParameters(ccModule.flags.Local.CFlags, ctx, f) + localCParameters := parseCompilerParameters(ccModule.LocalFlags.CFlags, ctx, f) translateToCMake(localCParameters, f, true, true) f.WriteString("\n# GLOBAL C ONLY FLAGS:\n") - globalConlyParameters := parseCompilerParameters(ccModule.flags.Global.ConlyFlags, ctx, f) + globalConlyParameters := parseCompilerParameters(ccModule.GlobalFlags.ConlyFlags, ctx, f) translateToCMake(globalConlyParameters, f, true, false) f.WriteString("\n# LOCAL C ONLY FLAGS:\n") - localConlyParameters := parseCompilerParameters(ccModule.flags.Local.ConlyFlags, ctx, f) + localConlyParameters := parseCompilerParameters(ccModule.LocalFlags.ConlyFlags, ctx, f) translateToCMake(localConlyParameters, f, true, false) f.WriteString("\n# GLOBAL CPP FLAGS:\n") - globalCppParameters := parseCompilerParameters(ccModule.flags.Global.CppFlags, ctx, f) + globalCppParameters := parseCompilerParameters(ccModule.GlobalFlags.CppFlags, ctx, f) translateToCMake(globalCppParameters, f, false, true) f.WriteString("\n# LOCAL CPP FLAGS:\n") - localCppParameters := parseCompilerParameters(ccModule.flags.Local.CppFlags, ctx, f) + localCppParameters := parseCompilerParameters(ccModule.LocalFlags.CppFlags, ctx, f) translateToCMake(localCppParameters, f, false, true) f.WriteString("\n# GLOBAL SYSTEM INCLUDE FLAGS:\n") - globalIncludeParameters := parseCompilerParameters(ccModule.flags.SystemIncludeFlags, ctx, f) + globalIncludeParameters := parseCompilerParameters(ccModule.SystemIncludeFlags, ctx, f) translateToCMake(globalIncludeParameters, f, true, true) // Add project executable. f.WriteString(fmt.Sprintf("\nadd_executable(%s ${SOURCE_FILES})\n", - cleanExecutableName(ccModule.ModuleBase.Name()))) + cleanExecutableName(module.Name()))) } func cleanExecutableName(s string) string { @@ -467,12 +467,13 @@ func evalVariable(ctx android.SingletonContext, str string) (string, error) { return "", err } -func getCMakeListsForModule(module *Module, ctx android.SingletonContext) string { +func getCMakeListsForModule(ctx android.SingletonContext, module android.ModuleProxy) string { + commonInfo := android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoProvider) return filepath.Join(android.AbsSrcDirForExistingUseCases(), cLionOutputProjectsDirectory, path.Dir(ctx.BlueprintFile(module)), - module.ModuleBase.Name()+"-"+ - module.ModuleBase.Arch().ArchType.Name+"-"+ - module.ModuleBase.Os().Name, + module.Name()+"-"+ + commonInfo.Target.Arch.ArchType.Name+"-"+ + commonInfo.Target.Os.Name, cMakeListsFilename) } diff --git a/cc/compdb.go b/cc/compdb.go index 3818e9c46..4f61e5793 100644 --- a/cc/compdb.go +++ b/cc/compdb.go @@ -69,10 +69,10 @@ func (c *compdbGeneratorSingleton) GenerateBuildActions(ctx android.SingletonCon // We only want one entry per file. We don't care what module/isa it's from m := make(map[string]compDbEntry) - ctx.VisitAllModules(func(module android.Module) { - if ccModule, ok := module.(*Module); ok { - if compiledModule, ok := ccModule.compiler.(CompiledInterface); ok { - generateCompdbProject(compiledModule, ctx, ccModule, m) + ctx.VisitAllModuleProxies(func(module android.ModuleProxy) { + if ccModule, ok := android.OtherModuleProvider(ctx, module, CcInfoProvider); ok { + if ccModule.CompilerInfo != nil { + generateCompdbProject(ctx, module, ccModule, m) } } }) @@ -127,7 +127,7 @@ func expandAllVars(ctx android.SingletonContext, args []string) []string { return out } -func getArguments(src android.Path, ctx android.SingletonContext, ccModule *Module, ccPath string, cxxPath string) []string { +func getArguments(ctx android.SingletonContext, src android.Path, ccModule *CcInfo, ccPath string, cxxPath string) []string { var args []string isCpp := false isAsm := false @@ -155,25 +155,25 @@ func getArguments(src android.Path, ctx android.SingletonContext, ccModule *Modu clangPath = ccPath } args = append(args, clangPath) - args = append(args, expandAllVars(ctx, ccModule.flags.Global.CommonFlags)...) - args = append(args, expandAllVars(ctx, ccModule.flags.Local.CommonFlags)...) - args = append(args, expandAllVars(ctx, ccModule.flags.Global.CFlags)...) - args = append(args, expandAllVars(ctx, ccModule.flags.Local.CFlags)...) + args = append(args, expandAllVars(ctx, ccModule.GlobalFlags.CommonFlags)...) + args = append(args, expandAllVars(ctx, ccModule.LocalFlags.CommonFlags)...) + args = append(args, expandAllVars(ctx, ccModule.GlobalFlags.CFlags)...) + args = append(args, expandAllVars(ctx, ccModule.LocalFlags.CFlags)...) if isCpp { - args = append(args, expandAllVars(ctx, ccModule.flags.Global.CppFlags)...) - args = append(args, expandAllVars(ctx, ccModule.flags.Local.CppFlags)...) + args = append(args, expandAllVars(ctx, ccModule.GlobalFlags.CppFlags)...) + args = append(args, expandAllVars(ctx, ccModule.LocalFlags.CppFlags)...) } else if !isAsm { - args = append(args, expandAllVars(ctx, ccModule.flags.Global.ConlyFlags)...) - args = append(args, expandAllVars(ctx, ccModule.flags.Local.ConlyFlags)...) + args = append(args, expandAllVars(ctx, ccModule.GlobalFlags.ConlyFlags)...) + args = append(args, expandAllVars(ctx, ccModule.LocalFlags.ConlyFlags)...) } - args = append(args, expandAllVars(ctx, ccModule.flags.SystemIncludeFlags)...) - args = append(args, expandAllVars(ctx, ccModule.flags.NoOverrideFlags)...) + args = append(args, expandAllVars(ctx, ccModule.SystemIncludeFlags)...) + args = append(args, expandAllVars(ctx, ccModule.NoOverrideFlags)...) args = append(args, src.String()) return args } -func generateCompdbProject(compiledModule CompiledInterface, ctx android.SingletonContext, ccModule *Module, builds map[string]compDbEntry) { - srcs := compiledModule.Srcs() +func generateCompdbProject(ctx android.SingletonContext, module android.ModuleProxy, ccModule *CcInfo, builds map[string]compDbEntry) { + srcs := ccModule.CompilerInfo.Srcs if len(srcs) == 0 { return } @@ -187,7 +187,7 @@ func generateCompdbProject(compiledModule CompiledInterface, ctx android.Singlet } for _, src := range srcs { if _, ok := builds[src.String()]; !ok { - args := getArguments(src, ctx, ccModule, ccPath, cxxPath) + args := getArguments(ctx, src, ccModule, ccPath, cxxPath) if args == nil { continue } diff --git a/cc/makevars.go b/cc/makevars.go index 9358755cc..edebe2dab 100644 --- a/cc/makevars.go +++ b/cc/makevars.go @@ -100,11 +100,11 @@ func makeVarsProvider(ctx android.MakeVarsContext) { // Filter vendor_public_library that are exported to make var exportedVendorPublicLibraries []string - ctx.VisitAllModules(func(module android.Module) { - if ccModule, ok := module.(*Module); ok { - baseName := ccModule.BaseModuleName() - if ccModule.IsVendorPublicLibrary() && module.ExportedToMake() { - exportedVendorPublicLibraries = append(exportedVendorPublicLibraries, baseName) + ctx.VisitAllModuleProxies(func(module android.ModuleProxy) { + if ccInfo, ok := android.OtherModuleProvider(ctx, module, CcInfoProvider); ok { + commonInfo := android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoProvider) + if ccInfo.IsVendorPublicLibrary && commonInfo.ExportedToMake { + exportedVendorPublicLibraries = append(exportedVendorPublicLibraries, commonInfo.BaseModuleName) } } }) diff --git a/cc/misc_disted_files.go b/cc/misc_disted_files.go index 4bdffaa03..ef0b4eb45 100644 --- a/cc/misc_disted_files.go +++ b/cc/misc_disted_files.go @@ -15,8 +15,9 @@ package cc import ( - "android/soong/android" "strings" + + "android/soong/android" ) func init() { @@ -36,7 +37,7 @@ func (s *ccMiscDistedFilesSingleton) GenerateBuildActions(ctx android.SingletonC var warningsAllowed []string var usingWnoErrors []string var missingProfiles []string - ctx.VisitAllModules(func(module android.Module) { + ctx.VisitAllModuleProxies(func(module android.ModuleProxy) { if v, ok := android.OtherModuleProvider(ctx, module, CcMakeVarsInfoProvider); ok { warningsAllowed = android.AppendIfNotZero(warningsAllowed, v.WarningsAllowed) usingWnoErrors = android.AppendIfNotZero(usingWnoErrors, v.UsingWnoError) diff --git a/phony/phony.go b/phony/phony.go index e75f4c809..5c2273ee1 100644 --- a/phony/phony.go +++ b/phony/phony.go @@ -57,7 +57,7 @@ func (p *phony) GenerateAndroidBuildActions(ctx android.ModuleContext) { p.hostRequiredModuleNames = ctx.HostRequiredModuleNames() p.targetRequiredModuleNames = ctx.TargetRequiredModuleNames() - ctx.VisitDirectDepsWithTag(android.RequiredDepTag, func(dep android.Module) { + ctx.VisitDirectDepsProxyWithTag(android.RequiredDepTag, func(dep android.ModuleProxy) { if o, ok := android.OtherModuleProvider(ctx, dep, android.OutputFilesProvider); ok { p.outputDeps = append(p.outputDeps, o.DefaultOutputFiles...) } -- cgit v1.2.3 From 7a468b7b63fec3cd903f94159569d265ce80c391 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 16 Apr 2025 14:10:30 -0700 Subject: Convert some of rust/ to ModuleProxy and Providers When cc modules are marked with FreeModuleAfterGenerateBuildActions it will be an error to visit any cc dependency using VisitDirectDeps, and VisitDirectDepsProxy must be used instead. Convert any part of rust/ that visits cc dependencies to ModuleProxy and Providers. Test: all Soong tests pass Change-Id: I6abe6d2befd5a80e8804d2352c4c888302794c92 --- rust/binary.go | 2 +- rust/builder.go | 4 +-- rust/compiler.go | 88 ++++++++++++++++++---------------------------------- rust/library.go | 14 ++++----- rust/object.go | 2 +- rust/prebuilt.go | 16 ++++++++++ rust/proc_macro.go | 2 +- rust/project_json.go | 73 ++++++++++++++++++++++--------------------- rust/rust.go | 23 ++++++++++++-- 9 files changed, 117 insertions(+), 107 deletions(-) diff --git a/rust/binary.go b/rust/binary.go index b413a40cc..b94fbca48 100644 --- a/rust/binary.go +++ b/rust/binary.go @@ -155,7 +155,7 @@ func (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps Path fileName := binary.getStem(ctx) + ctx.toolchain().ExecutableSuffix() outputFile := android.PathForModuleOut(ctx, fileName) ret := buildOutput{outputFile: outputFile} - crateRootPath := crateRootPath(ctx, binary) + crateRootPath := binary.crateRootPath(ctx) // Ensure link dirs are not duplicated deps.linkDirs = android.FirstUniqueStrings(deps.linkDirs) diff --git a/rust/builder.go b/rust/builder.go index 1c0ecf8d2..6deaa09d9 100644 --- a/rust/builder.go +++ b/rust/builder.go @@ -148,7 +148,7 @@ func getTransformProperties(ctx ModuleContext, crateType string) transformProper inRecovery: module.InRecovery(), inRamdisk: module.InRamdisk(), inVendorRamdisk: module.InVendorRamdisk(), - cargoOutDir: module.compiler.cargoOutDir(), + cargoOutDir: module.compiler.cargoOutDir(ctx), // crateType indicates what type of crate to build crateType: crateType, @@ -606,7 +606,7 @@ func Rustdoc(ctx ModuleContext, main android.Path, deps PathDeps, Args: map[string]string{ "rustdocFlags": strings.Join(rustdocFlags, " "), "outDir": docDir.String(), - "envVars": strings.Join(rustEnvVars(ctx, deps, crateName, ctx.RustModule().compiler.cargoOutDir()), " "), + "envVars": strings.Join(rustEnvVars(ctx, deps, crateName, ctx.RustModule().compiler.cargoOutDir(ctx)), " "), }, }) diff --git a/rust/compiler.go b/rust/compiler.go index b5f20fbef..373de4d99 100644 --- a/rust/compiler.go +++ b/rust/compiler.go @@ -15,12 +15,12 @@ package rust import ( - "android/soong/cc" - "errors" "fmt" "path/filepath" "strings" + "android/soong/cc" + "github.com/google/blueprint/proptools" "android/soong/android" @@ -35,24 +35,23 @@ const ( ) type compiler interface { - initialize(ctx ModuleContext) compilerFlags(ctx ModuleContext, flags Flags) Flags cfgFlags(ctx ModuleContext, flags Flags) Flags - featureFlags(ctx ModuleContext, module *Module, flags Flags) Flags + featureFlags(ctx ModuleContext, flags Flags) Flags baseCompilerProps() BaseCompilerProperties compilerProps() []interface{} compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput compilerDeps(ctx DepsContext, deps Deps) Deps crateName() string edition() string - features(ctx android.ConfigurableEvaluatorContext, module *Module) []string + features(ctx ModuleContext) []string rustdoc(ctx ModuleContext, flags Flags, deps PathDeps) android.OptionalPath Thinlto() bool begin(ctx BaseModuleContext) // Output directory in which source-generated code from dependencies is // copied. This is equivalent to Cargo's OUT_DIR variable. - cargoOutDir() android.OptionalPath + cargoOutDir(ctx ModuleContext) android.OptionalPath // cargoPkgVersion returns the value of the Cargo_pkg_version property. cargoPkgVersion() string @@ -76,7 +75,7 @@ type compiler interface { unstrippedOutputFilePath() android.Path strippedOutputFilePath() android.OptionalPath - checkedCrateRootPath() (android.Path, error) + crateRootPath(ctx ModuleContext) android.Path Aliases() map[string]string @@ -113,8 +112,7 @@ const ( InstallInData = iota NoInstall = iota - incorrectSourcesError = "srcs can only contain one path for a rust file and source providers prefixed by \":\"" - genSubDir = "out/" + genSubDir = "out/" ) type BaseCompilerProperties struct { @@ -268,19 +266,6 @@ type baseCompiler struct { // stripped output file. strippedOutputFile android.OptionalPath - - // If a crate has a source-generated dependency, a copy of the source file - // will be available in cargoOutDir (equivalent to Cargo OUT_DIR). - // This is stored internally because it may not be available during - // singleton-generation passes like rustdoc/rust_project.json, but should - // be stashed during initial generation. - cachedCargoOutDir android.ModuleOutPath - // Calculated crate root cached internally because ModuleContext is not - // available to singleton targets like rustdoc/rust_project.json - cachedCrateRootPath android.Path - // If cachedCrateRootPath is nil after initialization, this will contain - // an explanation of why - cachedCrateRootError error } func (compiler *baseCompiler) begin(ctx BaseModuleContext) {} @@ -382,23 +367,22 @@ func cfgsToFlags(cfgs []string) []string { return flags } -func (compiler *baseCompiler) features(ctx android.ConfigurableEvaluatorContext, module *Module) []string { - eval := module.ConfigurableEvaluator(ctx) - return compiler.Properties.Features.GetOrDefault(eval, nil) +func (compiler *baseCompiler) features(ctx ModuleContext) []string { + return compiler.Properties.Features.GetOrDefault(ctx, nil) } -func (compiler *baseCompiler) featuresToFlags(ctx android.ConfigurableEvaluatorContext, module *Module) []string { +func (compiler *baseCompiler) featuresToFlags(ctx ModuleContext) []string { flags := []string{} - for _, feature := range compiler.features(ctx, module) { + for _, feature := range compiler.features(ctx) { flags = append(flags, "--cfg 'feature=\""+feature+"\"'") } return flags } -func (compiler *baseCompiler) featureFlags(ctx ModuleContext, module *Module, flags Flags) Flags { - flags.RustFlags = append(flags.RustFlags, compiler.featuresToFlags(ctx, module)...) - flags.RustdocFlags = append(flags.RustdocFlags, compiler.featuresToFlags(ctx, module)...) +func (compiler *baseCompiler) featureFlags(ctx ModuleContext, flags Flags) Flags { + flags.RustFlags = append(flags.RustFlags, compiler.featuresToFlags(ctx)...) + flags.RustdocFlags = append(flags.RustdocFlags, compiler.featuresToFlags(ctx)...) return flags } @@ -502,18 +486,8 @@ func (compiler *baseCompiler) rustdoc(ctx ModuleContext, flags Flags, return android.OptionalPath{} } -func (compiler *baseCompiler) initialize(ctx ModuleContext) { - compiler.cachedCargoOutDir = android.PathForModuleOut(ctx, genSubDir) - if compiler.Properties.Crate_root == nil { - compiler.cachedCrateRootPath, compiler.cachedCrateRootError = srcPathFromModuleSrcs(ctx, compiler.Properties.Srcs) - } else { - compiler.cachedCrateRootPath = android.PathForModuleSrc(ctx, *compiler.Properties.Crate_root) - compiler.cachedCrateRootError = nil - } -} - -func (compiler *baseCompiler) cargoOutDir() android.OptionalPath { - return android.OptionalPathForPath(compiler.cachedCargoOutDir) +func (compiler *baseCompiler) cargoOutDir(ctx ModuleContext) android.OptionalPath { + return android.OptionalPathForPath(android.PathForModuleOut(ctx, genSubDir)) } func (compiler *baseCompiler) cargoEnvCompat() bool { @@ -662,20 +636,16 @@ func (compiler *baseCompiler) relativeInstallPath() string { return String(compiler.Properties.Relative_install_path) } -func (compiler *baseCompiler) checkedCrateRootPath() (android.Path, error) { - return compiler.cachedCrateRootPath, compiler.cachedCrateRootError -} - -func crateRootPath(ctx ModuleContext, compiler compiler) android.Path { - root, err := compiler.checkedCrateRootPath() - if err != nil { - ctx.PropertyErrorf("srcs", err.Error()) +func (compiler *baseCompiler) crateRootPath(ctx ModuleContext) android.Path { + if compiler.Properties.Crate_root == nil { + return srcPathFromModuleSrcs(ctx, compiler.Properties.Srcs) + } else { + return android.PathForModuleSrc(ctx, *compiler.Properties.Crate_root) } - return root } // Returns the Path for the main source file along with Paths for generated source files from modules listed in srcs. -func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) (android.Path, error) { +func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) android.Path { // The srcs can contain strings with prefix ":". // They are dependent modules of this module, with android.SourceDepTag. // They are not the main source file compiled by rustc. @@ -688,24 +658,28 @@ func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) (android.Path, erro } } if numSrcs > 1 { - return nil, errors.New(incorrectSourcesError) + ctx.PropertyErrorf("srcs", "srcs can only contain one path for a rust file and source providers prefixed by \":\"") + return nil } // If a main source file is not provided we expect only a single SourceProvider module to be defined // within srcs, with the expectation that the first source it provides is the entry point. if srcIndex != 0 { - return nil, errors.New("main source file must be the first in srcs") + ctx.PropertyErrorf("srcs", "main source file must be the first in srcs") + return nil } else if numSrcs > 1 { - return nil, errors.New("only a single generated source module can be defined without a main source file.") + ctx.PropertyErrorf("srcs", "only a single generated source module can be defined without a main source file.") + return nil } // TODO: b/297264540 - once all modules are sandboxed, we need to select the proper // entry point file from Srcs rather than taking the first one paths := android.PathsForModuleSrc(ctx, srcs) if len(paths) == 0 { - return nil, errors.New("srcs must not be empty") + ctx.PropertyErrorf("srcs", "srcs must not be empty") + return nil } - return paths[srcIndex], nil + return paths[srcIndex] } // Returns an emit type corresponding to the `--emit=` rustc flag. diff --git a/rust/library.go b/rust/library.go index df83122b0..04d03c8e3 100644 --- a/rust/library.go +++ b/rust/library.go @@ -15,7 +15,6 @@ package rust import ( - "errors" "fmt" "regexp" "strings" @@ -640,7 +639,7 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa var outputFile android.ModuleOutPath var ret buildOutput var fileName string - crateRootPath := crateRootPath(ctx, library) + crateRootPath := library.crateRootPath(ctx) if library.sourceProvider != nil { deps.srcProviderFiles = append(deps.srcProviderFiles, library.sourceProvider.Srcs()...) @@ -800,16 +799,17 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa return ret } -func (library *libraryDecorator) checkedCrateRootPath() (android.Path, error) { +func (library *libraryDecorator) crateRootPath(ctx ModuleContext) android.Path { if library.sourceProvider != nil { srcs := library.sourceProvider.Srcs() if len(srcs) == 0 { - return nil, errors.New("Source provider generated 0 sources") + ctx.PropertyErrorf("srcs", "Source provider generated 0 sources") + return nil } // Assume the first source from the source provider is the library entry point. - return srcs[0], nil + return srcs[0] } else { - return library.baseCompiler.checkedCrateRootPath() + return library.baseCompiler.crateRootPath(ctx) } } @@ -871,7 +871,7 @@ func (library *libraryDecorator) rustdoc(ctx ModuleContext, flags Flags, return android.OptionalPath{} } - return android.OptionalPathForPath(Rustdoc(ctx, crateRootPath(ctx, library), + return android.OptionalPathForPath(Rustdoc(ctx, library.crateRootPath(ctx), deps, flags)) } diff --git a/rust/object.go b/rust/object.go index 2334988ca..b2123c4a9 100644 --- a/rust/object.go +++ b/rust/object.go @@ -101,7 +101,7 @@ func (object *objectDecorator) compile(ctx ModuleContext, flags Flags, deps Path fileName := object.getStem(ctx) + ".o" outputFile := android.PathForModuleOut(ctx, fileName) ret := buildOutput{outputFile: outputFile} - crateRootPath := crateRootPath(ctx, object) + crateRootPath := object.crateRootPath(ctx) flags.RustFlags = append(flags.RustFlags, deps.depFlags...) object.baseCompiler.unstrippedOutputFile = outputFile diff --git a/rust/prebuilt.go b/rust/prebuilt.go index 7c92dda1e..a3537e9b4 100644 --- a/rust/prebuilt.go +++ b/rust/prebuilt.go @@ -197,6 +197,14 @@ func (prebuilt *prebuiltLibraryDecorator) prebuilt() *android.Prebuilt { return &prebuilt.Prebuilt } +func (prebuilt *prebuiltLibraryDecorator) crateRootPath(ctx ModuleContext) android.Path { + if prebuilt.baseCompiler.Properties.Crate_root == nil { + return srcPathFromModuleSrcs(ctx, prebuilt.prebuiltSrcs()) + } else { + return android.PathForModuleSrc(ctx, *prebuilt.baseCompiler.Properties.Crate_root) + } +} + func (prebuilt *prebuiltProcMacroDecorator) prebuiltSrcs() []string { srcs := prebuilt.Properties.Srcs return srcs @@ -233,3 +241,11 @@ func (prebuilt *prebuiltProcMacroDecorator) compilerDeps(ctx DepsContext, deps D func (prebuilt *prebuiltProcMacroDecorator) nativeCoverage() bool { return false } + +func (prebuilt *prebuiltProcMacroDecorator) crateRootPath(ctx ModuleContext) android.Path { + if prebuilt.baseCompiler.Properties.Crate_root == nil { + return srcPathFromModuleSrcs(ctx, prebuilt.prebuiltSrcs()) + } else { + return android.PathForModuleSrc(ctx, *prebuilt.baseCompiler.Properties.Crate_root) + } +} diff --git a/rust/proc_macro.go b/rust/proc_macro.go index 837e1a6c8..255ea2024 100644 --- a/rust/proc_macro.go +++ b/rust/proc_macro.go @@ -74,7 +74,7 @@ func (procMacro *procMacroDecorator) compilerFlags(ctx ModuleContext, flags Flag func (procMacro *procMacroDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput { fileName := procMacro.getStem(ctx) + ctx.toolchain().ProcMacroSuffix() outputFile := android.PathForModuleOut(ctx, fileName) - srcPath := crateRootPath(ctx, procMacro) + srcPath := procMacro.crateRootPath(ctx) ret := TransformSrctoProcMacro(ctx, srcPath, deps, flags, outputFile) procMacro.baseCompiler.unstrippedOutputFile = outputFile diff --git a/rust/project_json.go b/rust/project_json.go index 6e8cebeed..42369c186 100644 --- a/rust/project_json.go +++ b/rust/project_json.go @@ -18,6 +18,8 @@ import ( "encoding/json" "fmt" + "github.com/google/blueprint/proptools" + "android/soong/android" "android/soong/rust/config" ) @@ -83,23 +85,23 @@ func init() { // mergeDependencies visits all the dependencies for module and updates crate and deps // with any new dependency. func (singleton *projectGeneratorSingleton) mergeDependencies(ctx android.SingletonContext, - module *Module, crate *rustProjectCrate, deps map[string]int) { + module android.ModuleProxy, crate *rustProjectCrate, deps map[string]int) { - ctx.VisitDirectDeps(module, func(child android.Module) { + ctx.VisitDirectDepsProxies(module, func(child android.ModuleProxy) { // Skip intra-module dependencies (i.e., generated-source library depending on the source variant). if module.Name() == child.Name() { return } // Skip unsupported modules. - rChild, ok := isModuleSupported(ctx, child) + rustInfo, commonInfo, ok := isModuleSupported(ctx, child) if !ok { return } // For unknown dependency, add it first. var childId int - cInfo, known := singleton.knownCrates[rChild.Name()] + cInfo, known := singleton.knownCrates[child.Name()] if !known { - childId, ok = singleton.addCrate(ctx, rChild) + childId, ok = singleton.addCrate(ctx, child, rustInfo, commonInfo) if !ok { return } @@ -110,44 +112,43 @@ func (singleton *projectGeneratorSingleton) mergeDependencies(ctx android.Single if _, ok = deps[child.Name()]; ok { return } - crate.Deps = append(crate.Deps, rustProjectDep{Crate: childId, Name: rChild.CrateName()}) + crate.Deps = append(crate.Deps, rustProjectDep{Crate: childId, Name: rustInfo.CompilerInfo.CrateName}) deps[child.Name()] = childId }) } // isModuleSupported returns the RustModule if the module // should be considered for inclusion in rust-project.json. -func isModuleSupported(ctx android.SingletonContext, module android.Module) (*Module, bool) { - rModule, ok := module.(*Module) +func isModuleSupported(ctx android.SingletonContext, module android.ModuleProxy) (*RustInfo, *android.CommonModuleInfo, bool) { + info, ok := android.OtherModuleProvider(ctx, module, RustInfoProvider) if !ok { - return nil, false + return nil, nil, false } - if !rModule.Enabled(ctx) { - return nil, false + commonInfo := android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoProvider) + if !commonInfo.Enabled { + return nil, nil, false } - return rModule, true + return info, commonInfo, true } // addCrate adds a crate to singleton.project.Crates ensuring that required // dependencies are also added. It returns the index of the new crate in // singleton.project.Crates -func (singleton *projectGeneratorSingleton) addCrate(ctx android.SingletonContext, rModule *Module) (int, bool) { +func (singleton *projectGeneratorSingleton) addCrate(ctx android.SingletonContext, module android.ModuleProxy, rustInfo *RustInfo, + commonInfo *android.CommonModuleInfo) (int, bool) { + deps := make(map[string]int) - rootModule, err := rModule.compiler.checkedCrateRootPath() - if err != nil { - return 0, false - } var procMacroDylib *string = nil - if procDec, procMacro := rModule.compiler.(*procMacroDecorator); procMacro { - procMacroDylib = new(string) - *procMacroDylib = procDec.baseCompiler.unstrippedOutputFilePath().String() + + if procMacro := rustInfo.ProcMacroInfo; procMacro != nil { + procMacroDylib = proptools.StringPtr(procMacro.Dylib.String()) } crate := rustProjectCrate{ - DisplayName: rModule.Name(), - RootModule: rootModule.String(), - Edition: rModule.compiler.edition(), + DisplayName: module.Name(), + RootModule: rustInfo.CompilerInfo.CrateRootPath.String(), + Edition: rustInfo.CompilerInfo.Edition, Deps: make([]rustProjectDep, 0), Cfg: make([]string, 0), Env: make(map[string]string), @@ -155,49 +156,49 @@ func (singleton *projectGeneratorSingleton) addCrate(ctx android.SingletonContex ProcMacroDylib: procMacroDylib, } - if rModule.compiler.cargoOutDir().Valid() { - crate.Env["OUT_DIR"] = rModule.compiler.cargoOutDir().String() + if cargoOutDir := rustInfo.CompilerInfo.CargoOutDir; cargoOutDir.Valid() { + crate.Env["OUT_DIR"] = cargoOutDir.String() } - for _, feature := range rModule.compiler.features(ctx, rModule) { + for _, feature := range rustInfo.CompilerInfo.Features { crate.Cfg = append(crate.Cfg, "feature=\""+feature+"\"") } - singleton.mergeDependencies(ctx, rModule, &crate, deps) + singleton.mergeDependencies(ctx, module, &crate, deps) var idx int - if cInfo, ok := singleton.knownCrates[rModule.Name()]; ok { + if cInfo, ok := singleton.knownCrates[module.Name()]; ok { idx = cInfo.Idx singleton.project.Crates[idx] = crate } else { idx = len(singleton.project.Crates) singleton.project.Crates = append(singleton.project.Crates, crate) } - singleton.knownCrates[rModule.Name()] = crateInfo{Idx: idx, Deps: deps, Device: rModule.Device()} + singleton.knownCrates[module.Name()] = crateInfo{Idx: idx, Deps: deps, Device: commonInfo.Target.Os.Class == android.Device} return idx, true } // appendCrateAndDependencies creates a rustProjectCrate for the module argument and appends it to singleton.project. // It visits the dependencies of the module depth-first so the dependency ID can be added to the current module. If the // current module is already in singleton.knownCrates, its dependencies are merged. -func (singleton *projectGeneratorSingleton) appendCrateAndDependencies(ctx android.SingletonContext, module android.Module) { - rModule, ok := isModuleSupported(ctx, module) +func (singleton *projectGeneratorSingleton) appendCrateAndDependencies(ctx android.SingletonContext, module android.ModuleProxy) { + rustInfo, commonInfo, ok := isModuleSupported(ctx, module) if !ok { return } // If we have seen this crate already; merge any new dependencies. if cInfo, ok := singleton.knownCrates[module.Name()]; ok { // If we have a new device variant, override the old one - if !cInfo.Device && rModule.Device() { - singleton.addCrate(ctx, rModule) + if !cInfo.Device && commonInfo.Target.Os.Class == android.Device { + singleton.addCrate(ctx, module, rustInfo, commonInfo) return } crate := singleton.project.Crates[cInfo.Idx] - singleton.mergeDependencies(ctx, rModule, &crate, cInfo.Deps) + singleton.mergeDependencies(ctx, module, &crate, cInfo.Deps) singleton.project.Crates[cInfo.Idx] = crate return } - singleton.addCrate(ctx, rModule) + singleton.addCrate(ctx, module, rustInfo, commonInfo) } func (singleton *projectGeneratorSingleton) GenerateBuildActions(ctx android.SingletonContext) { @@ -208,7 +209,7 @@ func (singleton *projectGeneratorSingleton) GenerateBuildActions(ctx android.Sin singleton.project.Sysroot = config.RustPath(ctx) singleton.knownCrates = make(map[string]crateInfo) - ctx.VisitAllModules(func(module android.Module) { + ctx.VisitAllModuleProxies(func(module android.ModuleProxy) { singleton.appendCrateAndDependencies(ctx, module) }) diff --git a/rust/rust.go b/rust/rust.go index 3e7c659e1..369130129 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -44,6 +44,11 @@ type CompilerInfo struct { StdLinkageForDevice RustLinkage StdLinkageForNonDevice RustLinkage NoStdlibs bool + CrateName string + Edition string + CargoOutDir android.OptionalPath + Features []string + CrateRootPath android.Path LibraryInfo *LibraryInfo } @@ -54,6 +59,10 @@ type SourceProviderInfo struct { ProtobufDecoratorInfo *ProtobufDecoratorInfo } +type ProcMacroInfo struct { + Dylib android.Path +} + type RustInfo struct { AndroidMkSuffix string RustSubName string @@ -61,6 +70,7 @@ type RustInfo struct { CompilerInfo *CompilerInfo SnapshotInfo *cc.SnapshotInfo SourceProviderInfo *SourceProviderInfo + ProcMacroInfo *ProcMacroInfo XrefRustFiles android.Paths DocTimestampFile android.OptionalPath } @@ -1089,7 +1099,7 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { if mod.compiler != nil { flags = mod.compiler.compilerFlags(ctx, flags) flags = mod.compiler.cfgFlags(ctx, flags) - flags = mod.compiler.featureFlags(ctx, mod, flags) + flags = mod.compiler.featureFlags(ctx, flags) } if mod.coverage != nil { flags, deps = mod.coverage.flags(ctx, flags, deps) @@ -1119,7 +1129,6 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { } if mod.compiler != nil && !mod.compiler.Disabled() { - mod.compiler.initialize(ctx) buildOutput := mod.compiler.compile(ctx, flags, deps) if ctx.Failed() { return @@ -1193,6 +1202,11 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { if mod.compiler != nil { rustInfo.CompilerInfo = &CompilerInfo{ NoStdlibs: mod.compiler.noStdlibs(), + CrateName: mod.compiler.crateName(), + Edition: mod.compiler.edition(), + CargoOutDir: mod.compiler.cargoOutDir(ctx), + Features: mod.compiler.features(ctx), + CrateRootPath: mod.compiler.crateRootPath(ctx), StdLinkageForDevice: mod.compiler.stdLinkage(true), StdLinkageForNonDevice: mod.compiler.stdLinkage(false), } @@ -1216,6 +1230,11 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { rustInfo.SourceProviderInfo.ProtobufDecoratorInfo = &ProtobufDecoratorInfo{} } } + if _, ok := mod.compiler.(*procMacroDecorator); ok { + rustInfo.ProcMacroInfo = &ProcMacroInfo{ + Dylib: mod.compiler.unstrippedOutputFilePath(), + } + } android.SetProvider(ctx, RustInfoProvider, rustInfo) ccInfo := &cc.CcInfo{ -- cgit v1.2.3 From 38803c6ba1eef5fca4fcd2b6267611177e9710d8 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 16 Apr 2025 14:14:55 -0700 Subject: Convert some of java/ to ModuleProxy and Providers When cc modules are marked with FreeModuleAfterGenerateBuildActions it will be an error to visit any cc dependency using VisitDirectDeps, and VisitDirectDepsProxy must be used instead. Convert any part of java/ that visits cc dependencies to ModuleProxy and Providers. Test: all Soong tests pass Change-Id: Icf1f47ac27d4dc1acf227902a8ef7af5024e8d15 --- apex/classpath_element_test.go | 54 +++++++++---------- java/boot_jars.go | 15 ++++-- java/bootclasspath.go | 37 ++++++------- java/bootclasspath_fragment.go | 30 +++++++---- java/classpath_element.go | 26 +++++----- java/classpath_fragment.go | 26 +++++----- java/dexpreopt.go | 2 +- java/dexpreopt_bootjars.go | 29 ++++++----- java/fuzz.go | 56 ++++++++++++-------- java/hiddenapi.go | 15 ++---- java/hiddenapi_modular.go | 114 +++++++++++++++++------------------------ java/hiddenapi_monolithic.go | 7 +-- java/java.go | 28 ++++++++-- java/platform_bootclasspath.go | 22 ++++---- java/testing.go | 14 ++--- 15 files changed, 254 insertions(+), 221 deletions(-) diff --git a/apex/classpath_element_test.go b/apex/classpath_element_test.go index c2f2fc5b9..41fe16d56 100644 --- a/apex/classpath_element_test.go +++ b/apex/classpath_element_test.go @@ -29,7 +29,7 @@ import ( type testClasspathElementContext struct { android.OtherModuleProviderContext testContext *android.TestContext - module android.Module + module android.ModuleProxy errs []error } @@ -198,18 +198,18 @@ func TestCreateClasspathElements(t *testing.T) { result := preparer.RunTest(t) - artFragment := result.Module("art-bootclasspath-fragment", "android_common_com.android.art") - artBaz := result.Module("baz", "android_common_apex10000") - artQuuz := result.Module("quuz", "android_common_apex10000") + artFragment := result.ModuleProxy("art-bootclasspath-fragment", "android_common_com.android.art") + artBaz := result.ModuleProxy("baz", "android_common_apex10000") + artQuuz := result.ModuleProxy("quuz", "android_common_apex10000") - myFragment := result.Module("mybootclasspath-fragment", "android_common_myapex") - myBar := result.Module("bar", "android_common_apex10000") + myFragment := result.ModuleProxy("mybootclasspath-fragment", "android_common_myapex") + myBar := result.ModuleProxy("bar", "android_common_apex10000") - otherApexLibrary := result.Module("otherapexlibrary", "android_common_apex10000") + otherApexLibrary := result.ModuleProxy("otherapexlibrary", "android_common_apex10000") - platformFoo := result.Module("quuz", "android_common") + platformFoo := result.ModuleProxy("quuz", "android_common") - bootclasspath := result.Module("myplatform-bootclasspath", "android_common") + bootclasspath := result.ModuleProxy("myplatform-bootclasspath", "android_common") // Use a custom assertion method instead of AssertDeepEquals as the latter formats the output // using %#v which results in meaningless output as ClasspathElements are pointers. @@ -219,10 +219,10 @@ func TestCreateClasspathElements(t *testing.T) { } } - expectFragmentElement := func(module android.Module, contents ...android.Module) java.ClasspathElement { + expectFragmentElement := func(module android.ModuleProxy, contents ...android.ModuleProxy) java.ClasspathElement { return &java.ClasspathFragmentElement{module, contents} } - expectLibraryElement := func(module android.Module) java.ClasspathElement { + expectLibraryElement := func(module android.ModuleProxy) java.ClasspathElement { return &java.ClasspathLibraryElement{module} } @@ -239,10 +239,10 @@ func TestCreateClasspathElements(t *testing.T) { t.Parallel() ctx := newCtx() elements := java.CreateClasspathElements(ctx, - []android.Module{artBaz, artQuuz, myBar, platformFoo}, - []android.Module{artFragment, myFragment}, - map[android.Module]string{artBaz: "com.android.art", artQuuz: "com.android.art", myBar: "myapex"}, - map[string]android.Module{"com.android.art": artFragment, "myapex": myFragment}) + []android.ModuleProxy{artBaz, artQuuz, myBar, platformFoo}, + []android.ModuleProxy{artFragment, myFragment}, + map[android.ModuleProxy]string{artBaz: "com.android.art", artQuuz: "com.android.art", myBar: "myapex"}, + map[string]android.ModuleProxy{"com.android.art": artFragment, "myapex": myFragment}) expectedElements := java.ClasspathElements{ expectFragmentElement(artFragment, artBaz, artQuuz), expectFragmentElement(myFragment, myBar), @@ -257,10 +257,10 @@ func TestCreateClasspathElements(t *testing.T) { t.Parallel() ctx := newCtx() elements := java.CreateClasspathElements(ctx, - []android.Module{artBaz, myBar, artQuuz, platformFoo}, - []android.Module{artFragment, myFragment}, - map[android.Module]string{artBaz: "com.android.art", artQuuz: "com.android.art", myBar: "myapex"}, - map[string]android.Module{"com.android.art": artFragment, "myapex": myFragment}) + []android.ModuleProxy{artBaz, myBar, artQuuz, platformFoo}, + []android.ModuleProxy{artFragment, myFragment}, + map[android.ModuleProxy]string{artBaz: "com.android.art", artQuuz: "com.android.art", myBar: "myapex"}, + map[string]android.ModuleProxy{"com.android.art": artFragment, "myapex": myFragment}) expectedElements := java.ClasspathElements{ expectFragmentElement(artFragment, artBaz, artQuuz), expectFragmentElement(myFragment, myBar), @@ -276,10 +276,10 @@ func TestCreateClasspathElements(t *testing.T) { t.Parallel() ctx := newCtx() elements := java.CreateClasspathElements(ctx, - []android.Module{artBaz, platformFoo, artQuuz, myBar}, - []android.Module{artFragment, myFragment}, - map[android.Module]string{artBaz: "com.android.art", artQuuz: "com.android.art", myBar: "myapex"}, - map[string]android.Module{"com.android.art": artFragment, "myapex": myFragment}) + []android.ModuleProxy{artBaz, platformFoo, artQuuz, myBar}, + []android.ModuleProxy{artFragment, myFragment}, + map[android.ModuleProxy]string{artBaz: "com.android.art", artQuuz: "com.android.art", myBar: "myapex"}, + map[string]android.ModuleProxy{"com.android.art": artFragment, "myapex": myFragment}) expectedElements := java.ClasspathElements{ expectFragmentElement(artFragment, artBaz, artQuuz), expectLibraryElement(platformFoo), @@ -296,10 +296,10 @@ func TestCreateClasspathElements(t *testing.T) { t.Parallel() ctx := newCtx() elements := java.CreateClasspathElements(ctx, - []android.Module{artBaz, otherApexLibrary}, - []android.Module{artFragment}, - map[android.Module]string{artBaz: "com.android.art", otherApexLibrary: "otherapex"}, - map[string]android.Module{"com.android.art": artFragment}) + []android.ModuleProxy{artBaz, otherApexLibrary}, + []android.ModuleProxy{artFragment}, + map[android.ModuleProxy]string{artBaz: "com.android.art", otherApexLibrary: "otherapex"}, + map[string]android.ModuleProxy{"com.android.art": artFragment}) expectedElements := java.ClasspathElements{ expectFragmentElement(artFragment, artBaz), } diff --git a/java/boot_jars.go b/java/boot_jars.go index 3c3bd550c..75a35f13c 100644 --- a/java/boot_jars.go +++ b/java/boot_jars.go @@ -21,11 +21,18 @@ import ( // isActiveModule returns true if the given module should be considered for boot // jars, i.e. if it's enabled and the preferred one in case of source and // prebuilt alternatives. -func isActiveModule(ctx android.ConfigurableEvaluatorContext, module android.Module) bool { - if !module.Enabled(ctx) { - return false +func isActiveModule(ctx android.ModuleContext, module android.ModuleOrProxy) bool { + if android.EqualModules(ctx.Module(), module) { + if !ctx.Module().Enabled(ctx) { + return false + } + } else { + info := android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoProvider) + if !info.Enabled { + return false + } } - return android.IsModulePreferred(module) + return android.IsModulePreferredProxy(ctx, module) } // buildRuleForBootJarsPackageCheck generates the build rule to perform the boot jars package diff --git a/java/bootclasspath.go b/java/bootclasspath.go index 98fb417d0..6c82d330c 100644 --- a/java/bootclasspath.go +++ b/java/bootclasspath.go @@ -71,8 +71,8 @@ func addDependencyOntoApexModulePair(ctx android.BottomUpMutatorContext, apex st // gatherFragments collects fragments that are direct dependencies of this module, as well as // any fragments in apexes via the dependency on the apex. It returns a list of the fragment // modules and map from apex name to the fragment in that apex. -func gatherFragments(ctx android.BaseModuleContext) ([]android.Module, map[string]android.Module) { - var fragments []android.Module +func gatherFragments(ctx android.BaseModuleContext) ([]android.ModuleProxy, map[string]android.ModuleProxy) { + var fragments []android.ModuleProxy type fragmentInApex struct { module string @@ -82,7 +82,7 @@ func gatherFragments(ctx android.BaseModuleContext) ([]android.Module, map[strin var fragmentsInApexes []fragmentInApex // Find any direct dependencies, as well as a list of the modules in apexes. - ctx.VisitDirectDeps(func(module android.Module) { + ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) { t := ctx.OtherModuleDependencyTag(module) if bcpTag, ok := t.(bootclasspathDependencyTag); ok && bcpTag.typ == fragment { if bcpTag.moduleInApex != "" { @@ -93,13 +93,13 @@ func gatherFragments(ctx android.BaseModuleContext) ([]android.Module, map[strin } }) - fragmentsMap := make(map[string]android.Module) + fragmentsMap := make(map[string]android.ModuleProxy) for _, fragmentInApex := range fragmentsInApexes { - var found android.Module + var found android.ModuleProxy // Find a desired module in an apex. - ctx.WalkDeps(func(child, parent android.Module) bool { + ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool { t := ctx.OtherModuleDependencyTag(child) - if parent == ctx.Module() { + if android.EqualModules(parent, ctx.Module()) { if bcpTag, ok := t.(bootclasspathDependencyTag); ok && bcpTag.typ == fragment && ctx.OtherModuleName(child) == fragmentInApex.apex { // This is the dependency from this module to the apex, recurse into it. return true @@ -112,7 +112,7 @@ func gatherFragments(ctx android.BaseModuleContext) ([]android.Module, map[strin return false } else if android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child)) == fragmentInApex.module { // This is the desired module inside the apex. - if found != nil && child != found { + if !found.IsNil() && child != found { panic(fmt.Errorf("found two conflicting modules %q in apex %q: %s and %s", fragmentInApex.module, fragmentInApex.apex, found, child)) } @@ -120,7 +120,7 @@ func gatherFragments(ctx android.BaseModuleContext) ([]android.Module, map[strin } return false }) - if found != nil { + if !found.IsNil() { if existing, exists := fragmentsMap[fragmentInApex.apex]; exists { ctx.ModuleErrorf("apex %s has multiple fragments, %s and %s", fragmentInApex.apex, fragmentInApex.module, existing) } else { @@ -137,9 +137,10 @@ func gatherFragments(ctx android.BaseModuleContext) ([]android.Module, map[strin // gatherApexModulePairDepsWithTag returns the list of dependencies with the supplied tag that was // added by addDependencyOntoApexModulePair. -func gatherApexModulePairDepsWithTag(ctx android.BaseModuleContext, tagType bootclasspathDependencyTagType) ([]android.Module, map[android.Module]string) { - var modules []android.Module - modulesToApex := make(map[android.Module]string) +func gatherApexModulePairDepsWithTag(ctx android.BaseModuleContext, + tagType bootclasspathDependencyTagType) ([]android.ModuleProxy, map[android.ModuleProxy]string) { + var modules []android.ModuleProxy + modulesToApex := make(map[android.ModuleProxy]string) type moduleInApex struct { module string @@ -148,7 +149,7 @@ func gatherApexModulePairDepsWithTag(ctx android.BaseModuleContext, tagType boot var modulesInApexes []moduleInApex - ctx.VisitDirectDeps(func(module android.Module) { + ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) { t := ctx.OtherModuleDependencyTag(module) if bcpTag, ok := t.(bootclasspathDependencyTag); ok && bcpTag.typ == tagType { if bcpTag.moduleInApex != "" { @@ -160,10 +161,10 @@ func gatherApexModulePairDepsWithTag(ctx android.BaseModuleContext, tagType boot }) for _, moduleInApex := range modulesInApexes { - var found android.Module - ctx.WalkDeps(func(child, parent android.Module) bool { + var found android.ModuleProxy + ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool { t := ctx.OtherModuleDependencyTag(child) - if parent == ctx.Module() { + if android.EqualModules(parent, ctx.Module()) { if bcpTag, ok := t.(bootclasspathDependencyTag); ok && bcpTag.typ == tagType && ctx.OtherModuleName(child) == moduleInApex.apex { // recurse into the apex return true @@ -177,7 +178,7 @@ func gatherApexModulePairDepsWithTag(ctx android.BaseModuleContext, tagType boot } else if IsBootclasspathFragmentContentDepTag(t) { return false } else if android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child)) == moduleInApex.module { - if found != nil && child != found { + if !found.IsNil() && child != found { panic(fmt.Errorf("found two conflicting modules %q in apex %q: %s and %s", moduleInApex.module, moduleInApex.apex, found, child)) } @@ -185,7 +186,7 @@ func gatherApexModulePairDepsWithTag(ctx android.BaseModuleContext, tagType boot } return false }) - if found != nil { + if !found.IsNil() { modules = append(modules, found) if existing, exists := modulesToApex[found]; exists && existing != moduleInApex.apex { ctx.ModuleErrorf("module %s is in two apexes, %s and %s", moduleInApex.module, existing, moduleInApex.apex) diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go index e3ada4c44..4505a40c4 100644 --- a/java/bootclasspath_fragment.go +++ b/java/bootclasspath_fragment.go @@ -47,6 +47,7 @@ type BootclasspathFragmentInfo struct { ApiStubLibs []string CorePlatformApiStubLibs []string Fragments []ApexVariantReference + ProfilePathOnHost android.Path } var BootclasspathFragmentInfoProvider = blueprint.NewProvider[BootclasspathFragmentInfo]() @@ -273,7 +274,8 @@ type commonBootclasspathFragment interface { // Returns a *HiddenAPIOutput containing the paths for the generated files. Returns nil if the // module cannot contribute to hidden API processing, e.g. because it is a prebuilt module in a // versioned sdk. - produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, fragments []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput + produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.ModuleProxy, fragments []android.ModuleProxy, + input HiddenAPIFlagInput) *HiddenAPIOutput // getProfilePath returns the path to the boot image profile. getProfilePath() android.Path @@ -541,8 +543,8 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo moduleInfoJSON.SystemSharedLibs = []string{"none"} // Gather the bootclasspath fragment's contents. - var contents []android.Module - ctx.VisitDirectDeps(func(module android.Module) { + var contents []android.ModuleProxy + ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) { tag := ctx.OtherModuleDependencyTag(module) if IsBootclasspathFragmentContentDepTag(tag) { contents = append(contents, module) @@ -578,6 +580,7 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo ApiStubLibs: b.properties.Api.Stub_libs.GetOrDefault(ctx, nil), CorePlatformApiStubLibs: b.properties.Core_platform_api.Stub_libs.GetOrDefault(ctx, nil), Fragments: b.properties.Fragments, + ProfilePathOnHost: b.profilePath, }) } @@ -585,7 +588,7 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo // empty string if this module should not provide a boot image profile. func (b *BootclasspathFragmentModule) getProfileProviderApex(ctx android.BaseModuleContext) string { // Only use the profile from the module that is preferred. - if !isActiveModule(ctx, ctx.Module()) { + if !android.IsModulePreferredProxy(ctx, ctx.Module()) { return "" } @@ -692,7 +695,8 @@ func providerClasspathFragmentValidationInfoProvider(ctx android.ModuleContext, } // generateHiddenAPIBuildActions generates all the hidden API related build rules. -func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, contents []android.Module, fragments []android.Module) *HiddenAPIOutput { +func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, contents []android.ModuleProxy, + fragments []android.ModuleProxy) *HiddenAPIOutput { // Create hidden API input structure. input := b.createHiddenAPIFlagInput(ctx, contents, fragments) @@ -736,7 +740,8 @@ func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android. // createHiddenAPIFlagInput creates a HiddenAPIFlagInput struct and initializes it with information derived // from the properties on this module and its dependencies. -func (b *BootclasspathFragmentModule) createHiddenAPIFlagInput(ctx android.ModuleContext, contents []android.Module, fragments []android.Module) HiddenAPIFlagInput { +func (b *BootclasspathFragmentModule) createHiddenAPIFlagInput(ctx android.ModuleContext, contents []android.ModuleProxy, + fragments []android.ModuleProxy) HiddenAPIFlagInput { // Merge the HiddenAPIInfo from all the fragment dependencies. dependencyHiddenApiInfo := newHiddenAPIInfo() dependencyHiddenApiInfo.mergeFromFragmentDeps(ctx, fragments) @@ -768,7 +773,7 @@ func (b *BootclasspathFragmentModule) isTestFragment() bool { // generateHiddenApiFlagRules generates rules to generate hidden API flags and compute the signature // patterns file. -func (b *BootclasspathFragmentModule) generateHiddenApiFlagRules(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput, bootDexInfoByModule bootDexInfoByModule, suffix string) HiddenAPIFlagOutput { +func (b *BootclasspathFragmentModule) generateHiddenApiFlagRules(ctx android.ModuleContext, contents []android.ModuleProxy, input HiddenAPIFlagInput, bootDexInfoByModule bootDexInfoByModule, suffix string) HiddenAPIFlagOutput { // Generate the rules to create the hidden API flags and update the supplied hiddenAPIInfo with the // paths to the created files. flagOutput := hiddenAPIFlagRulesForBootclasspathFragment(ctx, bootDexInfoByModule, contents, input, suffix) @@ -797,7 +802,8 @@ func (b *BootclasspathFragmentModule) generateHiddenApiFlagRules(ctx android.Mod // produceHiddenAPIOutput produces the hidden API all-flags.csv file (and supporting files) // for the fragment as well as encoding the flags in the boot dex jars. -func (b *BootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, fragments []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput { +func (b *BootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.ModuleProxy, + fragments []android.ModuleProxy, input HiddenAPIFlagInput) *HiddenAPIOutput { // Gather information about the boot dex files for the boot libraries provided by this fragment. bootDexInfoByModule := extractBootDexInfoFromModules(ctx, contents) @@ -821,7 +827,7 @@ func (b *BootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleC // Filter the contents list to remove any modules that do not support the target build release. // The current build release supports all the modules. - contentsForSdkSnapshot := []android.Module{} + contentsForSdkSnapshot := []android.ModuleProxy{} for _, module := range contents { // If the module has a min_sdk_version that is higher than the target build release then it will // not work on the target build release and so must not be included in the sdk snapshot. @@ -860,7 +866,8 @@ func (b *BootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleC } // produceBootImageProfileFromSource builds the boot image profile from the source if it is required. -func (b *BootclasspathFragmentModule) produceBootImageProfileFromSource(ctx android.ModuleContext, contents []android.Module, modules bootDexJarByModule) android.WritablePath { +func (b *BootclasspathFragmentModule) produceBootImageProfileFromSource(ctx android.ModuleContext, + contents []android.ModuleProxy, modules bootDexJarByModule) android.WritablePath { apex := b.getProfileProviderApex(ctx) if apex == "" { return nil @@ -1125,7 +1132,8 @@ func (module *PrebuiltBootclasspathFragmentModule) Name() string { } // produceHiddenAPIOutput returns a path to the prebuilt all-flags.csv or nil if none is specified. -func (module *PrebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, fragments []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput { +func (module *PrebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleContext, + contents []android.ModuleProxy, fragments []android.ModuleProxy, input HiddenAPIFlagInput) *HiddenAPIOutput { pathForOptionalSrc := func(src *string, defaultPath android.Path) android.Path { if src == nil { return defaultPath diff --git a/java/classpath_element.go b/java/classpath_element.go index 4af277012..263a5f116 100644 --- a/java/classpath_element.go +++ b/java/classpath_element.go @@ -28,7 +28,7 @@ import ( // ClasspathElement represents a component that contributes to a classpath. That can be // either a java module or a classpath fragment module. type ClasspathElement interface { - Module() android.Module + Module() android.ModuleProxy String() string } @@ -36,11 +36,11 @@ type ClasspathElements []ClasspathElement // ClasspathFragmentElement is a ClasspathElement that encapsulates a classpath fragment module. type ClasspathFragmentElement struct { - Fragment android.Module - Contents []android.Module + Fragment android.ModuleProxy + Contents []android.ModuleProxy } -func (b *ClasspathFragmentElement) Module() android.Module { +func (b *ClasspathFragmentElement) Module() android.ModuleProxy { return b.Fragment } @@ -56,10 +56,10 @@ var _ ClasspathElement = (*ClasspathFragmentElement)(nil) // ClasspathLibraryElement is a ClasspathElement that encapsulates a java library. type ClasspathLibraryElement struct { - Library android.Module + Library android.ModuleProxy } -func (b *ClasspathLibraryElement) Module() android.Module { +func (b *ClasspathLibraryElement) Module() android.ModuleProxy { return b.Library } @@ -118,10 +118,10 @@ type ClasspathElementContext interface { // ClasspathFragmentElement(art-bootclasspath-fragment, [core-oj, core-libart]), // ClasspathLibraryElement(framework), // ClasspathLibraryElement(ext), -func CreateClasspathElements(ctx ClasspathElementContext, libraries []android.Module, fragments []android.Module, - libraryToApex map[android.Module]string, apexNameToFragment map[string]android.Module) ClasspathElements { +func CreateClasspathElements(ctx ClasspathElementContext, libraries []android.ModuleProxy, fragments []android.ModuleProxy, + libraryToApex map[android.ModuleProxy]string, apexNameToFragment map[string]android.ModuleProxy) ClasspathElements { - fragmentToElement := map[android.Module]*ClasspathFragmentElement{} + fragmentToElement := map[android.ModuleProxy]*ClasspathFragmentElement{} elements := []ClasspathElement{} var currentElement ClasspathElement @@ -130,11 +130,11 @@ skipLibrary: for _, library := range libraries { var element ClasspathElement if libraryApex, ok := libraryToApex[library]; ok { - var fragment android.Module + var fragment android.ModuleProxy // Make sure that the library is in only one fragment of the classpath. if f, ok := apexNameToFragment[libraryApex]; ok { - if fragment == nil { + if fragment.IsNil() { // This is the first fragment so just save it away. fragment = f } else if f != fragment { @@ -148,7 +148,7 @@ skipLibrary: // There is no fragment associated with the library's apex. } - if fragment == nil { + if fragment.IsNil() { ctx.ModuleErrorf("library %s is from apexes %s which have no corresponding fragment in %s", library, []string{libraryApex}, fragments) // Skip over this library entirely as otherwise the resulting classpath elements would @@ -184,7 +184,7 @@ skipLibrary: // including the library. fragmentElement := &ClasspathFragmentElement{ Fragment: fragment, - Contents: []android.Module{library}, + Contents: []android.ModuleProxy{library}, } // Store it away so we can detect when attempting to create another element for the same diff --git a/java/classpath_fragment.go b/java/classpath_fragment.go index 85dd38bae..6b9dc194a 100644 --- a/java/classpath_fragment.go +++ b/java/classpath_fragment.go @@ -104,17 +104,14 @@ type classpathJar struct { func gatherPossibleApexModuleNamesAndStems(ctx android.ModuleContext, contents []string, tag blueprint.DependencyTag) []string { set := map[string]struct{}{} for _, name := range contents { - dep := ctx.GetDirectDepWithTag(name, tag) - if dep == nil && ctx.Config().AllowMissingDependencies() { + dep := ctx.GetDirectDepProxyWithTag(name, tag) + if dep.IsNil() && ctx.Config().AllowMissingDependencies() { // Ignore apex boot jars from dexpreopt if it does not exist, and missing deps are allowed. continue } + info := android.OtherModuleProviderOrDefault(ctx, dep, JavaInfoProvider) set[ModuleStemForDeapexing(ctx, dep)] = struct{}{} - if m, ok := dep.(ModuleWithStem); ok { - set[m.Stem()] = struct{}{} - } else { - ctx.PropertyErrorf("contents", "%v is not a ModuleWithStem", name) - } + set[info.Stem] = struct{}{} } return android.SortedKeys(set) } @@ -129,12 +126,15 @@ func configuredJarListToClasspathJars(ctx android.ModuleContext, configuredJars classpath: classpathType, path: paths[i], } - ctx.VisitDirectDepsIf(func(m android.Module) bool { - return m.Name() == configuredJars.Jar(i) - }, func(m android.Module) { - if s, ok := m.(*SdkLibrary); ok { - minSdkVersion := s.MinSdkVersion(ctx) - maxSdkVersion := s.MaxSdkVersion(ctx) + ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) { + if m.Name() != configuredJars.Jar(i) { + return + } + if _, ok := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); ok { + info := android.OtherModuleProviderOrDefault(ctx, m, JavaInfoProvider) + commonInfo := android.OtherModulePointerProviderOrDefault(ctx, m, android.CommonModuleInfoProvider) + minSdkVersion := *commonInfo.MinSdkVersion.ApiLevel + maxSdkVersion := info.MaxSdkVersion // TODO(208456999): instead of mapping "current" to latest, min_sdk_version should never be set to "current" if minSdkVersion.Specified() { if minSdkVersion.IsCurrent() { diff --git a/java/dexpreopt.go b/java/dexpreopt.go index e8e1cd405..c42997b92 100644 --- a/java/dexpreopt.go +++ b/java/dexpreopt.go @@ -644,7 +644,7 @@ 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 { + ctx.WalkDepsProxy(func(dep android.ModuleProxy, parent android.ModuleProxy) 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. diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index 4af7227b1..8aa775635 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -562,9 +562,9 @@ func addDependenciesOntoSelectedBootImageApexes(ctx android.BottomUpMutatorConte } } -func gatherBootclasspathFragments(ctx android.ModuleContext) map[string]android.Module { +func gatherBootclasspathFragments(ctx android.ModuleContext) map[string]android.ModuleProxy { return ctx.Config().Once(dexBootJarsFragmentsKey, func() interface{} { - fragments := make(map[string]android.Module) + fragments := make(map[string]android.ModuleProxy) type moduleInApexPair struct { module string @@ -574,7 +574,7 @@ func gatherBootclasspathFragments(ctx android.ModuleContext) map[string]android. var modulesInApexes []moduleInApexPair // Find the list of modules in apexes. - ctx.WalkDeps(func(child, parent android.Module) bool { + ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool { if !isActiveModule(ctx, child) { return false } @@ -596,7 +596,7 @@ func gatherBootclasspathFragments(ctx android.ModuleContext) map[string]android. for _, moduleInApex := range modulesInApexes { // Find a desired module in an apex. - ctx.WalkDeps(func(child, parent android.Module) bool { + ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool { t := ctx.OtherModuleDependencyTag(child) if bcpTag, ok := t.(bootclasspathDependencyTag); ok { if bcpTag.typ == platform { @@ -615,10 +615,10 @@ func gatherBootclasspathFragments(ctx android.ModuleContext) map[string]android. } return fragments - }).(map[string]android.Module) + }).(map[string]android.ModuleProxy) } -func getBootclasspathFragmentByApex(ctx android.ModuleContext, apexName string) android.Module { +func getBootclasspathFragmentByApex(ctx android.ModuleContext, apexName string) android.ModuleProxy { return gatherBootclasspathFragments(ctx)[apexName] } @@ -863,7 +863,7 @@ func generateBootImage(ctx android.ModuleContext, imageConfig *bootImageConfig) type apexJarModulePair struct { apex string - jarModule android.Module + jarModule android.ModuleProxy } func getModulesForImage(ctx android.ModuleContext, imageConfig *bootImageConfig) []apexJarModulePair { @@ -949,7 +949,7 @@ func getDexJarForApex(ctx android.ModuleContext, pair apexJarModulePair, apexNam } else { // Use exactly the same jar that is packed into the APEX. fragment := getBootclasspathFragmentByApex(ctx, pair.apex) - if fragment == nil { + if fragment.IsNil() { ctx.ModuleErrorf("Boot jar '%[1]s' is from APEX '%[2]s', but a bootclasspath_fragment for "+ "APEX '%[2]s' doesn't exist or is not added as a dependency of dex_bootjars", pair.jarModule.Name(), @@ -1110,20 +1110,25 @@ func getProfilePathForApex(ctx android.ModuleContext, apexName string, apexNameT } // TODO: b/308174306 - Remove the legacy mechanism fragment := getBootclasspathFragmentByApex(ctx, apexName) - if fragment == nil { + if fragment.IsNil() { ctx.ModuleErrorf("Boot image config imports profile from '%[2]s', but a "+ "bootclasspath_fragment for APEX '%[2]s' doesn't exist or is not added as a "+ "dependency of dex_bootjars", apexName) return nil } - return fragment.(commonBootclasspathFragment).getProfilePath() + + if info, ok := android.OtherModuleProvider(ctx, fragment, BootclasspathFragmentInfoProvider); ok { + return info.ProfilePathOnHost + } else { + panic(fmt.Errorf("missing BootclasspathFragmentInfoProvider in %s", fragment)) + } } func getApexNameToApexExportsInfoMap(ctx android.ModuleContext) apexNameToApexExportsInfoMap { apexNameToApexExportsInfoMap := apexNameToApexExportsInfoMap{} - ctx.VisitDirectDeps(func(am android.Module) { + ctx.VisitDirectDepsProxy(func(am android.ModuleProxy) { tag := ctx.OtherModuleDependencyTag(am) if bcpTag, ok := tag.(bootclasspathDependencyTag); ok && bcpTag.typ == dexpreoptBootJar { if bcpTag.moduleInApex == "" { @@ -1623,7 +1628,7 @@ func (dbj *artBootImages) DepsMutator(ctx android.BottomUpMutatorContext) { } func (d *artBootImages) GenerateAndroidBuildActions(ctx android.ModuleContext) { - ctx.VisitDirectDeps(func(m android.Module) { + ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) { tag := ctx.OtherModuleDependencyTag(m) if bcpTag, ok := tag.(bootclasspathDependencyTag); ok && bcpTag.typ == dexpreoptBootJar { if bcpTag.moduleInApex != "" { diff --git a/java/fuzz.go b/java/fuzz.go index 2a38d53b6..6ea1c24c8 100644 --- a/java/fuzz.go +++ b/java/fuzz.go @@ -51,6 +51,12 @@ type JavaFuzzTest struct { jniFilePaths android.Paths } +type JavaFuzzTestInfo struct { + JniFilePaths android.Paths +} + +var JavaFuzzTestInfoProvider = blueprint.NewProvider[JavaFuzzTestInfo]() + // java_fuzz builds and links sources into a `.jar` file for the device. // This generates .class files in a jar which can then be instrumented before // fuzzing in Android Runtime (ART: Android OS on emulator or device) @@ -154,7 +160,18 @@ func (j *JavaFuzzTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { PerTestcaseDirectory: proptools.Bool(j.testProperties.Per_testcase_directory), }) - fuzz.SetFuzzPackagedModuleInfo(ctx, &j.fuzzPackagedModule) + fuzzModuleValidator := fuzz.FuzzModule{ + j.ModuleBase, + j.DefaultableModuleBase, + j.ApexModuleBase, + } + + if fuzz.IsValid(ctx, fuzzModuleValidator) { + fuzz.SetFuzzPackagedModuleInfo(ctx, &j.fuzzPackagedModule) + android.SetProvider(ctx, JavaFuzzTestInfoProvider, JavaFuzzTestInfo{ + JniFilePaths: j.jniFilePaths, + }) + } } type javaFuzzPackager struct { @@ -170,9 +187,9 @@ func (s *javaFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { archDirs := make(map[fuzz.ArchOs][]fuzz.FileToZip) s.FuzzTargets = make(map[string]bool) - ctx.VisitAllModules(func(module android.Module) { + ctx.VisitAllModuleProxies(func(module android.ModuleProxy) { // Discard non-fuzz targets. - javaFuzzModule, ok := module.(*JavaFuzzTest) + javaInfo, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider) if !ok { return } @@ -180,25 +197,21 @@ func (s *javaFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { if !ok { return } + javaFuzzTestInfo, ok := android.OtherModuleProvider(ctx, module, JavaFuzzTestInfoProvider) + if !ok { + return + } + + commonInfo := android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoProvider) hostOrTargetString := "target" - if javaFuzzModule.Target().HostCross { + if commonInfo.Target.HostCross { hostOrTargetString = "host_cross" - } else if javaFuzzModule.Host() { + } else if commonInfo.Host { hostOrTargetString = "host" } - fuzzModuleValidator := fuzz.FuzzModule{ - javaFuzzModule.ModuleBase, - javaFuzzModule.DefaultableModuleBase, - javaFuzzModule.ApexModuleBase, - } - - if ok := fuzz.IsValid(ctx, fuzzModuleValidator); !ok { - return - } - - archString := javaFuzzModule.Arch().ArchType.String() + archString := commonInfo.Target.Arch.ArchType.String() archDir := android.PathForIntermediates(ctx, "fuzz", hostOrTargetString, archString) archOs := fuzz.ArchOs{HostOrTarget: hostOrTargetString, Arch: archString, Dir: archDir.String()} @@ -209,14 +222,17 @@ func (s *javaFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { files = s.PackageArtifacts(ctx, module, &fuzzInfo, archDir, builder) // Add .jar - if !javaFuzzModule.Host() { - files = append(files, fuzz.FileToZip{SourceFilePath: javaFuzzModule.implementationJarFile, DestinationPathPrefix: "classes"}) + if !commonInfo.Host { + for _, jar := range javaInfo.ImplementationJars { + files = append(files, fuzz.FileToZip{SourceFilePath: jar, DestinationPathPrefix: "classes"}) + } } - files = append(files, fuzz.FileToZip{SourceFilePath: javaFuzzModule.outputFile}) + outputFile := android.OutputFileForModule(ctx, module, "") + files = append(files, fuzz.FileToZip{SourceFilePath: outputFile}) // Add jni .so files - for _, fPath := range javaFuzzModule.jniFilePaths { + for _, fPath := range javaFuzzTestInfo.JniFilePaths { files = append(files, fuzz.FileToZip{SourceFilePath: fPath}) } diff --git a/java/hiddenapi.go b/java/hiddenapi.go index c9a1f2bbe..fe2521cca 100644 --- a/java/hiddenapi.go +++ b/java/hiddenapi.go @@ -44,8 +44,7 @@ type hiddenAPI struct { // // This must be the path to the unencoded dex jar as the encoded dex jar indirectly depends on // this file so using the encoded dex jar here would result in a cycle in the ninja rules. - bootDexJarPath OptionalDexJarPath - bootDexJarPathErr error + bootDexJarPath OptionalDexJarPath // The paths to the classes jars that contain classes and class members annotated with // the UnsupportedAppUsage annotation that need to be extracted as part of the hidden API @@ -57,10 +56,7 @@ type hiddenAPI struct { uncompressDexState *bool } -func (h *hiddenAPI) bootDexJar(ctx android.ModuleErrorfContext) OptionalDexJarPath { - if h.bootDexJarPathErr != nil { - ctx.ModuleErrorf(h.bootDexJarPathErr.Error()) - } +func (h *hiddenAPI) bootDexJar() OptionalDexJarPath { return h.bootDexJarPath } @@ -81,7 +77,7 @@ type hiddenAPIModule interface { } type hiddenAPIIntf interface { - bootDexJar(ctx android.ModuleErrorfContext) OptionalDexJarPath + bootDexJar() OptionalDexJarPath classesJars() android.Paths uncompressDex() *bool } @@ -131,11 +127,6 @@ func (h *hiddenAPI) initHiddenAPI(ctx android.ModuleContext, dexJar OptionalDexJ h.active = isModuleInBootClassPath(ctx, module) } -// Store any error encountered during the initialization of hiddenapi structure (e.g. unflagged co-existing prebuilt apexes) -func (h *hiddenAPI) initHiddenAPIError(err error) { - h.bootDexJarPathErr = err -} - func isModuleInBootClassPath(ctx android.BaseModuleContext, module android.Module) bool { // Get the configured platform and apex boot jars. nonApexBootJars := ctx.Config().NonApexBootJars() diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go index 4d723be4a..2c7fd9313 100644 --- a/java/hiddenapi_modular.go +++ b/java/hiddenapi_modular.go @@ -296,7 +296,7 @@ func hiddenAPIAddStubLibDependencies(ctx android.BottomUpMutatorContext, apiScop // hiddenAPIRetrieveDexJarBuildPath retrieves the DexJarBuildPath from the specified module, if // available, or reports an error. -func hiddenAPIRetrieveDexJarBuildPath(ctx android.ModuleContext, module android.Module, kind android.SdkKind) android.Path { +func hiddenAPIRetrieveDexJarBuildPath(ctx android.ModuleContext, module android.ModuleProxy, kind android.SdkKind) android.Path { var dexJar OptionalDexJarPath if sdkLibrary, ok := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider); ok { if ctx.Config().ReleaseHiddenApiExportableStubs() { @@ -304,8 +304,8 @@ func hiddenAPIRetrieveDexJarBuildPath(ctx android.ModuleContext, module android. } else { dexJar = sdkLibrary.EverythingStubDexJarPaths[kind] } - } else if j, ok := module.(UsesLibraryDependency); ok { - dexJar = j.DexJarBuildPath(ctx) + } else if j, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok && j.UsesLibraryDependencyInfo != nil { + dexJar = j.DexJarBuildPath } else { ctx.ModuleErrorf("dependency %s of module type %s does not support providing a dex jar", module, ctx.OtherModuleType(module)) return nil @@ -586,7 +586,7 @@ func newHiddenAPIInfo() *HiddenAPIInfo { return &info } -func (i *HiddenAPIInfo) mergeFromFragmentDeps(ctx android.ModuleContext, fragments []android.Module) { +func (i *HiddenAPIInfo) mergeFromFragmentDeps(ctx android.ModuleContext, fragments []android.ModuleProxy) { // Merge all the information from the fragments. The fragments form a DAG so it is possible that // this will introduce duplicates so they will be resolved after processing all the fragments. for _, fragment := range fragments { @@ -656,7 +656,7 @@ func (s ModuleStubDexJars) stubDexJarForWidestAPIScope() android.Path { type StubDexJarsByModule map[string]ModuleStubDexJars // addStubDexJar adds a stub dex jar path provided by the specified module for the specified scope. -func (s StubDexJarsByModule) addStubDexJar(ctx android.ModuleContext, module android.Module, scope *HiddenAPIScope, stubDexJar android.Path) { +func (s StubDexJarsByModule) addStubDexJar(ctx android.ModuleContext, module android.ModuleProxy, scope *HiddenAPIScope, stubDexJar android.Path) { name := android.RemoveOptionalPrebuiltPrefix(module.Name()) // Each named module provides one dex jar for each scope. However, in some cases different API @@ -685,13 +685,16 @@ func (s StubDexJarsByModule) addStubDexJar(ctx android.ModuleContext, module and // conscrypt.module.public.api java_sdk_library which will be the case once the former has been // migrated to a module_lib API. name = "conscrypt.module.public.api" - } else if d, ok := module.(SdkLibraryComponentDependency); ok { - sdkLibraryName := d.SdkLibraryName() - if sdkLibraryName != nil { - // The module is a component of a java_sdk_library so use the name of the java_sdk_library. - // e.g. if this module is `foo.system.stubs` and is part of the `foo` java_sdk_library then - // use `foo` as the name. - name = *sdkLibraryName + } else { + if info, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok { + if slcDepInfo := info.SdkLibraryComponentDependencyInfo; slcDepInfo != nil { + if sdkLibraryName := slcDepInfo.SdkLibraryName; sdkLibraryName != nil { + // The module is a component of a java_sdk_library so use the name of the java_sdk_library. + // e.g. if this module is `foo.system.stubs` and is part of the `foo` java_sdk_library then + // use `foo` as the name. + name = *sdkLibraryName + } + } } } stubDexJarsByScope := s[name] @@ -785,7 +788,7 @@ func (i *HiddenAPIPropertyInfo) extractPackageRulesFromProperties(p *HiddenAPIPa i.SplitPackages = p.Hidden_api.Split_packages } -func (i *HiddenAPIPropertyInfo) gatherPropertyInfo(ctx android.ModuleContext, contents []android.Module) { +func (i *HiddenAPIPropertyInfo) gatherPropertyInfo(ctx android.ModuleContext, contents []android.ModuleProxy) { for _, module := range contents { if info, ok := android.OtherModuleProvider(ctx, module, hiddenAPIPropertyInfoProvider); ok { i.FlagFilesByCategory.append(info.FlagFilesByCategory) @@ -844,8 +847,8 @@ func newHiddenAPIFlagInput() HiddenAPIFlagInput { // dependencies added in hiddenAPIAddStubLibDependencies. // // That includes paths to the stub dex jars as well as paths to the *removed.txt files. -func (i *HiddenAPIFlagInput) gatherStubLibInfo(ctx android.ModuleContext, contents []android.Module) { - addFromModule := func(ctx android.ModuleContext, module android.Module, apiScope *HiddenAPIScope) { +func (i *HiddenAPIFlagInput) gatherStubLibInfo(ctx android.ModuleContext, contents []android.ModuleProxy) { + addFromModule := func(ctx android.ModuleContext, module android.ModuleProxy, apiScope *HiddenAPIScope) { sdkKind := apiScope.sdkKind dexJar := hiddenAPIRetrieveDexJarBuildPath(ctx, module, sdkKind) if dexJar != nil { @@ -868,7 +871,7 @@ func (i *HiddenAPIFlagInput) gatherStubLibInfo(ctx android.ModuleContext, conten } } - ctx.VisitDirectDeps(func(module android.Module) { + ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) { tag := ctx.OtherModuleDependencyTag(module) if hiddenAPIStubsTag, ok := tag.(hiddenAPIStubsDependencyTag); ok { apiScope := hiddenAPIStubsTag.apiScope @@ -927,7 +930,7 @@ type HiddenAPIFlagOutput struct { type bootDexJarByModule map[string]android.Path // addPath adds the path for a module to the map. -func (b bootDexJarByModule) addPath(module android.Module, path android.Path) { +func (b bootDexJarByModule) addPath(module android.ModuleProxy, path android.Path) { b[android.RemoveOptionalPrebuiltPrefix(module.Name())] = path } @@ -1168,7 +1171,7 @@ func buildRuleValidateOverlappingCsvFiles(ctx android.BuilderContext, name strin // * metadata.csv // * index.csv // * all-flags.csv -func hiddenAPIFlagRulesForBootclasspathFragment(ctx android.ModuleContext, bootDexInfoByModule bootDexInfoByModule, contents []android.Module, input HiddenAPIFlagInput, suffix string) HiddenAPIFlagOutput { +func hiddenAPIFlagRulesForBootclasspathFragment(ctx android.ModuleContext, bootDexInfoByModule bootDexInfoByModule, contents []android.ModuleProxy, input HiddenAPIFlagInput, suffix string) HiddenAPIFlagOutput { hiddenApiSubDir := "modular-hiddenapi" + suffix // Generate the stub-flags.csv. @@ -1176,7 +1179,7 @@ func hiddenAPIFlagRulesForBootclasspathFragment(ctx android.ModuleContext, bootD buildRuleToGenerateHiddenAPIStubFlagsFile(ctx, "modularHiddenAPIStubFlagsFile"+suffix, "modular hiddenapi stub flags", stubFlagsCSV, bootDexInfoByModule.bootDexJars(), input, nil) // Extract the classes jars from the contents. - classesJars := extractClassesJarsFromModules(contents) + classesJars := extractClassesJarsFromModules(ctx, contents) // Generate the set of flags from the annotations in the source code. annotationFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "annotation-flags.csv") @@ -1266,7 +1269,7 @@ func buildRuleToGenerateRemovedDexSignatures(ctx android.ModuleContext, suffix s // 1. New: Direct deps to _selected_ apexes. The apexes contain a ApexExportsInfo // 2. Legacy: An edge to java_sdk_library(_import) module. For prebuilt apexes, this serves as a hook and is populated by deapexers of prebuilt apxes // TODO: b/308174306 - Once all mainline modules have been flagged, drop (2) -func extractBootDexJarsFromModules(ctx android.ModuleContext, contents []android.Module) bootDexJarByModule { +func extractBootDexJarsFromModules(ctx android.ModuleContext, contents []android.ModuleProxy) bootDexJarByModule { bootDexJars := bootDexJarByModule{} apexNameToApexExportsInfoMap := getApexNameToApexExportsInfoMap(ctx) @@ -1283,28 +1286,12 @@ func extractBootDexJarsFromModules(ctx android.ModuleContext, contents []android if _, exists := bootDexJars[android.RemoveOptionalPrebuiltPrefix(module.Name())]; exists { continue } - hiddenAPIModule := hiddenAPIModuleFromModule(ctx, module) - if hiddenAPIModule == nil { - continue - } - bootDexJar := retrieveBootDexJarFromHiddenAPIModule(ctx, hiddenAPIModule) + bootDexJar := retrieveBootDexJarFromHiddenAPIModule(ctx, module) bootDexJars.addPath(module, bootDexJar) } return bootDexJars } -func hiddenAPIModuleFromModule(ctx android.BaseModuleContext, module android.Module) hiddenAPIModule { - if hiddenAPIModule, ok := module.(hiddenAPIModule); ok { - return hiddenAPIModule - } else if _, ok := module.(*DexImport); ok { - // Ignore this for the purposes of hidden API processing - } else { - ctx.ModuleErrorf("module %s does not implement hiddenAPIModule", module) - } - - return nil -} - // bootDexInfo encapsulates both the path and uncompressDex status retrieved from a hiddenAPIModule. type bootDexInfo struct { // The path to the dex jar that has not had hidden API flags encoded into it. @@ -1332,15 +1319,16 @@ func (b bootDexInfoByModule) bootDexJars() android.Paths { // extractBootDexInfoFromModules extracts the boot dex jar and uncompress dex state from // each of the supplied modules which must implement hiddenAPIModule. -func extractBootDexInfoFromModules(ctx android.ModuleContext, contents []android.Module) bootDexInfoByModule { +func extractBootDexInfoFromModules(ctx android.ModuleContext, contents []android.ModuleProxy) bootDexInfoByModule { bootDexJarsByModule := bootDexInfoByModule{} for _, module := range contents { - hiddenAPIModule := module.(hiddenAPIModule) - bootDexJar := retrieveBootDexJarFromHiddenAPIModule(ctx, hiddenAPIModule) + bootDexJar := retrieveBootDexJarFromHiddenAPIModule(ctx, module) + info := android.OtherModuleProviderOrDefault(ctx, module, JavaInfoProvider) + commonInfo := android.OtherModulePointerProviderOrDefault(ctx, module, android.CommonModuleInfoProvider) bootDexJarsByModule[module.Name()] = bootDexInfo{ path: bootDexJar, - uncompressDex: *hiddenAPIModule.uncompressDex(), - minSdkVersion: hiddenAPIModule.MinSdkVersion(ctx), + uncompressDex: Bool(info.UncompressDexState), + minSdkVersion: *commonInfo.MinSdkVersion.ApiLevel, } } @@ -1352,37 +1340,31 @@ func extractBootDexInfoFromModules(ctx android.ModuleContext, contents []android // If the module does not provide a boot dex jar, i.e. the returned boot dex jar is unset or // invalid, then create a fake path and either report an error immediately or defer reporting of the // error until the path is actually used. -func retrieveBootDexJarFromHiddenAPIModule(ctx android.ModuleContext, module hiddenAPIModule) android.Path { - bootDexJar := module.bootDexJar(ctx) - if !bootDexJar.Valid() { +func retrieveBootDexJarFromHiddenAPIModule(ctx android.ModuleContext, module android.ModuleProxy) android.Path { + info := android.OtherModuleProviderOrDefault(ctx, module, JavaInfoProvider) + if !info.BootDexJarPath.Valid() { fake := android.PathForModuleOut(ctx, fmt.Sprintf("fake/boot-dex/%s.jar", module.Name())) - handleMissingDexBootFile(ctx, module, fake, bootDexJar.InvalidReason()) + handleMissingDexBootFile(ctx, module, fake, info.BootDexJarPath.InvalidReason()) return fake } - return bootDexJar.Path() + + return info.BootDexJarPath.Path() } // extractClassesJarsFromModules extracts the class jars from the supplied modules. -func extractClassesJarsFromModules(contents []android.Module) android.Paths { +func extractClassesJarsFromModules(ctx android.ModuleContext, contents []android.ModuleProxy) android.Paths { classesJars := android.Paths{} for _, module := range contents { - classesJars = append(classesJars, retrieveClassesJarsFromModule(module)...) + if info, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok { + classesJars = append(classesJars, info.HiddenapiClassesJarPaths...) + } } return classesJars } -// retrieveClassesJarsFromModule retrieves the classes jars from the supplied module. -func retrieveClassesJarsFromModule(module android.Module) android.Paths { - if hiddenAPIModule, ok := module.(hiddenAPIModule); ok { - return hiddenAPIModule.classesJars() - } - - return nil -} - // deferReportingMissingBootDexJar returns true if a missing boot dex jar should not be reported by // Soong but should instead only be reported in ninja if the file is actually built. -func deferReportingMissingBootDexJar(ctx android.ModuleContext, module android.Module) bool { +func deferReportingMissingBootDexJar(ctx android.ModuleContext, module android.ModuleOrProxy) bool { // Any missing dependency should be allowed. if ctx.Config().AllowMissingDependencies() { return true @@ -1445,7 +1427,7 @@ func deferReportingMissingBootDexJar(ctx android.ModuleContext, module android.M // handleMissingDexBootFile will either log a warning or create an error rule to create the fake // file depending on the value returned from deferReportingMissingBootDexJar. -func handleMissingDexBootFile(ctx android.ModuleContext, module android.Module, fake android.WritablePath, reason string) { +func handleMissingDexBootFile(ctx android.ModuleContext, module android.ModuleOrProxy, fake android.WritablePath, reason string) { if deferReportingMissingBootDexJar(ctx, module) { // Create an error rule that pretends to create the output file but will actually fail if it // is run. @@ -1467,14 +1449,12 @@ func handleMissingDexBootFile(ctx android.ModuleContext, module android.Module, // The returned path will usually be to a dex jar file that has been encoded with hidden API flags. // However, under certain conditions, e.g. errors, or special build configurations it will return // a path to a fake file. -func retrieveEncodedBootDexJarFromModule(ctx android.ModuleContext, module android.Module) android.Path { - bootDexJar := module.(interface { - DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath - }).DexJarBuildPath(ctx) - if !bootDexJar.Valid() { +func retrieveEncodedBootDexJarFromModule(ctx android.ModuleContext, module android.ModuleProxy) android.Path { + info := android.OtherModuleProviderOrDefault(ctx, module, JavaInfoProvider) + if !info.DexJarBuildPath.Valid() { fake := android.PathForModuleOut(ctx, fmt.Sprintf("fake/encoded-dex/%s.jar", module.Name())) - handleMissingDexBootFile(ctx, module, fake, bootDexJar.InvalidReason()) + handleMissingDexBootFile(ctx, module, fake, info.DexJarBuildPath.InvalidReason()) return fake } - return bootDexJar.Path() + return info.DexJarBuildPath.Path() } diff --git a/java/hiddenapi_monolithic.go b/java/hiddenapi_monolithic.go index 1e30c5f82..52e444c6e 100644 --- a/java/hiddenapi_monolithic.go +++ b/java/hiddenapi_monolithic.go @@ -62,8 +62,9 @@ func newMonolithicHiddenAPIInfo(ctx android.ModuleContext, flagFilesByCategory F for _, element := range classpathElements { switch e := element.(type) { case *ClasspathLibraryElement: - classesJars := retrieveClassesJarsFromModule(e.Module()) - monolithicInfo.ClassesJars = append(monolithicInfo.ClassesJars, classesJars...) + if info, ok := android.OtherModuleProvider(ctx, e.Module(), JavaInfoProvider); ok { + monolithicInfo.ClassesJars = append(monolithicInfo.ClassesJars, info.HiddenapiClassesJarPaths...) + } case *ClasspathFragmentElement: fragment := e.Module() @@ -79,7 +80,7 @@ func newMonolithicHiddenAPIInfo(ctx android.ModuleContext, flagFilesByCategory F } // append appends all the files from the supplied info to the corresponding files in this struct. -func (i *MonolithicHiddenAPIInfo) append(ctx android.ModuleContext, otherModule android.Module, other *HiddenAPIInfo) { +func (i *MonolithicHiddenAPIInfo) append(ctx android.ModuleContext, otherModule android.ModuleOrProxy, other *HiddenAPIInfo) { i.FlagsFilesByCategory.append(other.FlagFilesByCategory) i.AnnotationFlagsPaths = append(i.AnnotationFlagsPaths, other.AnnotationFlagsPath) i.MetadataPaths = append(i.MetadataPaths, other.MetadataPath) diff --git a/java/java.go b/java/java.go index 7e510e845..231da8659 100644 --- a/java/java.go +++ b/java/java.go @@ -266,6 +266,8 @@ type UsesLibraryDependencyInfo struct { type SdkLibraryComponentDependencyInfo struct { // The name of the implementation library for the optional SDK library or nil, if there isn't one. OptionalSdkLibraryImplementation *string + // The name of the java_sdk_library/_import module if this module was created by one. + SdkLibraryName *string } type ProvidesUsesLibInfo struct { @@ -400,6 +402,11 @@ type JavaInfo struct { // this file so using the encoded dex jar here would result in a cycle in the ninja rules. BootDexJarPath OptionalDexJarPath + // The paths to the classes jars that contain classes and class members annotated with + // the UnsupportedAppUsage annotation that need to be extracted as part of the hidden API + // processing. + HiddenapiClassesJarPaths android.Paths + // The compressed state of the dex file being encoded. This is used to ensure that the encoded // dex file has the same state. UncompressDexState *bool @@ -448,6 +455,8 @@ type JavaInfo struct { SystemModules string Installable bool ApexDependencyInfo *ApexDependencyInfo + + MaxSdkVersion android.ApiLevel } var JavaInfoProvider = blueprint.NewProvider[*JavaInfo]() @@ -1171,8 +1180,6 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { javaInfo.ExtraOutputFiles = j.extraOutputFiles javaInfo.DexJarFile = j.dexJarFile javaInfo.InstallFile = j.installFile - javaInfo.BootDexJarPath = j.bootDexJarPath - javaInfo.UncompressDexState = j.uncompressDexState javaInfo.Active = j.active javaInfo.BuiltInstalled = j.builtInstalled javaInfo.ConfigPath = j.configPath @@ -1243,7 +1250,7 @@ func buildComplianceMetadata(ctx android.ModuleContext) { // Static deps staticDepNames := make([]string, 0) staticDepFiles := android.Paths{} - ctx.VisitDirectDepsWithTag(staticLibTag, func(module android.Module) { + ctx.VisitDirectDepsProxyWithTag(staticLibTag, func(module android.ModuleProxy) { if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok { staticDepNames = append(staticDepNames, module.Name()) staticDepFiles = append(staticDepFiles, dep.ImplementationJars...) @@ -3598,6 +3605,8 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { javaInfo := &JavaInfo{} setExtraJavaInfo(ctx, j, javaInfo) + javaInfo.BootDexJarPath = j.dexJarFile + android.SetProvider(ctx, JavaInfoProvider, javaInfo) android.SetProvider(ctx, JavaDexImportInfoProvider, JavaDexImportInfo{}) @@ -3880,6 +3889,7 @@ func setExtraJavaInfo(ctx android.ModuleContext, module android.Module, javaInfo if slcDep, ok := module.(SdkLibraryComponentDependency); ok { javaInfo.SdkLibraryComponentDependencyInfo = &SdkLibraryComponentDependencyInfo{ OptionalSdkLibraryImplementation: slcDep.OptionalSdkLibraryImplementation(), + SdkLibraryName: slcDep.SdkLibraryName(), } } @@ -3911,6 +3921,18 @@ func setExtraJavaInfo(ctx android.ModuleContext, module android.Module, javaInfo javaInfo.DexJarBuildPath = mm.DexJarBuildPath(ctx) } + if ham, ok := module.(hiddenAPIModule); ok { + javaInfo.BootDexJarPath = ham.bootDexJar() + javaInfo.HiddenapiClassesJarPaths = ham.classesJars() + javaInfo.UncompressDexState = ham.uncompressDex() + } + + if mm, ok := module.(interface { + MaxSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel + }); ok { + javaInfo.MaxSdkVersion = mm.MaxSdkVersion(ctx) + } + if di, ok := module.(DexpreopterInterface); ok { javaInfo.DexpreopterInfo = &DexpreopterInfo{ OutputProfilePathOnHost: di.OutputProfilePathOnHost(), diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go index 155afc6c2..130f625e9 100644 --- a/java/platform_bootclasspath.go +++ b/java/platform_bootclasspath.go @@ -51,16 +51,16 @@ type platformBootclasspathModule struct { properties platformBootclasspathProperties // The apex:module pairs obtained from the configured modules. - configuredModules []android.Module + configuredModules []android.ModuleProxy // The apex:module pairs obtained from the fragments. - fragments []android.Module + fragments []android.ModuleProxy // The map of apex to the fragments they contain. - apexNameToFragment map[string]android.Module + apexNameToFragment map[string]android.ModuleProxy // The map of library modules in the bootclasspath to the fragments that contain them. - libraryToApex map[android.Module]string + libraryToApex map[android.ModuleProxy]string // Path to the monolithic hiddenapi-flags.csv file. hiddenAPIFlagsCSV android.OutputPath @@ -181,8 +181,8 @@ func (b *platformBootclasspathModule) GenerateAndroidBuildActions(ctx android.Mo // Do not add implLibModule to allModules as the impl lib is only used to collect the // transitive source files - var implLibModule []android.Module - ctx.VisitDirectDepsWithTag(platformBootclasspathImplLibDepTag, func(m android.Module) { + var implLibModule []android.ModuleProxy + ctx.VisitDirectDepsProxyWithTag(platformBootclasspathImplLibDepTag, func(m android.ModuleProxy) { implLibModule = append(implLibModule, m) }) @@ -251,7 +251,7 @@ func (b *platformBootclasspathModule) platformJars(ctx android.PathContext) andr // checkPlatformModules ensures that the non-updatable modules supplied are not part of an // apex module. -func (b *platformBootclasspathModule) checkPlatformModules(ctx android.ModuleContext, modules []android.Module) { +func (b *platformBootclasspathModule) checkPlatformModules(ctx android.ModuleContext, modules []android.ModuleProxy) { // TODO(satayev): change this check to only allow core-icu4j, all apex jars should not be here. for _, m := range modules { apexInfo, _ := android.OtherModuleProvider(ctx, m, android.ApexInfoProvider) @@ -266,7 +266,7 @@ func (b *platformBootclasspathModule) checkPlatformModules(ctx android.ModuleCon } // checkApexModules ensures that the apex modules supplied are not from the platform. -func (b *platformBootclasspathModule) checkApexModules(ctx android.ModuleContext, modules []android.Module) { +func (b *platformBootclasspathModule) checkApexModules(ctx android.ModuleContext, modules []android.ModuleProxy) { for _, m := range modules { apexInfo, _ := android.OtherModuleProvider(ctx, m, android.ApexInfoProvider) fromUpdatableApex := apexInfo.Updatable @@ -298,8 +298,10 @@ func (b *platformBootclasspathModule) checkApexModules(ctx android.ModuleContext } // generateHiddenAPIBuildActions generates all the hidden API related build rules. -func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, modules []android.Module, - fragments []android.Module, libraryToApex map[android.Module]string, apexNameToFragment map[string]android.Module) bootDexJarByModule { +func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, modules []android.ModuleProxy, + fragments []android.ModuleProxy, libraryToApex map[android.ModuleProxy]string, + apexNameToFragment map[string]android.ModuleProxy) bootDexJarByModule { + createEmptyHiddenApiFiles := func() { paths := android.OutputPaths{b.hiddenAPIFlagsCSV, b.hiddenAPIIndexCSV, b.hiddenAPIMetadataCSV} for _, path := range paths { diff --git a/java/testing.go b/java/testing.go index 86849f28b..7bb721e16 100644 --- a/java/testing.go +++ b/java/testing.go @@ -583,7 +583,7 @@ func getModuleDependencies(t *testing.T, ctx *android.TestContext, name, variant t.Helper() module := ctx.ModuleForTests(t, name, variant).Module() deps := []string{} - ctx.VisitDirectDeps(module, func(m android.Module) { + ctx.VisitDirectDepsProxies(module, func(m android.ModuleProxy) { deps = append(deps, m.Name()) }) return android.SortedUniqueStrings(deps) @@ -649,9 +649,9 @@ func CheckClasspathFragmentProtoContentInfoProvider(t *testing.T, result *androi func CheckPlatformBootclasspathDependencies(t *testing.T, ctx *android.TestContext, name, variant string, expected []string) { t.Helper() platformBootclasspath := ctx.ModuleForTests(t, name, variant).Module().(*platformBootclasspathModule) - modules := []android.Module{} - ctx.VisitDirectDeps(platformBootclasspath, func(m android.Module) { - modules = append(modules, m.(android.Module)) + modules := []android.ModuleProxy{} + ctx.VisitDirectDepsProxies(platformBootclasspath, func(m android.ModuleProxy) { + modules = append(modules, m) }) pairs := apexNamePairsFromModules(ctx, modules, platformBootclasspath.libraryToApex) @@ -659,7 +659,7 @@ func CheckPlatformBootclasspathDependencies(t *testing.T, ctx *android.TestConte } // apexNamePairsFromModules returns the apex:module pair for the supplied modules. -func apexNamePairsFromModules(ctx *android.TestContext, modules []android.Module, modulesToApex map[android.Module]string) []string { +func apexNamePairsFromModules(ctx *android.TestContext, modules []android.ModuleProxy, modulesToApex map[android.ModuleProxy]string) []string { pairs := []string{} for _, module := range modules { pairs = append(pairs, apexNamePairFromModule(ctx, module, modulesToApex)) @@ -668,7 +668,7 @@ func apexNamePairsFromModules(ctx *android.TestContext, modules []android.Module } // ApexFragmentPairsFromModules returns the apex:fragment pair for the supplied fragments. -func ApexFragmentPairsFromModules(ctx *android.TestContext, fragments []android.Module, apexNameToFragment map[string]android.Module) []string { +func ApexFragmentPairsFromModules(ctx *android.TestContext, fragments []android.ModuleProxy, apexNameToFragment map[string]android.ModuleProxy) []string { pairs := []string{} for _, fragment := range fragments { found := false @@ -685,7 +685,7 @@ func ApexFragmentPairsFromModules(ctx *android.TestContext, fragments []android. return pairs } -func apexNamePairFromModule(ctx *android.TestContext, module android.Module, modulesToApex map[android.Module]string) string { +func apexNamePairFromModule(ctx *android.TestContext, module android.ModuleProxy, modulesToApex map[android.ModuleProxy]string) string { name := module.Name() apex := modulesToApex[module] if apex == "" { -- cgit v1.2.3 From 1afb4e8d2dcac7016789a2eda47a34051b860e56 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Mon, 21 Apr 2025 10:36:01 -0700 Subject: Disable cgo in the extractor Platform builds do not use cgo. Indexing cgo would require a hermetic clang toolchain that isn't configured at the moment. Test: Ran build_kzip.bash locally Bug: 411758228 Change-Id: Icdcf498e0b8b02d1f451927556a896d9e118aae9 --- build_kzip.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_kzip.bash b/build_kzip.bash index 850aedaf0..e90fa6b47 100755 --- a/build_kzip.bash +++ b/build_kzip.bash @@ -66,7 +66,7 @@ for dir in "${go_modules[@]}"; do outfile=$(echo "$dir" | sed -r 's|/|_|g;s|(.*)|\1.go.kzip|'); KYTHE_ROOT_DIRECTORY="${source_root}" "$go_extractor" --goroot="$go_root" \ --rules=<(printf '[{"pattern": "(.*)","vname": {"path": "@1@", "corpus":"%s"}}]' "${XREF_CORPUS}") \ - --canonicalize_package_corpus --output "${abspath_out}/soong/$outfile" ./... + --canonicalize_package_corpus --output "${abspath_out}/soong/$outfile" --gocgo=false ./... ) done set +e -- cgit v1.2.3 From 3470028fefb93957ca6a973ab058b7527f9d7429 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Mon, 21 Apr 2025 13:43:31 -0700 Subject: Remove newline from kernel version file The kernel version file can be generated via 2 different methods: - Extracting it from the kernel via the extract_kernel.py script - Specifying it via the BOARD_KERNEL_VERSION variable, in which case it must still match extract_kernel.py's results. extract_kernel.py never added a newline to the end of the file that it generated. But in make, when using BOARD_KERNEL_VERSION, it did add the newline. We ended up adding a newline to the soong-built kernel version file always, because we were comparing against a BOARD_KERNEL_VERSION scenario. But that didn't match in the non-BOARD_KERNEL_VERSION scenario, leading to slow builds when toggling between soong-only and soong+make. Bug: 412416205 Test: soong_only_diff_test.py Change-Id: I47f561b9629ceb03ac3c5e70f48e45aa82e1f44c --- filesystem/android_device.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/filesystem/android_device.go b/filesystem/android_device.go index 23a97d11d..783cb9afc 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -1163,12 +1163,11 @@ func (a *androidDevice) extractKernelVersionAndConfigs(ctx android.ModuleContext Flag("--tools lz4:"+lz4tool.String()).Implicit(lz4tool). FlagWithInput("--input ", kernel). FlagWithOutput("--output-release ", extractedVersionFile). - FlagWithOutput("--output-configs ", extractedConfigsFile). - Textf(`&& printf "\n" >> %s`, extractedVersionFile) + FlagWithOutput("--output-configs ", extractedConfigsFile) if specifiedVersion := proptools.String(a.deviceProps.Kernel_version); specifiedVersion != "" { specifiedVersionFile := android.PathForModuleOut(ctx, "specified_kernel_version.txt") - android.WriteFileRule(ctx, specifiedVersionFile, specifiedVersion) + android.WriteFileRuleVerbatim(ctx, specifiedVersionFile, specifiedVersion) builder.Command().Text("diff -q"). Input(specifiedVersionFile). Input(extractedVersionFile). -- cgit v1.2.3 From b179161f78f039f60ff41a6caa24185540220a73 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Mon, 21 Apr 2025 15:22:16 -0700 Subject: Dist build.log file for each build So that we can see what was rebuilt more easily. Bug: 412416205 Test: Presubmits Change-Id: I3b4c44b0a7b2a1df817ed8bf5d0b3e36ce87683e --- scripts/soong_only_diff_test.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/soong_only_diff_test.py b/scripts/soong_only_diff_test.py index 1a4eea145..ab3a7df81 100755 --- a/scripts/soong_only_diff_test.py +++ b/scripts/soong_only_diff_test.py @@ -135,6 +135,7 @@ def move_artifacts_to_subfolder(product: Product, soong_only: bool): files_to_move = [ os.path.join(dist_dir, f'{product.product}-target_files-{build_id}.zip'), # target_files.zip + os.path.join(out_dir, 'build.log'), ] for file in files_to_move: -- cgit v1.2.3 From 63018bdfee3e3c58f601b9187d1fad6d9664aa4d Mon Sep 17 00:00:00 2001 From: Satish Yalla Date: Thu, 17 Apr 2025 22:45:15 -0700 Subject: Revert "Upgrade clang to clang-r563880" This reverts commit 634ea6e97f61093b7c9227f61cf06f8ba37313fa. Reason for revert: Droid monitor: Likely culprit for b/411553971 verifying through ABTD before revert submission. This is part of the standard investigation process, and does not mean your CL will be reverted. Bug: 411553971 (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:05f0d57e8d7541301c12e405724837f82bc54a22) Merged-In: I7a28be9e812a6b895b8640ebfe2c85af514a13fa Change-Id: I7a28be9e812a6b895b8640ebfe2c85af514a13fa --- bpf/bpf.go | 2 +- cc/compiler.go | 5 +---- cc/config/global.go | 7 ++----- cc/stl.go | 2 +- 4 files changed, 5 insertions(+), 11 deletions(-) diff --git a/bpf/bpf.go b/bpf/bpf.go index b0be3e788..deb465dd6 100644 --- a/bpf/bpf.go +++ b/bpf/bpf.go @@ -41,7 +41,7 @@ var ( blueprint.RuleParams{ Depfile: "${out}.d", Deps: blueprint.DepsGCC, - Command: "$relPwd $ccCmd --target=bpf -mcpu=v1 -c $cFlags -MD -MF ${out}.d -o $out $in", + Command: "$relPwd $ccCmd --target=bpf -c $cFlags -MD -MF ${out}.d -o $out $in", CommandDeps: []string{"$ccCmd"}, }, "ccCmd", "cFlags") diff --git a/cc/compiler.go b/cc/compiler.go index 316cd9e1d..949603e40 100644 --- a/cc/compiler.go +++ b/cc/compiler.go @@ -711,10 +711,7 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps if ctx.optimizeForSize() { flags.Local.CFlags = append(flags.Local.CFlags, "-Oz") if !ctx.Config().IsEnvFalse("THINLTO_USE_MLGO") { - if ctx.Arch().ArchType == android.Arm64 { - flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-mllvm,-enable-ml-inliner=release") - flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-mllvm,-ml-inliner-model-selector=arm64-mixed") - } + flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-mllvm,-enable-ml-inliner=release") } } diff --git a/cc/config/global.go b/cc/config/global.go index b91697ded..e81ac0d47 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -292,9 +292,6 @@ var ( "-Wno-error=deprecated", // in external/googletest/googletest // New warnings to be fixed after clang-r522817 "-Wno-error=invalid-offsetof", - // New warnings to be fixed after clang-r563880 - "-Wno-nontrivial-memcall", - "-Wno-invalid-specialization", // Allow using VLA CXX extension. "-Wno-vla-cxx-extension", @@ -388,8 +385,8 @@ var ( // prebuilts/clang default settings. ClangDefaultBase = "prebuilts/clang/host" - ClangDefaultVersion = "clang-r563880" - ClangDefaultShortVersion = "21" + ClangDefaultVersion = "clang-r547379" + ClangDefaultShortVersion = "20" // Directories with warnings from Android.bp files. WarningAllowedProjects = []string{ diff --git a/cc/stl.go b/cc/stl.go index b91a1f1f5..8c4ef0b4a 100644 --- a/cc/stl.go +++ b/cc/stl.go @@ -212,7 +212,7 @@ func (stl *stl) flags(ctx ModuleContext, flags Flags) Flags { "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS=", "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS=", // Use Win32 threads in libc++. - "-D_LIBCPP_HAS_THREAD_API_WIN32=1") + "-D_LIBCPP_HAS_THREAD_API_WIN32=") } } case "libstdc++": -- cgit v1.2.3 From 0bc37f002b62a83fd2b2bc7f0ba0394e175dfcce Mon Sep 17 00:00:00 2001 From: kellyhung Date: Mon, 21 Apr 2025 13:58:10 +0000 Subject: Convert module-info to Soong-only - module_exports - sdk - test_module_config_host - test_package - cc_cmake_snapshot - install_symlink Bug: 389720048 Bug: 412316771 Test: lunch aosp_cf_x86_64_phone; (SOONG_ONLY=true) Test: m out/target/product/vsoc_x86_64/module-info.json (or refreshmod) Test: Inspect module-info.json diff, CI Change-Id: I59f06e4e205b023ec7aa88c40c3b179bbd247b23 --- cc/cmake_snapshot.go | 4 ++++ etc/install_symlink.go | 4 ++++ sdk/sdk.go | 3 +++ tradefed_modules/test_module_config.go | 9 +++++++++ 4 files changed, 20 insertions(+) diff --git a/cc/cmake_snapshot.go b/cc/cmake_snapshot.go index 3f6a01d1b..c51fa10dd 100644 --- a/cc/cmake_snapshot.go +++ b/cc/cmake_snapshot.go @@ -503,6 +503,10 @@ func (m *CmakeSnapshot) GenerateAndroidBuildActions(ctx android.ModuleContext) { zipRule.Build(m.zipPath.String(), "archiving "+ctx.ModuleName()) ctx.SetOutputFiles(android.Paths{m.zipPath}, "") + + moduleInfoJSON := ctx.ModuleInfoJSON() + moduleInfoJSON.Class = []string{"DATA"} + moduleInfoJSON.SystemSharedLibs = []string{"none"} } func (m *CmakeSnapshot) AndroidMkEntries() []android.AndroidMkEntries { diff --git a/etc/install_symlink.go b/etc/install_symlink.go index 31da3f653..ee5a56b91 100644 --- a/etc/install_symlink.go +++ b/etc/install_symlink.go @@ -87,6 +87,10 @@ func (m *InstallSymlink) GenerateAndroidBuildActions(ctx android.ModuleContext) name := filepath.Base(m.properties.Installed_location) installDir := android.PathForModuleInstall(ctx, filepath.Dir(m.properties.Installed_location)) m.installedPath = ctx.InstallAbsoluteSymlink(installDir, name, symlink_target) + + moduleInfoJSON := ctx.ModuleInfoJSON() + moduleInfoJSON.Class = []string{"FAKE"} + moduleInfoJSON.SystemSharedLibs = []string{"none"} } func (m *InstallSymlink) AndroidMkEntries() []android.AndroidMkEntries { diff --git a/sdk/sdk.go b/sdk/sdk.go index ab50659cd..46f7d27a7 100644 --- a/sdk/sdk.go +++ b/sdk/sdk.go @@ -186,6 +186,9 @@ func (s *sdk) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.SetOutputFiles([]android.Path{s.snapshotFile.Path()}, "") ctx.SetOutputFiles([]android.Path{s.snapshotFile.Path(), s.infoFile.Path()}, android.DefaultDistTag) } + moduleInfoJSON := ctx.ModuleInfoJSON() + moduleInfoJSON.Class = []string{"FAKE"} + moduleInfoJSON.SystemSharedLibs = []string{"none"} } func (s *sdk) AndroidMkEntries() []android.AndroidMkEntries { diff --git a/tradefed_modules/test_module_config.go b/tradefed_modules/test_module_config.go index c24eddccf..5535a0bc3 100644 --- a/tradefed_modules/test_module_config.go +++ b/tradefed_modules/test_module_config.go @@ -328,6 +328,15 @@ func (m *testModuleConfigHostModule) DepsMutator(ctx android.BottomUpMutatorCont func (m *testModuleConfigHostModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { m.validateBase(ctx, &testModuleConfigHostTag, "java_test_host", true) m.generateManifestAndConfig(ctx) + + moduleInfoJSON := ctx.ModuleInfoJSON() + moduleInfoJSON.Class = []string{"JAVA_LIBRARIES"} + moduleInfoJSON.Tags = append(moduleInfoJSON.Tags, "tests") + moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, m.tradefedProperties.Test_suites...) + moduleInfoJSON.SystemSharedLibs = []string{"none"} + moduleInfoJSON.TestConfig = []string{m.testConfig.String()} + moduleInfoJSON.AutoTestConfig = []string{"true"} + moduleInfoJSON.TestModuleConfigBase = proptools.String(m.Base) } // Ensure the base listed is the right type by checking that we get the expected provider data. -- cgit v1.2.3 From 974973b4a1a63f16e72867ac7d399d689ed599c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Kongstad?= Date: Thu, 17 Apr 2025 14:16:34 +0200 Subject: release_config_proto: add module liball_release_configs_proto Add a new module, liball_release_configs_proto, that exposes the release config proto files as a Rust library. Also give finalization-test access to the new module. Bug: 405872440 Test: m nothing Change-Id: I21830b0216668fa323fdcd03eb7bfc828d02a973 --- cmd/release_config/release_config_proto/Android.bp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/cmd/release_config/release_config_proto/Android.bp b/cmd/release_config/release_config_proto/Android.bp index c6869b1fc..943fb8bdc 100644 --- a/cmd/release_config/release_config_proto/Android.bp +++ b/cmd/release_config/release_config_proto/Android.bp @@ -31,3 +31,21 @@ bootstrap_go_package { "release_configs_contributions.pb.go", ], } + +rust_protobuf_host { + name: "liball_release_configs_proto", + protos: [ + "build_flags_common.proto", + "build_flags_declarations.proto", + "build_flags_out.proto", + "build_flags_src.proto", + "release_configs_contributions.proto", + ], + crate_name: "all_release_configs_proto", + source_stem: "all_release_configs_proto", + + // Keep visibility limited to tests only! + visibility: [ + "//build/make/tools/finalization/finalization-test", + ], +} -- cgit v1.2.3 From 3c8019ac415ab9d7b1e6094283dbd19cdb1431ca Mon Sep 17 00:00:00 2001 From: Brian Ryner Date: Tue, 22 Apr 2025 15:47:43 +0000 Subject: Update the proxy policy to disallow use of cipd tags. We will instead pin the instance ids for now. Test: none Bug: 400695406 Change-Id: I06ee859d86068f30446610d4fb229ddf51bd1f4a --- ui/build/cipd_proxy_policy.pb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/build/cipd_proxy_policy.pb b/ui/build/cipd_proxy_policy.pb index aa767ba06..98953a553 100644 --- a/ui/build/cipd_proxy_policy.pb +++ b/ui/build/cipd_proxy_policy.pb @@ -1,5 +1,5 @@ allowed_remotes: "chrome-infra-packages.appspot.com" resolve_version { - allow_tags: true + allow_tags: false allow_refs: false } -- cgit v1.2.3 From 6fb3926d6aaac2e2fc708c1cdb5f8d8dd2f620ce Mon Sep 17 00:00:00 2001 From: Brian Ryner Date: Tue, 22 Apr 2025 17:05:27 +0000 Subject: Rename the proxy config to .txtpb, the canonical extension for text-format protos. The .pb extension is commonly used for binary protos, so this avoids confusion. Test: none Bug: 400695406 Change-Id: I374aacd4cfd493221e175f41353a450d9557ae65 --- ui/build/cipd.go | 2 +- ui/build/cipd_proxy_policy.pb | 5 ----- ui/build/cipd_proxy_policy.txtpb | 5 +++++ 3 files changed, 6 insertions(+), 6 deletions(-) delete mode 100644 ui/build/cipd_proxy_policy.pb create mode 100644 ui/build/cipd_proxy_policy.txtpb diff --git a/ui/build/cipd.go b/ui/build/cipd.go index da0936a67..84fd2a088 100644 --- a/ui/build/cipd.go +++ b/ui/build/cipd.go @@ -22,7 +22,7 @@ import ( ) const ( - cipdProxyPolicyPath = "build/soong/ui/build/cipd_proxy_policy.pb" + cipdProxyPolicyPath = "build/soong/ui/build/cipd_proxy_policy.txtpb" cipdProxyUrlKey = "CIPD_PROXY_URL" ) diff --git a/ui/build/cipd_proxy_policy.pb b/ui/build/cipd_proxy_policy.pb deleted file mode 100644 index 98953a553..000000000 --- a/ui/build/cipd_proxy_policy.pb +++ /dev/null @@ -1,5 +0,0 @@ -allowed_remotes: "chrome-infra-packages.appspot.com" -resolve_version { - allow_tags: false - allow_refs: false -} diff --git a/ui/build/cipd_proxy_policy.txtpb b/ui/build/cipd_proxy_policy.txtpb new file mode 100644 index 000000000..98953a553 --- /dev/null +++ b/ui/build/cipd_proxy_policy.txtpb @@ -0,0 +1,5 @@ +allowed_remotes: "chrome-infra-packages.appspot.com" +resolve_version { + allow_tags: false + allow_refs: false +} -- cgit v1.2.3 From fde7419cb63a8ca4b3d9cbc7049354c10b2e3ac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Kongstad?= Date: Thu, 17 Apr 2025 13:14:56 +0200 Subject: all_release_config: make output accessible - Mark all_release_configs as host-only. - Call SetOutputFiles to make the module usable. - Update all_release_config's visibility to allow finalization-test to access it. Bug: 405872440 Test: atest finalization-test Change-Id: I14a71d037b476467e489aad49920f04f309da6eb --- aconfig/build_flags/Android.bp | 2 ++ aconfig/build_flags/release_configs.go | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/aconfig/build_flags/Android.bp b/aconfig/build_flags/Android.bp index 582eed854..7c124e611 100644 --- a/aconfig/build_flags/Android.bp +++ b/aconfig/build_flags/Android.bp @@ -26,4 +26,6 @@ bootstrap_go_package { all_release_configs { name: "all_release_configs", + // Visibility must be limited to host tests! + visibility: ["//build/make/tools/finalization/finalization-test"], } diff --git a/aconfig/build_flags/release_configs.go b/aconfig/build_flags/release_configs.go index 966939e0f..b5012152b 100644 --- a/aconfig/build_flags/release_configs.go +++ b/aconfig/build_flags/release_configs.go @@ -98,7 +98,7 @@ type AllReleaseConfigsModule struct { func AllReleaseConfigsFactory() android.Module { module := &AllReleaseConfigsModule{} - android.InitAndroidModule(module) + android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon) android.InitDefaultableModule(module) module.AddProperties(&module.properties) @@ -123,6 +123,7 @@ func (module *AllReleaseConfigsModule) GenerateAndroidBuildActions(ctx android.M Input: srcPath, Output: outputPath, }) + ctx.SetOutputFiles(android.Paths{outputPath}, "") android.SetProvider(ctx, AllReleaseConfigsProviderKey, AllReleaseConfigsProviderData{ AllReleaseConfigsPath: outputPath, -- cgit v1.2.3 From c5cf15fe9eec840e17a1253a42c6d5d9def0db15 Mon Sep 17 00:00:00 2001 From: Martin Stjernholm Date: Tue, 22 Apr 2025 19:03:19 +0100 Subject: Ignore PRODUCT_ART_TARGET_INCLUDE_DEBUG_BUILD if ART is a prebuilt module. Test: m Bug: 403309968 Bug: 398836954 Flag: EXEMPT build change Change-Id: I641992b07b3af1243789d8cac66753cefb40aab6 --- android/config.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/android/config.go b/android/config.go index ba8412357..1b778271b 100644 --- a/android/config.go +++ b/android/config.go @@ -2416,17 +2416,19 @@ func (c *config) OemProperties() []string { } func (c *config) UseDebugArt() bool { - // If the ArtTargetIncludeDebugBuild product variable is set then return its value. - if c.productVariables.ArtTargetIncludeDebugBuild != nil { - return Bool(c.productVariables.ArtTargetIncludeDebugBuild) - } - // If the RELEASE_APEX_CONTRIBUTIONS_ART build flag is set to use a prebuilt ART apex // then don't use the debug apex. if val, ok := c.GetBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ART"); ok && val != "" { return false } + // If the ArtTargetIncludeDebugBuild product variable is set then return its value. + // The prebuilt APEX check overrides this to be tolerant wrt build logic + // that sets PRODUCT_ART_TARGET_INCLUDE_DEBUG_BUILD regardless of module source. + if c.productVariables.ArtTargetIncludeDebugBuild != nil { + return Bool(c.productVariables.ArtTargetIncludeDebugBuild) + } + // Default to the debug apex for eng builds. return Bool(c.productVariables.Eng) } -- cgit v1.2.3 From 0024247516220ee19e59cbd5e2d691d12443572c Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Tue, 22 Apr 2025 11:26:14 -0700 Subject: Make the optimize property configurable By user request. Fixes: 411367058 Test: m nothing Change-Id: I55a3db31b15b0e1ef1a4c8ca1427d96b5436eaa5 --- java/dex.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/java/dex.go b/java/dex.go index e3058e9bf..f50f79fff 100644 --- a/java/dex.go +++ b/java/dex.go @@ -80,7 +80,7 @@ type DexProperties struct { Shrink *bool // If true, optimize bytecode. Defaults to false. - Optimize *bool + Optimize proptools.Configurable[bool] `android:"replace_instead_of_append"` // If true, obfuscate bytecode. Defaults to false. Obfuscate *bool @@ -182,8 +182,8 @@ func (d *DexProperties) optimizedResourceShrinkingEnabled(ctx android.ModuleCont return d.resourceShrinkingEnabled(ctx) && BoolDefault(d.Optimize.Optimized_shrink_resources, ctx.Config().UseOptimizedResourceShrinkingByDefault()) } -func (d *dexer) optimizeOrObfuscateEnabled(ctx android.EarlyModuleContext) bool { - return d.effectiveOptimizeEnabled(ctx) && (proptools.Bool(d.dexProperties.Optimize.Optimize) || proptools.Bool(d.dexProperties.Optimize.Obfuscate)) +func (d *dexer) optimizeOrObfuscateEnabled(ctx android.ModuleContext) bool { + return d.effectiveOptimizeEnabled(ctx) && (d.dexProperties.Optimize.Optimize.GetOrDefault(ctx, false) || proptools.Bool(d.dexProperties.Optimize.Obfuscate)) } var d8, d8RE = pctx.MultiCommandRemoteStaticRules("d8", @@ -525,7 +525,8 @@ func (d *dexer) r8Flags(ctx android.ModuleContext, dexParams *compileDexParams, // 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 { + optimize := opt.Optimize.GetOrDefault(ctx, false) + if (optimize || Bool(opt.Obfuscate)) && !debugMode { // TODO(b/213833843): Allow configuration of the prefix via a build variable. var sourceFilePrefix = "go/retraceme " var sourceFileTemplate = "\"" + sourceFilePrefix + "%MAP_ID\"" @@ -538,7 +539,7 @@ func (d *dexer) r8Flags(ctx android.ModuleContext, dexParams *compileDexParams, r8Flags = append(r8Flags, "-dontshrink") } - if !Bool(opt.Optimize) { + if !optimize { r8Flags = append(r8Flags, "-dontoptimize") } -- cgit v1.2.3 From 61ccb239506cb3dcc90dd9b019e06fa5bfc7b3d6 Mon Sep 17 00:00:00 2001 From: LaMont Jones Date: Tue, 22 Apr 2025 11:09:44 -0700 Subject: Reapply "dex: list dependency on D8Jar, R8Jar" This reverts commit 93e705afad0579e6f1ebb0f03945bdaec08917a6 and lists additional dependencies on D8Jar and R8Jar. Bug: b/371612856 Test: manual, ABTD Change-Id: I22236de8cefe5d4e2204bf170029f39d59adebba --- java/dex.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/java/dex.go b/java/dex.go index e3058e9bf..f1c208d0d 100644 --- a/java/dex.go +++ b/java/dex.go @@ -195,6 +195,7 @@ var d8, d8RE = pctx.MultiCommandRemoteStaticRules("d8", `rm -f "$outDir"/classes*.dex "$outDir/classes.dex.jar"`, CommandDeps: []string{ "${config.D8Cmd}", + "${config.D8Jar}", "${config.SoongZipCmd}", "${config.MergeZipsCmd}", }, @@ -250,7 +251,9 @@ var d8r8, d8r8RE = pctx.MultiCommandRemoteStaticRules("d8r8", `rm -f "$outDir"/classes*.dex "$outDir/classes.dex.jar" `, CommandDeps: []string{ "${config.D8Cmd}", + "${config.D8Jar}", "${config.R8Cmd}", + "${config.R8Jar}", "${config.SoongZipCmd}", "${config.MergeZipsCmd}", }, @@ -301,6 +304,7 @@ var r8, r8RE = pctx.MultiCommandRemoteStaticRules("r8", Deps: blueprint.DepsGCC, CommandDeps: []string{ "${config.R8Cmd}", + "${config.R8Jar}", "${config.SoongZipCmd}", "${config.MergeZipsCmd}", }, -- cgit v1.2.3 From dc35b9a9b4fccf7bebfcb380de09e781189361d8 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Tue, 22 Apr 2025 12:49:53 -0700 Subject: Add tests for new error message See other cl in this topic. Fixes: 397315538 Test: soong tests Change-Id: I260d80af3da483b03e0aba2cb8ce9a880f2da20a --- android/selects_test.go | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/android/selects_test.go b/android/selects_test.go index 8e469f8e3..c3dc5c84e 100644 --- a/android/selects_test.go +++ b/android/selects_test.go @@ -770,7 +770,7 @@ func TestSelects(t *testing.T) { }), } `, - expectedError: `can't assign select statement to non-configurable property "my_nonconfigurable_bool"`, + expectedError: `can't assign select statement to non-configurable property "my_nonconfigurable_bool". This requires a small soong change to enable`, }, { name: "Assigning select to nonconfigurable string", @@ -783,7 +783,7 @@ func TestSelects(t *testing.T) { }), } `, - expectedError: `can't assign select statement to non-configurable property "my_nonconfigurable_string"`, + expectedError: `can't assign select statement to non-configurable property "my_nonconfigurable_string". This requires a small soong change to enable`, }, { name: "Assigning appended selects to nonconfigurable string", @@ -799,7 +799,7 @@ func TestSelects(t *testing.T) { }), } `, - expectedError: `can't assign select statement to non-configurable property "my_nonconfigurable_string"`, + expectedError: `can't assign select statement to non-configurable property "my_nonconfigurable_string". This requires a small soong change to enable`, }, { name: "Assigning select to nonconfigurable string list", @@ -812,7 +812,20 @@ func TestSelects(t *testing.T) { }), } `, - expectedError: `can't assign select statement to non-configurable property "my_nonconfigurable_string_list"`, + expectedError: `can't assign select statement to non-configurable property "my_nonconfigurable_string_list". This requires a small soong change to enable`, + }, + { + name: "Assigning select to defaults property", + bp: ` + my_module_type { + name: "foo", + defaults: select(soong_config_variable("foo", "bar"), { + "x": ["foo"], + default: [], + }), + } + `, + expectedError: `can't assign select statement to non-configurable property "defaults". We explicitly don't support selects on this property`, }, { name: "Select in variable", -- cgit v1.2.3 From 65a0bdf3d058b745fadca6b969bc99499567fed0 Mon Sep 17 00:00:00 2001 From: Ryan Prichard Date: Tue, 22 Apr 2025 14:08:11 -0700 Subject: Upgrade bindgen to clang-r547379 The new clang has __builtin_ctzg, which is necessary for building the ToT libc++. Bug: 412736293 Test: presubmit Change-Id: I74f23352d357c102ab8a83ae3a0f9d496870035a --- rust/bindgen.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/bindgen.go b/rust/bindgen.go index 2f84168bd..bc26590fa 100644 --- a/rust/bindgen.go +++ b/rust/bindgen.go @@ -29,7 +29,7 @@ var ( defaultBindgenFlags = []string{""} // bindgen should specify its own Clang revision so updating Clang isn't potentially blocked on bindgen failures. - bindgenClangVersion = "clang-r530567" + bindgenClangVersion = "clang-r547379" _ = pctx.VariableFunc("bindgenClangVersion", func(ctx android.PackageVarContext) string { if override := ctx.Config().Getenv("LLVM_BINDGEN_PREBUILTS_VERSION"); override != "" { -- cgit v1.2.3 From 1370411275d55b2300986c9355b9e73e1261384d Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 16 Apr 2025 14:19:11 -0700 Subject: Convert filesystem/ to ModuleProxy and Providers Test: all Soong tests pass Change-Id: Ieca817438b75924a320e4cead49f9da74f47e253 --- filesystem/android_device.go | 8 ++++---- filesystem/android_device_product_out.go | 10 +++++----- filesystem/filesystem.go | 19 ++++++++++--------- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/filesystem/android_device.go b/filesystem/android_device.go index 1b5000c5b..f188cd8e7 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -378,15 +378,15 @@ func (a *androidDevice) allInstalledModules(ctx android.ModuleContext) []android } ret := []android.ModuleOrProxy{} - ctx.WalkDeps(func(mod, _ android.Module) bool { + ctx.WalkDepsProxy(func(mod, _ android.ModuleProxy) bool { commonInfo, ok := android.OtherModuleProvider(ctx, mod, android.CommonModuleInfoProvider) if !(ok && commonInfo.ExportedToMake) { return false } prebuiltInfo := android.OtherModuleProviderOrDefault(ctx, mod, android.PrebuiltInfoProvider) name := ctx.OtherModuleName(mod) - if o, ok := mod.(android.OverridableModule); ok && o.GetOverriddenBy() != "" { - name = o.GetOverriddenBy() + if info, ok := android.OtherModuleProvider(ctx, mod, android.OverrideInfoProvider); ok && info.OverriddenBy != "" { + name = info.OverriddenBy } if variations, ok := allOwners[name]; ok && android.InList(installedOwnerInfo{ @@ -758,7 +758,7 @@ func (a *androidDevice) copyMetadataToTargetZip(ctx android.ModuleContext, build writeFileWithNewLines(ctx, abOtaPostInstallConfigFilePath, a.deviceProps.Ab_ota_postinstall_config) builder.Command().Textf("cp").Input(abOtaPostInstallConfigFilePath).Textf(" %s/META/", targetFilesDir) // selinuxfc - fileContextsModule := ctx.GetDirectDepWithTag("file_contexts_bin_gen", fileContextsDepTag) + fileContextsModule := ctx.GetDirectDepProxyWithTag("file_contexts_bin_gen", fileContextsDepTag) outputFiles, ok := android.OtherModuleProvider(ctx, fileContextsModule, android.OutputFilesProvider) if !ok || len(outputFiles.DefaultOutputFiles) != 1 { ctx.ModuleErrorf("Expected exactly 1 output file from file_contexts_bin_gen") diff --git a/filesystem/android_device_product_out.go b/filesystem/android_device_product_out.go index 15c547350..1a3782b8e 100644 --- a/filesystem/android_device_product_out.go +++ b/filesystem/android_device_product_out.go @@ -117,7 +117,7 @@ func (a *androidDevice) copyFilesToProductOutForSoongOnly(ctx android.ModuleCont copyBootImg := func(prop *string, type_ string) { if proptools.String(prop) != "" { - partition := ctx.GetDirectDepWithTag(*prop, filesystemDepTag) + partition := ctx.GetDirectDepProxyWithTag(*prop, filesystemDepTag) if info, ok := android.OtherModuleProvider(ctx, partition, BootimgInfoProvider); ok { installPath := android.PathForModuleInPartitionInstall(ctx, "", type_+".img") ctx.Build(pctx, android.BuildParams{ @@ -137,7 +137,7 @@ func (a *androidDevice) copyFilesToProductOutForSoongOnly(ctx android.ModuleCont copyBootImg(a.partitionProps.Vendor_boot_partition_name, "vendor_boot") for _, vbmetaModName := range a.partitionProps.Vbmeta_partitions { - partition := ctx.GetDirectDepWithTag(vbmetaModName, filesystemDepTag) + partition := ctx.GetDirectDepProxyWithTag(vbmetaModName, filesystemDepTag) if info, ok := android.OtherModuleProvider(ctx, partition, vbmetaPartitionProvider); ok { installPath := android.PathForModuleInPartitionInstall(ctx, "", info.Name+".img") ctx.Build(pctx, android.BuildParams{ @@ -152,7 +152,7 @@ func (a *androidDevice) copyFilesToProductOutForSoongOnly(ctx android.ModuleCont } if proptools.String(a.partitionProps.Super_partition_name) != "" { - partition := ctx.GetDirectDepWithTag(*a.partitionProps.Super_partition_name, superPartitionDepTag) + partition := ctx.GetDirectDepProxyWithTag(*a.partitionProps.Super_partition_name, superPartitionDepTag) if info, ok := android.OtherModuleProvider(ctx, partition, SuperImageProvider); ok { installPath := android.PathForModuleInPartitionInstall(ctx, "", "super.img") ctx.Build(pctx, android.BuildParams{ @@ -226,7 +226,7 @@ func (a *androidDevice) getFsInfos(ctx android.ModuleContext) map[string]Filesys } for _, partitionDefinition := range partitionDefinitions { if proptools.String(partitionDefinition.prop) != "" { - partition := ctx.GetDirectDepWithTag(*partitionDefinition.prop, filesystemDepTag) + partition := ctx.GetDirectDepProxyWithTag(*partitionDefinition.prop, filesystemDepTag) if info, ok := android.OtherModuleProvider(ctx, partition, FilesystemProvider); ok { filesystemInfos[partitionDefinition.ty] = info } else { @@ -235,7 +235,7 @@ func (a *androidDevice) getFsInfos(ctx android.ModuleContext) map[string]Filesys } } if a.partitionProps.Super_partition_name != nil { - superPartition := ctx.GetDirectDepWithTag(*a.partitionProps.Super_partition_name, superPartitionDepTag) + superPartition := ctx.GetDirectDepProxyWithTag(*a.partitionProps.Super_partition_name, superPartitionDepTag) if info, ok := android.OtherModuleProvider(ctx, superPartition, SuperImageProvider); ok { for partition := range info.SubImageInfo { filesystemInfos[partition] = info.SubImageInfo[partition] diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index 638f3af0c..b63633c9b 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -851,7 +851,7 @@ func (f *filesystem) validateVintfFragments(ctx android.ModuleContext) { visitedModule := map[string]bool{} packagingSpecs := f.gatherFilteredPackagingSpecs(ctx) - moduleInFileSystem := func(mod android.Module) bool { + moduleInFileSystem := func(mod android.ModuleProxy) bool { for _, ps := range android.OtherModuleProviderOrDefault( ctx, mod, android.InstallFilesProvider).PackagingSpecs { if _, ok := packagingSpecs[ps.RelPathInPackage()]; ok { @@ -861,7 +861,7 @@ func (f *filesystem) validateVintfFragments(ctx android.ModuleContext) { return false } - ctx.WalkDeps(func(child, parent android.Module) bool { + ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool { if visitedModule[child.Name()] { return false } @@ -869,14 +869,15 @@ func (f *filesystem) validateVintfFragments(ctx android.ModuleContext) { visitedModule[child.Name()] = true return true } - if vintfFragments := child.VintfFragments(ctx); vintfFragments != nil { + + if installInfo, ok := android.OtherModuleProvider(ctx, child, android.InstallFilesProvider); ok && len(installInfo.VintfFragmentsPaths) > 0 { ctx.PropertyErrorf( "vintf_fragments", "Module %s is referenced by soong-defined filesystem %s with property vintf_fragments(%s) in use."+ " Use vintf_fragment_modules property instead.", child.Name(), f.BaseModuleName(), - strings.Join(vintfFragments, ", "), + strings.Join(installInfo.VintfFragmentsPaths.Strings(), ", "), ) } visitedModule[child.Name()] = true @@ -1317,7 +1318,7 @@ func (f *filesystem) checkFsTypePropertyError(ctx android.ModuleContext, t fsTyp } func includeFilesRootDir(ctx android.ModuleContext) (rootDirs android.Paths, partitions android.Paths) { - ctx.VisitDirectDepsWithTag(interPartitionInstallDependencyTag, func(m android.Module) { + ctx.VisitDirectDepsProxyWithTag(interPartitionInstallDependencyTag, func(m android.ModuleProxy) { if fsProvider, ok := android.OtherModuleProvider(ctx, m, FilesystemProvider); ok { rootDirs = append(rootDirs, fsProvider.RootDir) partitions = append(partitions, fsProvider.Output) @@ -1330,7 +1331,7 @@ func includeFilesRootDir(ctx android.ModuleContext) (rootDirs android.Paths, par } func includeFilesInstalledFiles(ctx android.ModuleContext) (ret []depset.DepSet[InstalledFilesStruct]) { - ctx.VisitDirectDepsWithTag(interPartitionInstallDependencyTag, func(m android.Module) { + ctx.VisitDirectDepsProxyWithTag(interPartitionInstallDependencyTag, func(m android.ModuleProxy) { if fsProvider, ok := android.OtherModuleProvider(ctx, m, FilesystemProvider); ok { ret = append(ret, fsProvider.InstalledFilesDepSet) } @@ -1343,7 +1344,7 @@ func (f *filesystem) hasOrIsRecovery(ctx android.ModuleContext) bool { return true } ret := false - ctx.VisitDirectDepsWithTag(interPartitionInstallDependencyTag, func(m android.Module) { + ctx.VisitDirectDepsProxyWithTag(interPartitionInstallDependencyTag, func(m android.ModuleProxy) { if fsProvider, ok := android.OtherModuleProvider(ctx, m, FilesystemProvider); ok && fsProvider.PartitionName == "recovery" { ret = true } @@ -1545,7 +1546,7 @@ func (f *filesystem) gatherOwners(specs map[string]android.PackagingSpec) []Inst } func (f *filesystem) gatherSubPartitionOwners(ctx android.ModuleContext) (ret []depset.DepSet[InstalledModuleInfo]) { - ctx.VisitDirectDepsWithTag(interPartitionInstallDependencyTag, func(m android.Module) { + ctx.VisitDirectDepsProxyWithTag(interPartitionInstallDependencyTag, func(m android.ModuleProxy) { if fsProvider, ok := android.OtherModuleProvider(ctx, m, FilesystemProvider); ok { ret = append(ret, fsProvider.Owners) } @@ -1716,7 +1717,7 @@ func addAutogeneratedRroDeps(ctx android.BottomUpMutatorContext) { } return } - ctx.WalkDeps(func(child, parent android.Module) bool { + ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool { depTag := ctx.OtherModuleDependencyTag(child) if parent.Name() == f.Name() && depTag != interPartitionDependencyTag { return false // This is a module listed in deps of vendor/product filesystem -- cgit v1.2.3 From 978f442b916781f7dbaab7738104b35a2dbced3f Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 16 Apr 2025 23:08:51 -0700 Subject: Convert aconfig/codegen/ to ModuleProxy Test: all Soong tests pass Change-Id: I09ddae44391c60b68fa02a258cbe874e7f7e498c --- aconfig/codegen/java_aconfig_library.go | 2 +- aconfig/codegen/rust_aconfig_library.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aconfig/codegen/java_aconfig_library.go b/aconfig/codegen/java_aconfig_library.go index bb734a02d..0c40d78a5 100644 --- a/aconfig/codegen/java_aconfig_library.go +++ b/aconfig/codegen/java_aconfig_library.go @@ -77,7 +77,7 @@ func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) DepsMutator(module *ja func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) GenerateSourceJarBuildActions(module *java.GeneratedJavaLibraryModule, ctx android.ModuleContext) (android.Path, android.Path) { // Get the values that came from the global RELEASE_ACONFIG_VALUE_SETS flag - declarationsModules := ctx.GetDirectDepsWithTag(declarationsTag) + declarationsModules := ctx.GetDirectDepsProxyWithTag(declarationsTag) if len(declarationsModules) != 1 { panic("Exactly one aconfig_declarations property required") } diff --git a/aconfig/codegen/rust_aconfig_library.go b/aconfig/codegen/rust_aconfig_library.go index 53818c250..fba7a42f1 100644 --- a/aconfig/codegen/rust_aconfig_library.go +++ b/aconfig/codegen/rust_aconfig_library.go @@ -60,7 +60,7 @@ func (a *aconfigDecorator) GenerateSource(ctx rust.ModuleContext, deps rust.Path generatedDir := android.PathForModuleGen(ctx) generatedSource := android.PathForModuleGen(ctx, "src", "lib.rs") - declarationsModules := ctx.GetDirectDepsWithTag(rustDeclarationsTag) + declarationsModules := ctx.GetDirectDepsProxyWithTag(rustDeclarationsTag) if len(declarationsModules) != 1 { panic(fmt.Errorf("Exactly one aconfig_declarations property required")) -- cgit v1.2.3 From de8e2c967fe238a896c1c33434b0f867e3df50c4 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Mon, 21 Apr 2025 09:39:45 -0700 Subject: Convert ci_tests/ to ModuleProxy Test: all Soong tests pass Change-Id: I9806afc991599d6bbc1d3f161b17de36918be1f6 --- ci_tests/ci_test_package_zip.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci_tests/ci_test_package_zip.go b/ci_tests/ci_test_package_zip.go index 737cca376..e4308fa02 100644 --- a/ci_tests/ci_test_package_zip.go +++ b/ci_tests/ci_test_package_zip.go @@ -186,7 +186,7 @@ func (p *testPackageZip) GenerateAndroidBuildActions(ctx android.ModuleContext) func getAllTestModules(ctx android.ModuleContext) []android.ModuleOrProxy { var ret []android.ModuleOrProxy - ctx.WalkDeps(func(child, parent android.Module) bool { + ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool { if info, ok := android.OtherModuleProvider(ctx, child, android.CommonModuleInfoProvider); !ok || !info.Enabled { return false } -- cgit v1.2.3 From dc39ea4ab1c7e9741090f6bcb8182d3208feacd3 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Mon, 7 Apr 2025 19:55:27 -0700 Subject: Mark cc.Module as FreeModuleAfterGenerateBuildActions Calling ctx.FreeModuleAfterGenerateBuildActions marks cc.Module as only being used by other modules via ModuleProxy and Providers, allowing the cc.Module object to be freed after GenerateBuildActions returns. Any module that visits a cc.Module after this point using a visitor that receives a Module instead of a ModuleProxy will panic. Test: all Soong tests pass Change-Id: I60cb8fe42b63c7038480154214179712b8ae6d91 --- cc/cc.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cc/cc.go b/cc/cc.go index d616978c0..db5d9b116 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -2732,6 +2732,8 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { if !c.hideApexVariantFromMake && !c.Properties.HideFromMake { c.collectSymbolsInfo(ctx) } + + ctx.FreeModuleAfterGenerateBuildActions() } func (c *Module) CleanupAfterBuildActions() { -- cgit v1.2.3 From b5e686bea9482c2f98e9750d7edd458f1633c775 Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Tue, 22 Apr 2025 15:15:50 -0700 Subject: Update the allowlist in the soong only diff test script Removed kernel_version.txt and temporarily added system_ext.img. Test: CI Bug: 409368614 Change-Id: If950169817b14206252e8e25243287a12de5db48 --- scripts/soong_only_diff_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/soong_only_diff_test.py b/scripts/soong_only_diff_test.py index 194378204..8f41f2019 100755 --- a/scripts/soong_only_diff_test.py +++ b/scripts/soong_only_diff_test.py @@ -143,9 +143,9 @@ def move_artifacts_to_subfolder(product: Product, soong_only: bool): SHA_DIFF_ALLOWLIST = { "IMAGES/system.img", + "IMAGES/system_ext.img", # TODO: b/406045340 - Remove from the allowlist once it's fixed "IMAGES/userdata.img", "IMAGES/vbmeta_system.img", - "META/kernel_version.txt", "META/misc_info.txt", "META/vbmeta_digest.txt", "SYSTEM_EXT/etc/vm/trusty_vm/trusty_security_vm.elf", # TODO: b/406045340 - Remove from the allowlist once it's fixed -- cgit v1.2.3 From be20f67bba7ccbae5efca6948177f5855f32112b Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Tue, 22 Apr 2025 11:40:10 -0700 Subject: Add $(build_date_file) support to genrules Similar to https://r.android.com/3225783, this change adds support to depend on `build_date_file` as an order only dependency in genrule modules. Test: m nothing --no-skip-soong-tests Bug: 412461375 Change-Id: I0017762e188f6fd1e6092f977162a351ba303d7b --- android/config.go | 9 ++++++++ android/testing.go | 6 +++++ genrule/genrule.go | 55 +++++++++++++++++++++++++++++++++++++++++++++ genrule/genrule_test.go | 60 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 130 insertions(+) diff --git a/android/config.go b/android/config.go index 2be3270b0..cd53c5883 100644 --- a/android/config.go +++ b/android/config.go @@ -1076,6 +1076,15 @@ func (c *config) BuildThumbprintFile(ctx PathContext) Path { return PathForArbitraryOutput(ctx, "target", "product", *c.deviceNameToInstall, String(c.productVariables.BuildThumbprintFile)) } +func (c *config) BuildDateFile(ctx PathContext) Path { + buildDateFile := c.Getenv("BUILD_DATETIME_FILE") + relPath, err := filepath.Rel(ctx.Config().OutDir(), buildDateFile) + if err != nil { + panic("build_date.txt is outside of OUT_DIR") + } + return PathForArbitraryOutput(ctx, relPath) +} + // DeviceName returns the name of the current device target. // TODO: take an AndroidModuleContext to select the device name for multi-device builds func (c *config) DeviceName() string { diff --git a/android/testing.go b/android/testing.go index dfee70f37..400a7e8de 100644 --- a/android/testing.go +++ b/android/testing.go @@ -1234,6 +1234,12 @@ func SetKatiEnabledForTests(config Config) { config.katiEnabled = true } +func SetBuildDateFileEnvVarForTests() FixturePreparer { + return FixtureModifyConfig(func(config Config) { + config.env["BUILD_DATETIME_FILE"] = filepath.Join(config.outDir, "build_date.txt") + }) +} + func AndroidMkEntriesForTest(t *testing.T, ctx *TestContext, mod Module) []AndroidMkEntries { t.Helper() var p AndroidMkEntriesProvider diff --git a/genrule/genrule.go b/genrule/genrule.go index c2e6ae87c..e497b3212 100644 --- a/genrule/genrule.go +++ b/genrule/genrule.go @@ -179,6 +179,19 @@ type generatorProperties struct { // number. Prefer using libbuildversion via the use_version_lib property on // cc modules. Uses_order_only_build_number_file *bool + + // When set to true, an additional $(build_date_file) label will be available + // to use in the cmd. This will be the location of a text file containing the + // build date. The dependency on this file will be "order-only", meaning that + // the genrule will not rerun when only this file changes, to avoid rerunning + // the genrule every build, because the build date changes every build. + // This also means that you should not attempt to consume the build date from + // the result of this genrule in another build rule. If you do, the build date + // in the second build rule will be stale when the second build rule rebuilds + // but this genrule does not. Only certain allowlisted modules are allowed to + // use this property, usages of the build date should be kept to the absolute + // minimum. + Uses_order_only_build_date_file *bool } type Module struct { @@ -266,6 +279,7 @@ func toolDepsMutator(ctx android.BottomUpMutatorContext) { } var buildNumberAllowlistKey = android.NewOnceKey("genruleBuildNumberAllowlistKey") +var buildDateAllowlistKey = android.NewOnceKey("genruleBuildDateAllowlistKey") // This allowlist should be kept to the bare minimum, it's // intended for things that existed before the build number @@ -297,6 +311,36 @@ func isModuleInBuildNumberAllowlist(ctx android.ModuleContext) bool { return ok } +func isModuleInBuildDateAllowlist(ctx android.ModuleContext) bool { + allowlist := ctx.Config().Once(buildDateAllowlistKey, func() interface{} { + // Define the allowlist as a list and then copy it into a map so that + // gofmt doesn't change unnecessary lines trying to align the values of the map. + allowlist := []string{ + // go/keep-sorted start + "build/soong/tests:gen", + "trusty/vendor/google/aosp/scripts:trusty_desktop_test_vm_arm64.bin", + "trusty/vendor/google/aosp/scripts:trusty_desktop_test_vm_x86_64.bin", + "trusty/vendor/google/aosp/scripts:trusty_desktop_vm_arm64.bin", + "trusty/vendor/google/aosp/scripts:trusty_desktop_vm_x86_64.bin", + "trusty/vendor/google/aosp/scripts:trusty_security_vm_arm64.bin", + "trusty/vendor/google/aosp/scripts:trusty_security_vm_x86_64.elf", + "trusty/vendor/google/aosp/scripts:trusty_test_vm_arm64.bin", + "trusty/vendor/google/aosp/scripts:trusty_test_vm_os_arm64.bin", + "trusty/vendor/google/aosp/scripts:trusty_test_vm_os_x86_64.elf", + "trusty/vendor/google/aosp/scripts:trusty_test_vm_x86_64.elf", + // go/keep-sorted end + } + allowlistMap := make(map[string]bool, len(allowlist)) + for _, a := range allowlist { + allowlistMap[a] = true + } + return allowlistMap + }).(map[string]bool) + + _, ok := allowlist[ctx.ModuleDir()+":"+ctx.ModuleName()] + return ok +} + // generateCommonBuildActions contains build action generation logic // common to both the mixed build case and the legacy case of genrule processing. // To fully support genrule in mixed builds, the contents of this function should @@ -556,6 +600,11 @@ func (g *Module) generateCommonBuildActions(ctx android.ModuleContext) { return reportError("to use the $(build_number_file) label, you must set uses_order_only_build_number_file: true") } return proptools.ShellEscape(cmd.PathForInput(ctx.Config().BuildNumberFile(ctx))), nil + case "build_date_file": + if !proptools.Bool(g.properties.Uses_order_only_build_date_file) { + return reportError("to use the $(build_date_file) label, you must set uses_order_only_build_date_file: true") + } + return proptools.ShellEscape(cmd.PathForInput(ctx.Config().BuildDateFile(ctx))), nil default: if strings.HasPrefix(name, "location ") { label := strings.TrimSpace(strings.TrimPrefix(name, "location ")) @@ -608,6 +657,12 @@ func (g *Module) generateCommonBuildActions(ctx android.ModuleContext) { } cmd.OrderOnly(ctx.Config().BuildNumberFile(ctx)) } + if proptools.Bool(g.properties.Uses_order_only_build_date_file) { + if !isModuleInBuildDateAllowlist(ctx) { + ctx.ModuleErrorf("Only allowlisted modules may use uses_order_only_build_date_file: true") + } + cmd.OrderOnly(ctx.Config().BuildDateFile(ctx)) + } if task.useNsjail { for _, input := range task.dirSrcs { diff --git a/genrule/genrule_test.go b/genrule/genrule_test.go index dcec2971b..25c87bce7 100644 --- a/genrule/genrule_test.go +++ b/genrule/genrule_test.go @@ -1252,6 +1252,66 @@ genrule { } } +func TestGenruleUsesOrderOnlyBuildDateFile(t *testing.T) { + testCases := []struct { + name string + bp string + fs android.MockFS + expectedError string + expectedCommand string + }{ + { + name: "not allowed when not in allowlist", + fs: android.MockFS{ + "foo/Android.bp": []byte(` + genrule { + name: "gen", + uses_order_only_build_date_file: true, + cmd: "cp $(build_date_file) $(out)", + out: ["out.txt"], + } + `), + }, + expectedError: `Only allowlisted modules may use uses_order_only_build_date_file: true`, + }, + { + name: "normal", + fs: android.MockFS{ + "build/soong/tests/Android.bp": []byte(` + genrule { + name: "gen", + uses_order_only_build_date_file: true, + cmd: "cp $(build_date_file) $(out)", + out: ["out.txt"], + } + `), + }, + expectedCommand: `cp BUILD_DATE_FILE __SBOX_SANDBOX_DIR__/out/out.txt`, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + fixtures := android.GroupFixturePreparers( + prepareForGenRuleTest, + android.PrepareForTestWithVisibility, + android.FixtureMergeMockFs(tc.fs), + android.SetBuildDateFileEnvVarForTests(), + ) + if tc.expectedError != "" { + fixtures = fixtures.ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(tc.expectedError)) + } + result := fixtures.RunTest(t) + + if tc.expectedError == "" { + tc.expectedCommand = strings.ReplaceAll(tc.expectedCommand, "BUILD_DATE_FILE", result.Config.OutDir()+"/build_date.txt") + gen := result.Module("gen", "").(*Module) + android.AssertStringEquals(t, "raw commands", tc.expectedCommand, gen.rawCommands[0]) + } + }) + } +} + type testTool struct { android.ModuleBase outputFile android.Path -- cgit v1.2.3 From f9a2de5799a65b9738db51ad0ac1a439cb6e7bdf Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Fri, 18 Apr 2025 22:04:04 +0000 Subject: Skip installing ApexSystemServer dexpreopt in soong-only Override variants of apexes with system server jars do not emit installation rules for dexpreopt artifacts. This prevents conflict with the non override variant. They do call ctx.PackageFile so that these do not get skipped from packaging. This causes issues in Soong only builds because `android_device` tries to copy these files to PRODUCT_OUT causing duplicate installation rules. To prevent this, skip creating the installation rule in the base variant for soong-only builds. Bug: 410570253 Test: lunch cf_x86_64_phone-trunk_staging-userdebug Test: m --soong-only Change-Id: I3692cbca4076602093eaf5f89d171c82bdcc0749 --- apex/builder.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apex/builder.go b/apex/builder.go index 3fda3c5f4..1f2f5b41a 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -579,7 +579,10 @@ func (a *apexBundle) installApexSystemServerFiles(ctx android.ModuleContext) { for _, fi := range a.filesInfo { for _, install := range fi.systemServerDexpreoptInstalls { var installedFile android.InstallPath - if performInstalls { + if performInstalls && ctx.Config().KatiEnabled() { + // android_device will create the install rule in soong-only builds. + // Skip creating the installation rule from the base variant + // in soong-only builds to prevent duplicate installation rules. installedFile = ctx.InstallFile(install.InstallDirOnDevice, install.InstallFileOnDevice, install.OutputPathOnHost) } else { // Another module created the install rules, but this module should still depend on -- cgit v1.2.3 From 13e955d202a6a58c20e9888dc0591d008215a418 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= Date: Tue, 22 Apr 2025 15:07:44 -0700 Subject: android/rule_builder.go: Add OrderOnlys bind mounts OrderOnlys were unaccessible in nsjail builds Bug: 412749002 Test: m trusty_security_vm_x86_64.elf and check version in image Change-Id: I37ba5195541b4b3f4c61319119bb966fbad6c4ca --- android/rule_builder.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/android/rule_builder.go b/android/rule_builder.go index 3b6189ae3..642d8e6cc 100644 --- a/android/rule_builder.go +++ b/android/rule_builder.go @@ -634,6 +634,9 @@ func (r *RuleBuilder) build(name string, desc string) { for _, input := range inputs { addBindMount(input.String(), r.nsjailPathForInputRel(input)) } + for _, input := range r.OrderOnlys() { + addBindMount(input.String(), r.nsjailPathForInputRel(input)) + } for _, tool := range tools { addBindMount(tool.String(), nsjailPathForToolRel(r.ctx, tool)) } -- cgit v1.2.3 From 0ac8c545a087e49248cb018f8026c01ad01f51f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= Date: Tue, 22 Apr 2025 15:10:49 -0700 Subject: genrule/genrule.go: Add trusty builds to BuildNumber Allowlist Bug: 412749002 Test: m trusty_security_vm_x86_64.elf and check version in image Change-Id: I0587319b5fa6eac3d433471ddfea31c0543d65d9 --- genrule/genrule.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/genrule/genrule.go b/genrule/genrule.go index e497b3212..64ad58322 100644 --- a/genrule/genrule.go +++ b/genrule/genrule.go @@ -296,6 +296,17 @@ func isModuleInBuildNumberAllowlist(ctx android.ModuleContext) bool { "build/soong/tests:gen", "hardware/google/camera/common/hal/aidl_service:aidl_camera_build_version", "tools/tradefederation/core:tradefed_zip", + "trusty/vendor/google/aosp/scripts:trusty_desktop_test_vm_arm64.bin", + "trusty/vendor/google/aosp/scripts:trusty_desktop_test_vm_x86_64.bin", + "trusty/vendor/google/aosp/scripts:trusty_desktop_vm_arm64.bin", + "trusty/vendor/google/aosp/scripts:trusty_desktop_vm_x86_64.bin", + "trusty/vendor/google/aosp/scripts:trusty_security_vm_arm64.bin", + "trusty/vendor/google/aosp/scripts:trusty_security_vm_x86_64.elf", + "trusty/vendor/google/aosp/scripts:trusty_tee_package", + "trusty/vendor/google/aosp/scripts:trusty_test_vm_arm64.bin", + "trusty/vendor/google/aosp/scripts:trusty_test_vm_os_arm64.bin", + "trusty/vendor/google/aosp/scripts:trusty_test_vm_os_x86_64.elf", + "trusty/vendor/google/aosp/scripts:trusty_test_vm_x86_64.elf", "vendor/google/services/LyricCameraHAL/src/apex:com.google.pixel.camera.hal.manifest", "vendor/google_tradefederation/core:gen_google_tradefed_zip", // go/keep-sorted end -- cgit v1.2.3 From 2e1aa9610973726cbfccb47a0615675ad1e6cc89 Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Tue, 22 Apr 2025 17:09:45 -0700 Subject: Print diffs even if allowlisted in soong only diff test So that regressions are not shadowed by the allowlist. Test: CI Bug: 409368614 Change-Id: I00e6aef5910691b066459451f54ddfeaa53face6 --- scripts/soong_only_diff_test.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/scripts/soong_only_diff_test.py b/scripts/soong_only_diff_test.py index 8f41f2019..a78bdb09e 100755 --- a/scripts/soong_only_diff_test.py +++ b/scripts/soong_only_diff_test.py @@ -158,17 +158,18 @@ def compare_sha_maps(soong_only_map: dict[str, bytes], soong_plus_make_map: dict all_keys = list(soong_only_map.keys() | soong_plus_make_map.keys()) all_identical = True for key in all_keys: - if key in SHA_DIFF_ALLOWLIST: - continue + allowlisted = key in SHA_DIFF_ALLOWLIST + allowlisted_str = "ALLOWLISTED" if allowlisted else "NOT ALLOWLISTED" + file = None if allowlisted else sys.stderr if key not in soong_only_map: - print(f'{key} not found in soong only build target_files.zip', file=sys.stderr) - all_identical = False + print(f'{key} not found in soong only build target_files.zip ({allowlisted_str})', file=file) + all_identical = all_identical and allowlisted elif key not in soong_plus_make_map: - print(f'{key} not found in soong plus make build target_files.zip', file=sys.stderr) - all_identical = False + print(f'{key} not found in soong plus make build target_files.zip ({allowlisted_str})', file=file) + all_identical = all_identical and allowlisted elif soong_only_map[key] != soong_plus_make_map[key]: - print(f'{key} sha value differ between soong only build and soong plus make build', file=sys.stderr) - all_identical = False + print(f'{key} sha value differ between soong only build and soong plus make build ({allowlisted_str})', file=file) + all_identical = all_identical and allowlisted return all_identical -- cgit v1.2.3 From 3f23922ae3d24858c6a1df659ffdff9396114560 Mon Sep 17 00:00:00 2001 From: Zhi Dou Date: Fri, 18 Apr 2025 20:38:27 +0000 Subject: make automatic jarjar to all flags in framework jar This change remove the limitation that automatic jarjar that only applies for flags with declaration having exportable: true. This change enable automatic jarjar for all flag classes in a java_library if it has jarjar_prefix. This change also changes the jarjar_profix rule propagation logic. If a module has sdk_level == test_current, then it won't collect jarjar rule so it won't propagate the jarjar rule up. Test: m Bug: 411715086 Change-Id: Ib21fd71ef1610a914014c39fddf921aa9dcf550b --- aconfig/codegen/java_aconfig_library.go | 22 ++++++---------------- java/base.go | 9 +++++++++ 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/aconfig/codegen/java_aconfig_library.go b/aconfig/codegen/java_aconfig_library.go index bb734a02d..1d1a2822f 100644 --- a/aconfig/codegen/java_aconfig_library.go +++ b/aconfig/codegen/java_aconfig_library.go @@ -91,12 +91,6 @@ func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) GenerateSourceJarBuild ctx.PropertyErrorf("mode", "%q is not a supported mode", mode) } - if mode == "exported" && !declarations.Exportable { - // if mode is exported, the corresponding aconfig_declaration must mark its - // exportable property true - ctx.PropertyErrorf("mode", "exported mode requires its aconfig_declaration has exportable prop true") - } - ctx.Build(pctx, android.BuildParams{ Rule: javaRule, Input: declarations.IntermediateCacheOutputPath, @@ -107,16 +101,12 @@ func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) GenerateSourceJarBuild }, }) - if declarations.Exportable { - // Mark our generated code as possibly needing jarjar repackaging - // The repackaging only happens when the corresponding aconfig_declaration - // has property exportable true - module.AddJarJarRenameRule(declarations.Package+".Flags", "") - module.AddJarJarRenameRule(declarations.Package+".FeatureFlags", "") - module.AddJarJarRenameRule(declarations.Package+".FeatureFlagsImpl", "") - module.AddJarJarRenameRule(declarations.Package+".CustomFeatureFlags", "") - module.AddJarJarRenameRule(declarations.Package+".FakeFeatureFlagsImpl", "") - } + // jarjar all flag classes if the java_library set jarjar_prefix + module.AddJarJarRenameRule(declarations.Package+".Flags", "") + module.AddJarJarRenameRule(declarations.Package+".FeatureFlags", "") + module.AddJarJarRenameRule(declarations.Package+".FeatureFlagsImpl", "") + module.AddJarJarRenameRule(declarations.Package+".CustomFeatureFlags", "") + module.AddJarJarRenameRule(declarations.Package+".FakeFeatureFlagsImpl", "") android.SetProvider(ctx, android.CodegenInfoProvider, android.CodegenInfo{ AconfigDeclarations: []string{declarationsModules[0].Name()}, diff --git a/java/base.go b/java/base.go index af3d493a1..f7d25dd14 100644 --- a/java/base.go +++ b/java/base.go @@ -2920,6 +2920,15 @@ func (this Module) GetDebugString() string { // Merge the jarjar rules we inherit from our dependencies, any that have been added directly to // us, and if it's been set, apply the jarjar_prefix property to rename them. func (module *Module) collectJarJarRules(ctx android.ModuleContext) *JarJarProviderData { + + // Stop collect jarjar_prefix jarjar rules if the module has test sdk scope. + // If a module uses test API scope, which means in its source code and static dependencies + // it could only use API exposed through the test surface. So it should not apply the jarjar + // rules set by any bootclass path jar + if module.SdkVersion(ctx).Kind == android.SdkTest { + return nil + } + // Gather repackage information from deps result := collectDirectDepsProviders(ctx) -- cgit v1.2.3 From 23f2680a4fb23fc9f1d639e8866a7b617ec06249 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= Date: Tue, 22 Apr 2025 19:45:32 -0700 Subject: genrule/genrule.go: Add missing trusty build to BuildDate Allowlist Bug: 412749002 Test: build qemu_trusty_arm64-trunk_staging-userdebug Change-Id: I16a8b763c211fa93feeb4054d234a6ecd7c3aedf --- genrule/genrule.go | 1 + 1 file changed, 1 insertion(+) diff --git a/genrule/genrule.go b/genrule/genrule.go index 64ad58322..f92cfee5e 100644 --- a/genrule/genrule.go +++ b/genrule/genrule.go @@ -335,6 +335,7 @@ func isModuleInBuildDateAllowlist(ctx android.ModuleContext) bool { "trusty/vendor/google/aosp/scripts:trusty_desktop_vm_x86_64.bin", "trusty/vendor/google/aosp/scripts:trusty_security_vm_arm64.bin", "trusty/vendor/google/aosp/scripts:trusty_security_vm_x86_64.elf", + "trusty/vendor/google/aosp/scripts:trusty_tee_package", "trusty/vendor/google/aosp/scripts:trusty_test_vm_arm64.bin", "trusty/vendor/google/aosp/scripts:trusty_test_vm_os_arm64.bin", "trusty/vendor/google/aosp/scripts:trusty_test_vm_os_x86_64.elf", -- cgit v1.2.3 From 41466dec04d0ca592d73d0a172b079bb7b162783 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Kongstad?= Date: Tue, 8 Apr 2025 19:10:43 +0200 Subject: finalized-flags.txt: use metalava's flag-report as source of truth The record-finalized-flags tool no longer greps through the signature files itself. Instead, it reads the output of `metalava flag-report`. Update the build rule for finalized-flags.txt to sequentially call - aconfig-to-metalava-flags - metalava flag-report - record-finalized-flags Bug: 404452062 Test: croot build/soong/aconfig && go test . Test: m out/soong/.intermediates/finalized-flags.txt && head out/soong/.intermediates/finalized-flags.txt Change-Id: I34db52c8fea001959fbc1818983ab0b63a3b40bc --- aconfig/all_aconfig_declarations.go | 29 ++++++++++++++-------- aconfig/all_aconfig_declarations_extension_test.go | 2 +- aconfig/init.go | 9 ------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/aconfig/all_aconfig_declarations.go b/aconfig/all_aconfig_declarations.go index 4165d2447..22e26f05c 100644 --- a/aconfig/all_aconfig_declarations.go +++ b/aconfig/all_aconfig_declarations.go @@ -112,16 +112,25 @@ func GenerateFinalizedFlagsForApiSurface(ctx android.ModuleContext, outputPath a } finalizedFlagsFile := android.PathForModuleSrc(ctx, apiSurface.Finalized_flags_file) - ctx.Build(pctx, android.BuildParams{ - Rule: RecordFinalizedFlagsRule, - Inputs: append(apiSignatureFiles, finalizedFlagsFile, parsedFlagsFile), - Output: outputPath, - Args: map[string]string{ - "api_signature_files": android.JoinPathsWithPrefix(apiSignatureFiles, "--api-signature-file "), - "finalized_flags_file": "--finalized-flags-file " + finalizedFlagsFile.String(), - "parsed_flags_file": "--parsed-flags-file " + parsedFlagsFile.String(), - }, - }) + intermediateMetalavaFlagsConfig := android.PathForModuleOut(ctx, "metalava-flags.config") + intermediateFlagReport := android.PathForModuleOut(ctx, "metalava-flag-report.csv") + builder := android.NewRuleBuilder(pctx, ctx) + builder.Command(). + BuiltTool("aconfig-to-metalava-flags"). + Input(parsedFlagsFile). + FlagWithOutput("> ", intermediateMetalavaFlagsConfig) + builder.Command(). + BuiltTool("metalava"). + Flag("flag-report"). + FlagWithInput("--config-file ", intermediateMetalavaFlagsConfig). + FlagWithOutput("--output-file ", intermediateFlagReport). + Inputs(apiSignatureFiles) + builder.Command(). + BuiltTool("record-finalized-flags"). + FlagWithInput("--finalized-flags ", finalizedFlagsFile). + FlagWithInput("--flag-report ", intermediateFlagReport). + FlagWithOutput("> ", outputPath) + builder.Build("finalized-flags", "Record all aconfig flags used with finalized @FlaggedApi APIs") } func GenerateExportedFlagCheck(ctx android.ModuleContext, outputPath android.WritablePath, diff --git a/aconfig/all_aconfig_declarations_extension_test.go b/aconfig/all_aconfig_declarations_extension_test.go index 5bd99d0c9..6a82af161 100644 --- a/aconfig/all_aconfig_declarations_extension_test.go +++ b/aconfig/all_aconfig_declarations_extension_test.go @@ -46,5 +46,5 @@ func TestAllAconfigDeclarationsExtension(t *testing.T) { `) finalizedFlags := result.ModuleForTests(t, "custom_aconfig_declarations", "").Output("finalized-flags.txt") - android.AssertStringContainsEquals(t, "must depend on all_aconfig_declarations", strings.Join(finalizedFlags.Inputs.Strings(), " "), "all_aconfig_declarations.pb", true) + android.AssertStringContainsEquals(t, "must (implicitly) depend on all_aconfig_declarations", strings.Join(finalizedFlags.Implicits.Strings(), " "), "all_aconfig_declarations.pb", true) } diff --git a/aconfig/init.go b/aconfig/init.go index 5c053978a..85f75150c 100644 --- a/aconfig/init.go +++ b/aconfig/init.go @@ -99,14 +99,6 @@ var ( "${aconfig}", }, }, "container", "cache_files", "version") - - RecordFinalizedFlagsRule = pctx.AndroidStaticRule("RecordFinalizedFlagsRule", - blueprint.RuleParams{ - Command: `${record-finalized-flags} ${parsed_flags_file} ${finalized_flags_file} ${api_signature_files} > ${out}`, - CommandDeps: []string{ - "${record-finalized-flags}", - }, - }, "api_signature_files", "finalized_flags_file", "parsed_flags_file") ExportedFlagCheckRule = pctx.AndroidStaticRule("ExportedFlagCheckRule", blueprint.RuleParams{ Command: `${exported-flag-check} validate-exported-flags ` + @@ -163,7 +155,6 @@ func init() { RegisterBuildComponents(android.InitRegistrationContext) pctx.HostBinToolVariable("aconfig", "aconfig") pctx.HostBinToolVariable("soong_zip", "soong_zip") - pctx.HostBinToolVariable("record-finalized-flags", "record-finalized-flags") pctx.HostBinToolVariable("exported-flag-check", "exported-flag-check") } -- cgit v1.2.3 From 024e8004d8c7955d830844dadd39349a4c323973 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Wed, 16 Apr 2025 23:51:55 +0000 Subject: Validate required entries This will be useful to catch incorrect usages like ag/33112829 Note that the enforcement will be on the equivalent `LOCAL_MODULE` value and not `name` as it appears in Android.bp. However, this enforcement is close enough. Test: m nothing Change-Id: If4a92e731c551c33258f022d50de66441f5d6ddb --- android/module.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/android/module.go b/android/module.go index 8ef7a44d6..221ca20cc 100644 --- a/android/module.go +++ b/android/module.go @@ -1045,6 +1045,9 @@ func (m *ModuleBase) baseOverridablePropertiesDepsMutator(ctx BottomUpMutatorCon // addRequiredDeps adds required, target_required, and host_required as dependencies. func addRequiredDeps(ctx BottomUpMutatorContext) { addDep := func(target Target, depName string) { + if !blueprint.IsValidModuleName(depName) { + ctx.PropertyErrorf("required", "%s is not a valid module", depName) + } if !ctx.OtherModuleExists(depName) { if ctx.Config().AllowMissingDependencies() { return -- cgit v1.2.3 From ca4725c65eb82f7ac853fcfb816dffbbcb9c3b37 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Wed, 23 Apr 2025 12:49:07 -0700 Subject: Rename host_first_src to host_first_srcs To be consistent with the other srcs properties. Bug: 393164499 Test: m nothing Change-Id: I6d8961dae6aaa948bafd6dfc4d5d1bcf4c58afcd --- genrule/genrule.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/genrule/genrule.go b/genrule/genrule.go index c2e6ae87c..c8bba123e 100644 --- a/genrule/genrule.go +++ b/genrule/genrule.go @@ -157,7 +157,7 @@ type generatorProperties struct { Common_os_srcs proptools.Configurable[[]string] `android:"path_common_os"` // Same as srcs, but will add dependencies on modules via for host os variation. - Host_first_src proptools.Configurable[[]string] `android:"path_host_first"` + Host_first_srcs proptools.Configurable[[]string] `android:"path_host_first"` // input files to exclude Exclude_srcs []string `android:"path,arch_variant"` @@ -456,7 +456,7 @@ func (g *Module) generateCommonBuildActions(ctx android.ModuleContext) { srcFiles = append(srcFiles, addLabelsForInputs("device_first_srcs", g.properties.Device_first_srcs.GetOrDefault(ctx, nil), nil)...) srcFiles = append(srcFiles, addLabelsForInputs("device_common_srcs", g.properties.Device_common_srcs.GetOrDefault(ctx, nil), nil)...) srcFiles = append(srcFiles, addLabelsForInputs("common_os_srcs", g.properties.Common_os_srcs.GetOrDefault(ctx, nil), nil)...) - srcFiles = append(srcFiles, addLabelsForInputs("host_first_src", g.properties.Host_first_src.GetOrDefault(ctx, nil), nil)...) + srcFiles = append(srcFiles, addLabelsForInputs("host_first_src", g.properties.Host_first_srcs.GetOrDefault(ctx, nil), nil)...) var copyFrom android.Paths var outputFiles android.WritablePaths -- cgit v1.2.3 From 93cafc3ab0ad00bd01ab705094aaac4ec74b34e1 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Wed, 23 Apr 2025 12:39:23 -0700 Subject: Add product copy files information to compliance ...in soong-only builds. This is a re-implementation of ag/32804637. Bug: 406019430 Bug: 406020107 Bug: 406021517 Test: Diff'd sbom before/after, saw some NOASSERTIONS change to LicenseRef-Android-Apache-2.0 Change-Id: Ia8591ff6fd8c6ed0f875a0562c97489995fd29e2 --- android/compliance_metadata.go | 21 +++++++++++++++++++++ etc/prebuilt_etc.go | 23 +++++++++++++++++++++++ filesystem/Android.bp | 1 + filesystem/android_device.go | 10 ++++++++++ fsgen/prebuilt_etc_modules_gen.go | 3 +++ 5 files changed, 58 insertions(+) diff --git a/android/compliance_metadata.go b/android/compliance_metadata.go index 032161b22..a595f6d78 100644 --- a/android/compliance_metadata.go +++ b/android/compliance_metadata.go @@ -133,6 +133,7 @@ type ComplianceMetadataInfo struct { filesContained []string prebuiltFilesCopied []string platformGeneratedFiles []string + productCopyFiles []string kernelModuleCopyFiles []string } @@ -142,6 +143,7 @@ type complianceMetadataInfoGob struct { PrebuiltFilesCopied []string PlatformGeneratedFiles []string KernelModuleCopyFiles []string + ProductCopyFiles []string } func NewComplianceMetadataInfo() *ComplianceMetadataInfo { @@ -151,6 +153,7 @@ func NewComplianceMetadataInfo() *ComplianceMetadataInfo { prebuiltFilesCopied: make([]string, 0), platformGeneratedFiles: make([]string, 0), kernelModuleCopyFiles: make([]string, 0), + productCopyFiles: make([]string, 0), } } @@ -161,6 +164,7 @@ func (m *ComplianceMetadataInfo) ToGob() *complianceMetadataInfoGob { PrebuiltFilesCopied: m.prebuiltFilesCopied, PlatformGeneratedFiles: m.platformGeneratedFiles, KernelModuleCopyFiles: m.kernelModuleCopyFiles, + ProductCopyFiles: m.productCopyFiles, } } @@ -170,6 +174,7 @@ func (m *ComplianceMetadataInfo) FromGob(data *complianceMetadataInfoGob) { m.prebuiltFilesCopied = data.PrebuiltFilesCopied m.platformGeneratedFiles = data.PlatformGeneratedFiles m.kernelModuleCopyFiles = data.KernelModuleCopyFiles + m.productCopyFiles = data.ProductCopyFiles } func (c *ComplianceMetadataInfo) GobEncode() ([]byte, error) { @@ -215,6 +220,14 @@ func (c *ComplianceMetadataInfo) GetPlatformGeneratedFiles() []string { return c.platformGeneratedFiles } +func (c *ComplianceMetadataInfo) SetProductCopyFiles(files []string) { + c.productCopyFiles = files +} + +func (c *ComplianceMetadataInfo) GetProductCopyFiles() []string { + return c.productCopyFiles +} + func (c *ComplianceMetadataInfo) SetKernelModuleCopyFiles(files []string) { c.kernelModuleCopyFiles = files } @@ -404,6 +417,12 @@ func (c *complianceMetadataSingleton) GenerateBuildActions(ctx SingletonContext) destToKernelModuleMap[pair[1]] = p } + destToProductCopyFiles := make(map[string]string) + for _, pcf := range metadataInfo.GetProductCopyFiles() { + pair := strings.Split(pcf, ":") + destToProductCopyFiles[pair[1]] = pcf + } + csvHeaders := "installed_file,module_path,is_soong_module,is_prebuilt_make_module,product_copy_files,kernel_module_copy_files,is_platform_generated,static_libs,whole_static_libs,license_text" csvContent := make([]string, 0, len(allFiles)+1) csvContent = append(csvContent, csvHeaders) @@ -415,6 +434,8 @@ func (c *complianceMetadataSingleton) GenerateBuildActions(ctx SingletonContext) csvContent = append(csvContent, file+",,,,,,Y,,,build/soong/licenses/LICENSE") } else if km, ok := destToKernelModuleMap[file]; ok { csvContent = append(csvContent, file+",,,,,"+km+",,,,") + } else if p, ok := destToProductCopyFiles[file]; ok { + csvContent = append(csvContent, file+",,,,"+p+",,,,,") } else { csvContent = append(csvContent, file+",,Y,,,,,,,") } diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go index a2efa637a..cccaa3690 100644 --- a/etc/prebuilt_etc.go +++ b/etc/prebuilt_etc.go @@ -107,6 +107,14 @@ type PrebuiltEtcInfo struct { var PrebuiltEtcInfoProvider = blueprint.NewProvider[PrebuiltEtcInfo]() +// If this provider is set, it means this module was converted from PRODUCT_COPY_FILES +type ProductCopyFilesModuleInfo struct { + // The entries as they would've appeared in PRODUCT_COPY_FILES, that is, src:dst + ProductCopyFileEntries []string +} + +var ProductCopyFilesModuleProvider = blueprint.NewProvider[ProductCopyFilesModuleInfo]() + var PrepareForTestWithPrebuiltEtc = android.FixtureRegisterWithContext(RegisterPrebuiltEtcBuildComponents) type PrebuiltEtcProperties struct { @@ -155,6 +163,11 @@ type PrebuiltEtcProperties struct { // Install to partition oem when set to true. Oem_specific *bool `android:"arch_variant"` + + // If this prebuilt_* module was auto-generated from a PRODUCT_COPY_FILES entry. + // Used for licensing/compliance/SBOM, as some legacy methods of specifying licenses were + // specific to PRODUCT_COPY_FILES. + From_product_copy_files *bool } // Dsts is useful in that it allows prebuilt_* modules to easily map the source files to the @@ -531,6 +544,16 @@ func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.SetOutputFiles(p.outputFilePaths.Paths(), "") SetCommonPrebuiltEtcInfo(ctx, p) + + if proptools.Bool(p.properties.From_product_copy_files) { + entries := make([]string, 0, len(installs)) + for _, install := range installs { + entries = append(entries, fmt.Sprintf("%s:%s", install.sourceFilePath, filepath.Join(install.installDirPath.String(), install.filename))) + } + android.SetProvider(ctx, ProductCopyFilesModuleProvider, ProductCopyFilesModuleInfo{ + ProductCopyFileEntries: entries, + }) + } } func SetCommonPrebuiltEtcInfo(ctx android.ModuleContext, p PrebuiltEtcModule) { diff --git a/filesystem/Android.bp b/filesystem/Android.bp index cb76df2d9..4b3780ae6 100644 --- a/filesystem/Android.bp +++ b/filesystem/Android.bp @@ -9,6 +9,7 @@ bootstrap_go_package { "blueprint", "soong", "soong-android", + "soong-etc", "soong-bpf", // for testing "soong-java", // for testing "soong-linkerconfig", diff --git a/filesystem/android_device.go b/filesystem/android_device.go index 4f6950f34..f2fb14885 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -25,6 +25,7 @@ import ( "sync/atomic" "android/soong/android" + "android/soong/etc" "android/soong/java" "github.com/google/blueprint" @@ -319,6 +320,15 @@ func (a *androidDevice) GenerateAndroidBuildActions(ctx android.ModuleContext) { buildComplianceMetadata(ctx, filesystemDepTag) } + complianceMetadataInfo := ctx.ComplianceMetadataInfo() + pcf := complianceMetadataInfo.GetProductCopyFiles() + for _, m := range allInstalledModules { + if info, ok := android.OtherModuleProvider(ctx, m, etc.ProductCopyFilesModuleProvider); ok { + pcf = append(pcf, info.ProductCopyFileEntries...) + } + } + complianceMetadataInfo.SetProductCopyFiles(pcf) + // Add the host tools as deps if !ctx.Config().KatiEnabled() && proptools.Bool(a.deviceProps.Main_device) { for _, hostTool := range ctx.Config().ProductVariables().ProductHostPackages { diff --git a/fsgen/prebuilt_etc_modules_gen.go b/fsgen/prebuilt_etc_modules_gen.go index b675b0dc0..61788769c 100644 --- a/fsgen/prebuilt_etc_modules_gen.go +++ b/fsgen/prebuilt_etc_modules_gen.go @@ -157,6 +157,8 @@ func processProductCopyFiles(ctx android.LoadHookContext) map[string]*prebuiltSr type prebuiltModuleProperties struct { Name *string + From_product_copy_files *bool + Soc_specific *bool Product_specific *bool System_ext_specific *bool @@ -283,6 +285,7 @@ func prebuiltEtcModuleProps(ctx android.LoadHookContext, moduleName, partition, } } + moduleProps.From_product_copy_files = proptools.BoolPtr(true) moduleProps.No_full_install = proptools.BoolPtr(true) moduleProps.NamespaceExportedToMake = true moduleProps.Visibility = []string{"//visibility:public"} -- cgit v1.2.3 From 2d307abdaffd1f2ca569eb746a1068d183353de2 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Wed, 23 Apr 2025 00:49:37 +0000 Subject: Introduce ndk_translation_package module type This will package native bridge prebuilts and build files (Android.bp,product.mk). It will use ctx.MultiTargets to get both the device arch and the native arch targets. A summary of the properties - Native_bridge_deps: A dependency will be created to both native arches (e.g. arm and arm64) - Device_*_deps: A dependency will be created to the requested device arch. e.g. both will create a dep to 32 and 64, while 64 will create a dep to 64 only - Device_*_extra_allowed_deps will not be packaged, but will be used as inputs to generate product.mk files Bug: 411745985 Test: Built the file locally Test: The file is identical expect one missing line in product*mk "system/lib64/libclcore_neon.bc" This is likely more correct since libclcore_neon.bc is 32 only Change-Id: I1a8372f213867578a4d1cedfccf98cb2c75c1b8e --- cc/Android.bp | 2 + cc/ndk_translation_package.go | 230 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 232 insertions(+) create mode 100644 cc/ndk_translation_package.go diff --git a/cc/Android.bp b/cc/Android.bp index 1ac5a4a8f..0643c826f 100644 --- a/cc/Android.bp +++ b/cc/Android.bp @@ -75,6 +75,8 @@ bootstrap_go_package { "ndk_library.go", "ndk_sysroot.go", + "ndk_translation_package.go", + "llndk_library.go", "kernel_headers.go", diff --git a/cc/ndk_translation_package.go b/cc/ndk_translation_package.go new file mode 100644 index 000000000..db0879099 --- /dev/null +++ b/cc/ndk_translation_package.go @@ -0,0 +1,230 @@ +// 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 cc + +import ( + "android/soong/android" + "path/filepath" + "strings" + + "github.com/google/blueprint" + "github.com/google/blueprint/proptools" +) + +func init() { + android.RegisterModuleType("ndk_translation_package", NdkTranslationPackageFactory) +} + +func NdkTranslationPackageFactory() android.Module { + module := &ndkTranslationPackage{} + module.AddProperties(&module.properties) + android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) + return module +} + +type ndkTranslationPackage struct { + android.ModuleBase + properties ndkTranslationPackageProperties +} + +type ndkTranslationPackageProperties struct { + // Dependencies with native bridge variants that should be packaged. + // (e.g. arm and arm64 on an x86_64 device) + Native_bridge_deps []string + // Non-native bridge variants that should be packaged. + // (e.g. x86 and x86_64 on an x86_64 device) + Device_both_deps []string + // Non-native bridge variants with lib64 that should be packaged. + // (e.g. x86_64 on an x86_64 device) + Device_64_deps []string + // Non-native bridge variants with lib32 that should be packaged. + // (e.g. x86 on an x86_64 device) + Device_32_deps []string + // Non-native bridge variants whose first variant should be packaged. + Device_first_deps []string + // Non-native bridge variants whose first variant should be packaged, + // but always into lib/, bin/ directories. + Device_first_to_32_deps []string + // Non-native bridge variants that should _not_ be packaged, but + // used as inputs to generate Android.mk and product.mk + Device_both_extra_allowed_deps []string + Device_32_extra_allowed_deps []string + + // Version to use in generating the new sysprops + Version *string + + // Path to Android.bp generator + Android_bp_gen_path *string + + // Path to product.mk generator + Product_mk_gen_path *string +} + +type ndkTranslationPackageDepTag struct { + blueprint.DependencyTag + name string +} + +func (_ ndkTranslationPackageDepTag) ExcludeFromVisibilityEnforcement() {} + +var ( + ndkTranslationPackageTag = ndkTranslationPackageDepTag{name: "dep"} + ndkTranslationPackageFirstTo32SrcsTag = ndkTranslationPackageDepTag{name: "first_to_32"} + ndkTranslationExtraAllowedDepsTag = ndkTranslationPackageDepTag{name: "extra_allowed_deps"} +) + +func (n *ndkTranslationPackage) DepsMutator(ctx android.BottomUpMutatorContext) { + for index, t := range ctx.MultiTargets() { + if t.NativeBridge == android.NativeBridgeEnabled { + ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationPackageTag, n.properties.Native_bridge_deps...) + } else if t.Arch.ArchType == android.X86_64 { + ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationPackageTag, n.properties.Device_64_deps...) + ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationPackageTag, n.properties.Device_both_deps...) + ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationExtraAllowedDepsTag, n.properties.Device_both_extra_allowed_deps...) + } else if t.Arch.ArchType == android.X86 { + ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationPackageTag, n.properties.Device_32_deps...) + ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationPackageTag, n.properties.Device_both_deps...) + ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationExtraAllowedDepsTag, n.properties.Device_both_extra_allowed_deps...) + ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationExtraAllowedDepsTag, n.properties.Device_32_extra_allowed_deps...) + } + if index == 0 { // Primary arch + ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationPackageTag, n.properties.Device_first_deps...) + ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationPackageFirstTo32SrcsTag, n.properties.Device_first_to_32_deps...) + } + } +} + +func (n *ndkTranslationPackage) GenerateAndroidBuildActions(ctx android.ModuleContext) { + var files []android.PackagingSpec // both arches + var files64 []android.PackagingSpec // 64 only + var extraFiles []android.PackagingSpec + var extraFiles64 []android.PackagingSpec + + ctx.VisitDirectDepsProxy(func(child android.ModuleProxy) { + tag := ctx.OtherModuleDependencyTag(child) + info := android.OtherModuleProviderOrDefault(ctx, child, android.InstallFilesProvider) + commonInfo := android.OtherModulePointerProviderOrDefault(ctx, child, android.CommonModuleInfoProvider) + if tag == ndkTranslationExtraAllowedDepsTag { + extraFiles = append(extraFiles, info.PackagingSpecs...) + if commonInfo.Target.Arch.ArchType == android.X86_64 || commonInfo.Target.Arch.ArchType == android.Arm64 { + extraFiles64 = append(extraFiles64, info.PackagingSpecs...) + } + return + } + files = append(files, info.PackagingSpecs...) + if (commonInfo.Target.Arch.ArchType == android.X86_64 || commonInfo.Target.Arch.ArchType == android.Arm64) && tag != ndkTranslationPackageFirstTo32SrcsTag { + files64 = append(files64, info.PackagingSpecs...) + } + }) + outBp := n.genAndroidBp(ctx, files) + outArm64ArmMk, outArm64Mk := n.genProductMk(ctx, files, files64, extraFiles, extraFiles64) + + outZip := android.PathForModuleOut(ctx, "ndk_translation_package.zip") + builder := android.NewRuleBuilder(pctx, ctx) + cmd := builder.Command(). + BuiltTool("soong_zip"). + FlagWithOutput("-o ", outZip) + for _, buildFile := range []android.Path{outBp, outArm64ArmMk, outArm64Mk} { + cmd. + FlagWithArg("-C ", filepath.Dir(buildFile.String())). + FlagWithInput("-f ", buildFile) + } + for _, file := range files { + // Copy to relative path inside the zip + cmd. + FlagWithArg("-e ", "system/"+file.RelPathInPackage()). + FlagWithInput("-f ", file.SrcPath()) + } + + builder.Build("ndk_translation_package.zip", "Build ndk_translation_package") + + ctx.CheckbuildFile(outZip) + ctx.DistForGoal("ndk_translation_package", outZip) +} + +// Creates a build rule to generate Android.bp and returns path of the generated file. +func (n *ndkTranslationPackage) genAndroidBp(ctx android.ModuleContext, files []android.PackagingSpec) android.Path { + genDir := android.PathForModuleOut(ctx, "android_bp_dir") + generator := android.PathForModuleSrc(ctx, proptools.String(n.properties.Android_bp_gen_path)) + builder := android.NewRuleBuilder(pctx, ctx).Sbox( + genDir, + android.PathForModuleOut(ctx, "Android.bp.sbox.textproto"), + ) + outBp := genDir.Join(ctx, "Android.bp") + builder.Command(). + Input(generator). + Implicits(specsToSrcPaths(files)). + Flag(strings.Join(filesRelativeToInstallDir(ctx, files), " ")). + FlagWithOutput("> ", outBp) + builder.Build("ndk_translation_package.Android.bp", "Build ndk_translation_package Android.bp") + + return outBp +} + +// Creates a build rule to generate product.mk and returns path of the generated files +func (n *ndkTranslationPackage) genProductMk(ctx android.ModuleContext, files, files64, extraFiles, extraFiles64 []android.PackagingSpec) (android.Path, android.Path) { + genDir := android.PathForModuleOut(ctx, "product_arm64_arm_dir") + generator := android.PathForModuleSrc(ctx, proptools.String(n.properties.Product_mk_gen_path)) + // Both arches + builder := android.NewRuleBuilder(pctx, ctx).Sbox( + genDir, + android.PathForModuleOut(ctx, "product_arm64_arm.mk.textproto"), + ) + outArm64ArmMk := genDir.Join(ctx, "product_arm64_arm.mk") + builder.Command(). + Input(generator). + Implicits(specsToSrcPaths(files)). + FlagWithArg("--version=", proptools.String(n.properties.Version)). + Flag("--arm64 --arm"). + FlagForEachArg("--extra_allowed_artifact ", filesRelativeToInstallDir(ctx, extraFiles)). + Flag(strings.Join(filesRelativeToInstallDir(ctx, files), " ")). + FlagWithOutput("> ", outArm64ArmMk) + builder.Build("ndk_translation_package.product_arm64_arm.mk", "Build ndk_translation_package product_arm64_arm.mk") + + // Arm64 only + genDir = android.PathForModuleOut(ctx, "product_arm64_dir") + builder = android.NewRuleBuilder(pctx, ctx).Sbox( + genDir, + android.PathForModuleOut(ctx, "product_arm64.mk.textproto"), + ) + outArm64Mk := genDir.Join(ctx, "product_arm64.mk") + builder.Command(). + Input(generator). + Implicits(specsToSrcPaths(files64)). + FlagWithArg("--version=", proptools.String(n.properties.Version)). + Flag("--arm64"). + FlagForEachArg("--extra_allowed_artifact ", filesRelativeToInstallDir(ctx, extraFiles64)). + Flag(strings.Join(filesRelativeToInstallDir(ctx, files64), " ")). + FlagWithOutput("> ", outArm64Mk) + builder.Build("ndk_translation_package.product_arm_64.mk", "Build ndk_translation_package product_arm64.mk") + + return outArm64ArmMk, outArm64Mk +} + +func filesRelativeToInstallDir(ctx android.ModuleContext, files []android.PackagingSpec) []string { + var ret []string + for _, file := range files { + ret = append(ret, "system/"+file.RelPathInPackage()) + } + return ret +} + +func specsToSrcPaths(specs []android.PackagingSpec) android.Paths { + var ret android.Paths + for _, spec := range specs { + ret = append(ret, spec.SrcPath()) + } + return ret +} -- cgit v1.2.3 From 5ff4c77f626c9b3b8f7c39f27bb5279a1e842e72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= Date: Wed, 23 Apr 2025 15:37:35 -0700 Subject: genrule/genrule.go: Add missing trusty builds to BuildDate/BuildNumber Allowlists Bug: 375543636 Bug: 412749002 Test: build qemu_trusty_arm64-trunk_staging-userdebug Change-Id: I1bb272ec35bc82cc2d60914555df53c004341ac4 --- genrule/genrule.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/genrule/genrule.go b/genrule/genrule.go index f92cfee5e..d9e1eb2ca 100644 --- a/genrule/genrule.go +++ b/genrule/genrule.go @@ -307,6 +307,9 @@ func isModuleInBuildNumberAllowlist(ctx android.ModuleContext) bool { "trusty/vendor/google/aosp/scripts:trusty_test_vm_os_arm64.bin", "trusty/vendor/google/aosp/scripts:trusty_test_vm_os_x86_64.elf", "trusty/vendor/google/aosp/scripts:trusty_test_vm_x86_64.elf", + "trusty/vendor/google/proprietary/scripts:trusty_tee_package_goog", + "trusty/vendor/google/proprietary/scripts:trusty_widevine_vm_arm64.bin", + "trusty/vendor/google/proprietary/scripts:trusty_widevine_vm_x86_64.elf", "vendor/google/services/LyricCameraHAL/src/apex:com.google.pixel.camera.hal.manifest", "vendor/google_tradefederation/core:gen_google_tradefed_zip", // go/keep-sorted end @@ -340,6 +343,9 @@ func isModuleInBuildDateAllowlist(ctx android.ModuleContext) bool { "trusty/vendor/google/aosp/scripts:trusty_test_vm_os_arm64.bin", "trusty/vendor/google/aosp/scripts:trusty_test_vm_os_x86_64.elf", "trusty/vendor/google/aosp/scripts:trusty_test_vm_x86_64.elf", + "trusty/vendor/google/proprietary/scripts:trusty_tee_package_goog", + "trusty/vendor/google/proprietary/scripts:trusty_widevine_vm_arm64.bin", + "trusty/vendor/google/proprietary/scripts:trusty_widevine_vm_x86_64.elf", // go/keep-sorted end } allowlistMap := make(map[string]bool, len(allowlist)) -- cgit v1.2.3 From 5f293b2df9a85a11dbdd13a3f95f233ccfd732d2 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Wed, 23 Apr 2025 16:07:24 -0700 Subject: Remove warning about missing optional_uses_lib modules This warning is printing 20+ times on every analysis on cuttlefish. It's not giving any useful information, and the allowlist for it has never been maintained since it was origionally added, so remove it. Bug: 282877248 Test: m nothing Change-Id: Ic6a22f597a9f5fa8b21b14af683634e350c65f43 --- android/config.go | 4 ---- android/variable.go | 2 -- java/app.go | 6 +----- java/app_test.go | 3 --- 4 files changed, 1 insertion(+), 14 deletions(-) diff --git a/android/config.go b/android/config.go index f8a1eaf42..d97318b27 100644 --- a/android/config.go +++ b/android/config.go @@ -2223,10 +2223,6 @@ func (c *deviceConfig) BuildBrokenDupSysprop() bool { return c.config.productVariables.BuildBrokenDupSysprop } -func (c *config) BuildWarningBadOptionalUsesLibsAllowlist() []string { - return c.productVariables.BuildWarningBadOptionalUsesLibsAllowlist -} - func (c *deviceConfig) GenruleSandboxing() bool { return Bool(c.config.productVariables.GenruleSandboxing) } diff --git a/android/variable.go b/android/variable.go index 3da50a326..c788688d6 100644 --- a/android/variable.go +++ b/android/variable.go @@ -463,8 +463,6 @@ type ProductVariables struct { BuildBrokenDontCheckSystemSdk bool `json:",omitempty"` BuildBrokenDupSysprop bool `json:",omitempty"` - BuildWarningBadOptionalUsesLibsAllowlist []string `json:",omitempty"` - BuildDebugfsRestrictionsEnabled bool `json:",omitempty"` RequiresInsecureExecmemForSwiftshader bool `json:",omitempty"` diff --git a/java/app.go b/java/app.go index 1e35506e3..1d3de149a 100644 --- a/java/app.go +++ b/java/app.go @@ -2094,11 +2094,7 @@ func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, addCompatDeps boo // presentOptionalUsesLibs returns optional_uses_libs after filtering out libraries that don't exist in the source tree. func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []string { optionalUsesLibs := android.FilterListPred(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil), func(s string) bool { - exists := ctx.OtherModuleExists(s) - if !exists && !android.InList(ctx.ModuleName(), ctx.Config().BuildWarningBadOptionalUsesLibsAllowlist()) { - fmt.Printf("Warning: Module '%s' depends on non-existing optional_uses_libs '%s'\n", ctx.ModuleName(), s) - } - return exists + return ctx.OtherModuleExists(s) }) return optionalUsesLibs } diff --git a/java/app_test.go b/java/app_test.go index ed6396a99..2303de103 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -3472,9 +3472,6 @@ func TestUsesLibraries(t *testing.T) { prepareForJavaTest, PrepareForTestWithJavaSdkLibraryFiles, FixtureWithLastReleaseApis("runtime-library", "foo", "quuz", "qux", "bar", "fred"), - android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { - variables.BuildWarningBadOptionalUsesLibsAllowlist = []string{"app", "prebuilt"} - }), ).RunTestWithBp(t, bp) app := result.ModuleForTests(t, "app", "android_common") -- cgit v1.2.3 From 3ec5a15ea93983408f42b17bba02ebc4a678eeff Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 23 Apr 2025 15:57:55 -0700 Subject: Add link to ui.perfetto.dev to docs/perf.md Systrace has been replaced with perfetto. Test: none Change-Id: I0856e641ec2ceb444fc57b892c95a2ca59092cd6 --- docs/perf.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/perf.md b/docs/perf.md index 446ba9df2..b64de0ac4 100644 --- a/docs/perf.md +++ b/docs/perf.md @@ -6,7 +6,7 @@ soong_ui has tracing built in, so that every build execution's trace can be viewed. Just open `$OUT_DIR/build.trace.gz` in Chrome's , or -with [catapult's trace viewer][catapult trace_viewer]. The last few traces are +with [Perfetto][perfetto]. The last few traces are stored in `build.trace.#.gz` (larger numbers are older). The associated logs are stored in `soong.#.log` and `verbose.#.log.gz`. @@ -289,6 +289,6 @@ A workaround to get out of this state is to remove the build.ninja entry from sed -i "/\/build.ninja/d" $(get_build_var OUT_DIR)/.ninja_log ``` -[catapult trace_viewer]: https://github.com/catapult-project/catapult/blob/master/tracing/README.md +[perfetto]: https://ui.perfetto.dev [ninja parse optimization]: https://android-review.googlesource.com/c/platform/external/ninja/+/461005 [blueprint_microfactory]: https://android-review.googlesource.com/q/topic:%22blueprint_microfactory%22+status:merged -- cgit v1.2.3 From 11142c92fe408805709e57d11f62485f08e86541 Mon Sep 17 00:00:00 2001 From: Troy Wang Date: Wed, 9 Apr 2025 16:26:49 -0700 Subject: Add ProductEnableLogcatPersistence to product variable The variable will be used to enable persistent log in logcat for userdebug, eng build and some specific user builds. Bug: 409646559 Test: m dist Test: Verified with a custom brya build Change-Id: Icdd4cc6d6d2c21c4ec57e0c01b52630e502dfa64 --- android/config.go | 4 ++++ android/variable.go | 2 ++ 2 files changed, 6 insertions(+) diff --git a/android/config.go b/android/config.go index f8a1eaf42..5aa75fde9 100644 --- a/android/config.go +++ b/android/config.go @@ -2259,6 +2259,10 @@ func (c *deviceConfig) AconfigContainerValidation() string { return c.config.productVariables.AconfigContainerValidation } +func (c *deviceConfig) ProductEnableLogcatPersistence() bool { + return c.config.productVariables.ProductEnableLogcatPersistence +} + func (c *config) IgnorePrefer32OnDevice() bool { return c.productVariables.IgnorePrefer32OnDevice } diff --git a/android/variable.go b/android/variable.go index 3da50a326..a9f577d82 100644 --- a/android/variable.go +++ b/android/variable.go @@ -556,6 +556,8 @@ type ProductVariables struct { // Will be used to install host tools in soong only builds ProductHostPackages []string `json:",omitempty"` + ProductEnableLogcatPersistence bool `json:",omitempty"` + EnforceSELinuxTrebleLabeling *bool `json:",omitempty"` } -- cgit v1.2.3 From c68c16ff45e9897e97fc23ac13a75cce3d9c32f5 Mon Sep 17 00:00:00 2001 From: Himanshu Gupta Date: Wed, 23 Apr 2025 14:45:58 +0100 Subject: Improvements in `incremental_javac_input` cmd tool. This fixes an issue where switching inc-javac after javac causes a build failure due to empty output dir. Also sets inc-javac to be on by default in partial_compile config. Bug: 387798027 Flag: NA Test: go test ./cmd/incremental_javac_input{,/incremental_javac_input_lib} Change-Id: I53150f81e7d2a8d8a2d616d36aa155269093e5e8 --- android/config.go | 2 +- .../generate_incremental_input.go | 14 +++++++++++++- .../generate_incremental_input_test.go | 5 ++++- cmd/incremental_javac_input/main.go | 9 +++++++-- java/builder.go | 5 +++-- 5 files changed, 28 insertions(+), 7 deletions(-) diff --git a/android/config.go b/android/config.go index f8a1eaf42..05f881e70 100644 --- a/android/config.go +++ b/android/config.go @@ -436,7 +436,7 @@ var defaultPartialCompileFlags = partialCompileFlags{} var enabledPartialCompileFlags = partialCompileFlags{ Use_d8: true, Disable_stub_validation: true, - Enable_inc_javac: false, + Enable_inc_javac: true, } // These are the flags when `SOONG_PARTIAL_COMPILE=all`. diff --git a/cmd/incremental_javac_input/incremental_javac_input_lib/generate_incremental_input.go b/cmd/incremental_javac_input/incremental_javac_input_lib/generate_incremental_input.go index 5f829d7ae..c292c4f4b 100644 --- a/cmd/incremental_javac_input/incremental_javac_input_lib/generate_incremental_input.go +++ b/cmd/incremental_javac_input/incremental_javac_input_lib/generate_incremental_input.go @@ -40,7 +40,7 @@ type UsageMap struct { GeneratedClasses []string } -func GenerateIncrementalInput(srcs, deps, javacTarget, srcDeps, localHeaderJars string) (err error) { +func GenerateIncrementalInput(classDir, srcs, deps, javacTarget, srcDeps, localHeaderJars string) (err error) { incInputPath := javacTarget + ".inc.rsp" removedClassesPath := javacTarget + ".rem.rsp" inputPcState := javacTarget + ".input.pc_state" @@ -72,6 +72,11 @@ func GenerateIncrementalInput(srcs, deps, javacTarget, srcDeps, localHeaderJars return writeOutput(incInputPath, removedClassesPath, srcList, classesForRemoval) } + // if the output directory of javac which will contain .class files is not present, include all sources + if !dirExists(classDir) { + incAllSources = true + } + // if javacTarget does not exist, we can include all sources if incAllSources || !fileExists(javacTarget) { incAllSources = true @@ -227,6 +232,13 @@ func fileExists(filePath string) bool { return true } +func dirExists(dirPath string) bool { + if _, err := os.Stat(dirPath); err == nil || !os.IsNotExist(err) { + return true + } + return false +} + func readRspFile(rspFile string) (list []string) { data, err := os.ReadFile(rspFile) if err != nil { diff --git a/cmd/incremental_javac_input/incremental_javac_input_lib/generate_incremental_input_test.go b/cmd/incremental_javac_input/incremental_javac_input_lib/generate_incremental_input_test.go index b1970de4e..f1f182eec 100644 --- a/cmd/incremental_javac_input/incremental_javac_input_lib/generate_incremental_input_test.go +++ b/cmd/incremental_javac_input/incremental_javac_input_lib/generate_incremental_input_test.go @@ -445,6 +445,7 @@ func TestGenerateIncrementalInputPartialCompileOff(t *testing.T) { type testFixture struct { t *testing.T tmpDir string + ClassDir string SrcRspFile string DepsRspFile string JavacTargetJar string @@ -465,6 +466,7 @@ func newTestFixture(t *testing.T) *testFixture { fixture := &testFixture{ t: t, tmpDir: tmpDir, + ClassDir: filepath.Join(tmpDir, "classes"), SrcRspFile: filepath.Join(tmpDir, "sources.rsp"), DepsRspFile: filepath.Join(tmpDir, "deps.rsp"), JavacTargetJar: filepath.Join(tmpDir, "output.jar"), @@ -480,6 +482,7 @@ func newTestFixture(t *testing.T) *testFixture { // Create directories and initial file contents createDir(t, filepath.Dir(fixture.JavaFile1)) createDir(t, filepath.Dir(fixture.JavaFile3)) + createDir(t, fixture.ClassDir) writeFile(t, fixture.JavaFile1, "package com.example; class File1 {}") writeFile(t, fixture.JavaFile2, "package com.example; class File2 {}") @@ -502,7 +505,7 @@ func newTestFixture(t *testing.T) *testFixture { func (tf *testFixture) runGenerator() { // Small delay often needed for filesystem timestamp granularity time.Sleep(15 * time.Millisecond) - err := GenerateIncrementalInput(tf.SrcRspFile, tf.DepsRspFile, tf.JavacTargetJar, tf.JavaSrcDeps, tf.HeadersRspFile) + err := GenerateIncrementalInput(tf.ClassDir, tf.SrcRspFile, tf.DepsRspFile, tf.JavacTargetJar, tf.JavaSrcDeps, tf.HeadersRspFile) if err != nil { tf.t.Fatalf("GenerateIncrementalInput() returned an error: %v", err) } diff --git a/cmd/incremental_javac_input/main.go b/cmd/incremental_javac_input/main.go index b3c820ba1..a3c8d9717 100644 --- a/cmd/incremental_javac_input/main.go +++ b/cmd/incremental_javac_input/main.go @@ -22,8 +22,9 @@ import ( ) func main() { - var srcs, deps, javacTarget, srcDepsProto, localHeaderJars string + var classDir, srcs, deps, javacTarget, srcDepsProto, localHeaderJars string + flag.StringVar(&classDir, "classDir", "", "dir which will contain compiled java classes") flag.StringVar(&srcs, "srcs", "", "rsp file containing java source paths") flag.StringVar(&deps, "deps", "", "rsp file enlisting all module deps") flag.StringVar(&javacTarget, "javacTarget", "", "javac output") @@ -32,6 +33,10 @@ func main() { flag.Parse() + if classDir == "" { + panic("must specify --classDir") + } + if deps == "" { panic("must specify --deps") } @@ -53,7 +58,7 @@ func main() { } if srcs != "" { - err := iji_lib.GenerateIncrementalInput(srcs, deps, javacTarget, srcDepsProto, localHeaderJars) + err := iji_lib.GenerateIncrementalInput(classDir, srcs, deps, javacTarget, srcDepsProto, localHeaderJars) if err != nil { panic("errored") } diff --git a/java/builder.go b/java/builder.go index 6d4605ea9..93a663416 100644 --- a/java/builder.go +++ b/java/builder.go @@ -62,12 +62,13 @@ var ( javacInc, javacIncRE = pctx.MultiCommandRemoteStaticRules("javac-inc", blueprint.RuleParams{ Command: `rm -rf "$annoDir" "$annoSrcJar.tmp" "$out.tmp" && ` + - `mkdir -p "$outDir" "$annoDir" && ` + + `mkdir -p "$annoDir" && ` + `if [ -s $out.rsp ] && [ -s $srcJarList ] ; then ` + `echo >> $out.rsp; fi && ` + `cat $srcJarList >> $out.rsp && ` + `${config.IncrementalJavacInputCmd} ` + - `--srcs $out.rsp --deps $javacDeps --javacTarget $out --srcDepsProto $out.proto --localHeaderJars $localHeaderJars && ` + + `--srcs $out.rsp --classDir $outDir --deps $javacDeps --javacTarget $out --srcDepsProto $out.proto --localHeaderJars $localHeaderJars && ` + + `mkdir -p "$outDir" && ` + `(if [ -s $out.inc.rsp ] ; then ` + `${config.SoongJavacWrapper} $javaTemplate${config.JavacCmd} ` + `${config.JavacHeapFlags} ${config.JavacVmFlags} ${config.CommonJdkFlags} ` + -- cgit v1.2.3 From 9cb530972d0c57470eeee16dea68e736f6e7e973 Mon Sep 17 00:00:00 2001 From: "Priyanka Advani (xWF)" Date: Thu, 24 Apr 2025 10:15:50 -0700 Subject: Revert "make automatic jarjar to all flags in framework jar" This reverts commit 3f23922ae3d24858c6a1df659ffdff9396114560. Reason for revert: Droidmonitor created revert due to b/413221444. Will be verifying through ABTD before submission. Bug: 411715086 Fix: 413221444 Change-Id: I5810c0ba646060a47e0fd124f1289e3ef5f2fc09 --- aconfig/codegen/java_aconfig_library.go | 22 ++++++++++++++++------ java/base.go | 9 --------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/aconfig/codegen/java_aconfig_library.go b/aconfig/codegen/java_aconfig_library.go index 1d1a2822f..bb734a02d 100644 --- a/aconfig/codegen/java_aconfig_library.go +++ b/aconfig/codegen/java_aconfig_library.go @@ -91,6 +91,12 @@ func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) GenerateSourceJarBuild ctx.PropertyErrorf("mode", "%q is not a supported mode", mode) } + if mode == "exported" && !declarations.Exportable { + // if mode is exported, the corresponding aconfig_declaration must mark its + // exportable property true + ctx.PropertyErrorf("mode", "exported mode requires its aconfig_declaration has exportable prop true") + } + ctx.Build(pctx, android.BuildParams{ Rule: javaRule, Input: declarations.IntermediateCacheOutputPath, @@ -101,12 +107,16 @@ func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) GenerateSourceJarBuild }, }) - // jarjar all flag classes if the java_library set jarjar_prefix - module.AddJarJarRenameRule(declarations.Package+".Flags", "") - module.AddJarJarRenameRule(declarations.Package+".FeatureFlags", "") - module.AddJarJarRenameRule(declarations.Package+".FeatureFlagsImpl", "") - module.AddJarJarRenameRule(declarations.Package+".CustomFeatureFlags", "") - module.AddJarJarRenameRule(declarations.Package+".FakeFeatureFlagsImpl", "") + if declarations.Exportable { + // Mark our generated code as possibly needing jarjar repackaging + // The repackaging only happens when the corresponding aconfig_declaration + // has property exportable true + module.AddJarJarRenameRule(declarations.Package+".Flags", "") + module.AddJarJarRenameRule(declarations.Package+".FeatureFlags", "") + module.AddJarJarRenameRule(declarations.Package+".FeatureFlagsImpl", "") + module.AddJarJarRenameRule(declarations.Package+".CustomFeatureFlags", "") + module.AddJarJarRenameRule(declarations.Package+".FakeFeatureFlagsImpl", "") + } android.SetProvider(ctx, android.CodegenInfoProvider, android.CodegenInfo{ AconfigDeclarations: []string{declarationsModules[0].Name()}, diff --git a/java/base.go b/java/base.go index f7d25dd14..af3d493a1 100644 --- a/java/base.go +++ b/java/base.go @@ -2920,15 +2920,6 @@ func (this Module) GetDebugString() string { // Merge the jarjar rules we inherit from our dependencies, any that have been added directly to // us, and if it's been set, apply the jarjar_prefix property to rename them. func (module *Module) collectJarJarRules(ctx android.ModuleContext) *JarJarProviderData { - - // Stop collect jarjar_prefix jarjar rules if the module has test sdk scope. - // If a module uses test API scope, which means in its source code and static dependencies - // it could only use API exposed through the test surface. So it should not apply the jarjar - // rules set by any bootclass path jar - if module.SdkVersion(ctx).Kind == android.SdkTest { - return nil - } - // Gather repackage information from deps result := collectDirectDepsProviders(ctx) -- cgit v1.2.3 From 66b8487593d9b9c9d972b46bb6632caecdcc2b0d Mon Sep 17 00:00:00 2001 From: Jerome Gaillard Date: Thu, 24 Apr 2025 18:41:59 +0100 Subject: Windows Rust toolchain is not be Bionic This overrides the Bionic method in the Windows Rust toolchain definition to mark it as not bionic, as the method otherwise returns true by default. Flag: NONE host-only change Fixes: 413388193 Test: N/A Change-Id: I20f919fef1fd42ecdc9c8a5b011012bcc4f76d3d --- rust/config/x86_windows_host.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/rust/config/x86_windows_host.go b/rust/config/x86_windows_host.go index f69a0ee58..772c43f08 100644 --- a/rust/config/x86_windows_host.go +++ b/rust/config/x86_windows_host.go @@ -102,6 +102,10 @@ func (toolchainWindowsX86) Supported() bool { return true } +func (toolchainWindowsX86) Bionic() bool { + return false +} + func (toolchainWindowsX86) StaticLibSuffix() string { return ".a" } @@ -164,6 +168,10 @@ func (toolchainWindowsX8664) Supported() bool { return true } +func (toolchainWindowsX8664) Bionic() bool { + return false +} + func (toolchainWindowsX8664) StaticLibSuffix() string { return ".a" } -- cgit v1.2.3 From 1faf8375f221f6eee7e2b866cf72c95dad08f496 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Thu, 24 Apr 2025 11:30:12 -0700 Subject: Bump "experimental" C from C2x to C2y. C23 (aka C2x) is the global default already. Change-Id: I2e03bf4d67cbe2a9837420d533ce88c09289116e --- cc/config/global.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cc/config/global.go b/cc/config/global.go index e81ac0d47..35efbf6f0 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -380,7 +380,7 @@ var ( CStdVersion = "gnu23" CppStdVersion = "gnu++20" - ExperimentalCStdVersion = "gnu2x" + ExperimentalCStdVersion = "gnu2y" ExperimentalCppStdVersion = "gnu++2b" // prebuilts/clang default settings. -- cgit v1.2.3 From 491d9eb3d4be6b45e7fdee6edf75f3758953837f Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 24 Apr 2025 13:48:41 -0700 Subject: Revert "Mark cc.Module as FreeModuleAfterGenerateBuildActions" This reverts commit dc39ea4ab1c7e9741090f6bcb8182d3208feacd3. Reason for revert: broken builds Bug: 413433560 Change-Id: If340a5ca654db0e6160bbdf1e96822a02b94e9fa --- cc/cc.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/cc/cc.go b/cc/cc.go index db5d9b116..d616978c0 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -2732,8 +2732,6 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { if !c.hideApexVariantFromMake && !c.Properties.HideFromMake { c.collectSymbolsInfo(ctx) } - - ctx.FreeModuleAfterGenerateBuildActions() } func (c *Module) CleanupAfterBuildActions() { -- cgit v1.2.3 From 201f825eee75b805ac78a907298b6872d76a037e Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Thu, 24 Apr 2025 14:52:47 -0700 Subject: Convert the llvm-profdata.zip to soong For soong-only builds. Bug: 413425319 Test: diff'd built file before/after Change-Id: Icf89f4dc19cfceb033fcb03ba029faef4c6ca352 --- cc/Android.bp | 1 + cc/llvm_coverage_tools_zip.go | 55 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 cc/llvm_coverage_tools_zip.go diff --git a/cc/Android.bp b/cc/Android.bp index 0643c826f..5559947b6 100644 --- a/cc/Android.bp +++ b/cc/Android.bp @@ -34,6 +34,7 @@ bootstrap_go_package { "generated_cc_library.go", "image.go", "linkable.go", + "llvm_coverage_tools_zip.go", "lto.go", "makevars.go", "misc_disted_files.go", diff --git a/cc/llvm_coverage_tools_zip.go b/cc/llvm_coverage_tools_zip.go new file mode 100644 index 000000000..0b0b0b649 --- /dev/null +++ b/cc/llvm_coverage_tools_zip.go @@ -0,0 +1,55 @@ +// 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 cc + +import ( + "android/soong/android" + "android/soong/cc/config" +) + +func init() { + android.RegisterParallelSingletonType("llvm_coverage_tools_zip", llvmCoverageToolsZipFactory) +} + +func llvmCoverageToolsZipFactory() android.Singleton { + return &llvmCoverageToolsZipSingleton{} +} + +type llvmCoverageToolsZipSingleton struct{} + +// GenerateBuildActions implements android.Singleton. +func (l *llvmCoverageToolsZipSingleton) GenerateBuildActions(ctx android.SingletonContext) { + if !ctx.DeviceConfig().ClangCoverageEnabled() { + return + } + + clangBase := config.ClangPath(ctx, "") + llvmProfdata := config.ClangPath(ctx, "bin/llvm-profdata") + llvmCov := config.ClangPath(ctx, "bin/llvm-cov") + libCxx := config.ClangPath(ctx, "lib/x86_64-unknown-linux-gnu/libc++.so") + llvmCoverageToolsZip := android.PathForOutput(ctx, "llvm-profdata.zip") + + builder := android.NewRuleBuilder(pctx, ctx) + builder.Command().BuiltTool("soong_zip"). + Flag("-d"). + FlagWithOutput("-o ", llvmCoverageToolsZip). + FlagWithArg("-C ", clangBase.String()). + FlagWithInput("-f ", llvmProfdata). + FlagWithInput("-f ", libCxx). + FlagWithInput("-f ", llvmCov) + builder.Build("llvm_coverage_tools_zip", "llvm coverage tools zip") + + ctx.DistForGoals([]string{"droidcore-unbundled", "apps_only"}, llvmCoverageToolsZip) +} -- cgit v1.2.3 From 0d36f3f9130c0d2bc8ca4dce3525d7d28dfce316 Mon Sep 17 00:00:00 2001 From: Jared Duke Date: Thu, 24 Apr 2025 22:13:04 +0000 Subject: Expose new build flag from soong Config Expose RELEASE_USE_SYSTEM_FEATURE_XML_FOR_UNAVAILABLE_FEATURES from the soong Config type. A follow-up change will integrate its use into the java_system_feature_srcs build rule. Flag: Build.RELEASE_USE_SYSTEM_FEATURE_XML_FOR_UNAVAILABLE_FEATURES Test: N/A Bug: 203143243 Change-Id: I3bda7d7818572df4c261817ac681f2a025ec4c9c --- android/config.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/android/config.go b/android/config.go index f8a1eaf42..7595870b8 100644 --- a/android/config.go +++ b/android/config.go @@ -290,6 +290,10 @@ func (c Config) ReleaseUseSystemFeatureBuildFlags() bool { return c.config.productVariables.GetBuildFlagBool("RELEASE_USE_SYSTEM_FEATURE_BUILD_FLAGS") } +func (c Config) ReleaseUseSystemFeatureXmlForUnavailableFeatures() bool { + return c.config.productVariables.GetBuildFlagBool("RELEASE_USE_SYSTEM_FEATURE_XML_FOR_UNAVAILABLE_FEATURES") +} + // TODO: b/409598478 - Remove FINGERPRINT build flag. func (c Config) ReleaseFingerprintAconfigPackages() bool { return c.config.productVariables.GetBuildFlagBool("RELEASE_FINGERPRINT_ACONFIG_PACKAGES") -- cgit v1.2.3 From bc2ec016daaf9f75878fc205edbada5e88510db3 Mon Sep 17 00:00:00 2001 From: "Liana Kazanova (xWF)" Date: Thu, 24 Apr 2025 15:37:41 -0700 Subject: Revert "Introduce ndk_translation_package module type" Revert submission 33214060-ndk_translation_package_soong Reason for revert: DroidMonitor: Potential culprit for http://b/413459913 - verifying through ABTD before revert submission. This is part of the standard investigation process, and does not mean your CL will be reverted. Reverted changes: /q/submissionid:33214060-ndk_translation_package_soong Bug: 413459913 Change-Id: I4657df63b59698a5584ddcc60e2b6a4e46894cac --- cc/Android.bp | 2 - cc/ndk_translation_package.go | 230 ------------------------------------------ 2 files changed, 232 deletions(-) delete mode 100644 cc/ndk_translation_package.go diff --git a/cc/Android.bp b/cc/Android.bp index 0643c826f..1ac5a4a8f 100644 --- a/cc/Android.bp +++ b/cc/Android.bp @@ -75,8 +75,6 @@ bootstrap_go_package { "ndk_library.go", "ndk_sysroot.go", - "ndk_translation_package.go", - "llndk_library.go", "kernel_headers.go", diff --git a/cc/ndk_translation_package.go b/cc/ndk_translation_package.go deleted file mode 100644 index db0879099..000000000 --- a/cc/ndk_translation_package.go +++ /dev/null @@ -1,230 +0,0 @@ -// 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 cc - -import ( - "android/soong/android" - "path/filepath" - "strings" - - "github.com/google/blueprint" - "github.com/google/blueprint/proptools" -) - -func init() { - android.RegisterModuleType("ndk_translation_package", NdkTranslationPackageFactory) -} - -func NdkTranslationPackageFactory() android.Module { - module := &ndkTranslationPackage{} - module.AddProperties(&module.properties) - android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) - return module -} - -type ndkTranslationPackage struct { - android.ModuleBase - properties ndkTranslationPackageProperties -} - -type ndkTranslationPackageProperties struct { - // Dependencies with native bridge variants that should be packaged. - // (e.g. arm and arm64 on an x86_64 device) - Native_bridge_deps []string - // Non-native bridge variants that should be packaged. - // (e.g. x86 and x86_64 on an x86_64 device) - Device_both_deps []string - // Non-native bridge variants with lib64 that should be packaged. - // (e.g. x86_64 on an x86_64 device) - Device_64_deps []string - // Non-native bridge variants with lib32 that should be packaged. - // (e.g. x86 on an x86_64 device) - Device_32_deps []string - // Non-native bridge variants whose first variant should be packaged. - Device_first_deps []string - // Non-native bridge variants whose first variant should be packaged, - // but always into lib/, bin/ directories. - Device_first_to_32_deps []string - // Non-native bridge variants that should _not_ be packaged, but - // used as inputs to generate Android.mk and product.mk - Device_both_extra_allowed_deps []string - Device_32_extra_allowed_deps []string - - // Version to use in generating the new sysprops - Version *string - - // Path to Android.bp generator - Android_bp_gen_path *string - - // Path to product.mk generator - Product_mk_gen_path *string -} - -type ndkTranslationPackageDepTag struct { - blueprint.DependencyTag - name string -} - -func (_ ndkTranslationPackageDepTag) ExcludeFromVisibilityEnforcement() {} - -var ( - ndkTranslationPackageTag = ndkTranslationPackageDepTag{name: "dep"} - ndkTranslationPackageFirstTo32SrcsTag = ndkTranslationPackageDepTag{name: "first_to_32"} - ndkTranslationExtraAllowedDepsTag = ndkTranslationPackageDepTag{name: "extra_allowed_deps"} -) - -func (n *ndkTranslationPackage) DepsMutator(ctx android.BottomUpMutatorContext) { - for index, t := range ctx.MultiTargets() { - if t.NativeBridge == android.NativeBridgeEnabled { - ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationPackageTag, n.properties.Native_bridge_deps...) - } else if t.Arch.ArchType == android.X86_64 { - ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationPackageTag, n.properties.Device_64_deps...) - ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationPackageTag, n.properties.Device_both_deps...) - ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationExtraAllowedDepsTag, n.properties.Device_both_extra_allowed_deps...) - } else if t.Arch.ArchType == android.X86 { - ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationPackageTag, n.properties.Device_32_deps...) - ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationPackageTag, n.properties.Device_both_deps...) - ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationExtraAllowedDepsTag, n.properties.Device_both_extra_allowed_deps...) - ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationExtraAllowedDepsTag, n.properties.Device_32_extra_allowed_deps...) - } - if index == 0 { // Primary arch - ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationPackageTag, n.properties.Device_first_deps...) - ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationPackageFirstTo32SrcsTag, n.properties.Device_first_to_32_deps...) - } - } -} - -func (n *ndkTranslationPackage) GenerateAndroidBuildActions(ctx android.ModuleContext) { - var files []android.PackagingSpec // both arches - var files64 []android.PackagingSpec // 64 only - var extraFiles []android.PackagingSpec - var extraFiles64 []android.PackagingSpec - - ctx.VisitDirectDepsProxy(func(child android.ModuleProxy) { - tag := ctx.OtherModuleDependencyTag(child) - info := android.OtherModuleProviderOrDefault(ctx, child, android.InstallFilesProvider) - commonInfo := android.OtherModulePointerProviderOrDefault(ctx, child, android.CommonModuleInfoProvider) - if tag == ndkTranslationExtraAllowedDepsTag { - extraFiles = append(extraFiles, info.PackagingSpecs...) - if commonInfo.Target.Arch.ArchType == android.X86_64 || commonInfo.Target.Arch.ArchType == android.Arm64 { - extraFiles64 = append(extraFiles64, info.PackagingSpecs...) - } - return - } - files = append(files, info.PackagingSpecs...) - if (commonInfo.Target.Arch.ArchType == android.X86_64 || commonInfo.Target.Arch.ArchType == android.Arm64) && tag != ndkTranslationPackageFirstTo32SrcsTag { - files64 = append(files64, info.PackagingSpecs...) - } - }) - outBp := n.genAndroidBp(ctx, files) - outArm64ArmMk, outArm64Mk := n.genProductMk(ctx, files, files64, extraFiles, extraFiles64) - - outZip := android.PathForModuleOut(ctx, "ndk_translation_package.zip") - builder := android.NewRuleBuilder(pctx, ctx) - cmd := builder.Command(). - BuiltTool("soong_zip"). - FlagWithOutput("-o ", outZip) - for _, buildFile := range []android.Path{outBp, outArm64ArmMk, outArm64Mk} { - cmd. - FlagWithArg("-C ", filepath.Dir(buildFile.String())). - FlagWithInput("-f ", buildFile) - } - for _, file := range files { - // Copy to relative path inside the zip - cmd. - FlagWithArg("-e ", "system/"+file.RelPathInPackage()). - FlagWithInput("-f ", file.SrcPath()) - } - - builder.Build("ndk_translation_package.zip", "Build ndk_translation_package") - - ctx.CheckbuildFile(outZip) - ctx.DistForGoal("ndk_translation_package", outZip) -} - -// Creates a build rule to generate Android.bp and returns path of the generated file. -func (n *ndkTranslationPackage) genAndroidBp(ctx android.ModuleContext, files []android.PackagingSpec) android.Path { - genDir := android.PathForModuleOut(ctx, "android_bp_dir") - generator := android.PathForModuleSrc(ctx, proptools.String(n.properties.Android_bp_gen_path)) - builder := android.NewRuleBuilder(pctx, ctx).Sbox( - genDir, - android.PathForModuleOut(ctx, "Android.bp.sbox.textproto"), - ) - outBp := genDir.Join(ctx, "Android.bp") - builder.Command(). - Input(generator). - Implicits(specsToSrcPaths(files)). - Flag(strings.Join(filesRelativeToInstallDir(ctx, files), " ")). - FlagWithOutput("> ", outBp) - builder.Build("ndk_translation_package.Android.bp", "Build ndk_translation_package Android.bp") - - return outBp -} - -// Creates a build rule to generate product.mk and returns path of the generated files -func (n *ndkTranslationPackage) genProductMk(ctx android.ModuleContext, files, files64, extraFiles, extraFiles64 []android.PackagingSpec) (android.Path, android.Path) { - genDir := android.PathForModuleOut(ctx, "product_arm64_arm_dir") - generator := android.PathForModuleSrc(ctx, proptools.String(n.properties.Product_mk_gen_path)) - // Both arches - builder := android.NewRuleBuilder(pctx, ctx).Sbox( - genDir, - android.PathForModuleOut(ctx, "product_arm64_arm.mk.textproto"), - ) - outArm64ArmMk := genDir.Join(ctx, "product_arm64_arm.mk") - builder.Command(). - Input(generator). - Implicits(specsToSrcPaths(files)). - FlagWithArg("--version=", proptools.String(n.properties.Version)). - Flag("--arm64 --arm"). - FlagForEachArg("--extra_allowed_artifact ", filesRelativeToInstallDir(ctx, extraFiles)). - Flag(strings.Join(filesRelativeToInstallDir(ctx, files), " ")). - FlagWithOutput("> ", outArm64ArmMk) - builder.Build("ndk_translation_package.product_arm64_arm.mk", "Build ndk_translation_package product_arm64_arm.mk") - - // Arm64 only - genDir = android.PathForModuleOut(ctx, "product_arm64_dir") - builder = android.NewRuleBuilder(pctx, ctx).Sbox( - genDir, - android.PathForModuleOut(ctx, "product_arm64.mk.textproto"), - ) - outArm64Mk := genDir.Join(ctx, "product_arm64.mk") - builder.Command(). - Input(generator). - Implicits(specsToSrcPaths(files64)). - FlagWithArg("--version=", proptools.String(n.properties.Version)). - Flag("--arm64"). - FlagForEachArg("--extra_allowed_artifact ", filesRelativeToInstallDir(ctx, extraFiles64)). - Flag(strings.Join(filesRelativeToInstallDir(ctx, files64), " ")). - FlagWithOutput("> ", outArm64Mk) - builder.Build("ndk_translation_package.product_arm_64.mk", "Build ndk_translation_package product_arm64.mk") - - return outArm64ArmMk, outArm64Mk -} - -func filesRelativeToInstallDir(ctx android.ModuleContext, files []android.PackagingSpec) []string { - var ret []string - for _, file := range files { - ret = append(ret, "system/"+file.RelPathInPackage()) - } - return ret -} - -func specsToSrcPaths(specs []android.PackagingSpec) android.Paths { - var ret android.Paths - for _, spec := range specs { - ret = append(ret, spec.SrcPath()) - } - return ret -} -- cgit v1.2.3 From abcb73050d308bfc53a17b9ba0242894fd8eaa61 Mon Sep 17 00:00:00 2001 From: Brian Ryner Date: Fri, 25 Apr 2025 00:19:30 +0000 Subject: Include get_instance_url in the proxy policy. Even though the message is currently empty, if it is not present in the proxy config then the GetInstanceURL RPC is disallowed. Test: none Bug: 400695406 Change-Id: I5ca6810ea05e961b8523018a344412e04dddc156 --- ui/build/cipd_proxy_policy.txtpb | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/build/cipd_proxy_policy.txtpb b/ui/build/cipd_proxy_policy.txtpb index 98953a553..35fcc0dc0 100644 --- a/ui/build/cipd_proxy_policy.txtpb +++ b/ui/build/cipd_proxy_policy.txtpb @@ -3,3 +3,4 @@ resolve_version { allow_tags: false allow_refs: false } +get_instance_url {} -- cgit v1.2.3 From 6bd8315bf2d896e8906b9c267d5925f83277a8d6 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Thu, 24 Apr 2025 22:53:22 +0000 Subject: Reapply "Introduce ndk_translation_package module type" This reverts commit bc2ec016daaf9f75878fc205edbada5e88510db3. Some dependencies of ndk_translation_package do not support riscv native bridge variants. This adds AllowDisabledModuleDependency to allow such deps during soong analysis. Bug: 411745985 Test: lunch sdk_phone64_x86_64_riscv64-trunk_staging-userdebug && m nothing with the revert^2 of ag/33203473 Change-Id: I7b7aa2f47f4995853ad7c981227eda78da7ac0f6 --- cc/Android.bp | 2 + cc/ndk_translation_package.go | 243 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 245 insertions(+) create mode 100644 cc/ndk_translation_package.go diff --git a/cc/Android.bp b/cc/Android.bp index 1ac5a4a8f..0643c826f 100644 --- a/cc/Android.bp +++ b/cc/Android.bp @@ -75,6 +75,8 @@ bootstrap_go_package { "ndk_library.go", "ndk_sysroot.go", + "ndk_translation_package.go", + "llndk_library.go", "kernel_headers.go", diff --git a/cc/ndk_translation_package.go b/cc/ndk_translation_package.go new file mode 100644 index 000000000..4af901e61 --- /dev/null +++ b/cc/ndk_translation_package.go @@ -0,0 +1,243 @@ +// 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 cc + +import ( + "android/soong/android" + "path/filepath" + "strings" + + "github.com/google/blueprint" + "github.com/google/blueprint/proptools" +) + +func init() { + android.RegisterModuleType("ndk_translation_package", NdkTranslationPackageFactory) +} + +func NdkTranslationPackageFactory() android.Module { + module := &ndkTranslationPackage{} + module.AddProperties(&module.properties) + android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) + return module +} + +type ndkTranslationPackage struct { + android.ModuleBase + properties ndkTranslationPackageProperties +} + +type ndkTranslationPackageProperties struct { + // Dependencies with native bridge variants that should be packaged. + // (e.g. arm and arm64 on an x86_64 device) + Native_bridge_deps []string + // Non-native bridge variants that should be packaged. + // (e.g. x86 and x86_64 on an x86_64 device) + Device_both_deps []string + // Non-native bridge variants with lib64 that should be packaged. + // (e.g. x86_64 on an x86_64 device) + Device_64_deps []string + // Non-native bridge variants with lib32 that should be packaged. + // (e.g. x86 on an x86_64 device) + Device_32_deps []string + // Non-native bridge variants whose first variant should be packaged. + Device_first_deps []string + // Non-native bridge variants whose first variant should be packaged, + // but always into lib/, bin/ directories. + Device_first_to_32_deps []string + // Non-native bridge variants that should _not_ be packaged, but + // used as inputs to generate Android.mk and product.mk + Device_both_extra_allowed_deps []string + Device_32_extra_allowed_deps []string + + // Version to use in generating the new sysprops + Version *string + + // Path to Android.bp generator + Android_bp_gen_path *string + + // Path to product.mk generator + Product_mk_gen_path *string +} + +type ndkTranslationPackageDepTag struct { + blueprint.DependencyTag + name string +} + +func (_ ndkTranslationPackageDepTag) ExcludeFromVisibilityEnforcement() {} + +// Some dependencies do not support native bridge variants for riscv +func (_ ndkTranslationPackageDepTag) AllowDisabledModuleDependency(target android.Module) bool { + return target.Target().NativeBridge == android.NativeBridgeEnabled && + target.Target().Arch.ArchType == android.Riscv64 +} + +func (_ ndkTranslationPackageDepTag) AllowDisabledModuleDependencyProxy(ctx android.OtherModuleProviderContext, mod android.ModuleProxy) bool { + commonInfo := android.OtherModulePointerProviderOrDefault(ctx, mod, android.CommonModuleInfoProvider) + return commonInfo.Target.NativeBridge == android.NativeBridgeEnabled && + commonInfo.Target.Arch.ArchType == android.Riscv64 + +} + +var ( + ndkTranslationPackageTag = ndkTranslationPackageDepTag{name: "dep"} + ndkTranslationPackageFirstTo32SrcsTag = ndkTranslationPackageDepTag{name: "first_to_32"} + ndkTranslationExtraAllowedDepsTag = ndkTranslationPackageDepTag{name: "extra_allowed_deps"} +) + +func (n *ndkTranslationPackage) DepsMutator(ctx android.BottomUpMutatorContext) { + for index, t := range ctx.MultiTargets() { + if t.NativeBridge == android.NativeBridgeEnabled { + ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationPackageTag, n.properties.Native_bridge_deps...) + } else if t.Arch.ArchType == android.X86_64 { + ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationPackageTag, n.properties.Device_64_deps...) + ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationPackageTag, n.properties.Device_both_deps...) + ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationExtraAllowedDepsTag, n.properties.Device_both_extra_allowed_deps...) + } else if t.Arch.ArchType == android.X86 { + ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationPackageTag, n.properties.Device_32_deps...) + ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationPackageTag, n.properties.Device_both_deps...) + ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationExtraAllowedDepsTag, n.properties.Device_both_extra_allowed_deps...) + ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationExtraAllowedDepsTag, n.properties.Device_32_extra_allowed_deps...) + } + if index == 0 { // Primary arch + ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationPackageTag, n.properties.Device_first_deps...) + ctx.AddFarVariationDependencies(t.Variations(), ndkTranslationPackageFirstTo32SrcsTag, n.properties.Device_first_to_32_deps...) + } + } +} + +func (n *ndkTranslationPackage) GenerateAndroidBuildActions(ctx android.ModuleContext) { + var files []android.PackagingSpec // both arches + var files64 []android.PackagingSpec // 64 only + var extraFiles []android.PackagingSpec + var extraFiles64 []android.PackagingSpec + + ctx.VisitDirectDepsProxy(func(child android.ModuleProxy) { + tag := ctx.OtherModuleDependencyTag(child) + info := android.OtherModuleProviderOrDefault(ctx, child, android.InstallFilesProvider) + commonInfo := android.OtherModulePointerProviderOrDefault(ctx, child, android.CommonModuleInfoProvider) + if tag == ndkTranslationExtraAllowedDepsTag { + extraFiles = append(extraFiles, info.PackagingSpecs...) + if commonInfo.Target.Arch.ArchType == android.X86_64 || commonInfo.Target.Arch.ArchType == android.Arm64 { + extraFiles64 = append(extraFiles64, info.PackagingSpecs...) + } + return + } + files = append(files, info.PackagingSpecs...) + if (commonInfo.Target.Arch.ArchType == android.X86_64 || commonInfo.Target.Arch.ArchType == android.Arm64) && tag != ndkTranslationPackageFirstTo32SrcsTag { + files64 = append(files64, info.PackagingSpecs...) + } + }) + outBp := n.genAndroidBp(ctx, files) + outArm64ArmMk, outArm64Mk := n.genProductMk(ctx, files, files64, extraFiles, extraFiles64) + + outZip := android.PathForModuleOut(ctx, "ndk_translation_package.zip") + builder := android.NewRuleBuilder(pctx, ctx) + cmd := builder.Command(). + BuiltTool("soong_zip"). + FlagWithOutput("-o ", outZip) + for _, buildFile := range []android.Path{outBp, outArm64ArmMk, outArm64Mk} { + cmd. + FlagWithArg("-C ", filepath.Dir(buildFile.String())). + FlagWithInput("-f ", buildFile) + } + for _, file := range files { + // Copy to relative path inside the zip + cmd. + FlagWithArg("-e ", "system/"+file.RelPathInPackage()). + FlagWithInput("-f ", file.SrcPath()) + } + + builder.Build("ndk_translation_package.zip", "Build ndk_translation_package") + + ctx.CheckbuildFile(outZip) + ctx.DistForGoal("ndk_translation_package", outZip) +} + +// Creates a build rule to generate Android.bp and returns path of the generated file. +func (n *ndkTranslationPackage) genAndroidBp(ctx android.ModuleContext, files []android.PackagingSpec) android.Path { + genDir := android.PathForModuleOut(ctx, "android_bp_dir") + generator := android.PathForModuleSrc(ctx, proptools.String(n.properties.Android_bp_gen_path)) + builder := android.NewRuleBuilder(pctx, ctx).Sbox( + genDir, + android.PathForModuleOut(ctx, "Android.bp.sbox.textproto"), + ) + outBp := genDir.Join(ctx, "Android.bp") + builder.Command(). + Input(generator). + Implicits(specsToSrcPaths(files)). + Flag(strings.Join(filesRelativeToInstallDir(ctx, files), " ")). + FlagWithOutput("> ", outBp) + builder.Build("ndk_translation_package.Android.bp", "Build ndk_translation_package Android.bp") + + return outBp +} + +// Creates a build rule to generate product.mk and returns path of the generated files +func (n *ndkTranslationPackage) genProductMk(ctx android.ModuleContext, files, files64, extraFiles, extraFiles64 []android.PackagingSpec) (android.Path, android.Path) { + genDir := android.PathForModuleOut(ctx, "product_arm64_arm_dir") + generator := android.PathForModuleSrc(ctx, proptools.String(n.properties.Product_mk_gen_path)) + // Both arches + builder := android.NewRuleBuilder(pctx, ctx).Sbox( + genDir, + android.PathForModuleOut(ctx, "product_arm64_arm.mk.textproto"), + ) + outArm64ArmMk := genDir.Join(ctx, "product_arm64_arm.mk") + builder.Command(). + Input(generator). + Implicits(specsToSrcPaths(files)). + FlagWithArg("--version=", proptools.String(n.properties.Version)). + Flag("--arm64 --arm"). + FlagForEachArg("--extra_allowed_artifact ", filesRelativeToInstallDir(ctx, extraFiles)). + Flag(strings.Join(filesRelativeToInstallDir(ctx, files), " ")). + FlagWithOutput("> ", outArm64ArmMk) + builder.Build("ndk_translation_package.product_arm64_arm.mk", "Build ndk_translation_package product_arm64_arm.mk") + + // Arm64 only + genDir = android.PathForModuleOut(ctx, "product_arm64_dir") + builder = android.NewRuleBuilder(pctx, ctx).Sbox( + genDir, + android.PathForModuleOut(ctx, "product_arm64.mk.textproto"), + ) + outArm64Mk := genDir.Join(ctx, "product_arm64.mk") + builder.Command(). + Input(generator). + Implicits(specsToSrcPaths(files64)). + FlagWithArg("--version=", proptools.String(n.properties.Version)). + Flag("--arm64"). + FlagForEachArg("--extra_allowed_artifact ", filesRelativeToInstallDir(ctx, extraFiles64)). + Flag(strings.Join(filesRelativeToInstallDir(ctx, files64), " ")). + FlagWithOutput("> ", outArm64Mk) + builder.Build("ndk_translation_package.product_arm_64.mk", "Build ndk_translation_package product_arm64.mk") + + return outArm64ArmMk, outArm64Mk +} + +func filesRelativeToInstallDir(ctx android.ModuleContext, files []android.PackagingSpec) []string { + var ret []string + for _, file := range files { + ret = append(ret, "system/"+file.RelPathInPackage()) + } + return ret +} + +func specsToSrcPaths(specs []android.PackagingSpec) android.Paths { + var ret android.Paths + for _, spec := range specs { + ret = append(ret, spec.SrcPath()) + } + return ret +} -- cgit v1.2.3 From 795e768daa8a9aeb7a6586677badf12837bd7ba2 Mon Sep 17 00:00:00 2001 From: Brian Ryner Date: Fri, 25 Apr 2025 00:26:14 +0000 Subject: Make sure the trailing newline is stripped from CIPD_PROXY_URL. Test: none Bug: 400695406 Change-Id: Ib9374644c5ce8183d33437420f237af8c5dbfe28 --- ui/build/cipd.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/build/cipd.go b/ui/build/cipd.go index 84fd2a088..2a31e1784 100644 --- a/ui/build/cipd.go +++ b/ui/build/cipd.go @@ -51,9 +51,9 @@ func startCIPDProxyServer(ctx Context, config Config) cipdProxy { log.Fatal(err) } if strings.HasPrefix(l, cipdProxyUrlKey) { - proxyUrl := l[len(cipdProxyUrlKey)+1:] + proxyUrl := strings.TrimSpace(l[len(cipdProxyUrlKey)+1:]) config.environ.Set(cipdProxyUrlKey, proxyUrl) - ctx.Printf("Started CIPD proxy listening on %s", proxyUrl) + ctx.Println("Started CIPD proxy listening on", proxyUrl) break } } -- cgit v1.2.3 From 6fdb09de316af1d7be4e76afe35bf8ac27683b61 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 24 Apr 2025 22:21:36 -0700 Subject: Convert sysprop/ to ModuleProxy and Providers When cc modules are marked with FreeModuleAfterGenerateBuildActions it will be an error to visit any cc dependency using VisitDirectDeps, and VisitDirectDepsProxy must be used instead. Convert sysprop to access dependencies via ModuleProxy and Providers. Test: sysprop_test.go Change-Id: Ied335055fd818aed67d69497c5cee9d5f9b40bb7 --- sysprop/sysprop_library.go | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go index a398cbce2..a80ff43eb 100644 --- a/sysprop/sysprop_library.go +++ b/sysprop/sysprop_library.go @@ -86,14 +86,20 @@ func init() { pctx.HostBinToolVariable("syspropRustCmd", "sysprop_rust") } +var SyspropLibraryInfoProvider = blueprint.NewProvider[SyspropLibraryInfo]() + +type SyspropLibraryInfo struct { + CheckApiFileTimeStamp android.WritablePath +} + // syspropJavaGenRule module generates srcjar containing generated java APIs. // It also depends on check api rule, so api check has to pass to use sysprop_library. func (g *syspropJavaGenRule) GenerateAndroidBuildActions(ctx android.ModuleContext) { var checkApiFileTimeStamp android.WritablePath ctx.VisitDirectDeps(func(dep android.Module) { - if m, ok := dep.(*syspropLibrary); ok { - checkApiFileTimeStamp = m.checkApiFileTimeStamp + if info, ok := android.OtherModuleProvider(ctx, dep, SyspropLibraryInfoProvider); ok { + checkApiFileTimeStamp = info.CheckApiFileTimeStamp } }) @@ -136,9 +142,9 @@ func syspropJavaGenFactory() android.Module { func (g *syspropRustGenRule) GenerateSource(ctx rust.ModuleContext, deps rust.PathDeps) android.Path { var checkApiFileTimeStamp android.WritablePath - ctx.VisitDirectDeps(func(dep android.Module) { - if m, ok := dep.(*syspropLibrary); ok { - checkApiFileTimeStamp = m.checkApiFileTimeStamp + ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) { + if info, ok := android.OtherModuleProvider(ctx, dep, SyspropLibraryInfoProvider); ok { + checkApiFileTimeStamp = info.CheckApiFileTimeStamp } }) @@ -207,8 +213,6 @@ type syspropLibrary struct { properties syspropLibraryProperties checkApiFileTimeStamp android.WritablePath - latestApiFile android.OptionalPath - currentApiFile android.OptionalPath dumpedApiFile android.WritablePath } @@ -335,10 +339,6 @@ func (m *syspropLibrary) BaseModuleName() string { return m.ModuleBase.Name() } -func (m *syspropLibrary) CurrentSyspropApiFile() android.OptionalPath { - return m.currentApiFile -} - // GenerateAndroidBuildActions of sysprop_library handles API dump and API check. // generated java_library will depend on these API files. func (m *syspropLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { @@ -357,8 +357,8 @@ func (m *syspropLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) apiDirectoryPath := path.Join(ctx.ModuleDir(), "api") currentApiFilePath := path.Join(apiDirectoryPath, baseModuleName+"-current.txt") latestApiFilePath := path.Join(apiDirectoryPath, baseModuleName+"-latest.txt") - m.currentApiFile = android.ExistentPathForSource(ctx, currentApiFilePath) - m.latestApiFile = android.ExistentPathForSource(ctx, latestApiFilePath) + currentApiFile := android.ExistentPathForSource(ctx, currentApiFilePath) + latestApiFile := android.ExistentPathForSource(ctx, latestApiFilePath) // dump API rule rule := android.NewRuleBuilder(pctx, ctx) @@ -379,15 +379,15 @@ func (m *syspropLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) // method. var apiFileList android.Paths currentApiArgument := os.DevNull - if m.currentApiFile.Valid() { - apiFileList = append(apiFileList, m.currentApiFile.Path()) - currentApiArgument = m.currentApiFile.String() + if currentApiFile.Valid() { + apiFileList = append(apiFileList, currentApiFile.Path()) + currentApiArgument = currentApiFile.String() } latestApiArgument := os.DevNull - if m.latestApiFile.Valid() { - apiFileList = append(apiFileList, m.latestApiFile.Path()) - latestApiArgument = m.latestApiFile.String() + if latestApiFile.Valid() { + apiFileList = append(apiFileList, latestApiFile.Path()) + latestApiArgument = latestApiFile.String() } // 1. compares current.txt to api-dump.txt @@ -431,6 +431,10 @@ func (m *syspropLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) Output(m.checkApiFileTimeStamp) rule.Build(baseModuleName+"_check_api", baseModuleName+" check api") + + android.SetProvider(ctx, SyspropLibraryInfoProvider, SyspropLibraryInfo{ + CheckApiFileTimeStamp: m.checkApiFileTimeStamp, + }) } func (m *syspropLibrary) AndroidMk() android.AndroidMkData { -- cgit v1.2.3 From 81db73660b4d15bdd6985c2d4e7e42d6ae31220d Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Mon, 7 Apr 2025 19:55:27 -0700 Subject: Mark cc.Module as FreeModuleAfterGenerateBuildActions Calling ctx.FreeModuleAfterGenerateBuildActions marks cc.Module as only being used by other modules via ModuleProxy and Providers, allowing the cc.Module object to be freed after GenerateBuildActions returns. Any module that visits a cc.Module after this point using a visitor that receives a Module instead of a ModuleProxy will panic. Test: all Soong tests pass Change-Id: I8ceee734d6b77533e857a2933d0215e8ecad8c34 --- cc/cc.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cc/cc.go b/cc/cc.go index d616978c0..db5d9b116 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -2732,6 +2732,8 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { if !c.hideApexVariantFromMake && !c.Properties.HideFromMake { c.collectSymbolsInfo(ctx) } + + ctx.FreeModuleAfterGenerateBuildActions() } func (c *Module) CleanupAfterBuildActions() { -- cgit v1.2.3 From 95b5028261574a0b3ea9347a0fffce07f536f106 Mon Sep 17 00:00:00 2001 From: Jordan Demeulenaere Date: Thu, 17 Apr 2025 13:10:11 +0200 Subject: Allow Kotlin targets to specify associates Want-Code-Review: all Bug: 240432457 Test: go test ./java -run TestKotlinAssociates Flag: EXEMPT no-op if Associates is not set Change-Id: I41dd39ab11ea089c9f6e05412d843d311f494181 --- java/base.go | 4 +++ java/java.go | 3 ++ java/kotlin.go | 54 +++++++++++++++++++++++++++++++ java/kotlin_test.go | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 153 insertions(+) diff --git a/java/base.go b/java/base.go index f7d25dd14..50659de1c 100644 --- a/java/base.go +++ b/java/base.go @@ -100,6 +100,9 @@ type CommonProperties struct { // list of java libraries that will be compiled into the resulting jar Static_libs proptools.Configurable[[]string] `android:"arch_variant"` + // List of Kotlin libraries whose `internal` members are accessible to this library + Associates []string `android:"arch_variant"` + // manifest file to be included in resulting jar Manifest *string `android:"path"` @@ -1962,6 +1965,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath RepackagedHeaderJars: android.PathsIfNonNil(repackagedHeaderJarFile), LocalHeaderJars: localHeaderJars, + KotlinHeaderJars: kotlinHeaderJars, TransitiveStaticLibsHeaderJars: depset.New(depset.PREORDER, localHeaderJars, transitiveStaticLibsHeaderJars), TransitiveStaticLibsImplementationJars: completeStaticLibsImplementationJars, TransitiveStaticLibsResourceJars: completeStaticLibsResourceJars, diff --git a/java/java.go b/java/java.go index 231da8659..fdc580844 100644 --- a/java/java.go +++ b/java/java.go @@ -329,6 +329,9 @@ type JavaInfo struct { // LocalHeaderJars is a list of jars that contain classes from this module, but not from any static dependencies. LocalHeaderJars android.Paths + // KotlinHeaderJars is a jar that only contains Kotlin classes from this module, but not from any static dependencies. + KotlinHeaderJars android.Paths + // AidlIncludeDirs is a list of directories that should be passed to the aidl tool when // depending on this module. AidlIncludeDirs android.Paths diff --git a/java/kotlin.go b/java/kotlin.go index 308bb0305..bd93921f3 100644 --- a/java/kotlin.go +++ b/java/kotlin.go @@ -123,6 +123,18 @@ func (j *Module) kotlinCompile(ctx android.ModuleContext, outputFile, headerOutp commonSrcFilesArg = "--common_srcs " + commonSrcsList.String() } + associateJars := getAssociateJars(ctx, j.properties.Associates) + if len(associateJars) > 0 { + flags.kotlincFlags += " -Xfriend-paths=" + strings.Join(associateJars.Strings(), ",") + deps = append(deps, associateJars...) + + // Prepend the associates classes jar in the classpath, so that they take priority over the other jars. + var newClasspath classpath + newClasspath = append(newClasspath, associateJars...) + newClasspath = append(newClasspath, flags.kotlincClasspath...) + flags.kotlincClasspath = newClasspath + } + classpathRspFile := android.PathForModuleOut(ctx, "kotlinc", "classpath.rsp") android.WriteFileRule(ctx, classpathRspFile, strings.Join(flags.kotlincClasspath.Strings(), " ")) deps = append(deps, classpathRspFile) @@ -176,6 +188,48 @@ func (j *Module) kotlinCompile(ctx android.ModuleContext, outputFile, headerOutp } } +func getAssociateJars(ctx android.ModuleContext, associates []string) android.Paths { + if len(associates) == 0 { + return nil + } + + associatesFound := make(map[string]bool) + for _, name := range associates { + associatesFound[name] = false + } + + var associateJars android.Paths + ctx.VisitDirectDepsProxy(func(depModule android.ModuleProxy) { + depName := ctx.OtherModuleName(depModule) + _, isAssociate := associatesFound[depName] + if !isAssociate { + return + } + + associatesFound[depName] = true + depInfo, ok := android.OtherModuleProvider(ctx, depModule, JavaInfoProvider) + if !ok { + ctx.PropertyErrorf("Associates", "associate module '%s' is not a Java module", depName) + return + } + + if len(depInfo.KotlinHeaderJars) == 0 { + ctx.PropertyErrorf("Associates", "associate module '%s' is not a Kotlin module", depName) + return + } + + associateJars = append(associateJars, depInfo.KotlinHeaderJars...) + }) + + for name, found := range associatesFound { + if !found { + ctx.PropertyErrorf("Associates", "associate module '%s' must also be listed as a direct dependency (e.g. in static_libs or libs)", name) + } + } + + return associateJars +} + var kaptStubs = pctx.AndroidRemoteStaticRule("kaptStubs", android.RemoteRuleSupports{Goma: true}, blueprint.RuleParams{ Command: `rm -rf "$srcJarDir" "$kotlinBuildFile" "$kaptDir" && ` + diff --git a/java/kotlin_test.go b/java/kotlin_test.go index 4b56cff1c..0a2eec2c6 100644 --- a/java/kotlin_test.go +++ b/java/kotlin_test.go @@ -521,3 +521,95 @@ func TestKotlinPlugin(t *testing.T) { android.AssertStringDoesNotContain(t, "unexpected kotlin plugin", noKotlinPlugin.VariablesForTestsRelativeToTop()["kotlincFlags"], "-Xplugin="+kotlinPlugin.String()) } + +func TestKotlinAssociates(t *testing.T) { + t.Parallel() + + targets := []string{"FooUtils", "FooTest"} + for _, target := range targets { + t.Run("Successful associate linking of "+target, func(t *testing.T) { + t.Parallel() + bp := ` + java_library { + name: "Foo", + srcs: ["Foo.kt"], + } + + java_library { + name: "FooUtils", + srcs: ["FooUtils.kt"], + libs: ["Foo"], + associates: ["Foo"], + } + + java_test { + name: "FooTest", + srcs: ["FooTest.kt"], + static_libs: ["Foo"], + associates: ["Foo"], + } + ` + result := android.GroupFixturePreparers( + PrepareForTestWithJavaDefaultModules, + ).RunTestWithBp(t, bp) + + module := result.ModuleForTests(t, target, "android_common") + kotlincRule := module.Rule("kotlinc") + expectedFriendPath := "out/soong/.intermediates/Foo/android_common/kotlin_headers/Foo.jar" + expectedFlag := "-Xfriend-paths=" + expectedFriendPath + + kotlincFlags := kotlincRule.Args["kotlincFlags"] + if !strings.Contains(kotlincFlags, expectedFlag) { + t.Errorf("kotlincFlags missing expected friend path:\n Flags: %s\n Expected: %s", kotlincFlags, expectedFlag) + } + + classpathRspFile := module.Output("kotlinc/classpath.rsp") + classpathContent := android.ContentFromFileRuleForTests(t, result.TestContext, classpathRspFile) + classpathEntries := strings.Fields(classpathContent) + android.AssertStringPathRelativeToTopEquals(t, "first classpath entry", result.Config, expectedFriendPath, classpathEntries[0]) + }) + } + + t.Run("Error: Associate not a dependency", func(t *testing.T) { + t.Parallel() + bp := ` + java_library { + name: "Foo", + srcs: ["Foo.kt"], + } + + java_library { + name: "FooUtils", + srcs: ["FooUtils.kt"], + associates: ["Foo"], + } + ` + android.GroupFixturePreparers( + PrepareForTestWithJavaDefaultModules, + ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern( + `\QAssociates: associate module 'Foo' must also be listed as a direct dependency\E`, + )).RunTestWithBp(t, bp) + }) + + t.Run("Error: Associate not a Kotlin module", func(t *testing.T) { + t.Parallel() + bp := ` + java_library { + name: "Foo", + srcs: ["Foo.java"], + } + + java_library { + name: "FooUtils", + srcs: ["FooUtils.kt"], + libs: ["Foo"], + associates: ["Foo"], + } + ` + android.GroupFixturePreparers( + PrepareForTestWithJavaDefaultModules, + ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern( + `\QAssociates: associate module 'Foo' is not a Kotlin module\E`, + )).RunTestWithBp(t, bp) + }) +} -- cgit v1.2.3 From 5f5546a34a9915ea4304c123d5cd1211d26a8007 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Fri, 25 Apr 2025 05:08:29 -0700 Subject: Add -Wno-everything to IllegalFlags. Bug: http://b/308179380 Change-Id: I3218dc69eec5bd16dad755009f3fb3126243bc2a --- cc/config/global.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cc/config/global.go b/cc/config/global.go index 35efbf6f0..82258cbee 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -376,6 +376,7 @@ var ( "-pedantic", "-pedantic-errors", "-Werror=pedantic", + "-Wno-everything", } CStdVersion = "gnu23" -- cgit v1.2.3 From f3f041f01baf04131eb21f5373bb0bc60af945b2 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Fri, 25 Apr 2025 12:01:08 -0700 Subject: Check for empty phony target names Just to ensure we don't have empty phonies / malformed makefiles. Test: m nothing Change-Id: Idb6ccc60d688fcfc88314e71cc0a315b109c66ac --- android/makevars.go | 3 +++ android/module_context.go | 3 +++ android/phony.go | 3 +++ filesystem/system_other.go | 1 + 4 files changed, 10 insertions(+) diff --git a/android/makevars.go b/android/makevars.go index 4cf222885..85d095c5e 100644 --- a/android/makevars.go +++ b/android/makevars.go @@ -599,6 +599,9 @@ func (c *makeVarsContext) addVariable(name, ninjaStr string, strict, sort bool) } func (c *makeVarsContext) addPhony(name string, deps []string) { + if name == "" { + panic("Phony name cannot be the empty string") + } c.phonies = append(c.phonies, phony{name, deps}) } diff --git a/android/module_context.go b/android/module_context.go index acfcd9b10..a9497d094 100644 --- a/android/module_context.go +++ b/android/module_context.go @@ -478,6 +478,9 @@ func (m *moduleContext) Phony(name string, deps ...Path) { panic("Phony dep cannot be nil") } } + if name == "" { + panic("Phony name cannot be the empty string") + } m.phonies[name] = append(m.phonies[name], deps...) } diff --git a/android/phony.go b/android/phony.go index 99ff0aaa4..765770083 100644 --- a/android/phony.go +++ b/android/phony.go @@ -40,6 +40,9 @@ func getSingletonPhonyMap(config Config) phonyMap { } func addSingletonPhony(config Config, name string, deps ...Path) { + if name == "" { + panic("Phony name cannot be the empty string") + } phonyMap := getSingletonPhonyMap(config) phonyMapLock.Lock() defer phonyMapLock.Unlock() diff --git a/filesystem/system_other.go b/filesystem/system_other.go index 044211150..14895bd3f 100644 --- a/filesystem/system_other.go +++ b/filesystem/system_other.go @@ -164,6 +164,7 @@ func (m *systemOtherImage) GenerateAndroidBuildActions(ctx android.ModuleContext fsInfo := FilesystemInfo{ Output: output, RootDir: stagingDir, + ModuleName: ctx.ModuleName(), FilesystemConfig: m.generateFilesystemConfig(ctx, stagingDir, stagingDirTimestamp), PropFileForMiscInfo: m.buildPropFileForMiscInfo(ctx), InstalledFilesDepSet: depset.New( -- cgit v1.2.3 From 5708330a2acd26e4afdf366ae8a466bc977663f8 Mon Sep 17 00:00:00 2001 From: Jared Duke Date: Thu, 24 Apr 2025 21:34:02 +0000 Subject: Update feature XML support in java_system_features_srcs Guard use of feature XML file parsing behind a build flag, and change the behavior to only finalize features marked as . This is a safer incremental step, as any feature marked by any config file can never be overridden or updated (via mainline). Flag: build.RELEASE_USE_SYSTEM_FEATURE_XML_FOR_UNAVAILABLE_FEATURES Test: go test systemfeatures/. Bug: 203143243 Change-Id: Ie5246da2724adbfe1d52a53832548141ec1f7faf --- systemfeatures/system_features.go | 10 ++++------ systemfeatures/system_features_test.go | 8 ++++---- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/systemfeatures/system_features.go b/systemfeatures/system_features.go index 1e6182b27..51f69bbe4 100644 --- a/systemfeatures/system_features.go +++ b/systemfeatures/system_features.go @@ -46,9 +46,6 @@ type javaSystemFeaturesSrcs struct { // This is useful for tools that rely on the mapping from feature names to their generated // method names, but don't want the fully generated API class (e.g., for linting). Metadata_only *bool - // Whether to parse feature definitions from feature XML files for the - // target's PRODUCT_COPY_FILES. Defaults to false. - Use_product_copy_files *bool } outputFiles android.WritablePaths } @@ -83,11 +80,13 @@ func (m *javaSystemFeaturesSrcs) GenerateAndroidBuildActions(ctx android.ModuleC FlagForEachArg("--feature=", features). FlagWithArg("--readonly=", fmt.Sprint(ctx.Config().ReleaseUseSystemFeatureBuildFlags())). FlagWithArg("--metadata-only=", fmt.Sprint(proptools.Bool(m.properties.Metadata_only))) - if proptools.Bool(m.properties.Use_product_copy_files) { + + if ctx.Config().ReleaseUseSystemFeatureXmlForUnavailableFeatures() { if featureXmlFiles := uniquePossibleFeatureXmlPaths(ctx); len(featureXmlFiles) > 0 { - ruleCmd.FlagWithInputList("--feature-xml-files=", featureXmlFiles, ",") + ruleCmd.FlagWithInputList("--unavailable-feature-xml-files=", featureXmlFiles, ",") } } + ruleCmd.FlagWithOutput(" > ", outputFile) rule.Build(ctx.ModuleName(), "Generating systemfeatures srcs filegroup") @@ -114,7 +113,6 @@ func JavaSystemFeaturesSrcsFactory() android.Module { module := &javaSystemFeaturesSrcs{} module.AddProperties(&module.properties) module.properties.Metadata_only = proptools.BoolPtr(false) - module.properties.Use_product_copy_files = proptools.BoolPtr(false) android.InitAndroidModule(module) return module } diff --git a/systemfeatures/system_features_test.go b/systemfeatures/system_features_test.go index e0210731f..3f6060b0a 100644 --- a/systemfeatures/system_features_test.go +++ b/systemfeatures/system_features_test.go @@ -51,18 +51,18 @@ java_system_features_srcs { android.AssertPathsRelativeToTopEquals(t, "Expected output file", []string{expectedOutputPath}, systemFeaturesModule.Srcs()) } -func TestJavaSystemFeaturesSrcsFromProductFiles(t *testing.T) { +func TestJavaSystemFeaturesSrcsFromXml(t *testing.T) { bp := ` java_system_features_srcs { name: "system-features-srcs", full_class_name: "com.android.test.RoSystemFeatures", - use_product_copy_files: true, } ` res := android.GroupFixturePreparers( android.FixtureRegisterWithContext(registerSystemFeaturesComponents), android.PrepareForTestWithBuildFlag("RELEASE_USE_SYSTEM_FEATURE_BUILD_FLAGS", "true"), + android.PrepareForTestWithBuildFlag("RELEASE_USE_SYSTEM_FEATURE_XML_FOR_UNAVAILABLE_FEATURES", "true"), android.PrepareForTestWithBuildFlag("RELEASE_SYSTEM_FEATURE_AUTOMOTIVE", "0"), android.FixtureModifyConfig(func(config android.Config) { config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.ProductCopyFiles = []string{ @@ -95,7 +95,7 @@ java_system_features_srcs { android.AssertStringDoesContain(t, "Expected fully class name", cmd, " com.android.test.RoSystemFeatures ") android.AssertStringDoesContain(t, "Expected readonly flag", cmd, "--readonly=true") android.AssertStringDoesContain(t, "Expected AUTOMOTIVE feature flag", cmd, "--feature=AUTOMOTIVE:0 ") - android.AssertStringDoesContain(t, "Expected feature xml files flag", cmd, "--feature-xml-files=frameworks/features.xml,frameworks/features2.xml,frameworks/featureswithowner.xml") + android.AssertStringDoesContain(t, "Expected feature xml files flag", cmd, "--unavailable-feature-xml-files=frameworks/features.xml,frameworks/features2.xml,frameworks/featureswithowner.xml") android.AssertStringDoesNotContain(t, "Unexpected feature xml file", cmd, "dstalreadyexists.xml") android.AssertStringDoesNotContain(t, "Unexpected feature xml file", cmd, "nonexistent.xml") android.AssertStringDoesNotContain(t, "Unexpected feature xml file", cmd, "wrongsubdir.xml") @@ -111,12 +111,12 @@ func TestJavaSystemFeaturesSrcsFromInvalidProductFiles(t *testing.T) { java_system_features_srcs { name: "system-features-srcs", full_class_name: "com.android.test.RoSystemFeatures", - use_product_copy_files: true, } ` android.GroupFixturePreparers( android.FixtureRegisterWithContext(registerSystemFeaturesComponents), + android.PrepareForTestWithBuildFlag("RELEASE_USE_SYSTEM_FEATURE_XML_FOR_UNAVAILABLE_FEATURES", "true"), android.FixtureModifyConfig(func(config android.Config) { config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.ProductCopyFiles = []string{ "frameworks/dstmissing.xml", -- cgit v1.2.3 From f79a5041bba9a731037fb5fe6a79c9429a3e60f4 Mon Sep 17 00:00:00 2001 From: John Wu Date: Fri, 25 Apr 2025 15:38:29 -0700 Subject: [Ravenizer] Support setting extra ravenizer args in Android.bp Test: TH Flag: EXEMPT host tool change only Bug: 411506416 Change-Id: I0830e98dadf3a60d1d7b0110d660aa6bc7a21167 --- java/base.go | 9 +++++++-- java/builder.go | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/java/base.go b/java/base.go index af3d493a1..f584535d3 100644 --- a/java/base.go +++ b/java/base.go @@ -256,6 +256,9 @@ type CommonProperties struct { // If true, the "Ravenizer" tool will remove all Mockito and DexMaker // classes from the output jar. Strip_mockito *bool + + // Extra arguments passed to Ravenizer + Flags []string } // Contributing api surface of the stub module. Is not visible to bp modules, and should @@ -1714,10 +1717,12 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath if j.ravenizer.enabled { ravenizerInput := outputFile ravenizerOutput := android.PathForModuleOut(ctx, "ravenizer", "", jarName) - ravenizerArgs := "" + + ravenizerArgs := j.properties.Ravenizer.Flags if proptools.Bool(j.properties.Ravenizer.Strip_mockito) { - ravenizerArgs = "--strip-mockito" + ravenizerArgs = append(ravenizerArgs, "--strip-mockito") } + TransformRavenizer(ctx, ravenizerOutput, ravenizerInput, ravenizerArgs) outputFile = ravenizerOutput localImplementationJars = android.Paths{ravenizerOutput} diff --git a/java/builder.go b/java/builder.go index 6d4605ea9..798af96e0 100644 --- a/java/builder.go +++ b/java/builder.go @@ -1093,14 +1093,14 @@ func TransformJetifier(ctx android.ModuleContext, outputFile android.WritablePat } func TransformRavenizer(ctx android.ModuleContext, outputFile android.WritablePath, - inputFile android.Path, ravenizerArgs string) { + inputFile android.Path, ravenizerArgs []string) { ctx.Build(pctx, android.BuildParams{ Rule: ravenizer, Description: "ravenizer", Output: outputFile, Input: inputFile, Args: map[string]string{ - "ravenizerArgs": ravenizerArgs, + "ravenizerArgs": strings.Join(ravenizerArgs, " "), }, }) } -- cgit v1.2.3 From f2bf7aa76b0d9c6e91456a0a50989ca836bda229 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Fri, 25 Apr 2025 16:05:02 -0700 Subject: Preallocate phony file string This saves about 1 second from soong-only analysis time. Test: Presubmits Change-Id: Ie60efee52dc434d1441046481d46e918e12de1ba --- android/phony.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/android/phony.go b/android/phony.go index 99ff0aaa4..c3144177a 100644 --- a/android/phony.go +++ b/android/phony.go @@ -15,6 +15,7 @@ package android import ( + "fmt" "strings" "sync" @@ -73,7 +74,15 @@ func (p *phonySingleton) GenerateBuildActions(ctx SingletonContext) { // be generated in the packaging step. Instead of emitting a blueprint/ninja phony directly, // create a makefile that defines the phonies that will be included in the packaging step. // Make will dedup the phonies there. + phonyFileSize := 0 + for _, phony := range p.phonyList { + phonyFileSize += 2*len(phony) + 11 + for _, dep := range p.phonyMap[phony] { + phonyFileSize += len(dep.String()) + 1 + } + } var buildPhonyFileContents strings.Builder + buildPhonyFileContents.Grow(phonyFileSize) for _, phony := range p.phonyList { buildPhonyFileContents.WriteString(".PHONY: ") buildPhonyFileContents.WriteString(phony) @@ -86,6 +95,9 @@ func (p *phonySingleton) GenerateBuildActions(ctx SingletonContext) { } buildPhonyFileContents.WriteString("\n") } + if buildPhonyFileContents.Len() != phonyFileSize { + panic(fmt.Sprintf("phonyFileSize calculation incorrect, expected %d, actual len: %d", phonyFileSize, buildPhonyFileContents.Len())) + } buildPhonyFile := PathForOutput(ctx, "soong_phony_targets.mk") writeValueIfChanged(ctx, absolutePath(buildPhonyFile.String()), buildPhonyFileContents.String()) } -- cgit v1.2.3 From 939be4e550e741979b8862c5368dd646ff3c4a1d Mon Sep 17 00:00:00 2001 From: Makoto Onuki Date: Fri, 25 Apr 2025 16:27:08 -0700 Subject: Support "data" for Ravenwood tests. Fix: 411656960 Test: atest RavenwoodCoreTest-light Test: m nothing --no-skip-soong-tests Flag: EXEMPT host side change only Change-Id: I894d6ae77503af103dfcb9ce05c590be3a72247a --- java/ravenwood.go | 26 +++++++++++++++++++++++++- java/ravenwood_test.go | 6 ++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/java/ravenwood.go b/java/ravenwood.go index 01aa25cd6..7886a38dc 100644 --- a/java/ravenwood.go +++ b/java/ravenwood.go @@ -99,7 +99,9 @@ type ravenwoodTest struct { ravenwoodTestProperties ravenwoodTestProperties testProperties testProperties - testConfig android.Path + + testConfig android.Path + data android.Paths forceOSType android.OsType forceArchType android.ArchType @@ -177,6 +179,22 @@ func (r *ravenwoodTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { DeviceTemplate: "${RavenwoodTestConfigTemplate}", HostTemplate: "${RavenwoodTestConfigTemplate}", }) + r.data = android.PathsForModuleSrc(ctx, r.testProperties.Data) + 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)...) + + r.data = android.SortedUniquePaths(r.data) + + var testData []android.DataPath + for _, data := range r.data { + dataPath := android.DataPath{SrcPath: data} + testData = append(testData, dataPath) + } + for _, d := range r.extraOutputFiles { + testData = append(testData, android.DataPath{SrcPath: d}) + } // Always enable Ravenizer for ravenwood tests. r.Library.ravenizer.enabled = true @@ -260,6 +278,12 @@ func (r *ravenwoodTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { installProps := ctx.InstallFile(installPath, "ravenwood.properties", propertiesOutputPath) installDeps = append(installDeps, installProps) + // Copy data files + for _, data := range r.data { + installedData := ctx.InstallFile(installPath, data.Rel(), data) + installDeps = append(installDeps, installedData) + } + // Install our JAR with all dependencies ctx.InstallFile(installPath, ctx.ModuleName()+".jar", r.outputFile, installDeps...) diff --git a/java/ravenwood_test.go b/java/ravenwood_test.go index 79a22e74e..90bfb216a 100644 --- a/java/ravenwood_test.go +++ b/java/ravenwood_test.go @@ -190,6 +190,10 @@ func TestRavenwoodTest(t *testing.T) { "jni-lib1", "ravenwood-runtime-jni2", ], + data: [ + "data/file1.txt", + "data2/sub/file2", + ], resource_apk: "app2", inst_resource_apk: "app3", sdk_version: "test_current", @@ -227,6 +231,8 @@ func TestRavenwoodTest(t *testing.T) { module.Output(installPathPrefix + "/ravenwood-test/lib64/libpink.so") module.Output(installPathPrefix + "/ravenwood-test/ravenwood-res-apks/ravenwood-res.apk") module.Output(installPathPrefix + "/ravenwood-test/ravenwood-res-apks/ravenwood-inst-res.apk") + module.Output(installPathPrefix + "/ravenwood-test/data/file1.txt") + module.Output(installPathPrefix + "/ravenwood-test/data2/sub/file2") module = ctx.ModuleForTests(t, "ravenwood-test-empty", "android_common") module.Output(installPathPrefix + "/ravenwood-test-empty/ravenwood.properties") -- cgit v1.2.3 From c12c20c7f60ee257b4a61ecf25bc7231bb673a45 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Fri, 25 Apr 2025 14:26:35 -0700 Subject: Convert more to ModuleProxy Convert most of the remaining uses of VisitDirectDeps, WalkDeps, GetDirectDepWithTag and GetDirectDepsWithTag to the ModuleProxy versions. Test: all soong tests pass Change-Id: Ia68d05c7dc91a99dc166c4f8c55fdab8f9c7446b --- aconfig/aconfig_declarations.go | 5 +++-- aconfig/aconfig_value_set.go | 5 +++-- aconfig/codegen/aconfig_declarations_group.go | 2 +- aidl_library/aidl_library.go | 2 +- android/filegroup.go | 2 +- android/mutator_test.go | 2 +- android/neverallow.go | 2 +- android/path_properties_test.go | 2 +- android/visibility.go | 2 +- cc/coverage.go | 4 ++-- cc/test.go | 2 +- filesystem/bootimg.go | 8 ++++---- filesystem/super_image.go | 4 ++-- filesystem/vbmeta.go | 4 ++-- fsgen/filesystem_creator.go | 4 ++-- java/device_host_converter.go | 2 +- java/dexpreopt_bootjars.go | 2 +- java/dexpreopt_check.go | 11 ++++++----- java/droiddoc.go | 6 +++--- java/genrule_combiner.go | 4 ++-- java/rro.go | 8 ++++---- java/system_modules.go | 2 +- java/systemserver_classpath_fragment.go | 5 +++-- sysprop/sysprop_library.go | 2 +- tradefed_modules/test_module_config.go | 2 +- 25 files changed, 49 insertions(+), 45 deletions(-) diff --git a/aconfig/aconfig_declarations.go b/aconfig/aconfig_declarations.go index 9589bf1fa..537420ca6 100644 --- a/aconfig/aconfig_declarations.go +++ b/aconfig/aconfig_declarations.go @@ -15,12 +15,13 @@ package aconfig import ( - "android/soong/android" "path/filepath" "slices" "strconv" "strings" + "android/soong/android" + "github.com/google/blueprint" ) @@ -145,7 +146,7 @@ func (module *DeclarationsModule) GenerateAndroidBuildActions(ctx android.Module values := make(map[string][]string) valuesFiles := make(map[string][]android.Path, 0) providerData := android.AconfigReleaseDeclarationsProviderData{} - ctx.VisitDirectDeps(func(dep android.Module) { + ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) { if depData, ok := android.OtherModuleProvider(ctx, dep, valueSetProviderKey); ok { depTag := ctx.OtherModuleDependencyTag(dep) for _, config := range configs { diff --git a/aconfig/aconfig_value_set.go b/aconfig/aconfig_value_set.go index d72ec48ff..cf0582664 100644 --- a/aconfig/aconfig_value_set.go +++ b/aconfig/aconfig_value_set.go @@ -15,10 +15,11 @@ package aconfig import ( - "android/soong/android" "fmt" "strings" + "android/soong/android" + "github.com/google/blueprint" ) @@ -106,7 +107,7 @@ func (module *ValueSetModule) GenerateAndroidBuildActions(ctx android.ModuleCont // valueSetProviderKey provider that aconfig modules can read and use // to append values to their aconfig actions. packages := make(map[string]android.Paths) - ctx.VisitDirectDeps(func(dep android.Module) { + ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) { if depData, ok := android.OtherModuleProvider(ctx, dep, valuesProviderKey); ok { srcs := make([]android.Path, len(depData.Values)) copy(srcs, depData.Values) diff --git a/aconfig/codegen/aconfig_declarations_group.go b/aconfig/codegen/aconfig_declarations_group.go index 6811d06b9..042762d42 100644 --- a/aconfig/codegen/aconfig_declarations_group.go +++ b/aconfig/codegen/aconfig_declarations_group.go @@ -76,7 +76,7 @@ func (adg *AconfigDeclarationsGroup) GenerateAndroidBuildActions(ctx android.Mod var aconfigDeclarationNames []string var intermediateCacheOutputPaths android.Paths var javaSrcjars android.Paths - ctx.VisitDirectDeps(func(dep android.Module) { + ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) { tag := ctx.OtherModuleDependencyTag(dep) if provider, ok := android.OtherModuleProvider(ctx, dep, android.CodegenInfoProvider); ok { diff --git a/aidl_library/aidl_library.go b/aidl_library/aidl_library.go index 1e0ab3056..690b458f6 100644 --- a/aidl_library/aidl_library.go +++ b/aidl_library/aidl_library.go @@ -99,7 +99,7 @@ func (lib *AidlLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { ) includeDirsDepSetBuilder.Direct(includeDir) - for _, dep := range ctx.GetDirectDepsWithTag(aidlLibraryTag) { + for _, dep := range ctx.GetDirectDepsProxyWithTag(aidlLibraryTag) { if info, ok := android.OtherModuleProvider(ctx, dep, AidlLibraryProvider); ok { includeDirsDepSetBuilder.Transitive(info.IncludeDirs) hdrsDepSetBuilder.Transitive(info.Hdrs) diff --git a/android/filegroup.go b/android/filegroup.go index 4fad52aaa..ffb99eaed 100644 --- a/android/filegroup.go +++ b/android/filegroup.go @@ -109,7 +109,7 @@ func (fg *fileGroup) GenerateAndroidBuildActions(ctx ModuleContext) { var intermediateCacheOutputPaths Paths var srcjars Paths modeInfos := make(map[string]ModeInfo) - ctx.VisitDirectDeps(func(module Module) { + ctx.VisitDirectDepsProxy(func(module ModuleProxy) { if dep, ok := OtherModuleProvider(ctx, module, CodegenInfoProvider); ok { aconfigDeclarations = append(aconfigDeclarations, dep.AconfigDeclarations...) intermediateCacheOutputPaths = append(intermediateCacheOutputPaths, dep.IntermediateCacheOutputPaths...) diff --git a/android/mutator_test.go b/android/mutator_test.go index f7ee7d857..cd4b68f0d 100644 --- a/android/mutator_test.go +++ b/android/mutator_test.go @@ -129,7 +129,7 @@ func TestFinalDepsPhase(t *testing.T) { ctx.BottomUp("final", func(ctx BottomUpMutatorContext) { counter, _ := finalGot.LoadOrStore(ctx.Module().String(), &atomic.Int64{}) counter.(*atomic.Int64).Add(1) - ctx.VisitDirectDeps(func(mod Module) { + ctx.VisitDirectDepsProxy(func(mod ModuleProxy) { counter, _ := finalGot.LoadOrStore(fmt.Sprintf("%s -> %s", ctx.Module().String(), mod), &atomic.Int64{}) counter.(*atomic.Int64).Add(1) }) diff --git a/android/neverallow.go b/android/neverallow.go index 530759052..7004751d9 100644 --- a/android/neverallow.go +++ b/android/neverallow.go @@ -742,7 +742,7 @@ func (r *rule) appliesToDirectDeps(ctx BottomUpMutatorContext) bool { } matches := false - ctx.VisitDirectDeps(func(m Module) { + ctx.VisitDirectDepsProxy(func(m ModuleProxy) { if !matches { name := ctx.OtherModuleName(m) matches = r.directDeps[name] diff --git a/android/path_properties_test.go b/android/path_properties_test.go index f2adf7e64..81bb5c1bc 100644 --- a/android/path_properties_test.go +++ b/android/path_properties_test.go @@ -55,7 +55,7 @@ func pathDepsMutatorTestModuleFactory() Module { } func (p *pathDepsMutatorTestModule) GenerateAndroidBuildActions(ctx ModuleContext) { - ctx.VisitDirectDeps(func(dep Module) { + ctx.VisitDirectDepsProxy(func(dep ModuleProxy) { if _, ok := ctx.OtherModuleDependencyTag(dep).(sourceOrOutputDependencyTag); ok { p.sourceDeps = append(p.sourceDeps, ctx.OtherModuleName(dep)) } diff --git a/android/visibility.go b/android/visibility.go index 915368710..ea5450a6a 100644 --- a/android/visibility.go +++ b/android/visibility.go @@ -533,7 +533,7 @@ func visibilityRuleEnforcer(ctx BottomUpMutatorContext) { qualified := createVisibilityModuleReference(ctx.ModuleName(), ctx.ModuleDir(), ctx.Module()) // Visit all the dependencies making sure that this module has access to them all. - ctx.VisitDirectDeps(func(dep Module) { + ctx.VisitDirectDepsProxy(func(dep ModuleProxy) { // Ignore dependencies that have an ExcludeFromVisibilityEnforcementTag tag := ctx.OtherModuleDependencyTag(dep) if _, ok := tag.(ExcludeFromVisibilityEnforcementTag); ok { diff --git a/cc/coverage.go b/cc/coverage.go index 371a1d304..15eace601 100644 --- a/cc/coverage.go +++ b/cc/coverage.go @@ -188,8 +188,8 @@ func (cov *coverage) flags(ctx ModuleContext, flags Flags, deps PathDeps) (Flags flags.Local.LdFlags = append(flags.Local.LdFlags, "--coverage") if ctx.Device() { - coverage := ctx.GetDirectDepWithTag(getGcovProfileLibraryName(ctx), CoverageDepTag).(*Module) - deps.WholeStaticLibs = append(deps.WholeStaticLibs, coverage.OutputFile().Path()) + coverage := ctx.GetDirectDepProxyWithTag(getGcovProfileLibraryName(ctx), CoverageDepTag) + deps.WholeStaticLibs = append(deps.WholeStaticLibs, android.OutputFileForModule(ctx, coverage, "")) flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--wrap,getenv") } } else if clangCoverage { diff --git a/cc/test.go b/cc/test.go index fed24671d..12b9716b4 100644 --- a/cc/test.go +++ b/cc/test.go @@ -435,7 +435,7 @@ func (test *testBinary) install(ctx ModuleContext, file android.Path) { if Bool(test.Properties.Standalone_test) { packagingSpecsBuilder := depset.NewBuilder[android.PackagingSpec](depset.TOPOLOGICAL) - ctx.VisitDirectDeps(func(dep android.Module) { + ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) { deps := android.OtherModuleProviderOrDefault(ctx, dep, android.InstallFilesProvider) packagingSpecsBuilder.Transitive(deps.TransitivePackagingSpecs) }) diff --git a/filesystem/bootimg.go b/filesystem/bootimg.go index 06d493e75..bf6323707 100644 --- a/filesystem/bootimg.go +++ b/filesystem/bootimg.go @@ -230,7 +230,7 @@ func (b *bootimg) GenerateAndroidBuildActions(ctx android.ModuleContext) { // TODO: Move this under BootimgInfo, as is, it's easy to confuse the bootImg module for // the underlying ramdisk module. if ramdisk := proptools.String(b.properties.Ramdisk_module); ramdisk != "" { - ramdiskModule := ctx.GetDirectDepWithTag(ramdisk, bootimgRamdiskDep) + ramdiskModule := ctx.GetDirectDepProxyWithTag(ramdisk, bootimgRamdiskDep) fsInfo, _ := android.OtherModuleProvider(ctx, ramdiskModule, FilesystemProvider) android.SetProvider(ctx, FilesystemProvider, fsInfo) } else { @@ -377,12 +377,12 @@ func (b *bootimg) buildBootImage(ctx android.ModuleContext, kernel android.Path) ramdiskName := proptools.String(b.properties.Ramdisk_module) if ramdiskName != "" { ramdisk := ctx.GetDirectDepWithTag(ramdiskName, bootimgRamdiskDep) - if filesystem, ok := ramdisk.(*filesystem); ok { + if fsInfo, ok := android.OtherModuleProvider(ctx, ramdisk, FilesystemProvider); ok { flag := "--ramdisk " if b.bootImageType.isVendorBoot() { flag = "--vendor_ramdisk " } - cmd.FlagWithInput(flag, filesystem.OutputPath()) + cmd.FlagWithInput(flag, fsInfo.Output) } else { ctx.PropertyErrorf("ramdisk", "%q is not android_filesystem module", ramdisk.Name()) return output @@ -546,7 +546,7 @@ func (b *bootimg) buildPropFileForMiscInfo(ctx android.ModuleContext) android.Pa bootImgType := proptools.String(b.properties.Boot_image_type) addStr("avb_"+bootImgType+"_add_hash_footer_args", b.getAvbHashFooterArgs(ctx)) if ramdisk := proptools.String(b.properties.Ramdisk_module); ramdisk != "" { - ramdiskModule := ctx.GetDirectDepWithTag(ramdisk, bootimgRamdiskDep) + ramdiskModule := ctx.GetDirectDepProxyWithTag(ramdisk, bootimgRamdiskDep) fsInfo, _ := android.OtherModuleProvider(ctx, ramdiskModule, FilesystemProvider) if fsInfo.HasOrIsRecovery { // Create a dup entry for recovery diff --git a/filesystem/super_image.go b/filesystem/super_image.go index cf7e125a0..3a0dcd07d 100644 --- a/filesystem/super_image.go +++ b/filesystem/super_image.go @@ -240,8 +240,8 @@ func (s *superImage) buildMiscInfo(ctx android.ModuleContext, superEmpty bool) ( missingPartitionErrorMessage += fmt.Sprintf("%s image listed in partition groups, but its module was not specified. ", partitionType) return } - mod := ctx.GetDirectDepWithTag(*name, subImageDepTag) - if mod == nil { + mod := ctx.GetDirectDepProxyWithTag(*name, subImageDepTag) + if mod.IsNil() { ctx.ModuleErrorf("Could not get dep %q", *name) return } diff --git a/filesystem/vbmeta.go b/filesystem/vbmeta.go index ac95988b5..c71fbb791 100644 --- a/filesystem/vbmeta.go +++ b/filesystem/vbmeta.go @@ -240,7 +240,7 @@ func (v *vbmeta) GenerateAndroidBuildActions(ctx android.ModuleContext) { Output android.Path } var includeDescriptorsFromImages []partitionWithName - for _, p := range ctx.GetDirectDepsWithTag(vbmetaPartitionDep) { + for _, p := range ctx.GetDirectDepsProxyWithTag(vbmetaPartitionDep) { bootImgInfo, ok := android.OtherModuleProvider(ctx, p, BootimgInfoProvider) if ok { includeDescriptorsFromImages = append(includeDescriptorsFromImages, partitionWithName{ @@ -284,7 +284,7 @@ func (v *vbmeta) GenerateAndroidBuildActions(ctx android.ModuleContext) { } seenRils := make(map[int]bool) - for _, cp := range ctx.GetDirectDepsWithTag(vbmetaChainedPartitionDep) { + for _, cp := range ctx.GetDirectDepsProxyWithTag(vbmetaChainedPartitionDep) { info, ok := android.OtherModuleProvider(ctx, cp, vbmetaPartitionProvider) if !ok { ctx.PropertyErrorf("chained_partitions", "Expected all modules in chained_partitions to provide vbmetaPartitionProvider, but %s did not", cp.Name()) diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go index 5e592059b..033d606f2 100644 --- a/fsgen/filesystem_creator.go +++ b/fsgen/filesystem_creator.go @@ -1128,7 +1128,7 @@ func getAvbInfo(config android.Config, partitionType string) avbInfo { } func (f *filesystemCreator) createFileListDiffTest(ctx android.ModuleContext, partitionType string, partitionModuleName string) android.Path { - partitionImage := ctx.GetDirectDepWithTag(partitionModuleName, generatedFilesystemDepTag) + partitionImage := ctx.GetDirectDepProxyWithTag(partitionModuleName, generatedFilesystemDepTag) filesystemInfo, ok := android.OtherModuleProvider(ctx, partitionImage, filesystem.FilesystemProvider) if !ok { ctx.ModuleErrorf("Expected module %s to provide FileysystemInfo", partitionModuleName) @@ -1160,7 +1160,7 @@ func createFailingCommand(ctx android.ModuleContext, message string) android.Pat } func createVbmetaDiff(ctx android.ModuleContext, vbmetaModuleName string, vbmetaPartitionName string) android.Path { - vbmetaModule := ctx.GetDirectDepWithTag(vbmetaModuleName, generatedVbmetaPartitionDepTag) + vbmetaModule := ctx.GetDirectDepProxyWithTag(vbmetaModuleName, generatedVbmetaPartitionDepTag) outputFilesProvider, ok := android.OtherModuleProvider(ctx, vbmetaModule, android.OutputFilesProvider) if !ok { ctx.ModuleErrorf("Expected module %s to provide OutputFiles", vbmetaModule) diff --git a/java/device_host_converter.go b/java/device_host_converter.go index b2a3674d2..ecf014fcc 100644 --- a/java/device_host_converter.go +++ b/java/device_host_converter.go @@ -102,7 +102,7 @@ func (d *DeviceHostConverter) GenerateAndroidBuildActions(ctx android.ModuleCont var transitiveImplementationJars []depset.DepSet[android.Path] var transitiveResourceJars []depset.DepSet[android.Path] - ctx.VisitDirectDepsWithTag(deviceHostConverterDepTag, func(m android.Module) { + ctx.VisitDirectDepsProxyWithTag(deviceHostConverterDepTag, func(m android.ModuleProxy) { if dep, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok { d.headerJars = append(d.headerJars, dep.HeaderJars...) d.implementationJars = append(d.implementationJars, dep.ImplementationJars...) diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index 8aa775635..bedc7f20c 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -540,7 +540,7 @@ func (dbj *dexpreoptBootJars) DepsMutator(ctx android.BottomUpMutatorContext) { // This dependency will be used to get the path to the deapexed dex boot jars and profile (via a provider) func addDependenciesOntoSelectedBootImageApexes(ctx android.BottomUpMutatorContext, apexes ...string) { psi := android.PrebuiltSelectionInfoMap{} - ctx.VisitDirectDepsWithTag(apexContributionsMetadataDepTag, func(am android.Module) { + ctx.VisitDirectDepsProxyWithTag(apexContributionsMetadataDepTag, func(am android.ModuleProxy) { if info, exists := android.OtherModuleProvider(ctx, am, android.PrebuiltSelectionInfoProvider); exists { psi = info } diff --git a/java/dexpreopt_check.go b/java/dexpreopt_check.go index 9d0f539ba..f7d46144a 100644 --- a/java/dexpreopt_check.go +++ b/java/dexpreopt_check.go @@ -95,16 +95,17 @@ func (m *dexpreoptSystemserverCheck) GenerateAndroidBuildActions(ctx android.Mod global := dexpreopt.GetGlobalConfig(ctx) targets := ctx.Config().Targets[android.Android] - ctx.VisitDirectDepsWithTag(systemServerJarDepTag, func(systemServerJar android.Module) { + ctx.VisitDirectDepsProxyWithTag(systemServerJarDepTag, func(systemServerJar android.ModuleProxy) { partition := "system" - if systemServerJar.InstallInSystemExt() && ctx.Config().InstallApexSystemServerDexpreoptSamePartition() { + commonInfo := android.OtherModulePointerProviderOrDefault(ctx, systemServerJar, android.CommonModuleInfoProvider) + if commonInfo.SystemExtSpecific && ctx.Config().InstallApexSystemServerDexpreoptSamePartition() { partition = ctx.DeviceConfig().SystemExtPath() // system_ext } var dexLocation string - if m, ok := systemServerJar.(ModuleWithStem); ok { - dexLocation = dexpreopt.GetSystemServerDexLocation(ctx, global, m.Stem()) + if javaInfo, ok := android.OtherModuleProvider(ctx, systemServerJar, JavaInfoProvider); ok { + dexLocation = dexpreopt.GetSystemServerDexLocation(ctx, global, javaInfo.Stem) } else { - ctx.PropertyErrorf("dexpreopt_systemserver_check", "%v is not a ModuleWithStem", systemServerJar.Name()) + ctx.PropertyErrorf("dexpreopt_systemserver_check", "%v does not have JavaInfo", systemServerJar.Name()) } odexLocation := dexpreopt.ToOdexPath(dexLocation, targets[0].Arch.ArchType, partition) odexPath := getInstallPath(ctx, odexLocation) diff --git a/java/droiddoc.go b/java/droiddoc.go index 67bd61318..a65427f8b 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -648,9 +648,9 @@ func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.Rule ctx.PropertyErrorf("custom_template", "must specify a template") } - ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) { - if t, ok := m.(*ExportedDroiddocDir); ok { - cmd.FlagWithArg("-templatedir ", t.dir.String()).Implicits(t.deps) + ctx.VisitDirectDepsProxyWithTag(droiddocTemplateTag, func(m android.ModuleProxy) { + if t, ok := android.OtherModuleProvider(ctx, m, ExportedDroiddocDirInfoProvider); ok { + cmd.FlagWithArg("-templatedir ", t.Dir.String()).Implicits(t.Deps) } else { ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_exported_dir", ctx.OtherModuleName(m)) } diff --git a/java/genrule_combiner.go b/java/genrule_combiner.go index feff60b7e..ec02ecef9 100644 --- a/java/genrule_combiner.go +++ b/java/genrule_combiner.go @@ -95,7 +95,7 @@ func (j *GenruleCombiner) GenerateAndroidBuildActions(ctx android.ModuleContext) // Collect the headers first, so that aconfig flag values for the libraries will override // values from the headers (if they are different). - ctx.VisitDirectDepsWithTag(genruleCombinerHeaderDepTag, func(m android.Module) { + ctx.VisitDirectDepsProxyWithTag(genruleCombinerHeaderDepTag, func(m android.ModuleProxy) { if dep, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok { j.headerJars = append(j.headerJars, dep.HeaderJars...) @@ -113,7 +113,7 @@ func (j *GenruleCombiner) GenerateAndroidBuildActions(ctx android.ModuleContext) ctx.PropertyErrorf("headers", "module %q cannot be used as a dependency", ctx.OtherModuleName(m)) } }) - ctx.VisitDirectDepsWithTag(staticLibTag, func(m android.Module) { + ctx.VisitDirectDepsProxyWithTag(staticLibTag, func(m android.ModuleProxy) { if dep, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok { j.implementationJars = append(j.implementationJars, dep.ImplementationJars...) j.implementationAndResourceJars = append(j.implementationAndResourceJars, dep.ImplementationAndResourcesJars...) diff --git a/java/rro.go b/java/rro.go index 4ae8d7fc7..0f9714d4a 100644 --- a/java/rro.go +++ b/java/rro.go @@ -358,12 +358,12 @@ func (a *AutogenRuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android. } var rroDirs android.Paths // Get rro dirs of the base app - ctx.VisitDirectDepsWithTag(rroDepTag, func(m android.Module) { - aarDep, _ := m.(AndroidLibraryDependency) + ctx.VisitDirectDepsProxyWithTag(rroDepTag, func(m android.ModuleProxy) { + javaInfo, _ := android.OtherModuleProvider(ctx, m, JavaInfoProvider) if ctx.InstallInProduct() { - rroDirs = filterRRO(aarDep.RRODirsDepSet(), product) + rroDirs = filterRRO(javaInfo.AndroidLibraryDependencyInfo.RRODirsDepSet, product) } else { - rroDirs = filterRRO(aarDep.RRODirsDepSet(), device) + rroDirs = filterRRO(javaInfo.AndroidLibraryDependencyInfo.RRODirsDepSet, device) } }) diff --git a/java/system_modules.go b/java/system_modules.go index 0d64f37ac..8b17c6d87 100644 --- a/java/system_modules.go +++ b/java/system_modules.go @@ -166,7 +166,7 @@ func (system *SystemModules) commonBuildActions(ctx android.ModuleContext) *Syst var jars android.Paths var transitiveStaticLibsHeaderJars []depset.DepSet[android.Path] - ctx.VisitDirectDepsWithTag(systemModulesLibsTag, func(module android.Module) { + ctx.VisitDirectDepsProxyWithTag(systemModulesLibsTag, func(module android.ModuleProxy) { if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok { jars = append(jars, dep.HeaderJars...) transitiveStaticLibsHeaderJars = append(transitiveStaticLibsHeaderJars, dep.TransitiveStaticLibsHeaderJars) diff --git a/java/systemserver_classpath_fragment.go b/java/systemserver_classpath_fragment.go index d745afc79..345090067 100644 --- a/java/systemserver_classpath_fragment.go +++ b/java/systemserver_classpath_fragment.go @@ -164,8 +164,9 @@ var LibraryNameToPartitionInfoProvider = blueprint.NewProvider[LibraryNameToPart func (s *SystemServerClasspathModule) setPartitionInfoOfLibraries(ctx android.ModuleContext) { libraryNameToPartition := map[string]string{} - ctx.VisitDirectDepsWithTag(systemServerClasspathFragmentContentDepTag, func(m android.Module) { - libraryNameToPartition[m.Name()] = m.PartitionTag(ctx.DeviceConfig()) + ctx.VisitDirectDepsProxyWithTag(systemServerClasspathFragmentContentDepTag, func(m android.ModuleProxy) { + info := android.OtherModulePointerProviderOrDefault(ctx, m, android.CommonModuleInfoProvider) + libraryNameToPartition[m.Name()] = info.PartitionTag }) android.SetProvider(ctx, LibraryNameToPartitionInfoProvider, LibraryNameToPartitionInfo{ LibraryNameToPartition: libraryNameToPartition, diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go index a80ff43eb..a82bf66de 100644 --- a/sysprop/sysprop_library.go +++ b/sysprop/sysprop_library.go @@ -97,7 +97,7 @@ type SyspropLibraryInfo struct { func (g *syspropJavaGenRule) GenerateAndroidBuildActions(ctx android.ModuleContext) { var checkApiFileTimeStamp android.WritablePath - ctx.VisitDirectDeps(func(dep android.Module) { + ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) { if info, ok := android.OtherModuleProvider(ctx, dep, SyspropLibraryInfoProvider); ok { checkApiFileTimeStamp = info.CheckApiFileTimeStamp } diff --git a/tradefed_modules/test_module_config.go b/tradefed_modules/test_module_config.go index 5535a0bc3..c9ef551d6 100644 --- a/tradefed_modules/test_module_config.go +++ b/tradefed_modules/test_module_config.go @@ -342,7 +342,7 @@ func (m *testModuleConfigHostModule) GenerateAndroidBuildActions(ctx android.Mod // Ensure the base listed is the right type by checking that we get the expected provider data. // Returns false on errors and the context is updated with an error indicating the baseType expected. func (m *testModuleConfigModule) validateBase(ctx android.ModuleContext, depTag *dependencyTag, baseType string, baseShouldBeHost bool) { - ctx.VisitDirectDepsWithTag(*depTag, func(dep android.Module) { + ctx.VisitDirectDepsProxyWithTag(*depTag, func(dep android.ModuleProxy) { if provider, ok := android.OtherModuleProvider(ctx, dep, tradefed.BaseTestProviderKey); ok { if baseShouldBeHost == provider.IsHost { m.provider = provider -- cgit v1.2.3 From 3348b97c2fc861d268a5754c105d8639dae63344 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Fri, 25 Apr 2025 14:52:17 -0700 Subject: Move checkDoubleLoadableLibraries to GenerateAndroidBuildActions Move checkDoubleLoadableLibraries to GenerateAndroidBuildActions where it can access the LinkableInfoProvider from its dependencies. Test: TestDoubleLoadableDep Change-Id: I251c881de9596467b663638058118a445540e4e7 --- cc/cc.go | 30 ++++++++++++++++-------------- cc/testing.go | 2 ++ 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/cc/cc.go b/cc/cc.go index db5d9b116..a93e88780 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -174,6 +174,7 @@ type CcInfo struct { OdmAvailable bool ProductAvailable bool IsVendorPublicLibrary bool + DoubleLoadable bool // Allowable SdkMemberTypes of this module type. SdkMemberTypes []android.SdkMemberType LocalFlags LocalOrGlobalFlagsInfo @@ -291,7 +292,6 @@ func RegisterCCBuildComponents(ctx android.RegistrationContext) { ctx.Transition("lto", <oTransitionMutator{}) ctx.BottomUp("check_linktype", checkLinkTypeMutator) - ctx.BottomUp("double_loadable", checkDoubleLoadableLibraries) }) ctx.PostApexMutators(func(ctx android.RegisterMutatorsContext) { @@ -2540,6 +2540,8 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { buildComplianceMetadataInfo(ctx, c, deps) + c.checkDoubleLoadableLibraries(ctx) + if b, ok := c.compiler.(*baseCompiler); ok { c.hasAidl = b.hasSrcExt(ctx, ".aidl") c.hasLex = b.hasSrcExt(ctx, ".l") || b.hasSrcExt(ctx, ".ll") @@ -2585,6 +2587,7 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { ProductAvailable: c.ProductAvailable(), SdkMemberTypes: c.sdkMemberTypes, IsVendorPublicLibrary: c.IsVendorPublicLibrary(), + DoubleLoadable: Bool(c.VendorProperties.Double_loadable), LocalFlags: LocalOrGlobalFlagsInfo{ CommonFlags: c.flags.Local.CommonFlags, CFlags: c.flags.Local.CFlags, @@ -3572,14 +3575,15 @@ func checkLinkTypeMutator(ctx android.BottomUpMutatorContext) { // If a library has a vendor variant and is a (transitive) dependency of an LLNDK library, // it is subject to be double loaded. Such lib should be explicitly marked as double_loadable: true // or as vndk-sp (vndk: { enabled: true, support_system_process: true}). -func checkDoubleLoadableLibraries(ctx android.BottomUpMutatorContext) { - check := func(child, parent android.Module) bool { - to, ok := child.(*Module) +func (c *Module) checkDoubleLoadableLibraries(ctx android.ModuleContext) { + check := func(child, parent android.ModuleProxy) bool { + ccInfo, ok := android.OtherModuleProvider(ctx, child, CcInfoProvider) if !ok { return false } - if lib, ok := to.linker.(*libraryDecorator); !ok || !lib.shared() { + linkableInfo, ok := android.OtherModuleProvider(ctx, child, LinkableInfoProvider) + if !ok || !linkableInfo.Shared { return false } @@ -3602,30 +3606,28 @@ func checkDoubleLoadableLibraries(ctx android.BottomUpMutatorContext) { // Even if target lib has no vendor variant, keep checking dependency // graph in case it depends on vendor_available or product_available // but not double_loadable transtively. - if !to.HasNonSystemVariants() { + if !linkableInfo.HasNonSystemVariants { return true } // The happy path. Keep tracking dependencies until we hit a non double-loadable // one. - if Bool(to.VendorProperties.Double_loadable) { + if ccInfo.DoubleLoadable { return true } - if to.IsLlndk() { + if linkableInfo.IsLlndk { return false } ctx.ModuleErrorf("links a library %q which is not LL-NDK, "+ "VNDK-SP, or explicitly marked as 'double_loadable:true'. "+ - "Dependency list: %s", ctx.OtherModuleName(to), ctx.GetPathString(false)) + "Dependency list: %s", ctx.OtherModuleName(child), ctx.GetPathString(false)) return false } - if module, ok := ctx.Module().(*Module); ok { - if lib, ok := module.linker.(*libraryDecorator); ok && lib.shared() { - if lib.HasLLNDKStubs() { - ctx.WalkDeps(check) - } + if lib, ok := c.linker.(*libraryDecorator); ok && lib.shared() { + if lib.HasLLNDKStubs() { + ctx.WalkDepsProxy(check) } } } diff --git a/cc/testing.go b/cc/testing.go index 69ae11dfd..7cfcac8c5 100644 --- a/cc/testing.go +++ b/cc/testing.go @@ -104,6 +104,7 @@ func commonDefaultModules() string { name: "libclang_rt.hwasan", defaults: ["toolchain_libs_defaults"], srcs: [""], + double_loadable: true, } cc_prebuilt_library_static { @@ -130,6 +131,7 @@ func commonDefaultModules() string { cc_prebuilt_library_shared { name: "libclang_rt.ubsan_standalone", defaults: ["toolchain_libs_defaults"], + double_loadable: true, srcs: [""], } -- cgit v1.2.3 From 4e1fa776d3561565d58911a818c21642b313b540 Mon Sep 17 00:00:00 2001 From: Zhi Dou Date: Thu, 24 Apr 2025 23:04:45 +0000 Subject: add dependency check for mts test This change adds dependency check for mts test. For mts test it should not depends on the implementation of the framework jars, and it should not add static libraries which depends on the implementation of the framework. This change adds a allow list for the existing modules. Test: m Bug: 411715086 Change-Id: I620533827bcfc3844884b2c379828ac404e127dd --- android/container.go | 6 +- android/container_violations.go | 333 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 319 insertions(+), 20 deletions(-) diff --git a/android/container.go b/android/container.go index b2a774c7d..b57ba0582 100644 --- a/android/container.go +++ b/android/container.go @@ -177,7 +177,9 @@ var ctsContainerBoundaryFunc containerBoundaryFunc = func(mctx ModuleContext) bo val := reflect.ValueOf(prop).Elem() if val.Kind() == reflect.Struct { testSuites := val.FieldByName("Test_suites") - if testSuites.IsValid() && testSuites.Kind() == reflect.Slice && slices.Contains(testSuites.Interface().([]string), "cts") { + if testSuites.IsValid() && testSuites.Kind() == reflect.Slice && slices.ContainsFunc(testSuites.Interface().([]string), func(s string) bool { + return s == "cts" || strings.HasPrefix(s, "mts") + }) { return true } } @@ -299,7 +301,7 @@ var ( restricted: []restriction{ { dependency: UnstableContainer, - errorMessage: "CTS module should not depend on the modules that contain the " + + errorMessage: "CTS/MTS module should not depend on the modules that contain the " + "platform implementation details, including \"framework\". Depending on these " + "modules may lead to disclosure of implementation details and regression " + "due to API changes across platform versions. Try depending on the stubs instead " + diff --git a/android/container_violations.go b/android/container_violations.go index 4c6386df6..bfb9c257a 100644 --- a/android/container_violations.go +++ b/android/container_violations.go @@ -4,21 +4,29 @@ // 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 +// 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 var ContainerDependencyViolationAllowlist = map[string][]string{ + // go/keep-sorted start case=no block=yes newline_separated=yes + "AdExtServicesApkUITestsAppConsent": { + "framework", // cts -> unstable + }, + "adservices-service-core": { "gson", // apex [com.android.adservices, com.android.extservices] -> apex [com.android.virt] }, + "AdServicesSharedLibrariesUnitTests": { + "framework", // cts -> unstable + }, + "android.car-module.impl": { "modules-utils-preconditions", // apex [com.android.car.framework] -> apex [com.android.adservices, com.android.appsearch, com.android.cellbroadcast, com.android.extservices, com.android.ondevicepersonalization, com.android.tethering, com.android.uwb, com.android.wifi, test_com.android.cellbroadcast, test_com.android.wifi] }, @@ -27,10 +35,30 @@ var ContainerDependencyViolationAllowlist = map[string][]string{ "framework", // cts -> unstable }, + "AppSearchMockingServicesTests": { + "framework", // cts -> unstable + }, + + "AppSearchServicesTests": { + "framework", // cts -> unstable + }, + + "AppsIndexerTests": { + "framework", // cts -> unstable + }, + "art-aconfig-flags-java-lib": { "framework-api-annotations-lib", // apex [com.android.art, com.android.art.debug, com.android.art.testing, test_imgdiag_com.android.art, test_jitzygote_com.android.art] -> system }, + "AvfRkpdAppIntegrationTests": { + "framework", // cts -> unstable + }, + + "BitmapTestApp": { + "framework", // cts -> unstable + }, + "Bluetooth": { "app-compat-annotations", // apex [com.android.bt] -> system "framework-bluetooth-pre-jarjar", // apex [com.android.bt] -> system @@ -44,6 +72,10 @@ var ContainerDependencyViolationAllowlist = map[string][]string{ "app-compat-annotations", // apex [com.android.bt] -> system }, + "CaptivePortalLoginTests": { + "framework", // cts -> unstable + }, + "CarServiceUpdatable": { "modules-utils-os", // apex [com.android.car.framework] -> apex [com.android.permission, test_com.android.permission] "modules-utils-preconditions", // apex [com.android.car.framework] -> apex [com.android.adservices, com.android.appsearch, com.android.cellbroadcast, com.android.extservices, com.android.ondevicepersonalization, com.android.tethering, com.android.uwb, com.android.wifi, test_com.android.cellbroadcast, test_com.android.wifi] @@ -55,14 +87,38 @@ var ContainerDependencyViolationAllowlist = map[string][]string{ "framework", // apex [com.android.cellbroadcast, test_com.android.cellbroadcast] -> system }, + "CellBroadcastReceiverComplianceTests": { + "framework", // cts -> unstable + }, + + "CellBroadcastReceiverOemUnitTests": { + "framework", // cts -> unstable + }, + + "CellBroadcastServiceTests": { + "framework", // cts -> unstable + }, + "connectivity-net-module-utils-bpf": { "net-utils-device-common-struct-base", // apex [com.android.tethering] -> system }, + "ConnectivityCoverageTests": { + "framework", // cts -> unstable + }, + "conscrypt-aconfig-flags-lib": { "aconfig-annotations-lib-sdk-none", // apex [com.android.conscrypt, test_com.android.conscrypt] -> system }, + "ContactsIndexerTests": { + "framework", // cts -> unstable + }, + + "CrashRecoveryModuleTests": { + "framework", // cts -> unstable + }, + "cronet_aml_base_base_java": { "framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system "jsr305", // apex [com.android.tethering] -> apex [com.android.adservices, com.android.devicelock, com.android.extservices, com.android.healthfitness, com.android.media, com.android.mediaprovider, test_com.android.media, test_com.android.mediaprovider] @@ -174,6 +230,14 @@ var ContainerDependencyViolationAllowlist = map[string][]string{ "framework", // cts -> unstable }, + "CtsAppLocalesBackupApp1": { + "framework", // cts -> unstable + }, + + "CtsAppLocalesBackupApp2": { + "framework", // cts -> unstable + }, + "CtsAppOpsTestCases": { "framework", // cts -> unstable }, @@ -198,6 +262,10 @@ var ContainerDependencyViolationAllowlist = map[string][]string{ "framework", // cts -> unstable }, + "CtsBackupRestoreEventLoggerApp": { + "framework", // cts -> unstable + }, + "CtsBatterySavingTestCases": { "framework", // cts -> unstable }, @@ -338,6 +406,10 @@ var ContainerDependencyViolationAllowlist = map[string][]string{ "framework", // cts -> unstable }, + "CtsFullBackupApp": { + "framework", // cts -> unstable + }, + "CtsHostsideCompatChangeTestsApp": { "framework", // cts -> unstable }, @@ -374,6 +446,10 @@ var ContainerDependencyViolationAllowlist = map[string][]string{ "framework", // cts -> unstable }, + "CtsKeyValueBackupApp": { + "framework", // cts -> unstable + }, + "CtsLegacyNotification27TestCases": { "framework", // cts -> unstable }, @@ -474,11 +550,6 @@ var ContainerDependencyViolationAllowlist = map[string][]string{ "framework", // cts -> unstable }, - // TODO(b/387499846): Remove once migrated to sdk_version. - "CtsMediaRouterTestCases": { - "framework", // cts -> unstable - }, - "CtsMediaRouterHostSideTestBluetoothPermissionsApp": { "framework", // cts -> unstable }, @@ -491,6 +562,11 @@ var ContainerDependencyViolationAllowlist = map[string][]string{ "framework", // cts -> unstable }, + // TODO(b/387499846): Remove once migrated to sdk_version. + "CtsMediaRouterTestCases": { + "framework", // cts -> unstable + }, + // TODO(b/387500109): Remove once migrated to sdk_version. "CtsMediaSessionTestCases": { "framework", // cts -> unstable @@ -572,6 +648,14 @@ var ContainerDependencyViolationAllowlist = map[string][]string{ "framework", // cts -> unstable }, + "CtsPermissionBackupApp": { + "framework", // cts -> unstable + }, + + "CtsPermissionBackupApp22": { + "framework", // cts -> unstable + }, + "CtsPermissionsSyncTestApp": { "framework", // cts -> unstable }, @@ -604,6 +688,26 @@ var ContainerDependencyViolationAllowlist = map[string][]string{ "framework", // cts -> unstable }, + "CtsRestrictedModeNoActionApp1": { + "framework", // cts -> unstable + }, + + "CtsRestrictedModeNoActionApp2": { + "framework", // cts -> unstable + }, + + "CtsRestrictedModeOptedInApp": { + "framework", // cts -> unstable + }, + + "CtsRestrictedModeOptedOutApp": { + "framework", // cts -> unstable + }, + + "CtsRootBluetoothTestCases": { + "framework", // cts -> unstable + }, + "CtsSandboxedAdIdManagerTests": { "framework", // cts -> unstable }, @@ -833,6 +937,14 @@ var ContainerDependencyViolationAllowlist = map[string][]string{ "modules-utils-expresslog", // apex [com.android.devicelock] -> apex [com.android.bt, com.android.car.framework] }, + "DisruptiveTestApp": { + "framework", // cts -> unstable + }, + + "DocumentsUITests": { + "framework", // cts -> unstable + }, + "FederatedCompute": { "auto_value_annotations", // apex [com.android.ondevicepersonalization] -> apex [com.android.adservices, com.android.extservices, com.android.extservices_tplus] }, @@ -849,14 +961,14 @@ var ContainerDependencyViolationAllowlist = map[string][]string{ "configinfra_framework_flags_java_lib", // apex [com.android.configinfrastructure] -> system }, - "framework-connectivity-t.impl": { + // TODO(b/382743602): Remove "app-compat-annotations" and depend on the stub version jar + // TODO(b/382301972): Remove the violations and use jarjar_rename or jarjar_prefix + "framework-connectivity-b.impl": { "app-compat-annotations", // apex [com.android.tethering] -> system "framework-connectivity-pre-jarjar", // apex [com.android.tethering] -> system }, - // TODO(b/382743602): Remove "app-compat-annotations" and depend on the stub version jar - // TODO(b/382301972): Remove the violations and use jarjar_rename or jarjar_prefix - "framework-connectivity-b.impl": { + "framework-connectivity-t.impl": { "app-compat-annotations", // apex [com.android.tethering] -> system "framework-connectivity-pre-jarjar", // apex [com.android.tethering] -> system }, @@ -888,6 +1000,22 @@ var ContainerDependencyViolationAllowlist = map[string][]string{ "app-compat-annotations", // apex [com.android.wifi, test_com.android.wifi] -> system }, + "FrameworksIkeTests": { + "framework", // cts -> unstable + }, + + "FrameworksVcnTests": { + "framework", // cts -> unstable + }, + + "FrameworksWifiApiTests": { + "framework", // cts -> unstable + }, + + "FrameworksWifiTests": { + "framework", // cts -> unstable + }, + "grpc-java-core-internal": { "gson", // apex [com.android.adservices, com.android.devicelock, com.android.extservices] -> apex [com.android.virt] "perfmark-api-lib", // apex [com.android.adservices, com.android.devicelock, com.android.extservices] -> system @@ -905,6 +1033,14 @@ var ContainerDependencyViolationAllowlist = map[string][]string{ "framework-api-annotations-lib", // apex [com.android.art, com.android.art.debug, com.android.art.testing, test_imgdiag_com.android.art, test_jitzygote_com.android.art] -> system }, + "LibStatsPullTests": { + "framework", // cts -> unstable + }, + + "libtextclassifier_java_tests": { + "framework", // cts -> unstable + }, + "loadlibrarytest_product_app": { "libnativeloader_vendor_shared_lib", // product -> vendor }, @@ -976,6 +1112,18 @@ var ContainerDependencyViolationAllowlist = map[string][]string{ "framework", // apex [com.android.mediaprovider, test_com.android.mediaprovider] -> system }, + "MediaProviderClientTests": { + "framework", // cts -> unstable + }, + + "MediaProviderTests": { + "framework", // cts -> unstable + }, + + "MediaRouterServiceTests": { + "framework", // cts -> unstable + }, + "MockSatelliteGatewayServiceApp": { "framework", // cts -> unstable }, @@ -984,6 +1132,30 @@ var ContainerDependencyViolationAllowlist = map[string][]string{ "framework", // cts -> unstable }, + "MtsConscryptFdSocketTestCases": { + "framework", // cts -> unstable + }, + + "MtsConscryptTestCases": { + "framework", // cts -> unstable + }, + + "MtsLibcoreBouncyCastleTestCases": { + "framework", // cts -> unstable + }, + + "MtsLibcoreOkHttpTestCases": { + "framework", // cts -> unstable + }, + + "MtsTetheringTestLatestSdk": { + "framework", // cts -> unstable + }, + + "MtsWifiTestCases": { + "framework", // cts -> unstable + }, + "net-utils-device-common-netlink": { "net-utils-device-common-struct-base", // apex [com.android.tethering] -> system }, @@ -992,6 +1164,26 @@ var ContainerDependencyViolationAllowlist = map[string][]string{ "net-utils-device-common-struct-base", // apex [com.android.tethering] -> system }, + "NetHttpCoverageTests": { + "framework", // cts -> unstable + }, + + "NetworkStackCoverageTests": { + "framework", // cts -> unstable + }, + + "NetworkStackRootTests": { + "framework", // cts -> unstable + }, + + "NetworkStackTests": { + "framework", // cts -> unstable + }, + + "NfcManagerTests": { + "framework", // cts -> unstable + }, + "NfcNciApex": { // TODO(b/383782511): Remove the violations once the infra is fixed. "android.nfc.flags-aconfig-java", // apex [com.android.nfcservices] -> system @@ -1000,6 +1192,14 @@ var ContainerDependencyViolationAllowlist = map[string][]string{ "framework-nfc.impl", // apex [com.android.nfcservices] -> system }, + "NfcNciUnitTests": { + "framework", // cts -> unstable + }, + + "NfcTestCases": { + "framework", // cts -> unstable + }, + "okhttp-norepackage": { "okhttp-android-util-log", // apex [com.android.adservices, com.android.devicelock, com.android.extservices] -> system }, @@ -1012,14 +1212,46 @@ var ContainerDependencyViolationAllowlist = map[string][]string{ "auto_value_annotations", // apex [com.android.devicelock] -> apex [com.android.adservices, com.android.extservices, com.android.extservices_tplus] }, + "PackageWatchdogTest": { + "framework", // cts -> unstable + }, + "PermissionController-lib": { "safety-center-annotations", // apex [com.android.permission, test_com.android.permission] -> system }, + "PermissionControllerOutOfProcessTests": { + "framework", // cts -> unstable + }, + "PlatformProperties": { "sysprop-library-stub-platform", // apex [com.android.bt, com.android.nfcservices, com.android.tethering, com.android.virt, com.android.wifi, test_com.android.wifi] -> system }, + "pts-bot-mts": { + "framework", // cts -> unstable + }, + + "RebootReadinessUnitTests": { + "framework", // cts -> unstable + }, + + "RkpdAppIntegrationTests": { + "framework", // cts -> unstable + }, + + "RkpdAppStressTests": { + "framework", // cts -> unstable + }, + + "RkpdAppUnitTests": { + "framework", // cts -> unstable + }, + + "RollbackPackageHealthObserverTests": { + "framework", // cts -> unstable + }, + "safety-center-config": { "safety-center-annotations", // apex [com.android.permission, test_com.android.permission] -> system }, @@ -1040,14 +1272,30 @@ var ContainerDependencyViolationAllowlist = map[string][]string{ "safety-center-annotations", // apex [com.android.permission, test_com.android.permission] -> system }, + "SdkSandboxFrameworkUnitTests": { + "framework", // cts -> unstable + }, + "SdkSandboxManagerDisabledTests": { "framework", // cts -> unstable }, + "SdkSandboxManagerServiceUnitTests": { + "framework", // cts -> unstable + }, + "SdkSandboxManagerTests": { "framework", // cts -> unstable }, + "SdkSandboxRestrictionsTests": { + "framework", // cts -> unstable + }, + + "SdkSandboxUnitTests": { + "framework", // cts -> unstable + }, + "service-art.impl": { "auto_value_annotations", // apex [com.android.art, com.android.art.debug, com.android.art.testing, test_imgdiag_com.android.art, test_jitzygote_com.android.art] -> apex [com.android.adservices, com.android.extservices, com.android.extservices_tplus] }, @@ -1061,6 +1309,13 @@ var ContainerDependencyViolationAllowlist = map[string][]string{ "libprotobuf-java-nano", // apex [com.android.tethering] -> apex [com.android.wifi, test_com.android.wifi] }, + // TODO(b/382301972): Remove the violations and use jarjar_rename or jarjar_prefix + "service-connectivity-b-pre-jarjar": { + "framework-connectivity-pre-jarjar", // apex [com.android.tethering] -> system + "framework-connectivity-b-pre-jarjar", // apex [com.android.tethering] -> system + "framework-connectivity-t-pre-jarjar", // apex [com.android.tethering] -> system + }, + "service-connectivity-pre-jarjar": { "framework-connectivity-pre-jarjar", // apex [com.android.tethering] -> system }, @@ -1074,13 +1329,6 @@ var ContainerDependencyViolationAllowlist = map[string][]string{ "framework-connectivity-t-pre-jarjar", // apex [com.android.tethering] -> system }, - // TODO(b/382301972): Remove the violations and use jarjar_rename or jarjar_prefix - "service-connectivity-b-pre-jarjar": { - "framework-connectivity-pre-jarjar", // apex [com.android.tethering] -> system - "framework-connectivity-b-pre-jarjar", // apex [com.android.tethering] -> system - "framework-connectivity-t-pre-jarjar", // apex [com.android.tethering] -> system - }, - "service-entitlement": { "auto_value_annotations", // apex [com.android.wifi, test_com.android.wifi] -> apex [com.android.adservices, com.android.extservices, com.android.extservices_tplus] }, @@ -1115,6 +1363,10 @@ var ContainerDependencyViolationAllowlist = map[string][]string{ "framework-connectivity-t-pre-jarjar", // apex [com.android.tethering] -> system }, + "service-rkp-unittest": { + "framework", // cts -> unstable + }, + "service-thread-pre-jarjar": { "framework-connectivity-pre-jarjar", // apex [com.android.tethering] -> system "framework-connectivity-t-pre-jarjar", // apex [com.android.tethering] -> system @@ -1128,10 +1380,30 @@ var ContainerDependencyViolationAllowlist = map[string][]string{ "auto_value_annotations", // apex [com.android.wifi, test_com.android.wifi] -> apex [com.android.adservices, com.android.extservices, com.android.extservices_tplus] }, + "ServiceBluetoothTests": { + "framework", // cts -> unstable + }, + + "ServiceUwbTests": { + "framework", // cts -> unstable + }, + + "StableNetHttpCoverageTests": { + "framework", // cts -> unstable + }, + + "StatsdTestUtilsTest": { + "framework", // cts -> unstable + }, + "TelephonyDeviceTest": { "framework", // cts -> unstable }, + "TeleServiceTests": { + "framework", // cts -> unstable + }, + "tensorflowlite_java": { "android-support-annotations", // apex [com.android.adservices, com.android.extservices, com.android.ondevicepersonalization] -> system }, @@ -1152,11 +1424,35 @@ var ContainerDependencyViolationAllowlist = map[string][]string{ "connectivity-internal-api-util", // apex [com.android.tethering] -> system }, + "TetheringPrivilegedTests": { + "framework", // cts -> unstable + }, + "tetheringstatsprotos": { "ext", // apex [com.android.tethering] -> system "framework", // apex [com.android.tethering] -> system }, + "TetheringTests": { + "framework-minus-apex", // cts -> unstable + }, + + "TextClassifierNotificationTests": { + "framework", // cts -> unstable + }, + + "ThreadBorderRouterIntegrationTests": { + "framework", // cts -> unstable + }, + + "ThreadNetworkIntegrationTests": { + "framework", // cts -> unstable + }, + + "ThreadNetworkTrelDisabledTests": { + "framework", // cts -> unstable + }, + "uwb_aconfig_flags_lib": { "ext", // apex [com.android.uwb] -> system "framework", // apex [com.android.uwb] -> system @@ -1172,4 +1468,5 @@ var ContainerDependencyViolationAllowlist = map[string][]string{ "framework-wifi-pre-jarjar", // apex [com.android.wifi, test_com.android.wifi] -> system "jsr305", // apex [com.android.wifi, test_com.android.wifi] -> apex [com.android.adservices, com.android.devicelock, com.android.extservices, com.android.healthfitness, com.android.media, com.android.mediaprovider, test_com.android.media, test_com.android.mediaprovider] }, + // go/keep-sorted end } -- cgit v1.2.3 From 0d8360a391461338e62a640bb45eabcbf203349e Mon Sep 17 00:00:00 2001 From: Jiakai Zhang Date: Mon, 28 Apr 2025 12:17:04 +0100 Subject: Ignore bootclasspath libraries in manifest_check. A shared library may be added to the bootclasspath since a certain platform version. Apps' manifests may still include such a library, to maintain compilatibility with old platforms, especially when the app is built elsewhere and dropped as a prebuilt, not being part of the platform build. Soong filters out bootclasspath libraries when constructing CLC, and passes the filtered CLC to manifest_check, causing an expected discrepancy between the build time value and the manifest value. This change fixes it by filtering out bootclasspath libraries from the manifest value, to match the build time value. Bug: 413330617 Test: m Flag: EXEMPT bugfix Change-Id: Ic46909c096e208e3fc4cee99cf298f571e9bc269 --- java/app.go | 4 ++++ scripts/manifest_check.py | 17 +++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/java/app.go b/java/app.go index 1e35506e3..b82ffd140 100644 --- a/java/app.go +++ b/java/app.go @@ -2224,6 +2224,10 @@ func (u *usesLibrary) verifyUsesLibraries(ctx android.ModuleContext, inputFile a cmd.FlagWithArg("--missing-optional-uses-library ", lib) } + for _, lib := range ctx.Config().BootJars() { + cmd.FlagWithArg("--bootclasspath-libs ", lib) + } + rule.Build("verify_uses_libraries", "verify ") return outputFile } diff --git a/scripts/manifest_check.py b/scripts/manifest_check.py index 96dc5a6ce..975709e72 100755 --- a/scripts/manifest_check.py +++ b/scripts/manifest_check.py @@ -80,6 +80,13 @@ def parse_args(): dest='dexpreopt_configs', action='append', help='a paths to a dexpreopt.config of some library') + parser.add_argument( + '--bootclasspath-libs', + dest='bootclasspath_libs', + action='append', + help='jars in the bootclasspath, which should be ignored by the uses ' + 'libraries check', + default=[]) parser.add_argument('--aapt', dest='aapt', help='path to aapt executable') parser.add_argument( '--output', '-o', dest='output', help='output AndroidManifest.xml file') @@ -94,7 +101,8 @@ C_OFF = "\033[0m" C_BOLD = "\033[1m" -def enforce_uses_libraries(manifest, required, optional, missing_optional, relax, is_apk, path): +def enforce_uses_libraries(manifest, required, optional, missing_optional, relax, is_apk, path, + bootclasspath_libs): """Verify that the tags in the manifest match those provided by the build system. @@ -113,6 +121,10 @@ def enforce_uses_libraries(manifest, required, optional, missing_optional, relax manifest_required, manifest_optional, tags = extract_uses_libs_xml( manifest) + # Filter out bootclasspath libs from the manifest to ignore them in the check. + manifest_required = [lib for lib in manifest_required if lib not in bootclasspath_libs] + manifest_optional = [lib for lib in manifest_optional if lib not in bootclasspath_libs] + # Trim namespace component. Normally Soong does that automatically when it # handles module names specified in Android.bp properties. However not all # entries in the manifest correspond to real modules: some of @@ -361,7 +373,8 @@ def main(): # script was passed a special parameter to suppress exceptions. errmsg = enforce_uses_libraries(manifest, required, optional, args.missing_optional_uses_libraries, - args.enforce_uses_libraries_relax, is_apk, args.input) + args.enforce_uses_libraries_relax, is_apk, args.input, + args.bootclasspath_libs) # Create a status file that is empty on success, or contains an # error message on failure. When exceptions are suppressed, -- cgit v1.2.3 From dcbb556465616a6c5073f85c967f4c1e6cefdde9 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Mon, 28 Apr 2025 17:29:32 +0000 Subject: Replace PrimaryModule with IsPrimaryModule cc.Module is now marked as `FreeModuleAfterGenerateAndroidBuildActions` which sets the `logicMogic` to nil. This means if a secondary variant is visited after the primary variant, we will run into nil pointer exceptions. To fix this, introduce a new IsPrimaryModule function. Bug: 414037543 Test: XREF_CORPUS=foo m nothing Change-Id: I192ea1102dd99f3e60892dbc1cdd661ab513e4ff --- android/base_module_context.go | 10 ++++++++++ cc/builder.go | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/android/base_module_context.go b/android/base_module_context.go index 55220fe9b..1e8de8198 100644 --- a/android/base_module_context.go +++ b/android/base_module_context.go @@ -197,6 +197,12 @@ type BaseModuleContext interface { // only done once for all variants of a module. PrimaryModule() Module + // IsPrimaryModule returns if the current module is the first variant. Variants of a module are always visited in + // order by mutators and GenerateBuildActions, so the data created by the current mutator can be read from the + // Module returned by PrimaryModule without data races. This can be used to perform singleton actions that are + // only done once for all variants of a module. + IsPrimaryModule(module ModuleOrProxy) bool + // IsFinalModule returns if the current module is the last variant. Variants of a module are always visited in // order by mutators and GenerateBuildActions, so the data created by the current mutator can be read from all // variants using VisitAllModuleVariants if the current module is the last one. This can be used to perform @@ -563,6 +569,10 @@ func (b *baseModuleContext) PrimaryModule() Module { return b.bp.PrimaryModule().(Module) } +func (b *baseModuleContext) IsPrimaryModule(module ModuleOrProxy) bool { + return b.bp.IsPrimaryModule(module) +} + func (b *baseModuleContext) IsFinalModule(module ModuleOrProxy) bool { return b.bp.IsFinalModule(module) } diff --git a/cc/builder.go b/cc/builder.go index 98816e3d6..10e228040 100644 --- a/cc/builder.go +++ b/cc/builder.go @@ -517,7 +517,7 @@ func transformSourceToObj(ctx android.ModuleContext, subdir string, srcFiles, no coverageFiles = make(android.Paths, 0, len(srcObjFiles)) } var kytheFiles android.Paths - if flags.emitXrefs && ctx.Module() == ctx.PrimaryModule() { + if flags.emitXrefs && ctx.IsPrimaryModule(ctx.Module()) { kytheFiles = make(android.Paths, 0, len(srcObjFiles)) } @@ -694,7 +694,7 @@ func transformSourceToObj(ctx android.ModuleContext, subdir string, srcFiles, no }) // Register post-process build statements (such as for tidy or kythe). - if emitXref && ctx.Module() == ctx.PrimaryModule() { + if emitXref && ctx.IsPrimaryModule(ctx.Module()) { kytheFile := android.ObjPathWithExt(ctx, subdir, srcFile, "kzip") ctx.Build(pctx, android.BuildParams{ Rule: kytheExtract, -- cgit v1.2.3 From 55826fb950ebabc56743249898734b0f982657b4 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Mon, 28 Apr 2025 10:48:13 -0700 Subject: Ban -Wno-all. Bug: http://b/308179380 Change-Id: I411d7483846ceda9d5d2d46c27ac5217076aeba1 --- cc/config/global.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cc/config/global.go b/cc/config/global.go index 82258cbee..442bc36a0 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -376,6 +376,7 @@ var ( "-pedantic", "-pedantic-errors", "-Werror=pedantic", + "-Wno-all", "-Wno-everything", } -- cgit v1.2.3 From 54340509f82f1fd966ff8a114b2ad6dd2d807487 Mon Sep 17 00:00:00 2001 From: Zhi Dou Date: Mon, 28 Apr 2025 19:04:42 +0000 Subject: make automatic jarjar to all flags in framework jar This change remove the limitation that automatic jarjar that only applies for flags with declaration having exportable: true. This change enable automatic jarjar for all flag classes in a java_library if it has jarjar_prefix. This change also changes the jarjar_profix rule propagation logic. If a module has sdk_level == test_current, then it won't collect jarjar rule so it won't propagate the jarjar rule up. Test: m Flag: RELEASE_JARJAR_FLAGS_IN_FRAMEWORK Bug: 411715086 Change-Id: Ia74aa0bec50e9122ff27e0a6acd782dbe7fb8f88 --- aconfig/codegen/java_aconfig_library.go | 2 +- android/config.go | 5 +++++ java/base.go | 9 +++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/aconfig/codegen/java_aconfig_library.go b/aconfig/codegen/java_aconfig_library.go index 0c40d78a5..f6c511159 100644 --- a/aconfig/codegen/java_aconfig_library.go +++ b/aconfig/codegen/java_aconfig_library.go @@ -107,7 +107,7 @@ func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) GenerateSourceJarBuild }, }) - if declarations.Exportable { + if ctx.Config().ReleaseJarjarFlagsInFramework() || declarations.Exportable { // Mark our generated code as possibly needing jarjar repackaging // The repackaging only happens when the corresponding aconfig_declaration // has property exportable true diff --git a/android/config.go b/android/config.go index aa60ab2fd..cae5a54ae 100644 --- a/android/config.go +++ b/android/config.go @@ -316,6 +316,11 @@ func (c Config) ReleaseAconfigStorageVersion() string { } } +// TODO: b/414412266 Remove this flag after feature released. +func (c Config) ReleaseJarjarFlagsInFramework() bool { + return c.config.productVariables.GetBuildFlagBool("RELEASE_JARJAR_FLAGS_IN_FRAMEWORK") +} + // A DeviceConfig object represents the configuration for a particular device // being built. For now there will only be one of these, but in the future there // may be multiple devices being built. diff --git a/java/base.go b/java/base.go index f584535d3..27fd06afd 100644 --- a/java/base.go +++ b/java/base.go @@ -2925,6 +2925,15 @@ func (this Module) GetDebugString() string { // Merge the jarjar rules we inherit from our dependencies, any that have been added directly to // us, and if it's been set, apply the jarjar_prefix property to rename them. func (module *Module) collectJarJarRules(ctx android.ModuleContext) *JarJarProviderData { + + // Stop collect jarjar_prefix jarjar rules if the module has test sdk scope. + // If a module uses test API scope, which means in its source code and static dependencies + // it could only use API exposed through the test surface. So it should not apply the jarjar + // rules set by any bootclass path jar + if ctx.Config().ReleaseJarjarFlagsInFramework() && module.SdkVersion(ctx).Kind == android.SdkTest { + return nil + } + // Gather repackage information from deps result := collectDirectDepsProviders(ctx) -- cgit v1.2.3 From 4d7a3956cc00acebff8340f2ecb2907db27b4d8a Mon Sep 17 00:00:00 2001 From: Zhi Dou Date: Mon, 28 Apr 2025 19:08:54 +0000 Subject: Remove methods for new storage features This change removes methods for RELEASE_READ_FROM_NEW_STORAGE_CC, AND RELEASE_FINGERPRINT_ACONFIG_PACKAGES since these two features have been completed. Test: m Bug: 409598478 Bug: 328444881 Change-Id: I1c466a3b891bfd34a3e17f96956b213f1e9dcbe7 --- android/config.go | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/android/config.go b/android/config.go index aa60ab2fd..b8d2b1103 100644 --- a/android/config.go +++ b/android/config.go @@ -271,11 +271,6 @@ func (c Config) ReleaseNdkAbiMonitored() bool { return c.config.productVariables.GetBuildFlagBool("RELEASE_NDK_ABI_MONITORED") } -// Enable read flag from new storage, for C/C++ -func (c Config) ReleaseReadFromNewStorageCc() bool { - return c.config.productVariables.GetBuildFlagBool("RELEASE_READ_FROM_NEW_STORAGE_CC") -} - func (c Config) ReleaseHiddenApiExportableStubs() bool { return c.config.productVariables.GetBuildFlagBool("RELEASE_HIDDEN_API_EXPORTABLE_STUBS") || Bool(c.config.productVariables.HiddenapiExportableStubs) @@ -294,11 +289,6 @@ func (c Config) ReleaseUseSystemFeatureXmlForUnavailableFeatures() bool { return c.config.productVariables.GetBuildFlagBool("RELEASE_USE_SYSTEM_FEATURE_XML_FOR_UNAVAILABLE_FEATURES") } -// TODO: b/409598478 - Remove FINGERPRINT build flag. -func (c Config) ReleaseFingerprintAconfigPackages() bool { - return c.config.productVariables.GetBuildFlagBool("RELEASE_FINGERPRINT_ACONFIG_PACKAGES") -} - func (c Config) ReleaseRustUseArmTargetArchVariant() bool { return c.config.productVariables.GetBuildFlagBool("RELEASE_RUST_USE_ARM_TARGET_ARCH_VARIANT") } -- cgit v1.2.3 From 7edab0f0bd696957943480d0cfc5c41585888d72 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Mon, 28 Apr 2025 12:57:31 -0700 Subject: Disallow output from soong on RUN_BUILD_TEST builds If soong prints to stdout/stderr, users see that print every time they run analysis, and it's oftentimes unactionable. Require that soong is silent on successful builds. Bug: 414415162 Test: manually Change-Id: Id8f3892ae08c28fe8e3df80eaeeb44c6ea1cb448 --- ui/build/build.go | 2 +- ui/build/soong.go | 141 +++++++++++++++++++++++++++-------------------------- ui/status/ninja.go | 24 ++++++--- 3 files changed, 91 insertions(+), 76 deletions(-) diff --git a/ui/build/build.go b/ui/build/build.go index 79c461be0..ad1ab03e7 100644 --- a/ui/build/build.go +++ b/ui/build/build.go @@ -367,7 +367,7 @@ func Build(ctx Context, config Config) { genKatiSuffix(ctx, config) if what&RunSoong != 0 { - runSoong(ctx, config) + runSoong(ctx, config, what&RunBuildTests != 0) } if what&RunKati != 0 { diff --git a/ui/build/soong.go b/ui/build/soong.go index 44b39cd82..ab00c1280 100644 --- a/ui/build/soong.go +++ b/ui/build/soong.go @@ -559,7 +559,7 @@ func migrateOutputSymlinks(ctx Context, config Config) error { return fixOutDirSymlinks(ctx, config, outDir) } -func runSoong(ctx Context, config Config) { +func runSoong(ctx Context, config Config, enforceNoSoongOutput bool) { ctx.BeginTrace(metrics.RunSoong, "soong") defer ctx.EndTrace() @@ -611,81 +611,86 @@ func runSoong(ctx Context, config Config) { fifo := filepath.Join(config.OutDir(), ".ninja_fifo") nr := status.NewNinjaReader(ctx, ctx.Status.StartTool(), fifo) - defer nr.Close() - - var ninjaCmd string - var ninjaArgs []string - switch config.ninjaCommand { - case NINJA_N2: - ninjaCmd = config.N2Bin() - ninjaArgs = []string{ - // TODO: implement these features, or remove them. - //"-d", "keepdepfile", - //"-d", "stats", - //"-o", "usesphonyoutputs=yes", - //"-o", "preremoveoutputs=yes", - //"-w", "dupbuild=err", - //"-w", "outputdir=err", - //"-w", "missingoutfile=err", - "-v", - "-j", strconv.Itoa(config.Parallel()), - "--frontend-file", fifo, - "-f", filepath.Join(config.SoongOutDir(), "bootstrap.ninja"), - } - case NINJA_SISO: - ninjaCmd = config.SisoBin() - ninjaArgs = []string{ - "ninja", - // TODO: implement these features, or remove them. - //"-d", "keepdepfile", - //"-d", "stats", - //"-o", "usesphonyoutputs=yes", - //"-o", "preremoveoutputs=yes", - //"-w", "dupbuild=err", - //"-w", "outputdir=err", - //"-w", "missingoutfile=err", - "-v", - "-j", strconv.Itoa(config.Parallel()), - //"--frontend-file", fifo, - "--log_dir", config.SoongOutDir(), - "-f", filepath.Join(config.SoongOutDir(), "bootstrap.ninja"), + func() { + defer nr.Close() + var ninjaCmd string + var ninjaArgs []string + switch config.ninjaCommand { + case NINJA_N2: + ninjaCmd = config.N2Bin() + ninjaArgs = []string{ + // TODO: implement these features, or remove them. + //"-d", "keepdepfile", + //"-d", "stats", + //"-o", "usesphonyoutputs=yes", + //"-o", "preremoveoutputs=yes", + //"-w", "dupbuild=err", + //"-w", "outputdir=err", + //"-w", "missingoutfile=err", + "-v", + "-j", strconv.Itoa(config.Parallel()), + "--frontend-file", fifo, + "-f", filepath.Join(config.SoongOutDir(), "bootstrap.ninja"), + } + case NINJA_SISO: + ninjaCmd = config.SisoBin() + ninjaArgs = []string{ + "ninja", + // TODO: implement these features, or remove them. + //"-d", "keepdepfile", + //"-d", "stats", + //"-o", "usesphonyoutputs=yes", + //"-o", "preremoveoutputs=yes", + //"-w", "dupbuild=err", + //"-w", "outputdir=err", + //"-w", "missingoutfile=err", + "-v", + "-j", strconv.Itoa(config.Parallel()), + //"--frontend-file", fifo, + "--log_dir", config.SoongOutDir(), + "-f", filepath.Join(config.SoongOutDir(), "bootstrap.ninja"), + } + default: + // NINJA_NINJA is the default. + ninjaCmd = config.NinjaBin() + ninjaArgs = []string{ + "-d", "keepdepfile", + "-d", "stats", + "-o", "usesphonyoutputs=yes", + "-o", "preremoveoutputs=yes", + "-w", "dupbuild=err", + "-w", "outputdir=err", + "-w", "missingoutfile=err", + "-j", strconv.Itoa(config.Parallel()), + "--frontend_file", fifo, + "-f", filepath.Join(config.SoongOutDir(), "bootstrap.ninja"), + } } - default: - // NINJA_NINJA is the default. - ninjaCmd = config.NinjaBin() - ninjaArgs = []string{ - "-d", "keepdepfile", - "-d", "stats", - "-o", "usesphonyoutputs=yes", - "-o", "preremoveoutputs=yes", - "-w", "dupbuild=err", - "-w", "outputdir=err", - "-w", "missingoutfile=err", - "-j", strconv.Itoa(config.Parallel()), - "--frontend_file", fifo, - "-f", filepath.Join(config.SoongOutDir(), "bootstrap.ninja"), + + if extra, ok := config.Environment().Get("SOONG_UI_NINJA_ARGS"); ok { + ctx.Printf(`CAUTION: arguments in $SOONG_UI_NINJA_ARGS=%q, e.g. "-n", can make soong_build FAIL or INCORRECT`, extra) + ninjaArgs = append(ninjaArgs, strings.Fields(extra)...) } - } - if extra, ok := config.Environment().Get("SOONG_UI_NINJA_ARGS"); ok { - ctx.Printf(`CAUTION: arguments in $SOONG_UI_NINJA_ARGS=%q, e.g. "-n", can make soong_build FAIL or INCORRECT`, extra) - ninjaArgs = append(ninjaArgs, strings.Fields(extra)...) - } + ninjaArgs = append(ninjaArgs, targets...) - ninjaArgs = append(ninjaArgs, targets...) + cmd := Command(ctx, config, "soong bootstrap", + ninjaCmd, ninjaArgs...) - cmd := Command(ctx, config, "soong bootstrap", - ninjaCmd, ninjaArgs...) + var ninjaEnv Environment - var ninjaEnv Environment + // This is currently how the command line to invoke soong_build finds the + // root of the source tree and the output root + ninjaEnv.Set("TOP", os.Getenv("TOP")) - // This is currently how the command line to invoke soong_build finds the - // root of the source tree and the output root - ninjaEnv.Set("TOP", os.Getenv("TOP")) + cmd.Environment = &ninjaEnv + cmd.Sandbox = soongSandbox + cmd.RunAndStreamOrFatal() + }() - cmd.Environment = &ninjaEnv - cmd.Sandbox = soongSandbox - cmd.RunAndStreamOrFatal() + if enforceNoSoongOutput && nr.HasAnyOutput() { + ctx.Fatalf("Soong must not output anything to stdout/stderr on a successful build, please remove the prints") + } } targets := make([]string, 0, 0) diff --git a/ui/status/ninja.go b/ui/status/ninja.go index 73edbf625..ba9f0f9d7 100644 --- a/ui/status/ninja.go +++ b/ui/status/ninja.go @@ -55,12 +55,13 @@ func NewNinjaReader(ctx logger.Logger, status ToolStatus, fifo string) *NinjaRea } type NinjaReader struct { - status ToolStatus - fifo string - forceClose chan bool - done chan bool - cancelOpen chan bool - running map[uint32]*Action + status ToolStatus + fifo string + forceClose chan bool + done chan bool + cancelOpen chan bool + running map[uint32]*Action + hasAnyOutput bool } const NINJA_READER_CLOSE_TIMEOUT = 5 * time.Second @@ -240,7 +241,8 @@ func (n *NinjaReader) run() { err = fmt.Errorf("exited with code: %d", exitCode) } - outputWithErrorHint := errorHintGenerator.GetOutputWithErrorHint(msg.EdgeFinished.GetOutput(), exitCode) + rawOutput := msg.EdgeFinished.GetOutput() + outputWithErrorHint := errorHintGenerator.GetOutputWithErrorHint(rawOutput, exitCode) n.status.FinishAction(ActionResult{ Action: started, Output: outputWithErrorHint, @@ -258,6 +260,8 @@ func (n *NinjaReader) run() { Tags: msg.EdgeFinished.GetTags(), }, }) + + n.hasAnyOutput = n.hasAnyOutput || len(rawOutput) > 0 } } if msg.Message != nil { @@ -281,6 +285,12 @@ func (n *NinjaReader) run() { } } +// Returns true if any command run by ninja had any output to stdout/stderr. Be sure to only +// call this after close() to ensure all commands have been seen. +func (n *NinjaReader) HasAnyOutput() bool { + return n.hasAnyOutput +} + func readVarInt(r *bufio.Reader) (int, error) { ret := 0 shift := uint(0) -- cgit v1.2.3 From 14fce53e3ef2c5f505c48459fb5d18eaf86fc5a7 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Mon, 28 Apr 2025 20:48:37 +0000 Subject: Delete multitree related code Multitree introduced a special-case in Soong finder to look for generated Android.bp files in out/. Multitree development is not supported, so remove this special-case. Test: m nothing --no-skip-soong-tests Change-Id: I20d48e340e3184687b76555dcd4a31730c0d4fbc --- android/config.go | 11 ----------- ui/build/config.go | 7 ------- ui/build/finder.go | 11 +---------- 3 files changed, 1 insertion(+), 28 deletions(-) diff --git a/android/config.go b/android/config.go index cae5a54ae..7d5500f81 100644 --- a/android/config.go +++ b/android/config.go @@ -2292,17 +2292,6 @@ func (c *config) UseHostMusl() bool { return Bool(c.productVariables.HostMusl) } -// ApiSurfaces directory returns the source path inside the api_surfaces repo -// (relative to workspace root). -func (c *config) ApiSurfacesDir(s ApiSurface, version string) string { - return filepath.Join( - "build", - "bazel", - "api_surfaces", - s.String(), - version) -} - func (c *config) JavaCoverageEnabled() bool { return c.IsEnvTrue("EMMA_INSTRUMENT") || c.IsEnvTrue("EMMA_INSTRUMENT_STATIC") || c.IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") } diff --git a/ui/build/config.go b/ui/build/config.go index 92a88bbe5..4fc2ef78e 100644 --- a/ui/build/config.go +++ b/ui/build/config.go @@ -100,7 +100,6 @@ type configImpl struct { skipSoong bool skipNinja bool skipSoongTests bool - searchApiDir bool // Scan the Android.bp files generated in out/api_surfaces skipMetricsUpload bool buildStartedTime int64 // For metrics-upload-only - manually specify a build-started time buildFromSourceStub bool @@ -943,8 +942,6 @@ func (c *configImpl) parseArgs(ctx Context, args []string) { c.skipMetricsUpload = true } else if arg == "--mk-metrics" { c.reportMkMetrics = true - } else if arg == "--search-api-dir" { - c.searchApiDir = true } else if strings.HasPrefix(arg, "--ninja_weight_source=") { source := strings.TrimPrefix(arg, "--ninja_weight_source=") if source == "ninja_log" { @@ -1165,10 +1162,6 @@ func (c *configImpl) SoongOutDir() string { return filepath.Join(c.OutDir(), "soong") } -func (c *configImpl) ApiSurfacesOutDir() string { - return filepath.Join(c.OutDir(), "api_surfaces") -} - func (c *configImpl) PrebuiltOS() string { switch runtime.GOOS { case "linux": diff --git a/ui/build/finder.go b/ui/build/finder.go index a4834f6f3..8407f6397 100644 --- a/ui/build/finder.go +++ b/ui/build/finder.go @@ -63,7 +63,7 @@ func NewSourceFinder(ctx Context, config Config) (f *finder.Finder) { // Set up configuration parameters for the Finder cache. cacheParams := finder.CacheParams{ WorkingDirectory: dir, - RootDirs: androidBpSearchDirs(config), + RootDirs: []string{"."}, FollowSymlinks: config.environ.IsEnvTrue("ALLOW_BP_UNDER_SYMLINKS"), ExcludeDirs: []string{".git", ".repo"}, PruneFiles: pruneFiles, @@ -106,15 +106,6 @@ func NewSourceFinder(ctx Context, config Config) (f *finder.Finder) { return f } -func androidBpSearchDirs(config Config) []string { - dirs := []string{"."} // always search from root of source tree. - if config.searchApiDir { - // Search in out/api_surfaces - dirs = append(dirs, config.ApiSurfacesOutDir()) - } - return dirs -} - func findProductAndBoardConfigFiles(entries finder.DirEntries) (dirNames []string, fileNames []string) { matches := []string{} for _, foundName := range entries.FileNames { -- cgit v1.2.3 From 1ab9be5e35cf023e860ac42f449617955e06cd49 Mon Sep 17 00:00:00 2001 From: Makoto Onuki Date: Mon, 28 Apr 2025 11:54:57 -0700 Subject: Support "tradefed_options" and "test_runner_options" in android_ravenwood_test Bug: 292141694 Test: $ANDROID_BUILD_TOP/frameworks/base/ravenwood/scripts/run-ravenwood-tests.sh -s Flag: EXEMPT host test change only Change-Id: I36d6af9de775575e63ca57b2681e988d92a3d3d8 --- java/ravenwood.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/java/ravenwood.go b/java/ravenwood.go index 7886a38dc..c0cdc32eb 100644 --- a/java/ravenwood.go +++ b/java/ravenwood.go @@ -172,12 +172,14 @@ func (r *ravenwoodTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { r.forceArchType = ctx.Config().BuildArch r.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{ - TestConfigProp: r.testProperties.Test_config, - TestConfigTemplateProp: r.testProperties.Test_config_template, - TestSuites: r.testProperties.Test_suites, - AutoGenConfig: r.testProperties.Auto_gen_config, - DeviceTemplate: "${RavenwoodTestConfigTemplate}", - HostTemplate: "${RavenwoodTestConfigTemplate}", + TestConfigProp: r.testProperties.Test_config, + TestConfigTemplateProp: r.testProperties.Test_config_template, + OptionsForAutogenerated: r.testProperties.Test_options.Tradefed_options, + TestRunnerOptions: r.testProperties.Test_options.Test_runner_options, + TestSuites: r.testProperties.Test_suites, + AutoGenConfig: r.testProperties.Auto_gen_config, + DeviceTemplate: "${RavenwoodTestConfigTemplate}", + HostTemplate: "${RavenwoodTestConfigTemplate}", }) r.data = android.PathsForModuleSrc(ctx, r.testProperties.Data) r.data = append(r.data, android.PathsForModuleSrc(ctx, r.testProperties.Device_common_data)...) -- cgit v1.2.3 From 042b8210a572946ce5b4102cd41a4a3b5631b669 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Mon, 28 Apr 2025 15:54:14 -0700 Subject: Track deps on build fingerprint/thumbprint files In make builds, we rely on `m installclean` to delete a bunch of files and force them to be regenerated. CI always runs `m installclean`, but locally it's often not run. In soon-only builds, we try to avoid requiring that step, so we more precisely track dependencies. However, we don't want to cause excessive rebuilds still, so we don't add dependencies on stuff like the build date. Previously, I think I was concerned that the build fingerprint/ thumbprint files would change every build and cause excessive rebuilds, so I didn't add them as dependencies. And they actually did use to change every build, and still do on ci, because they contain the build number. But we've changed it so that now local builds don't include the build number, so it doesn't cause rebuilds locally, but still will on CI. And we do want the rebuild behavior on CI in order to update the build number. There was a bug reported where the build number was not being updated correctly, due to the lack of rebuilds. Bug: 411231354 Test: m out/soong/.intermediates/build/soong/fsgen/aosp_cf_x86_64_only_phone_generated_device/android_x86_64_silvermont/target_files.zip, check the build number in META/misc_info.txt and ODM/etc/build.prop. Then change the build number and rebuild, ensure both of those files get the new build number. Then rebuild without changing the build number, ensure you get the "no work to do" message. Change-Id: I0d5ada76da4af6465c71c3e0b000a480c647f2fe --- android/build_prop.go | 7 ++----- filesystem/filesystem.go | 27 ++++++++++++++++++++------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/android/build_prop.go b/android/build_prop.go index 2f71bc03f..59f11655b 100644 --- a/android/build_prop.go +++ b/android/build_prop.go @@ -142,14 +142,11 @@ func (p *buildPropModule) GenerateAndroidBuildActions(ctx ModuleContext) { cmd.FlagWithInput("--build-hostname-file=", config.BuildHostnameFile(ctx)) cmd.FlagWithInput("--build-number-file=", config.BuildNumberFile(ctx)) - // shouldn't depend on BuildFingerprintFile and BuildThumbprintFile to prevent from rebuilding - // on every incremental build. - cmd.FlagWithArg("--build-fingerprint-file=", config.BuildFingerprintFile(ctx).String()) + cmd.FlagWithInput("--build-fingerprint-file=", config.BuildFingerprintFile(ctx)) // Export build thumbprint only if the product has specified at least one oem fingerprint property // b/17888863 if shouldAddBuildThumbprint(config) { - // In the previous make implementation, a dependency was not added on the thumbprint file - cmd.FlagWithArg("--build-thumbprint-file=", config.BuildThumbprintFile(ctx).String()) + cmd.FlagWithInput("--build-thumbprint-file=", config.BuildThumbprintFile(ctx)) } cmd.FlagWithArg("--build-username=", config.Getenv("BUILD_USERNAME")) // shouldn't depend on BUILD_DATETIME_FILE to prevent from rebuilding on every incremental diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index b63633c9b..2b8d7f80e 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -1115,7 +1115,9 @@ func (f *filesystem) buildPropFile(ctx android.ModuleContext) (android.Path, and addPath("avb_key_path", key) } addStr("partition_name", f.partitionName()) - addStr("avb_add_hashtree_footer_args", f.getAvbAddHashtreeFooterArgs(ctx)) + avbAddHashTreeFooterArgs, avbAddHashTreeFooterDeps := f.getAvbAddHashtreeFooterArgs(ctx) + addStr("avb_add_hashtree_footer_args", avbAddHashTreeFooterArgs) + deps = append(deps, avbAddHashTreeFooterDeps...) } if f.properties.File_contexts != nil && f.properties.Precompiled_file_contexts != nil { @@ -1200,6 +1202,7 @@ func (f *filesystem) buildPropFileForMiscInfo(ctx android.ModuleContext) android addStr := func(name string, value string) { lines = append(lines, fmt.Sprintf("%s=%s", name, value)) } + var deps android.Paths addStr("use_dynamic_partition_size", "true") addStr("ext_mkuserimg", "mkuserimg_mke2fs") @@ -1209,7 +1212,9 @@ func (f *filesystem) buildPropFileForMiscInfo(ctx android.ModuleContext) android if proptools.Bool(f.properties.Use_avb) { addStr("avb_"+f.partitionName()+"_hashtree_enable", "true") - addStr("avb_"+f.partitionName()+"_add_hashtree_footer_args", strings.TrimSpace(f.getAvbAddHashtreeFooterArgs(ctx))) + avbAddHashTreeFooterArgs, avbAddHashTreeFooterDeps := f.getAvbAddHashtreeFooterArgs(ctx) + addStr("avb_"+f.partitionName()+"_add_hashtree_footer_args", strings.TrimSpace(avbAddHashTreeFooterArgs)) + deps = append(deps, avbAddHashTreeFooterDeps...) } if f.selinuxFc != nil { @@ -1260,15 +1265,21 @@ func (f *filesystem) buildPropFileForMiscInfo(ctx android.ModuleContext) android android.WriteFileRule(ctx, propFilePreProcessing, strings.Join(lines, "\n")) propFile := android.PathForModuleOut(ctx, "prop_file_for_misc_info") ctx.Build(pctx, android.BuildParams{ - Rule: textFileProcessorRule, - Input: propFilePreProcessing, - Output: propFile, + Rule: textFileProcessorRule, + Input: propFilePreProcessing, + Output: propFile, + Implicits: deps, }) return propFile } -func (f *filesystem) getAvbAddHashtreeFooterArgs(ctx android.ModuleContext) string { +// Returns the avb_add_hashtree_footer_args value for this module. This value depends on the +// contents of some other files, which will be returned as the second return value, and must +// be tracked as implicit deps. The result should also be passed through textFileProcessorRule +// to read the files and incorporate the results into the args. +func (f *filesystem) getAvbAddHashtreeFooterArgs(ctx android.ModuleContext) (string, android.Paths) { + var deps android.Paths avb_add_hashtree_footer_args := "" if !proptools.BoolDefault(f.properties.Use_fec, true) { avb_add_hashtree_footer_args += " --do_not_generate_fec" @@ -1288,13 +1299,15 @@ func (f *filesystem) getAvbAddHashtreeFooterArgs(ctx android.ModuleContext) stri // number. if ctx.Module().UseGenericConfig() { avb_add_hashtree_footer_args += fmt.Sprintf(" --prop com.android.build.%s.fingerprint:{CONTENTS_OF:%s}", f.partitionName(), ctx.Config().BuildThumbprintFile(ctx)) + deps = append(deps, ctx.Config().BuildThumbprintFile(ctx)) } else { avb_add_hashtree_footer_args += fmt.Sprintf(" --prop com.android.build.%s.fingerprint:{CONTENTS_OF:%s}", f.partitionName(), ctx.Config().BuildFingerprintFile(ctx)) + deps = append(deps, ctx.Config().BuildFingerprintFile(ctx)) } if f.properties.Security_patch != nil && proptools.String(f.properties.Security_patch) != "" { avb_add_hashtree_footer_args += fmt.Sprintf(" --prop com.android.build.%s.security_patch:%s", f.partitionName(), proptools.String(f.properties.Security_patch)) } - return avb_add_hashtree_footer_args + return avb_add_hashtree_footer_args, deps } // This method checks if there is any property set for the fstype(s) other than -- cgit v1.2.3 From 3d31ee7fe26985633497af668fda7362eac4f9f3 Mon Sep 17 00:00:00 2001 From: Jordan Demeulenaere Date: Thu, 13 Mar 2025 15:18:54 +0100 Subject: Enable Compose groups optimizations Bug: 403236545 Test: Presubmits Flag: EXEMPT compiler optimization Change-Id: I8b308c1645df2b384f5800b15a2576613c2a90e6 --- java/base.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/java/base.go b/java/base.go index f7d25dd14..ac27e4d4f 100644 --- a/java/base.go +++ b/java/base.go @@ -1383,6 +1383,11 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath } flags.kotlincDeps = append(flags.kotlincDeps, deps.kotlinPlugins...) + // TODO(b/403236545): Remove this once the Kotlin compiler version is >= 2.2.0. + if j.useCompose(ctx) { + kotlincFlags = append(kotlincFlags, "-P", "plugin:androidx.compose.compiler.plugins.kotlin:featureFlag=+OptimizeNonSkippingGroups") + } + if len(kotlincFlags) > 0 { // optimization. ctx.Variable(pctx, "kotlincFlags", strings.Join(kotlincFlags, " ")) -- cgit v1.2.3 From b84aa9523045d02e5d0f9172d1f26555479ea0ca Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Tue, 29 Apr 2025 10:24:35 -0700 Subject: Ignore build thumprint in build test This is similar to the build fingerprint, it's generated by a $(shell) in product config. Nothing added dependencies on it until ag/33295940, but now that there are dependencies it needs to be excluded from the dangling rules check. Bug: 411231354 Test: RUN_BUILD_TESTS=true m nothing Change-Id: Ibffcd5e645af04ef41078f9f7f0ab9ca5388acf4 --- ui/build/test_build.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/build/test_build.go b/ui/build/test_build.go index 87bec93a2..0d80d8796 100644 --- a/ui/build/test_build.go +++ b/ui/build/test_build.go @@ -87,7 +87,7 @@ func testForDanglingRules(ctx Context, config Config) { // out/target/product//build_fingerprint.txt is a source file created in sysprop.mk // ^out/target/product/[^/]+/build_fingerprint.txt$ - buildFingerPrintFilePattern := regexp.MustCompile("^" + filepath.Join(outDir, "target", "product") + "/[^/]+/build_fingerprint.txt$") + buildFingerPrintFilePattern := regexp.MustCompile("^" + filepath.Join(outDir, "target", "product") + "/[^/]+/build_(fingerprint|thumbprint).txt$") danglingRules := make(map[string]bool) -- cgit v1.2.3 From 85df2b34cc3a683e8d68dd3cf27f7fab3f082243 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Mon, 28 Apr 2025 16:31:58 -0700 Subject: Remove use_clang_lld use_clang_lld is obsolete, remove the property and the related code that is now unreachable. Bug: 268030137 Test: all soong tests pass Change-Id: Ib1b6ea8c99e271dddfec38aaeadeaf8c8e0d9068 --- cc/cc.go | 6 ---- cc/config/arm64_device.go | 15 +--------- cc/config/arm64_linux_host.go | 13 ++------- cc/config/arm_device.go | 33 +-------------------- cc/config/arm_linux_host.go | 34 ++++----------------- cc/config/darwin_host.go | 5 ---- cc/config/global.go | 11 ++----- cc/config/riscv64_device.go | 17 ++--------- cc/config/toolchain.go | 1 - cc/config/x86_64_device.go | 11 ++----- cc/config/x86_device.go | 5 ---- cc/config/x86_linux_bionic_host.go | 14 +++------ cc/config/x86_linux_host.go | 43 ++------------------------- cc/config/x86_windows_host.go | 18 ++---------- cc/linker.go | 60 ++++++++++++-------------------------- cc/makevars.go | 6 ---- rust/config/x86_windows_host.go | 4 +-- rust/library.go | 2 +- 18 files changed, 47 insertions(+), 251 deletions(-) diff --git a/cc/cc.go b/cc/cc.go index d616978c0..9c5be8b6a 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -735,7 +735,6 @@ type ModuleContextIntf interface { isCfi() bool isFuzzer() bool isNDKStubLibrary() bool - useClangLld(actx ModuleContext) bool apexVariationName() string bootstrap() bool nativeCoverage() bool @@ -815,7 +814,6 @@ type linker interface { linkerFlags(ctx ModuleContext, flags Flags) Flags linkerProps() []interface{} baseLinkerProps() BaseLinkerProperties - useClangLld(actx ModuleContext) bool link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path appendLdflags([]string) @@ -1941,10 +1939,6 @@ func (ctx *moduleContextImpl) selectedStl() string { return "" } -func (ctx *moduleContextImpl) useClangLld(actx ModuleContext) bool { - return ctx.mod.linker.useClangLld(actx) -} - func (ctx *moduleContextImpl) baseModuleName() string { return ctx.mod.BaseModuleName() } diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go index 7bf5117f2..27d7147d6 100644 --- a/cc/config/arm64_device.go +++ b/cc/config/arm64_device.go @@ -48,13 +48,11 @@ var ( }, } - arm64Ldflags = []string{ + arm64Lldflags = []string{ "-Wl,-z,separate-code", "-Wl,-z,separate-loadable-segments", } - arm64Lldflags = arm64Ldflags - arm64Cppflags = []string{} arm64CpuVariantCflags = map[string][]string{ @@ -91,8 +89,6 @@ var ( ) func init() { - pctx.StaticVariable("Arm64Ldflags", strings.Join(arm64Ldflags, " ")) - pctx.VariableFunc("Arm64Lldflags", func(ctx android.PackageVarContext) string { maxPageSizeFlag := "-Wl,-z,max-page-size=" + ctx.Config().MaxPageSizeSupported() flags := append(arm64Lldflags, maxPageSizeFlag) @@ -152,7 +148,6 @@ type toolchainArm64 struct { toolchainBionic toolchain64Bit - ldflags string lldflags string toolchainCflags string } @@ -177,10 +172,6 @@ func (t *toolchainArm64) Cppflags() string { return "${config.Arm64Cppflags}" } -func (t *toolchainArm64) Ldflags() string { - return t.ldflags -} - func (t *toolchainArm64) Lldflags() string { return t.lldflags } @@ -208,10 +199,6 @@ func arm64ToolchainFactory(arch android.Arch) Toolchain { extraLdflags := variantOrDefault(arm64CpuVariantLdflags, arch.CpuVariant) return &toolchainArm64{ - ldflags: strings.Join([]string{ - "${config.Arm64Ldflags}", - extraLdflags, - }, " "), lldflags: strings.Join([]string{ "${config.Arm64Lldflags}", extraLdflags, diff --git a/cc/config/arm64_linux_host.go b/cc/config/arm64_linux_host.go index a19b0ed92..8bb4ecdb3 100644 --- a/cc/config/arm64_linux_host.go +++ b/cc/config/arm64_linux_host.go @@ -36,18 +36,15 @@ var ( "-nostdlibinc", ) - linuxCrossLdflags = []string{ + linuxCrossLldflags = []string{ "-Wl,-z,noexecstack", "-Wl,-z,relro", "-Wl,-z,now", "-Wl,--build-id=md5", "-Wl,--fatal-warnings", "-Wl,--no-undefined-version", - } - - linuxCrossLldflags = append(linuxCrossLdflags, "-Wl,--compress-debug-sections=zstd", - ) + } // Embed the linker into host bionic binaries. This is needed to support host bionic, // as the linux kernel requires that the ELF interpreter referenced by PT_INTERP be @@ -62,7 +59,6 @@ var ( func init() { pctx.StaticVariable("LinuxBionicArm64Cflags", strings.Join(linuxCrossCflags, " ")) - pctx.StaticVariable("LinuxBionicArm64Ldflags", strings.Join(linuxCrossLdflags, " ")) pctx.StaticVariable("LinuxBionicArm64Lldflags", strings.Join(linuxCrossLldflags, " ")) } @@ -97,11 +93,6 @@ func linuxBionicArm64ToolchainFactory(arch android.Arch) Toolchain { ret := toolchainLinuxBionicArm64{} // add the extra ld and lld flags - ret.toolchainArm64.ldflags = strings.Join([]string{ - "${config.Arm64Ldflags}", - "${config.LinuxBionicArm64Ldflags}", - extraLdflags, - }, " ") ret.toolchainArm64.lldflags = strings.Join([]string{ "${config.Arm64Lldflags}", "${config.LinuxBionicArm64Ldflags}", diff --git a/cc/config/arm_device.go b/cc/config/arm_device.go index 3cb190966..975a8873b 100644 --- a/cc/config/arm_device.go +++ b/cc/config/arm_device.go @@ -15,7 +15,6 @@ package config import ( - "fmt" "strings" "android/soong/android" @@ -37,14 +36,12 @@ var ( "-mllvm", "-enable-shrink-wrap=false", } - armLdflags = []string{ + armLldflags = []string{ "-Wl,-m,armelf", // Revert this after b/322359235 is fixed "-Wl,-mllvm", "-Wl,-enable-shrink-wrap=false", } - armLldflags = armLdflags - armFixCortexA8LdFlags = []string{"-Wl,--fix-cortex-a8"} armNoFixCortexA8LdFlags = []string{"-Wl,--no-fix-cortex-a8"} @@ -185,7 +182,6 @@ const ( ) func init() { - pctx.StaticVariable("ArmLdflags", strings.Join(armLdflags, " ")) pctx.StaticVariable("ArmLldflags", strings.Join(armLldflags, " ")) pctx.StaticVariable("ArmFixCortexA8LdFlags", strings.Join(armFixCortexA8LdFlags, " ")) @@ -251,7 +247,6 @@ var ( type toolchainArm struct { toolchainBionic toolchain32Bit - ldflags string lldflags string toolchainCflags string } @@ -286,10 +281,6 @@ func (t *toolchainArm) Cppflags() string { return "${config.ArmCppflags}" } -func (t *toolchainArm) Ldflags() string { - return t.ldflags -} - func (t *toolchainArm) Lldflags() string { return t.lldflags // TODO: handle V8 cases } @@ -310,7 +301,6 @@ func (toolchainArm) LibclangRuntimeLibraryArch() string { } func armToolchainFactory(arch android.Arch) Toolchain { - var fixCortexA8 string toolchainCflags := make([]string, 2, 3) toolchainCflags[0] = "${config.ArmToolchainCflags}" @@ -319,28 +309,7 @@ func armToolchainFactory(arch android.Arch) Toolchain { toolchainCflags = append(toolchainCflags, variantOrDefault(armCpuVariantCflagsVar, arch.CpuVariant)) - switch arch.ArchVariant { - case "armv7-a-neon": - switch arch.CpuVariant { - case "cortex-a8", "": - // Generic ARM might be a Cortex A8 -- better safe than sorry - fixCortexA8 = "${config.ArmFixCortexA8LdFlags}" - default: - fixCortexA8 = "${config.ArmNoFixCortexA8LdFlags}" - } - case "armv7-a": - fixCortexA8 = "${config.ArmFixCortexA8LdFlags}" - case "armv8-a", "armv8-2a": - // Nothing extra for armv8-a/armv8-2a - default: - panic(fmt.Sprintf("Unknown ARM architecture version: %q", arch.ArchVariant)) - } - return &toolchainArm{ - ldflags: strings.Join([]string{ - "${config.ArmLdflags}", - fixCortexA8, - }, " "), lldflags: "${config.ArmLldflags}", toolchainCflags: strings.Join(toolchainCflags, " "), } diff --git a/cc/config/arm_linux_host.go b/cc/config/arm_linux_host.go index e7c7bc466..11acfc82e 100644 --- a/cc/config/arm_linux_host.go +++ b/cc/config/arm_linux_host.go @@ -15,8 +15,9 @@ package config import ( - "android/soong/android" "strings" + + "android/soong/android" ) var ( @@ -26,27 +27,20 @@ var ( linuxArm64Cflags = []string{} - linuxArmLdflags = []string{ + linuxArmLldflags = []string{ "-march=armv7a", - } - - linuxArmLldflags = append(linuxArmLdflags, "-Wl,--compress-debug-sections=zstd", - ) - - linuxArm64Ldflags = []string{} + } - linuxArm64Lldflags = append(linuxArm64Ldflags, + linuxArm64Lldflags = []string{ "-Wl,--compress-debug-sections=zstd", - ) + } ) func init() { pctx.StaticVariable("LinuxArmCflags", strings.Join(linuxArmCflags, " ")) pctx.StaticVariable("LinuxArm64Cflags", strings.Join(linuxArm64Cflags, " ")) - pctx.StaticVariable("LinuxArmLdflags", strings.Join(linuxArmLdflags, " ")) pctx.StaticVariable("LinuxArmLldflags", strings.Join(linuxArmLldflags, " ")) - pctx.StaticVariable("LinuxArm64Ldflags", strings.Join(linuxArm64Ldflags, " ")) pctx.StaticVariable("LinuxArm64Lldflags", strings.Join(linuxArm64Lldflags, " ")) pctx.StaticVariable("LinuxArmYasmFlags", "-f elf32 -m arm") @@ -89,18 +83,10 @@ func (t *toolchainLinuxArm64) Cppflags() string { return "" } -func (t *toolchainLinuxArm) Ldflags() string { - return "${config.LinuxLdflags} ${config.LinuxArmLdflags}" -} - func (t *toolchainLinuxArm) Lldflags() string { return "${config.LinuxLldflags} ${config.LinuxArmLldflags}" } -func (t *toolchainLinuxArm64) Ldflags() string { - return "${config.LinuxLdflags} ${config.LinuxArm64Ldflags}" -} - func (t *toolchainLinuxArm64) Lldflags() string { return "${config.LinuxLldflags} ${config.LinuxArm64Lldflags}" } @@ -144,10 +130,6 @@ func (t *toolchainLinuxMuslArm) Cflags() string { return t.toolchainLinuxArm.Cflags() + " " + t.toolchainMusl.Cflags() } -func (t *toolchainLinuxMuslArm) Ldflags() string { - return t.toolchainLinuxArm.Ldflags() + " " + t.toolchainMusl.Ldflags() -} - func (t *toolchainLinuxMuslArm) Lldflags() string { return t.toolchainLinuxArm.Lldflags() + " " + t.toolchainMusl.Lldflags() } @@ -160,10 +142,6 @@ func (t *toolchainLinuxMuslArm64) Cflags() string { return t.toolchainLinuxArm64.Cflags() + " " + t.toolchainMusl.Cflags() } -func (t *toolchainLinuxMuslArm64) Ldflags() string { - return t.toolchainLinuxArm64.Ldflags() + " " + t.toolchainMusl.Ldflags() -} - func (t *toolchainLinuxMuslArm64) Lldflags() string { return t.toolchainLinuxArm64.Lldflags() + " " + t.toolchainMusl.Lldflags() } diff --git a/cc/config/darwin_host.go b/cc/config/darwin_host.go index 716965a3a..bdfbda804 100644 --- a/cc/config/darwin_host.go +++ b/cc/config/darwin_host.go @@ -98,7 +98,6 @@ func init() { }) pctx.StaticVariable("DarwinCflags", strings.Join(darwinCflags, " ")) - pctx.StaticVariable("DarwinLdflags", strings.Join(darwinLdflags, " ")) pctx.StaticVariable("DarwinLldflags", strings.Join(darwinLdflags, " ")) pctx.StaticVariable("DarwinYasmFlags", "-f macho -m amd64") @@ -208,10 +207,6 @@ func (t *toolchainDarwin) Cppflags() string { return "" } -func (t *toolchainDarwin) Ldflags() string { - return "${config.DarwinLdflags}" -} - func (t *toolchainDarwin) Lldflags() string { return "${config.DarwinLldflags}" } diff --git a/cc/config/global.go b/cc/config/global.go index e81ac0d47..f394e0962 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -188,7 +188,7 @@ var ( } // Linking flags for device code; not applied to host binaries. - deviceGlobalLdflags = []string{ + deviceGlobalLldflags = slices.Concat([]string{ "-Wl,-z,noexecstack", "-Wl,-z,relro", "-Wl,-z,now", @@ -201,18 +201,13 @@ var ( "-Wl,--exclude-libs,libgcc_stripped.a", "-Wl,--exclude-libs,libunwind_llvm.a", "-Wl,--exclude-libs,libunwind.a", - } - - deviceGlobalLldflags = append(append(deviceGlobalLdflags, commonGlobalLldflags...), "-Wl,--compress-debug-sections=zstd", - ) + }, commonGlobalLldflags) hostGlobalCflags = []string{} hostGlobalCppflags = []string{} - hostGlobalLdflags = []string{} - hostGlobalLldflags = commonGlobalLldflags commonGlobalCppflags = []string{ @@ -408,10 +403,8 @@ func init() { pctx.StaticVariable("CommonGlobalConlyflags", strings.Join(commonGlobalConlyflags, " ")) pctx.StaticVariable("CommonGlobalAsflags", strings.Join(commonGlobalAsflags, " ")) pctx.StaticVariable("DeviceGlobalCppflags", strings.Join(deviceGlobalCppflags, " ")) - pctx.StaticVariable("DeviceGlobalLdflags", strings.Join(deviceGlobalLdflags, " ")) pctx.StaticVariable("DeviceGlobalLldflags", strings.Join(deviceGlobalLldflags, " ")) pctx.StaticVariable("HostGlobalCppflags", strings.Join(hostGlobalCppflags, " ")) - pctx.StaticVariable("HostGlobalLdflags", strings.Join(hostGlobalLdflags, " ")) pctx.StaticVariable("HostGlobalLldflags", strings.Join(hostGlobalLldflags, " ")) pctx.VariableFunc("CommonGlobalCflags", func(ctx android.PackageVarContext) string { diff --git a/cc/config/riscv64_device.go b/cc/config/riscv64_device.go index b0ab30d79..65f1b720a 100644 --- a/cc/config/riscv64_device.go +++ b/cc/config/riscv64_device.go @@ -37,15 +37,12 @@ var ( riscv64ArchVariantCflags = map[string][]string{} - riscv64Ldflags = []string{ + riscv64Lldflags = []string{ // This is already the driver's Android default, but duplicated here (and // above) for ease of experimentation with additional extensions. "-march=rv64gcv_zba_zbb_zbs", - } - - riscv64Lldflags = append(riscv64Ldflags, "-Wl,-z,max-page-size=4096", - ) + } riscv64Cppflags = []string{} @@ -56,7 +53,6 @@ const () func init() { - pctx.StaticVariable("Riscv64Ldflags", strings.Join(riscv64Ldflags, " ")) pctx.StaticVariable("Riscv64Lldflags", strings.Join(riscv64Lldflags, " ")) pctx.StaticVariable("Riscv64Cflags", strings.Join(riscv64Cflags, " ")) @@ -75,7 +71,6 @@ type toolchainRiscv64 struct { toolchainBionic toolchain64Bit - ldflags string lldflags string toolchainCflags string } @@ -100,10 +95,6 @@ func (t *toolchainRiscv64) Cppflags() string { return "${config.Riscv64Cppflags}" } -func (t *toolchainRiscv64) Ldflags() string { - return t.ldflags -} - func (t *toolchainRiscv64) Lldflags() string { return t.lldflags } @@ -129,10 +120,6 @@ func riscv64ToolchainFactory(arch android.Arch) Toolchain { extraLdflags := variantOrDefault(riscv64CpuVariantLdflags, arch.CpuVariant) return &toolchainRiscv64{ - ldflags: strings.Join([]string{ - "${config.Riscv64Ldflags}", - extraLdflags, - }, " "), lldflags: strings.Join([]string{ "${config.Riscv64Lldflags}", extraLdflags, diff --git a/cc/config/toolchain.go b/cc/config/toolchain.go index 5d8c351ab..398c71266 100644 --- a/cc/config/toolchain.go +++ b/cc/config/toolchain.go @@ -78,7 +78,6 @@ type Toolchain interface { Asflags() string Cflags() string Cppflags() string - Ldflags() string Lldflags() string InstructionSetFlags(string) (string, error) diff --git a/cc/config/x86_64_device.go b/cc/config/x86_64_device.go index e7ac03863..2c0e70f8a 100644 --- a/cc/config/x86_64_device.go +++ b/cc/config/x86_64_device.go @@ -29,12 +29,10 @@ var ( x86_64Cppflags = []string{} - x86_64Ldflags = []string{ + x86_64Lldflags = []string{ "-Wl,-z,separate-loadable-segments", } - X86_64Lldflags = x86_64Ldflags - x86_64ArchVariantCflags = map[string][]string{ "": []string{ "-march=x86-64", @@ -103,10 +101,9 @@ func init() { pctx.StaticVariable("X86_64ToolchainCflags", "-m64") pctx.StaticVariable("X86_64ToolchainLdflags", "-m64") - pctx.StaticVariable("X86_64Ldflags", strings.Join(x86_64Ldflags, " ")) pctx.VariableFunc("X86_64Lldflags", func(ctx android.PackageVarContext) string { maxPageSizeFlag := "-Wl,-z,max-page-size=" + ctx.Config().MaxPageSizeSupported() - flags := append(X86_64Lldflags, maxPageSizeFlag) + flags := append(x86_64Lldflags, maxPageSizeFlag) return strings.Join(flags, " ") }) @@ -166,10 +163,6 @@ func (t *toolchainX86_64) Cppflags() string { return "${config.X86_64Cppflags}" } -func (t *toolchainX86_64) Ldflags() string { - return "${config.X86_64Ldflags}" -} - func (t *toolchainX86_64) Lldflags() string { return "${config.X86_64Lldflags}" } diff --git a/cc/config/x86_device.go b/cc/config/x86_device.go index a92881d91..d1552a0db 100644 --- a/cc/config/x86_device.go +++ b/cc/config/x86_device.go @@ -107,7 +107,6 @@ func init() { pctx.StaticVariable("X86ToolchainCflags", "-m32") pctx.StaticVariable("X86ToolchainLdflags", "-m32") - pctx.StaticVariable("X86Ldflags", strings.Join(x86Ldflags, " ")) pctx.StaticVariable("X86Lldflags", strings.Join(x86Ldflags, " ")) // Clang cflags @@ -157,10 +156,6 @@ func (t *toolchainX86) Cppflags() string { return "${config.X86Cppflags}" } -func (t *toolchainX86) Ldflags() string { - return "${config.X86Ldflags}" -} - func (t *toolchainX86) Lldflags() string { return "${config.X86Lldflags}" } diff --git a/cc/config/x86_linux_bionic_host.go b/cc/config/x86_linux_bionic_host.go index d2f88ef34..e27eb8fe0 100644 --- a/cc/config/x86_linux_bionic_host.go +++ b/cc/config/x86_linux_bionic_host.go @@ -15,8 +15,9 @@ package config import ( - "android/soong/android" "strings" + + "android/soong/android" ) var ( @@ -43,7 +44,7 @@ var ( "-nostdlibinc", } - linuxBionicLdflags = []string{ + linuxBionicLldflags = []string{ "-Wl,-z,noexecstack", "-Wl,-z,relro", "-Wl,-z,now", @@ -53,11 +54,9 @@ var ( // Use the device gcc toolchain "--gcc-toolchain=${LinuxBionicGccRoot}", - } - linuxBionicLldflags = append(linuxBionicLdflags, "-Wl,--compress-debug-sections=zstd", - ) + } // Embed the linker into host bionic binaries. This is needed to support host bionic, // as the linux kernel requires that the ELF interpreter referenced by PT_INTERP be @@ -76,7 +75,6 @@ const ( func init() { pctx.StaticVariable("LinuxBionicCflags", strings.Join(linuxBionicCflags, " ")) - pctx.StaticVariable("LinuxBionicLdflags", strings.Join(linuxBionicLdflags, " ")) pctx.StaticVariable("LinuxBionicLldflags", strings.Join(linuxBionicLldflags, " ")) // Use the device gcc toolchain for now @@ -111,10 +109,6 @@ func (t *toolchainLinuxBionic) Cppflags() string { return "" } -func (t *toolchainLinuxBionic) Ldflags() string { - return "${config.LinuxBionicLdflags}" -} - func (t *toolchainLinuxBionic) Lldflags() string { return "${config.LinuxBionicLldflags}" } diff --git a/cc/config/x86_linux_host.go b/cc/config/x86_linux_host.go index c3f25aa21..cd06ffbcf 100644 --- a/cc/config/x86_linux_host.go +++ b/cc/config/x86_linux_host.go @@ -46,18 +46,16 @@ var ( "--sysroot /dev/null", } - linuxLdflags = []string{ + linuxLldflags = []string{ "-Wl,-z,noexecstack", "-Wl,-z,relro", "-Wl,-z,now", "-Wl,--no-undefined-version", "--gcc-toolchain=${LinuxGccRoot}", - } - linuxLldflags = append(linuxLdflags, "-Wl,--compress-debug-sections=zstd", - ) + } linuxGlibcLdflags = []string{ "--sysroot ${LinuxGccRoot}/sysroot", @@ -137,20 +135,15 @@ func init() { pctx.StaticVariable("LinuxGccTriple", "x86_64-linux") pctx.StaticVariable("LinuxCflags", strings.Join(linuxCflags, " ")) - pctx.StaticVariable("LinuxLdflags", strings.Join(linuxLdflags, " ")) pctx.StaticVariable("LinuxLldflags", strings.Join(linuxLldflags, " ")) pctx.StaticVariable("LinuxGlibcCflags", strings.Join(linuxGlibcCflags, " ")) - pctx.StaticVariable("LinuxGlibcLdflags", strings.Join(linuxGlibcLdflags, " ")) pctx.StaticVariable("LinuxGlibcLldflags", strings.Join(linuxGlibcLdflags, " ")) pctx.StaticVariable("LinuxMuslCflags", strings.Join(linuxMuslCflags, " ")) - pctx.StaticVariable("LinuxMuslLdflags", strings.Join(linuxMuslLdflags, " ")) pctx.StaticVariable("LinuxMuslLldflags", strings.Join(linuxMuslLdflags, " ")) pctx.StaticVariable("LinuxX86Cflags", strings.Join(linuxX86Cflags, " ")) pctx.StaticVariable("LinuxX8664Cflags", strings.Join(linuxX8664Cflags, " ")) - pctx.StaticVariable("LinuxX86Ldflags", strings.Join(linuxX86Ldflags, " ")) pctx.StaticVariable("LinuxX86Lldflags", strings.Join(linuxX86Ldflags, " ")) - pctx.StaticVariable("LinuxX8664Ldflags", strings.Join(linuxX8664Ldflags, " ")) pctx.StaticVariable("LinuxX8664Lldflags", strings.Join(linuxX8664Ldflags, " ")) // Yasm flags pctx.StaticVariable("LinuxX86YasmFlags", "-f elf32 -m x86") @@ -200,18 +193,10 @@ func (t *toolchainLinuxX8664) Cppflags() string { return "" } -func (t *toolchainLinuxX86) Ldflags() string { - return "${config.LinuxLdflags} ${config.LinuxX86Ldflags}" -} - func (t *toolchainLinuxX86) Lldflags() string { return "${config.LinuxLldflags} ${config.LinuxX86Lldflags}" } -func (t *toolchainLinuxX8664) Ldflags() string { - return "${config.LinuxLdflags} ${config.LinuxX8664Ldflags}" -} - func (t *toolchainLinuxX8664) Lldflags() string { return "${config.LinuxLldflags} ${config.LinuxX8664Lldflags}" } @@ -256,10 +241,6 @@ func (toolchainGlibc) Cflags() string { return "${config.LinuxGlibcCflags}" } -func (toolchainGlibc) Ldflags() string { - return "${config.LinuxGlibcLdflags}" -} - func (toolchainGlibc) Lldflags() string { return "${config.LinuxGlibcLldflags}" } @@ -282,10 +263,6 @@ func (t *toolchainLinuxGlibcX86) Cflags() string { return t.toolchainLinuxX86.Cflags() + " " + t.toolchainGlibc.Cflags() } -func (t *toolchainLinuxGlibcX86) Ldflags() string { - return t.toolchainLinuxX86.Ldflags() + " " + t.toolchainGlibc.Ldflags() -} - func (t *toolchainLinuxGlibcX86) Lldflags() string { return t.toolchainLinuxX86.Lldflags() + " " + t.toolchainGlibc.Lldflags() } @@ -298,10 +275,6 @@ func (t *toolchainLinuxGlibcX8664) Cflags() string { return t.toolchainLinuxX8664.Cflags() + " " + t.toolchainGlibc.Cflags() } -func (t *toolchainLinuxGlibcX8664) Ldflags() string { - return t.toolchainLinuxX8664.Ldflags() + " " + t.toolchainGlibc.Ldflags() -} - func (t *toolchainLinuxGlibcX8664) Lldflags() string { return t.toolchainLinuxX8664.Lldflags() + " " + t.toolchainGlibc.Lldflags() } @@ -338,10 +311,6 @@ func (toolchainMusl) Cflags() string { return "${config.LinuxMuslCflags}" } -func (toolchainMusl) Ldflags() string { - return "${config.LinuxMuslLdflags}" -} - func (toolchainMusl) Lldflags() string { return "${config.LinuxMuslLldflags}" } @@ -364,10 +333,6 @@ func (t *toolchainLinuxMuslX86) Cflags() string { return t.toolchainLinuxX86.Cflags() + " " + t.toolchainMusl.Cflags() } -func (t *toolchainLinuxMuslX86) Ldflags() string { - return t.toolchainLinuxX86.Ldflags() + " " + t.toolchainMusl.Ldflags() -} - func (t *toolchainLinuxMuslX86) Lldflags() string { return t.toolchainLinuxX86.Lldflags() + " " + t.toolchainMusl.Lldflags() } @@ -380,10 +345,6 @@ func (t *toolchainLinuxMuslX8664) Cflags() string { return t.toolchainLinuxX8664.Cflags() + " " + t.toolchainMusl.Cflags() } -func (t *toolchainLinuxMuslX8664) Ldflags() string { - return t.toolchainLinuxX8664.Ldflags() + " " + t.toolchainMusl.Ldflags() -} - func (t *toolchainLinuxMuslX8664) Lldflags() string { return t.toolchainLinuxX8664.Lldflags() + " " + t.toolchainMusl.Lldflags() } diff --git a/cc/config/x86_windows_host.go b/cc/config/x86_windows_host.go index c007f454d..848c89e28 100644 --- a/cc/config/x86_windows_host.go +++ b/cc/config/x86_windows_host.go @@ -66,13 +66,12 @@ var ( windowsX8664Cppflags = []string{} - windowsLdflags = []string{ + windowsLldflags = []string{ "-Wl,--dynamicbase", "-Wl,--nxcompat", - } - windowsLldflags = append(windowsLdflags, []string{ + "-Wl,--Xlink=-Brepro", // Enable deterministic build - }...) + } windowsX86Cflags = []string{ "-m32", @@ -141,15 +140,12 @@ func init() { pctx.StaticVariable("WindowsGccTriple", "x86_64-w64-mingw32") pctx.StaticVariable("WindowsCflags", strings.Join(windowsCflags, " ")) - pctx.StaticVariable("WindowsLdflags", strings.Join(windowsLdflags, " ")) pctx.StaticVariable("WindowsLldflags", strings.Join(windowsLldflags, " ")) pctx.StaticVariable("WindowsCppflags", strings.Join(windowsCppflags, " ")) pctx.StaticVariable("WindowsX86Cflags", strings.Join(windowsX86Cflags, " ")) pctx.StaticVariable("WindowsX8664Cflags", strings.Join(windowsX8664Cflags, " ")) - pctx.StaticVariable("WindowsX86Ldflags", strings.Join(windowsX86Ldflags, " ")) pctx.StaticVariable("WindowsX86Lldflags", strings.Join(windowsX86Ldflags, " ")) - pctx.StaticVariable("WindowsX8664Ldflags", strings.Join(windowsX8664Ldflags, " ")) pctx.StaticVariable("WindowsX8664Lldflags", strings.Join(windowsX8664Ldflags, " ")) pctx.StaticVariable("WindowsX86Cppflags", strings.Join(windowsX86Cppflags, " ")) pctx.StaticVariable("WindowsX8664Cppflags", strings.Join(windowsX8664Cppflags, " ")) @@ -220,18 +216,10 @@ func (t *toolchainWindowsX8664) Cppflags() string { return "${config.WindowsCppflags} ${config.WindowsX8664Cppflags}" } -func (t *toolchainWindowsX86) Ldflags() string { - return "${config.WindowsLdflags} ${config.WindowsX86Ldflags}" -} - func (t *toolchainWindowsX86) Lldflags() string { return "${config.WindowsLldflags} ${config.WindowsX86Lldflags}" } -func (t *toolchainWindowsX8664) Ldflags() string { - return "${config.WindowsLdflags} ${config.WindowsX8664Ldflags}" -} - func (t *toolchainWindowsX8664) Lldflags() string { return "${config.WindowsLldflags} ${config.WindowsX8664Lldflags}" } diff --git a/cc/linker.go b/cc/linker.go index f85493726..e051263e4 100644 --- a/cc/linker.go +++ b/cc/linker.go @@ -69,9 +69,6 @@ type BaseLinkerProperties struct { // don't link in libclang_rt.builtins-*.a No_libcrt *bool `android:"arch_variant"` - // Use clang lld instead of gnu ld. - Use_clang_lld *bool `android:"arch_variant"` - // -l arguments to pass to linker for host-provided shared libraries Host_ldlibs []string `android:"arch_variant"` @@ -445,13 +442,6 @@ func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps { return deps } -func (linker *baseLinker) useClangLld(ctx ModuleContext) bool { - if linker.Properties.Use_clang_lld != nil { - return Bool(linker.Properties.Use_clang_lld) - } - return true -} - // Check whether the SDK version is not older than the specific one func CheckSdkVersionAtLeast(ctx ModuleContext, SdkVersion android.ApiLevel) bool { if ctx.minSdkVersion() == "current" { @@ -471,8 +461,7 @@ func CheckSdkVersionAtLeast(ctx ModuleContext, SdkVersion android.ApiLevel) bool // ModuleContext extends BaseModuleContext // BaseModuleContext should know if LLD is used? -func CommonLinkerFlags(ctx android.ModuleContext, flags Flags, useClangLld bool, - toolchain config.Toolchain, allow_undefined_symbols bool) Flags { +func CommonLinkerFlags(ctx android.ModuleContext, flags Flags, toolchain config.Toolchain, allow_undefined_symbols bool) Flags { hod := "Host" if ctx.Os().Class == android.Device { hod = "Device" @@ -483,11 +472,7 @@ func CommonLinkerFlags(ctx android.ModuleContext, flags Flags, useClangLld bool, ctx.ModuleErrorf("trying to add CommonLinkerFlags to non-LinkableInterface module.") return flags } - if useClangLld { - flags.Global.LdFlags = append(flags.Global.LdFlags, fmt.Sprintf("${config.%sGlobalLldflags}", hod)) - } else { - flags.Global.LdFlags = append(flags.Global.LdFlags, fmt.Sprintf("${config.%sGlobalLdflags}", hod)) - } + flags.Global.LdFlags = append(flags.Global.LdFlags, fmt.Sprintf("${config.%sGlobalLldflags}", hod)) if allow_undefined_symbols { if ctx.Darwin() { @@ -498,11 +483,7 @@ func CommonLinkerFlags(ctx android.ModuleContext, flags Flags, useClangLld bool, flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--no-undefined") } - if useClangLld { - flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.Lldflags()) - } else { - flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.Ldflags()) - } + flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.Lldflags()) if !toolchain.Bionic() && ctx.Os() != android.LinuxMusl { if !ctx.Windows() { @@ -531,8 +512,7 @@ func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags { toolchain := ctx.toolchain() allow_undefined_symbols := Bool(linker.Properties.Allow_undefined_symbols) - flags = CommonLinkerFlags(ctx, flags, linker.useClangLld(ctx), toolchain, - allow_undefined_symbols) + flags = CommonLinkerFlags(ctx, flags, toolchain, allow_undefined_symbols) if !toolchain.Bionic() && ctx.Os() != android.LinuxMusl { CheckBadHostLdlibs(ctx, "host_ldlibs", linker.Properties.Host_ldlibs) @@ -541,23 +521,21 @@ func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags { CheckBadLinkerFlags(ctx, "ldflags", linker.Properties.Ldflags) - if linker.useClangLld(ctx) { - if !BoolDefault(linker.Properties.Pack_relocations, packRelocationsDefault) { - flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--pack-dyn-relocs=none") - } else if ctx.Device() { - // SHT_RELR relocations are only supported at API level >= 30. - // ANDROID_RELR relocations were supported at API level >= 28. - // Relocation packer was supported at API level >= 23. - // Do the best we can... - if (!ctx.useSdk() && ctx.minSdkVersion() == "") || CheckSdkVersionAtLeast(ctx, android.FirstShtRelrVersion) { - flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--pack-dyn-relocs=android+relr") - } else if CheckSdkVersionAtLeast(ctx, android.FirstAndroidRelrVersion) { - flags.Global.LdFlags = append(flags.Global.LdFlags, - "-Wl,--pack-dyn-relocs=android+relr", - "-Wl,--use-android-relr-tags") - } else if CheckSdkVersionAtLeast(ctx, android.FirstPackedRelocationsVersion) { - flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--pack-dyn-relocs=android") - } + if !BoolDefault(linker.Properties.Pack_relocations, packRelocationsDefault) { + flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--pack-dyn-relocs=none") + } else if ctx.Device() { + // SHT_RELR relocations are only supported at API level >= 30. + // ANDROID_RELR relocations were supported at API level >= 28. + // Relocation packer was supported at API level >= 23. + // Do the best we can... + if (!ctx.useSdk() && ctx.minSdkVersion() == "") || CheckSdkVersionAtLeast(ctx, android.FirstShtRelrVersion) { + flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--pack-dyn-relocs=android+relr") + } else if CheckSdkVersionAtLeast(ctx, android.FirstAndroidRelrVersion) { + flags.Global.LdFlags = append(flags.Global.LdFlags, + "-Wl,--pack-dyn-relocs=android+relr", + "-Wl,--use-android-relr-tags") + } else if CheckSdkVersionAtLeast(ctx, android.FirstPackedRelocationsVersion) { + flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--pack-dyn-relocs=android") } } diff --git a/cc/makevars.go b/cc/makevars.go index edebe2dab..00d99fe1d 100644 --- a/cc/makevars.go +++ b/cc/makevars.go @@ -241,12 +241,6 @@ func makeVarsToolchain(ctx android.MakeVarsContext, secondPrefix string, fmt.Sprintf("${config.%sGlobalCppflags}", hod), toolchain.Cppflags(), }, " ")) - ctx.Strict(clangPrefix+"GLOBAL_LDFLAGS", strings.Join([]string{ - fmt.Sprintf("${config.%sGlobalLdflags}", hod), - toolchain.Ldflags(), - toolchain.ToolchainLdflags(), - productExtraLdflags, - }, " ")) ctx.Strict(clangPrefix+"GLOBAL_LLDFLAGS", strings.Join([]string{ fmt.Sprintf("${config.%sGlobalLldflags}", hod), toolchain.Lldflags(), diff --git a/rust/config/x86_windows_host.go b/rust/config/x86_windows_host.go index 772c43f08..3d83d3f20 100644 --- a/rust/config/x86_windows_host.go +++ b/rust/config/x86_windows_host.go @@ -82,7 +82,7 @@ func (t *toolchainWindowsX86) Name() string { func (t *toolchainWindowsX86) ToolchainLinkFlags() string { // Prepend the lld flags from cc_config so we stay in sync with cc - return "${cc_config.WindowsLldflags} ${cc_config.WindowsX86Ldflags} ${cc_config.WindowsAvailableLibraries} " + + return "${cc_config.WindowsLldflags} ${cc_config.WindowsX86Lldflags} ${cc_config.WindowsAvailableLibraries} " + "${config.WindowsToolchainRustLinkFlags} ${config.WindowsX86ToolchainRustLinkFlags}" } @@ -149,7 +149,7 @@ func (t *toolchainWindowsX8664) Name() string { func (t *toolchainWindowsX8664) ToolchainLinkFlags() string { // Prepend the lld flags from cc_config so we stay in sync with cc - return "${cc_config.WindowsLldflags} ${cc_config.WindowsX8664Ldflags} ${cc_config.WindowsAvailableLibraries} " + + return "${cc_config.WindowsLldflags} ${cc_config.WindowsX8664Lldflags} ${cc_config.WindowsAvailableLibraries} " + "${config.WindowsToolchainRustLinkFlags} ${config.WindowsX8664ToolchainRustLinkFlags}" } diff --git a/rust/library.go b/rust/library.go index 04d03c8e3..e52b6acc7 100644 --- a/rust/library.go +++ b/rust/library.go @@ -824,7 +824,7 @@ func (library *libraryDecorator) getApiStubsCcFlags(ctx ModuleContext) cc.Flags minSdkVersion := cc.MinSdkVersion(ctx.RustModule(), cc.CtxIsForPlatform(ctx), ctx.Device(), platformSdkVersion) // Collect common CC compilation flags - ccFlags = cc.CommonLinkerFlags(ctx, ccFlags, true, toolchain, false) + ccFlags = cc.CommonLinkerFlags(ctx, ccFlags, toolchain, false) ccFlags = cc.CommonLibraryLinkerFlags(ctx, ccFlags, toolchain, library.getStem(ctx)) ccFlags = cc.AddStubLibraryCompilerFlags(ccFlags) ccFlags = cc.AddTargetFlags(ctx, ccFlags, toolchain, minSdkVersion, false) -- cgit v1.2.3 From 3488002ed0cc2200654b79ae453baa5a7e4ec592 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Mon, 28 Apr 2025 19:21:01 -0700 Subject: Replace lldflags with ldflags lld is always used now, replace all instances of lldflags with ldflags. Bug: 268030137 Test: all soong tests pass Change-Id: I1110faccccb73cf1b468f6e443d3ea3f4dea27ea --- cc/config/arm64_device.go | 16 ++++++------- cc/config/arm64_linux_host.go | 8 +++---- cc/config/arm_device.go | 12 +++++----- cc/config/arm_linux_host.go | 24 ++++++++++---------- cc/config/darwin_host.go | 6 ++--- cc/config/global.go | 12 +++++----- cc/config/riscv64_device.go | 14 ++++++------ cc/config/toolchain.go | 2 +- cc/config/x86_64_device.go | 10 ++++---- cc/config/x86_device.go | 6 ++--- cc/config/x86_linux_bionic_host.go | 8 +++---- cc/config/x86_linux_host.go | 44 ++++++++++++++++++------------------ cc/config/x86_windows_host.go | 16 ++++++------- cc/linker.go | 4 ++-- cc/makevars.go | 6 ++--- rust/config/arm64_device.go | 2 +- rust/config/arm_device.go | 2 +- rust/config/arm_linux_host.go | 4 ++-- rust/config/darwin_host.go | 4 ++-- rust/config/global.go | 4 ++-- rust/config/riscv64_device.go | 2 +- rust/config/x86_64_device.go | 2 +- rust/config/x86_device.go | 2 +- rust/config/x86_linux_bionic_host.go | 2 +- rust/config/x86_linux_host.go | 4 ++-- rust/config/x86_windows_host.go | 4 ++-- 26 files changed, 110 insertions(+), 110 deletions(-) diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go index 27d7147d6..332c138c7 100644 --- a/cc/config/arm64_device.go +++ b/cc/config/arm64_device.go @@ -48,7 +48,7 @@ var ( }, } - arm64Lldflags = []string{ + arm64Ldflags = []string{ "-Wl,-z,separate-code", "-Wl,-z,separate-loadable-segments", } @@ -89,9 +89,9 @@ var ( ) func init() { - pctx.VariableFunc("Arm64Lldflags", func(ctx android.PackageVarContext) string { + pctx.VariableFunc("Arm64Ldflags", func(ctx android.PackageVarContext) string { maxPageSizeFlag := "-Wl,-z,max-page-size=" + ctx.Config().MaxPageSizeSupported() - flags := append(arm64Lldflags, maxPageSizeFlag) + flags := append(arm64Ldflags, maxPageSizeFlag) return strings.Join(flags, " ") }) @@ -148,7 +148,7 @@ type toolchainArm64 struct { toolchainBionic toolchain64Bit - lldflags string + ldflags string toolchainCflags string } @@ -172,8 +172,8 @@ func (t *toolchainArm64) Cppflags() string { return "${config.Arm64Cppflags}" } -func (t *toolchainArm64) Lldflags() string { - return t.lldflags +func (t *toolchainArm64) Ldflags() string { + return t.ldflags } func (t *toolchainArm64) ToolchainCflags() string { @@ -199,8 +199,8 @@ func arm64ToolchainFactory(arch android.Arch) Toolchain { extraLdflags := variantOrDefault(arm64CpuVariantLdflags, arch.CpuVariant) return &toolchainArm64{ - lldflags: strings.Join([]string{ - "${config.Arm64Lldflags}", + ldflags: strings.Join([]string{ + "${config.Arm64Ldflags}", extraLdflags, }, " "), toolchainCflags: strings.Join(toolchainCflags, " "), diff --git a/cc/config/arm64_linux_host.go b/cc/config/arm64_linux_host.go index 8bb4ecdb3..32cf722c5 100644 --- a/cc/config/arm64_linux_host.go +++ b/cc/config/arm64_linux_host.go @@ -36,7 +36,7 @@ var ( "-nostdlibinc", ) - linuxCrossLldflags = []string{ + linuxCrossLdflags = []string{ "-Wl,-z,noexecstack", "-Wl,-z,relro", "-Wl,-z,now", @@ -59,7 +59,7 @@ var ( func init() { pctx.StaticVariable("LinuxBionicArm64Cflags", strings.Join(linuxCrossCflags, " ")) - pctx.StaticVariable("LinuxBionicArm64Lldflags", strings.Join(linuxCrossLldflags, " ")) + pctx.StaticVariable("LinuxBionicArm64Ldflags", strings.Join(linuxCrossLdflags, " ")) } // toolchain config for ARM64 Linux CrossHost. Almost everything is the same as the ARM64 Android @@ -93,8 +93,8 @@ func linuxBionicArm64ToolchainFactory(arch android.Arch) Toolchain { ret := toolchainLinuxBionicArm64{} // add the extra ld and lld flags - ret.toolchainArm64.lldflags = strings.Join([]string{ - "${config.Arm64Lldflags}", + ret.toolchainArm64.ldflags = strings.Join([]string{ + "${config.Arm64Ldflags}", "${config.LinuxBionicArm64Ldflags}", extraLdflags, }, " ") diff --git a/cc/config/arm_device.go b/cc/config/arm_device.go index 975a8873b..de9c749b0 100644 --- a/cc/config/arm_device.go +++ b/cc/config/arm_device.go @@ -36,7 +36,7 @@ var ( "-mllvm", "-enable-shrink-wrap=false", } - armLldflags = []string{ + armLdflags = []string{ "-Wl,-m,armelf", // Revert this after b/322359235 is fixed "-Wl,-mllvm", "-Wl,-enable-shrink-wrap=false", @@ -182,7 +182,7 @@ const ( ) func init() { - pctx.StaticVariable("ArmLldflags", strings.Join(armLldflags, " ")) + pctx.StaticVariable("ArmLdflags", strings.Join(armLdflags, " ")) pctx.StaticVariable("ArmFixCortexA8LdFlags", strings.Join(armFixCortexA8LdFlags, " ")) pctx.StaticVariable("ArmNoFixCortexA8LdFlags", strings.Join(armNoFixCortexA8LdFlags, " ")) @@ -247,7 +247,7 @@ var ( type toolchainArm struct { toolchainBionic toolchain32Bit - lldflags string + ldflags string toolchainCflags string } @@ -281,8 +281,8 @@ func (t *toolchainArm) Cppflags() string { return "${config.ArmCppflags}" } -func (t *toolchainArm) Lldflags() string { - return t.lldflags // TODO: handle V8 cases +func (t *toolchainArm) Ldflags() string { + return t.ldflags // TODO: handle V8 cases } func (t *toolchainArm) InstructionSetFlags(isa string) (string, error) { @@ -310,7 +310,7 @@ func armToolchainFactory(arch android.Arch) Toolchain { variantOrDefault(armCpuVariantCflagsVar, arch.CpuVariant)) return &toolchainArm{ - lldflags: "${config.ArmLldflags}", + ldflags: "${config.ArmLdflags}", toolchainCflags: strings.Join(toolchainCflags, " "), } } diff --git a/cc/config/arm_linux_host.go b/cc/config/arm_linux_host.go index 11acfc82e..ebac56f8a 100644 --- a/cc/config/arm_linux_host.go +++ b/cc/config/arm_linux_host.go @@ -27,12 +27,12 @@ var ( linuxArm64Cflags = []string{} - linuxArmLldflags = []string{ + linuxArmLdflags = []string{ "-march=armv7a", "-Wl,--compress-debug-sections=zstd", } - linuxArm64Lldflags = []string{ + linuxArm64Ldflags = []string{ "-Wl,--compress-debug-sections=zstd", } ) @@ -40,8 +40,8 @@ var ( func init() { pctx.StaticVariable("LinuxArmCflags", strings.Join(linuxArmCflags, " ")) pctx.StaticVariable("LinuxArm64Cflags", strings.Join(linuxArm64Cflags, " ")) - pctx.StaticVariable("LinuxArmLldflags", strings.Join(linuxArmLldflags, " ")) - pctx.StaticVariable("LinuxArm64Lldflags", strings.Join(linuxArm64Lldflags, " ")) + pctx.StaticVariable("LinuxArmLdflags", strings.Join(linuxArmLdflags, " ")) + pctx.StaticVariable("LinuxArm64Ldflags", strings.Join(linuxArm64Ldflags, " ")) pctx.StaticVariable("LinuxArmYasmFlags", "-f elf32 -m arm") pctx.StaticVariable("LinuxArm64YasmFlags", "-f elf64 -m aarch64") @@ -83,12 +83,12 @@ func (t *toolchainLinuxArm64) Cppflags() string { return "" } -func (t *toolchainLinuxArm) Lldflags() string { - return "${config.LinuxLldflags} ${config.LinuxArmLldflags}" +func (t *toolchainLinuxArm) Ldflags() string { + return "${config.LinuxLdflags} ${config.LinuxArmLdflags}" } -func (t *toolchainLinuxArm64) Lldflags() string { - return "${config.LinuxLldflags} ${config.LinuxArm64Lldflags}" +func (t *toolchainLinuxArm64) Ldflags() string { + return "${config.LinuxLdflags} ${config.LinuxArm64Ldflags}" } func (t *toolchainLinuxArm) YasmFlags() string { @@ -130,8 +130,8 @@ func (t *toolchainLinuxMuslArm) Cflags() string { return t.toolchainLinuxArm.Cflags() + " " + t.toolchainMusl.Cflags() } -func (t *toolchainLinuxMuslArm) Lldflags() string { - return t.toolchainLinuxArm.Lldflags() + " " + t.toolchainMusl.Lldflags() +func (t *toolchainLinuxMuslArm) Ldflags() string { + return t.toolchainLinuxArm.Ldflags() + " " + t.toolchainMusl.Ldflags() } func (t *toolchainLinuxMuslArm64) ClangTriple() string { @@ -142,8 +142,8 @@ func (t *toolchainLinuxMuslArm64) Cflags() string { return t.toolchainLinuxArm64.Cflags() + " " + t.toolchainMusl.Cflags() } -func (t *toolchainLinuxMuslArm64) Lldflags() string { - return t.toolchainLinuxArm64.Lldflags() + " " + t.toolchainMusl.Lldflags() +func (t *toolchainLinuxMuslArm64) Ldflags() string { + return t.toolchainLinuxArm64.Ldflags() + " " + t.toolchainMusl.Ldflags() } var toolchainLinuxMuslArmSingleton Toolchain = &toolchainLinuxMuslArm{} diff --git a/cc/config/darwin_host.go b/cc/config/darwin_host.go index bdfbda804..03eefc096 100644 --- a/cc/config/darwin_host.go +++ b/cc/config/darwin_host.go @@ -98,7 +98,7 @@ func init() { }) pctx.StaticVariable("DarwinCflags", strings.Join(darwinCflags, " ")) - pctx.StaticVariable("DarwinLldflags", strings.Join(darwinLdflags, " ")) + pctx.StaticVariable("DarwinLdflags", strings.Join(darwinLdflags, " ")) pctx.StaticVariable("DarwinYasmFlags", "-f macho -m amd64") } @@ -207,8 +207,8 @@ func (t *toolchainDarwin) Cppflags() string { return "" } -func (t *toolchainDarwin) Lldflags() string { - return "${config.DarwinLldflags}" +func (t *toolchainDarwin) Ldflags() string { + return "${config.DarwinLdflags}" } func (t *toolchainDarwin) YasmFlags() string { diff --git a/cc/config/global.go b/cc/config/global.go index f394e0962..0a8d80d87 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -177,7 +177,7 @@ var ( "-Werror=format-security", } - commonGlobalLldflags = []string{ + commonGlobalLdflags = []string{ "-fuse-ld=lld", "-Wl,--icf=safe", "-Wl,--no-demangle", @@ -188,7 +188,7 @@ var ( } // Linking flags for device code; not applied to host binaries. - deviceGlobalLldflags = slices.Concat([]string{ + deviceGlobalLdflags = slices.Concat([]string{ "-Wl,-z,noexecstack", "-Wl,-z,relro", "-Wl,-z,now", @@ -202,13 +202,13 @@ var ( "-Wl,--exclude-libs,libunwind_llvm.a", "-Wl,--exclude-libs,libunwind.a", "-Wl,--compress-debug-sections=zstd", - }, commonGlobalLldflags) + }, commonGlobalLdflags) hostGlobalCflags = []string{} hostGlobalCppflags = []string{} - hostGlobalLldflags = commonGlobalLldflags + hostGlobalLdflags = commonGlobalLdflags commonGlobalCppflags = []string{ // -Wimplicit-fallthrough is not enabled by -Wall. @@ -403,9 +403,9 @@ func init() { pctx.StaticVariable("CommonGlobalConlyflags", strings.Join(commonGlobalConlyflags, " ")) pctx.StaticVariable("CommonGlobalAsflags", strings.Join(commonGlobalAsflags, " ")) pctx.StaticVariable("DeviceGlobalCppflags", strings.Join(deviceGlobalCppflags, " ")) - pctx.StaticVariable("DeviceGlobalLldflags", strings.Join(deviceGlobalLldflags, " ")) + pctx.StaticVariable("DeviceGlobalLdflags", strings.Join(deviceGlobalLdflags, " ")) pctx.StaticVariable("HostGlobalCppflags", strings.Join(hostGlobalCppflags, " ")) - pctx.StaticVariable("HostGlobalLldflags", strings.Join(hostGlobalLldflags, " ")) + pctx.StaticVariable("HostGlobalLdflags", strings.Join(hostGlobalLdflags, " ")) pctx.VariableFunc("CommonGlobalCflags", func(ctx android.PackageVarContext) string { flags := slices.Clone(commonGlobalCflags) diff --git a/cc/config/riscv64_device.go b/cc/config/riscv64_device.go index 65f1b720a..4bbf9fcef 100644 --- a/cc/config/riscv64_device.go +++ b/cc/config/riscv64_device.go @@ -37,7 +37,7 @@ var ( riscv64ArchVariantCflags = map[string][]string{} - riscv64Lldflags = []string{ + riscv64Ldflags = []string{ // This is already the driver's Android default, but duplicated here (and // above) for ease of experimentation with additional extensions. "-march=rv64gcv_zba_zbb_zbs", @@ -53,7 +53,7 @@ const () func init() { - pctx.StaticVariable("Riscv64Lldflags", strings.Join(riscv64Lldflags, " ")) + pctx.StaticVariable("Riscv64Ldflags", strings.Join(riscv64Ldflags, " ")) pctx.StaticVariable("Riscv64Cflags", strings.Join(riscv64Cflags, " ")) pctx.StaticVariable("Riscv64Cppflags", strings.Join(riscv64Cppflags, " ")) @@ -71,7 +71,7 @@ type toolchainRiscv64 struct { toolchainBionic toolchain64Bit - lldflags string + ldflags string toolchainCflags string } @@ -95,8 +95,8 @@ func (t *toolchainRiscv64) Cppflags() string { return "${config.Riscv64Cppflags}" } -func (t *toolchainRiscv64) Lldflags() string { - return t.lldflags +func (t *toolchainRiscv64) Ldflags() string { + return t.ldflags } func (t *toolchainRiscv64) ToolchainCflags() string { @@ -120,8 +120,8 @@ func riscv64ToolchainFactory(arch android.Arch) Toolchain { extraLdflags := variantOrDefault(riscv64CpuVariantLdflags, arch.CpuVariant) return &toolchainRiscv64{ - lldflags: strings.Join([]string{ - "${config.Riscv64Lldflags}", + ldflags: strings.Join([]string{ + "${config.Riscv64Ldflags}", extraLdflags, }, " "), toolchainCflags: strings.Join(toolchainCflags, " "), diff --git a/cc/config/toolchain.go b/cc/config/toolchain.go index 398c71266..7adb07beb 100644 --- a/cc/config/toolchain.go +++ b/cc/config/toolchain.go @@ -78,7 +78,7 @@ type Toolchain interface { Asflags() string Cflags() string Cppflags() string - Lldflags() string + Ldflags() string InstructionSetFlags(string) (string, error) ndkTriple() string diff --git a/cc/config/x86_64_device.go b/cc/config/x86_64_device.go index 2c0e70f8a..2ee425db0 100644 --- a/cc/config/x86_64_device.go +++ b/cc/config/x86_64_device.go @@ -29,7 +29,7 @@ var ( x86_64Cppflags = []string{} - x86_64Lldflags = []string{ + x86_64Ldflags = []string{ "-Wl,-z,separate-loadable-segments", } @@ -101,9 +101,9 @@ func init() { pctx.StaticVariable("X86_64ToolchainCflags", "-m64") pctx.StaticVariable("X86_64ToolchainLdflags", "-m64") - pctx.VariableFunc("X86_64Lldflags", func(ctx android.PackageVarContext) string { + pctx.VariableFunc("X86_64Ldflags", func(ctx android.PackageVarContext) string { maxPageSizeFlag := "-Wl,-z,max-page-size=" + ctx.Config().MaxPageSizeSupported() - flags := append(x86_64Lldflags, maxPageSizeFlag) + flags := append(x86_64Ldflags, maxPageSizeFlag) return strings.Join(flags, " ") }) @@ -163,8 +163,8 @@ func (t *toolchainX86_64) Cppflags() string { return "${config.X86_64Cppflags}" } -func (t *toolchainX86_64) Lldflags() string { - return "${config.X86_64Lldflags}" +func (t *toolchainX86_64) Ldflags() string { + return "${config.X86_64Ldflags}" } func (t *toolchainX86_64) YasmFlags() string { diff --git a/cc/config/x86_device.go b/cc/config/x86_device.go index d1552a0db..bd8d9d6de 100644 --- a/cc/config/x86_device.go +++ b/cc/config/x86_device.go @@ -107,7 +107,7 @@ func init() { pctx.StaticVariable("X86ToolchainCflags", "-m32") pctx.StaticVariable("X86ToolchainLdflags", "-m32") - pctx.StaticVariable("X86Lldflags", strings.Join(x86Ldflags, " ")) + pctx.StaticVariable("X86Ldflags", strings.Join(x86Ldflags, " ")) // Clang cflags pctx.StaticVariable("X86Cflags", strings.Join(x86Cflags, " ")) @@ -156,8 +156,8 @@ func (t *toolchainX86) Cppflags() string { return "${config.X86Cppflags}" } -func (t *toolchainX86) Lldflags() string { - return "${config.X86Lldflags}" +func (t *toolchainX86) Ldflags() string { + return "${config.X86Ldflags}" } func (t *toolchainX86) YasmFlags() string { diff --git a/cc/config/x86_linux_bionic_host.go b/cc/config/x86_linux_bionic_host.go index e27eb8fe0..6d3512920 100644 --- a/cc/config/x86_linux_bionic_host.go +++ b/cc/config/x86_linux_bionic_host.go @@ -44,7 +44,7 @@ var ( "-nostdlibinc", } - linuxBionicLldflags = []string{ + linuxBionicLdflags = []string{ "-Wl,-z,noexecstack", "-Wl,-z,relro", "-Wl,-z,now", @@ -75,7 +75,7 @@ const ( func init() { pctx.StaticVariable("LinuxBionicCflags", strings.Join(linuxBionicCflags, " ")) - pctx.StaticVariable("LinuxBionicLldflags", strings.Join(linuxBionicLldflags, " ")) + pctx.StaticVariable("LinuxBionicLdflags", strings.Join(linuxBionicLdflags, " ")) // Use the device gcc toolchain for now pctx.StaticVariable("LinuxBionicGccVersion", x86_64GccVersion) @@ -109,8 +109,8 @@ func (t *toolchainLinuxBionic) Cppflags() string { return "" } -func (t *toolchainLinuxBionic) Lldflags() string { - return "${config.LinuxBionicLldflags}" +func (t *toolchainLinuxBionic) Ldflags() string { + return "${config.LinuxBionicLdflags}" } func (t *toolchainLinuxBionic) ToolchainCflags() string { diff --git a/cc/config/x86_linux_host.go b/cc/config/x86_linux_host.go index cd06ffbcf..0601b2f7e 100644 --- a/cc/config/x86_linux_host.go +++ b/cc/config/x86_linux_host.go @@ -46,7 +46,7 @@ var ( "--sysroot /dev/null", } - linuxLldflags = []string{ + linuxLdflags = []string{ "-Wl,-z,noexecstack", "-Wl,-z,relro", "-Wl,-z,now", @@ -135,16 +135,16 @@ func init() { pctx.StaticVariable("LinuxGccTriple", "x86_64-linux") pctx.StaticVariable("LinuxCflags", strings.Join(linuxCflags, " ")) - pctx.StaticVariable("LinuxLldflags", strings.Join(linuxLldflags, " ")) + pctx.StaticVariable("LinuxLdflags", strings.Join(linuxLdflags, " ")) pctx.StaticVariable("LinuxGlibcCflags", strings.Join(linuxGlibcCflags, " ")) - pctx.StaticVariable("LinuxGlibcLldflags", strings.Join(linuxGlibcLdflags, " ")) + pctx.StaticVariable("LinuxGlibcLdflags", strings.Join(linuxGlibcLdflags, " ")) pctx.StaticVariable("LinuxMuslCflags", strings.Join(linuxMuslCflags, " ")) - pctx.StaticVariable("LinuxMuslLldflags", strings.Join(linuxMuslLdflags, " ")) + pctx.StaticVariable("LinuxMuslLdflags", strings.Join(linuxMuslLdflags, " ")) pctx.StaticVariable("LinuxX86Cflags", strings.Join(linuxX86Cflags, " ")) pctx.StaticVariable("LinuxX8664Cflags", strings.Join(linuxX8664Cflags, " ")) - pctx.StaticVariable("LinuxX86Lldflags", strings.Join(linuxX86Ldflags, " ")) - pctx.StaticVariable("LinuxX8664Lldflags", strings.Join(linuxX8664Ldflags, " ")) + pctx.StaticVariable("LinuxX86Ldflags", strings.Join(linuxX86Ldflags, " ")) + pctx.StaticVariable("LinuxX8664Ldflags", strings.Join(linuxX8664Ldflags, " ")) // Yasm flags pctx.StaticVariable("LinuxX86YasmFlags", "-f elf32 -m x86") pctx.StaticVariable("LinuxX8664YasmFlags", "-f elf64 -m amd64") @@ -193,12 +193,12 @@ func (t *toolchainLinuxX8664) Cppflags() string { return "" } -func (t *toolchainLinuxX86) Lldflags() string { - return "${config.LinuxLldflags} ${config.LinuxX86Lldflags}" +func (t *toolchainLinuxX86) Ldflags() string { + return "${config.LinuxLdflags} ${config.LinuxX86Ldflags}" } -func (t *toolchainLinuxX8664) Lldflags() string { - return "${config.LinuxLldflags} ${config.LinuxX8664Lldflags}" +func (t *toolchainLinuxX8664) Ldflags() string { + return "${config.LinuxLdflags} ${config.LinuxX8664Ldflags}" } func (t *toolchainLinuxX86) YasmFlags() string { @@ -241,8 +241,8 @@ func (toolchainGlibc) Cflags() string { return "${config.LinuxGlibcCflags}" } -func (toolchainGlibc) Lldflags() string { - return "${config.LinuxGlibcLldflags}" +func (toolchainGlibc) Ldflags() string { + return "${config.LinuxGlibcLdflags}" } type toolchainLinuxGlibcX86 struct { @@ -263,8 +263,8 @@ func (t *toolchainLinuxGlibcX86) Cflags() string { return t.toolchainLinuxX86.Cflags() + " " + t.toolchainGlibc.Cflags() } -func (t *toolchainLinuxGlibcX86) Lldflags() string { - return t.toolchainLinuxX86.Lldflags() + " " + t.toolchainGlibc.Lldflags() +func (t *toolchainLinuxGlibcX86) Ldflags() string { + return t.toolchainLinuxX86.Ldflags() + " " + t.toolchainGlibc.Ldflags() } func (t *toolchainLinuxGlibcX8664) ClangTriple() string { @@ -275,8 +275,8 @@ func (t *toolchainLinuxGlibcX8664) Cflags() string { return t.toolchainLinuxX8664.Cflags() + " " + t.toolchainGlibc.Cflags() } -func (t *toolchainLinuxGlibcX8664) Lldflags() string { - return t.toolchainLinuxX8664.Lldflags() + " " + t.toolchainGlibc.Lldflags() +func (t *toolchainLinuxGlibcX8664) Ldflags() string { + return t.toolchainLinuxX8664.Ldflags() + " " + t.toolchainGlibc.Ldflags() } var toolchainLinuxGlibcX86Singleton Toolchain = &toolchainLinuxGlibcX86{} @@ -311,8 +311,8 @@ func (toolchainMusl) Cflags() string { return "${config.LinuxMuslCflags}" } -func (toolchainMusl) Lldflags() string { - return "${config.LinuxMuslLldflags}" +func (toolchainMusl) Ldflags() string { + return "${config.LinuxMuslLdflags}" } type toolchainLinuxMuslX86 struct { @@ -333,8 +333,8 @@ func (t *toolchainLinuxMuslX86) Cflags() string { return t.toolchainLinuxX86.Cflags() + " " + t.toolchainMusl.Cflags() } -func (t *toolchainLinuxMuslX86) Lldflags() string { - return t.toolchainLinuxX86.Lldflags() + " " + t.toolchainMusl.Lldflags() +func (t *toolchainLinuxMuslX86) Ldflags() string { + return t.toolchainLinuxX86.Ldflags() + " " + t.toolchainMusl.Ldflags() } func (t *toolchainLinuxMuslX8664) ClangTriple() string { @@ -345,8 +345,8 @@ func (t *toolchainLinuxMuslX8664) Cflags() string { return t.toolchainLinuxX8664.Cflags() + " " + t.toolchainMusl.Cflags() } -func (t *toolchainLinuxMuslX8664) Lldflags() string { - return t.toolchainLinuxX8664.Lldflags() + " " + t.toolchainMusl.Lldflags() +func (t *toolchainLinuxMuslX8664) Ldflags() string { + return t.toolchainLinuxX8664.Ldflags() + " " + t.toolchainMusl.Ldflags() } var toolchainLinuxMuslX86Singleton Toolchain = &toolchainLinuxMuslX86{} diff --git a/cc/config/x86_windows_host.go b/cc/config/x86_windows_host.go index 848c89e28..6d2794d2e 100644 --- a/cc/config/x86_windows_host.go +++ b/cc/config/x86_windows_host.go @@ -66,7 +66,7 @@ var ( windowsX8664Cppflags = []string{} - windowsLldflags = []string{ + windowsLdflags = []string{ "-Wl,--dynamicbase", "-Wl,--nxcompat", @@ -140,13 +140,13 @@ func init() { pctx.StaticVariable("WindowsGccTriple", "x86_64-w64-mingw32") pctx.StaticVariable("WindowsCflags", strings.Join(windowsCflags, " ")) - pctx.StaticVariable("WindowsLldflags", strings.Join(windowsLldflags, " ")) + pctx.StaticVariable("WindowsLdflags", strings.Join(windowsLdflags, " ")) pctx.StaticVariable("WindowsCppflags", strings.Join(windowsCppflags, " ")) pctx.StaticVariable("WindowsX86Cflags", strings.Join(windowsX86Cflags, " ")) pctx.StaticVariable("WindowsX8664Cflags", strings.Join(windowsX8664Cflags, " ")) - pctx.StaticVariable("WindowsX86Lldflags", strings.Join(windowsX86Ldflags, " ")) - pctx.StaticVariable("WindowsX8664Lldflags", strings.Join(windowsX8664Ldflags, " ")) + pctx.StaticVariable("WindowsX86Ldflags", strings.Join(windowsX86Ldflags, " ")) + pctx.StaticVariable("WindowsX8664Ldflags", strings.Join(windowsX8664Ldflags, " ")) pctx.StaticVariable("WindowsX86Cppflags", strings.Join(windowsX86Cppflags, " ")) pctx.StaticVariable("WindowsX8664Cppflags", strings.Join(windowsX8664Cppflags, " ")) @@ -216,12 +216,12 @@ func (t *toolchainWindowsX8664) Cppflags() string { return "${config.WindowsCppflags} ${config.WindowsX8664Cppflags}" } -func (t *toolchainWindowsX86) Lldflags() string { - return "${config.WindowsLldflags} ${config.WindowsX86Lldflags}" +func (t *toolchainWindowsX86) Ldflags() string { + return "${config.WindowsLdflags} ${config.WindowsX86Ldflags}" } -func (t *toolchainWindowsX8664) Lldflags() string { - return "${config.WindowsLldflags} ${config.WindowsX8664Lldflags}" +func (t *toolchainWindowsX8664) Ldflags() string { + return "${config.WindowsLdflags} ${config.WindowsX8664Ldflags}" } func (t *toolchainWindowsX86) YasmFlags() string { diff --git a/cc/linker.go b/cc/linker.go index e051263e4..e138203a4 100644 --- a/cc/linker.go +++ b/cc/linker.go @@ -472,7 +472,7 @@ func CommonLinkerFlags(ctx android.ModuleContext, flags Flags, toolchain config. ctx.ModuleErrorf("trying to add CommonLinkerFlags to non-LinkableInterface module.") return flags } - flags.Global.LdFlags = append(flags.Global.LdFlags, fmt.Sprintf("${config.%sGlobalLldflags}", hod)) + flags.Global.LdFlags = append(flags.Global.LdFlags, fmt.Sprintf("${config.%sGlobalLdflags}", hod)) if allow_undefined_symbols { if ctx.Darwin() { @@ -483,7 +483,7 @@ func CommonLinkerFlags(ctx android.ModuleContext, flags Flags, toolchain config. flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--no-undefined") } - flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.Lldflags()) + flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.Ldflags()) if !toolchain.Bionic() && ctx.Os() != android.LinuxMusl { if !ctx.Windows() { diff --git a/cc/makevars.go b/cc/makevars.go index 00d99fe1d..624f7482f 100644 --- a/cc/makevars.go +++ b/cc/makevars.go @@ -241,9 +241,9 @@ func makeVarsToolchain(ctx android.MakeVarsContext, secondPrefix string, fmt.Sprintf("${config.%sGlobalCppflags}", hod), toolchain.Cppflags(), }, " ")) - ctx.Strict(clangPrefix+"GLOBAL_LLDFLAGS", strings.Join([]string{ - fmt.Sprintf("${config.%sGlobalLldflags}", hod), - toolchain.Lldflags(), + ctx.Strict(clangPrefix+"GLOBAL_LDFLAGS", strings.Join([]string{ + fmt.Sprintf("${config.%sGlobalLdflags}", hod), + toolchain.Ldflags(), toolchain.ToolchainLdflags(), productExtraLdflags, }, " ")) diff --git a/rust/config/arm64_device.go b/rust/config/arm64_device.go index 9dd414cc0..ba7458e94 100644 --- a/rust/config/arm64_device.go +++ b/rust/config/arm64_device.go @@ -123,7 +123,7 @@ func (t *toolchainArm64) RustTriple() string { func (t *toolchainArm64) ToolchainLinkFlags() string { // Prepend the lld flags from cc_config so we stay in sync with cc - return "${config.DeviceGlobalLinkFlags} ${cc_config.Arm64Lldflags} ${config.Arm64ToolchainLinkFlags}" + return "${config.DeviceGlobalLinkFlags} ${cc_config.Arm64Ldflags} ${config.Arm64ToolchainLinkFlags}" } func (t *toolchainArm64) ToolchainRustFlags() string { diff --git a/rust/config/arm_device.go b/rust/config/arm_device.go index 5394e8a09..ce6fb7f34 100644 --- a/rust/config/arm_device.go +++ b/rust/config/arm_device.go @@ -58,7 +58,7 @@ func (t *toolchainArm) RustTriple() string { func (t *toolchainArm) ToolchainLinkFlags() string { // Prepend the lld flags from cc_config so we stay in sync with cc - return "${config.DeviceGlobalLinkFlags} ${cc_config.ArmLldflags} ${config.ArmToolchainLinkFlags}" + return "${config.DeviceGlobalLinkFlags} ${cc_config.ArmLdflags} ${config.ArmToolchainLinkFlags}" } func (t *toolchainArm) ToolchainRustFlags() string { diff --git a/rust/config/arm_linux_host.go b/rust/config/arm_linux_host.go index 22bdaee3e..6e7593204 100644 --- a/rust/config/arm_linux_host.go +++ b/rust/config/arm_linux_host.go @@ -56,7 +56,7 @@ func (t *toolchainLinuxArm64) Name() string { func (t *toolchainLinuxArm64) ToolchainLinkFlags() string { // Prepend the lld flags from cc_config so we stay in sync with cc - return "${cc_config.LinuxLldflags} ${cc_config.LinuxArm64Lldflags} " + + return "${cc_config.LinuxLdflags} ${cc_config.LinuxArm64Ldflags} " + "${config.LinuxToolchainLinkFlags} ${config.LinuxToolchainArm64LinkFlags}" } @@ -113,7 +113,7 @@ func (toolchainLinuxArm64) LibclangRuntimeLibraryArch() string { func (t *toolchainLinuxArm) ToolchainLinkFlags() string { // Prepend the lld flags from cc_config so we stay in sync with cc - return "${cc_config.LinuxLldflags} ${cc_config.LinuxArmLldflags} " + + return "${cc_config.LinuxLdflags} ${cc_config.LinuxArmLdflags} " + "${config.LinuxToolchainLinkFlags} ${config.LinuxToolchainArmLinkFlags}" } diff --git a/rust/config/darwin_host.go b/rust/config/darwin_host.go index df8c6ac5a..986621053 100644 --- a/rust/config/darwin_host.go +++ b/rust/config/darwin_host.go @@ -104,7 +104,7 @@ func (t *toolchainDarwin) ProcMacroSuffix() string { func (t *toolchainDarwinArm64) ToolchainLinkFlags() string { // Prepend the lld flags from cc_config so we stay in sync with cc - return "${cc_config.DarwinLldflags} ${config.DarwinToolchainLinkFlags} ${config.DarwinToolchainArm64LinkFlags}" + return "${cc_config.DarwinLdflags} ${config.DarwinToolchainLinkFlags} ${config.DarwinToolchainArm64LinkFlags}" } func (t *toolchainDarwinArm64) ToolchainRustFlags() string { @@ -113,7 +113,7 @@ func (t *toolchainDarwinArm64) ToolchainRustFlags() string { func (t *toolchainDarwinX8664) ToolchainLinkFlags() string { // Prepend the lld flags from cc_config so we stay in sync with cc - return "${cc_config.DarwinLldflags} ${config.DarwinToolchainLinkFlags} ${config.DarwinToolchainX8664LinkFlags}" + return "${cc_config.DarwinLdflags} ${config.DarwinToolchainLinkFlags} ${config.DarwinToolchainX8664LinkFlags}" } func (t *toolchainDarwinX8664) ToolchainRustFlags() string { diff --git a/rust/config/global.go b/rust/config/global.go index 75d3f38a4..03e1b6e05 100644 --- a/rust/config/global.go +++ b/rust/config/global.go @@ -83,7 +83,7 @@ var ( deviceGlobalLinkFlags = []string{ // Prepend the lld flags from cc_config so we stay in sync with cc - "${cc_config.DeviceGlobalLldflags}", + "${cc_config.DeviceGlobalLdflags}", // Override cc's --no-undefined-version to allow rustc's generated alloc functions "-Wl,--undefined-version", @@ -138,7 +138,7 @@ func init() { pctx.StaticVariable("DEVICE_GLOBAL_LINK_FLAGS", strings.Join(android.RemoveListFromList(deviceGlobalLinkFlags, []string{ // The cc_config flags are retrieved from cc_toolchain by rust rules. - "${cc_config.DeviceGlobalLldflags}", + "${cc_config.DeviceGlobalLdflags}", "-B${cc_config.ClangBin}", }), " ")) } diff --git a/rust/config/riscv64_device.go b/rust/config/riscv64_device.go index 0a9c61a64..a8a0990ae 100644 --- a/rust/config/riscv64_device.go +++ b/rust/config/riscv64_device.go @@ -58,7 +58,7 @@ func (t *toolchainRiscv64) RustTriple() string { func (t *toolchainRiscv64) ToolchainLinkFlags() string { // Prepend the lld flags from cc_config so we stay in sync with cc - return "${config.DeviceGlobalLinkFlags} ${cc_config.Riscv64Lldflags} ${config.Riscv64ToolchainLinkFlags}" + return "${config.DeviceGlobalLinkFlags} ${cc_config.Riscv64Ldflags} ${config.Riscv64ToolchainLinkFlags}" } func (t *toolchainRiscv64) ToolchainRustFlags() string { diff --git a/rust/config/x86_64_device.go b/rust/config/x86_64_device.go index 3c484d894..eb04cbd96 100644 --- a/rust/config/x86_64_device.go +++ b/rust/config/x86_64_device.go @@ -69,7 +69,7 @@ func (t *toolchainX86_64) RustTriple() string { func (t *toolchainX86_64) ToolchainLinkFlags() string { // Prepend the lld flags from cc_config so we stay in sync with cc - return "${config.DeviceGlobalLinkFlags} ${cc_config.X86_64Lldflags} ${config.X86_64ToolchainLinkFlags}" + return "${config.DeviceGlobalLinkFlags} ${cc_config.X86_64Ldflags} ${config.X86_64ToolchainLinkFlags}" } func (t *toolchainX86_64) ToolchainRustFlags() string { diff --git a/rust/config/x86_device.go b/rust/config/x86_device.go index 3c597cc23..d524e205c 100644 --- a/rust/config/x86_device.go +++ b/rust/config/x86_device.go @@ -71,7 +71,7 @@ func (t *toolchainX86) RustTriple() string { func (t *toolchainX86) ToolchainLinkFlags() string { // Prepend the lld flags from cc_config so we stay in sync with cc - return "${config.DeviceGlobalLinkFlags} ${cc_config.X86Lldflags} ${config.X86ToolchainLinkFlags}" + return "${config.DeviceGlobalLinkFlags} ${cc_config.X86Ldflags} ${config.X86ToolchainLinkFlags}" } func (t *toolchainX86) ToolchainRustFlags() string { diff --git a/rust/config/x86_linux_bionic_host.go b/rust/config/x86_linux_bionic_host.go index 79c40ce41..495ab20ab 100644 --- a/rust/config/x86_linux_bionic_host.go +++ b/rust/config/x86_linux_bionic_host.go @@ -61,7 +61,7 @@ func (t *toolchainLinuxBionicX8664) RustTriple() string { func (t *toolchainLinuxBionicX8664) ToolchainLinkFlags() string { // Prepend the lld flags from cc_config so we stay in sync with cc - return "${cc_config.LinuxBionicLldflags} ${config.LinuxBionicToolchainLinkFlags}" + return "${cc_config.LinuxBionicLdflags} ${config.LinuxBionicToolchainLinkFlags}" } func (t *toolchainLinuxBionicX8664) ToolchainRustFlags() string { diff --git a/rust/config/x86_linux_host.go b/rust/config/x86_linux_host.go index 512b0430d..e9a3b41ed 100644 --- a/rust/config/x86_linux_host.go +++ b/rust/config/x86_linux_host.go @@ -87,7 +87,7 @@ func (t *toolchainLinuxX8664) Name() string { func (t *toolchainLinuxX8664) ToolchainLinkFlags() string { // Prepend the lld flags from cc_config so we stay in sync with cc - return "${cc_config.LinuxLldflags} ${cc_config.LinuxX8664Lldflags} " + + return "${cc_config.LinuxLdflags} ${cc_config.LinuxX8664Ldflags} " + "${config.LinuxToolchainLinkFlags} ${config.LinuxToolchainX8664LinkFlags}" } @@ -170,7 +170,7 @@ func (toolchainLinuxX8664) LibclangRuntimeLibraryArch() string { func (t *toolchainLinuxX86) ToolchainLinkFlags() string { // Prepend the lld flags from cc_config so we stay in sync with cc - return "${cc_config.LinuxLldflags} ${cc_config.LinuxX86Lldflags} " + + return "${cc_config.LinuxLdflags} ${cc_config.LinuxX86Ldflags} " + "${config.LinuxToolchainLinkFlags} ${config.LinuxToolchainX86LinkFlags}" } diff --git a/rust/config/x86_windows_host.go b/rust/config/x86_windows_host.go index 3d83d3f20..5e87829fd 100644 --- a/rust/config/x86_windows_host.go +++ b/rust/config/x86_windows_host.go @@ -82,7 +82,7 @@ func (t *toolchainWindowsX86) Name() string { func (t *toolchainWindowsX86) ToolchainLinkFlags() string { // Prepend the lld flags from cc_config so we stay in sync with cc - return "${cc_config.WindowsLldflags} ${cc_config.WindowsX86Lldflags} ${cc_config.WindowsAvailableLibraries} " + + return "${cc_config.WindowsLdflags} ${cc_config.WindowsX86Ldflags} ${cc_config.WindowsAvailableLibraries} " + "${config.WindowsToolchainRustLinkFlags} ${config.WindowsX86ToolchainRustLinkFlags}" } @@ -149,7 +149,7 @@ func (t *toolchainWindowsX8664) Name() string { func (t *toolchainWindowsX8664) ToolchainLinkFlags() string { // Prepend the lld flags from cc_config so we stay in sync with cc - return "${cc_config.WindowsLldflags} ${cc_config.WindowsX8664Lldflags} ${cc_config.WindowsAvailableLibraries} " + + return "${cc_config.WindowsLdflags} ${cc_config.WindowsX8664Ldflags} ${cc_config.WindowsAvailableLibraries} " + "${config.WindowsToolchainRustLinkFlags} ${config.WindowsX8664ToolchainRustLinkFlags}" } -- cgit v1.2.3 From 335ea1a74dcd716fc614d5628afaa343444e3259 Mon Sep 17 00:00:00 2001 From: Jiakai Zhang Date: Tue, 29 Apr 2025 21:57:12 +0100 Subject: Fix manifest_check_test. Test was broken by Ic46909c096e208e3fc4cee99cf298f571e9bc269. Bug: 414554599 Test: atest manifest_check_test Flag: TEST_ONLY Change-Id: Ic4033651cb5a4352e36722eba051e7351324dfb8 --- scripts/manifest_check_test.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/scripts/manifest_check_test.py b/scripts/manifest_check_test.py index abe0d8b0e..eedce18b6 100755 --- a/scripts/manifest_check_test.py +++ b/scripts/manifest_check_test.py @@ -45,18 +45,17 @@ class EnforceUsesLibrariesTest(unittest.TestCase): """Unit tests for add_extract_native_libs function.""" def run_test(self, xml, apk, uses_libraries=(), optional_uses_libraries=(), - missing_optional_uses_libraries=()): #pylint: disable=dangerous-default-value + missing_optional_uses_libraries=(), + bootclasspath_libs=()): #pylint: disable=dangerous-default-value doc = minidom.parseString(xml) try: relax = False manifest_check.enforce_uses_libraries( doc, uses_libraries, optional_uses_libraries, missing_optional_uses_libraries, - relax, False, 'path/to/X/AndroidManifest.xml') - manifest_check.enforce_uses_libraries(apk, uses_libraries, - optional_uses_libraries, - missing_optional_uses_libraries, - relax, True, - 'path/to/X/X.apk') + relax, False, 'path/to/X/AndroidManifest.xml', bootclasspath_libs) + manifest_check.enforce_uses_libraries( + apk, uses_libraries, optional_uses_libraries, missing_optional_uses_libraries, + relax, True, 'path/to/X/X.apk', bootclasspath_libs) return True except manifest_check.ManifestMismatchError: return False @@ -260,6 +259,15 @@ class EnforceUsesLibrariesTest(unittest.TestCase): optional_uses_libraries=['//x/y/z:bar', '//x/y/z:qux']) self.assertTrue(matches) + def test_ignore_bootclasspath_libs(self): + xml = self.xml_tmpl % (uses_library_xml('foo', required_xml(True))) + apk = self.apk_tmpl % (uses_library_apk('foo', required_apk(True))) + xml = self.xml_tmpl % (uses_library_xml('bar', required_xml(False))) + apk = self.apk_tmpl % (uses_library_apk('bar', required_apk(False))) + matches = self.run_test(xml, apk, uses_libraries=[], optional_uses_libraries=[], + bootclasspath_libs=['foo', 'bar']) + self.assertTrue(matches) + class ExtractTargetSdkVersionTest(unittest.TestCase): -- cgit v1.2.3 From 14934e9f5ae985a262538f5a7bf29a3514fa00c7 Mon Sep 17 00:00:00 2001 From: LaMont Jones Date: Tue, 29 Apr 2025 14:47:12 -0700 Subject: release-config: include $TARGET_PRODUCT in artifacts Rename the partition build flag files to build_flags_{TARGET_PRODUCT}-{PARTITION}.json Bug: None Test: manual Change-Id: I5e116598b58e09d22fc2b3635e3dfb6d6e73abdd --- aconfig/build_flags/build_flags.go | 8 ++++++-- cmd/release_config/release_config/main.go | 2 +- cmd/release_config/release_config_lib/release_config.go | 4 ++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/aconfig/build_flags/build_flags.go b/aconfig/build_flags/build_flags.go index 94e1eb193..eeead6edf 100644 --- a/aconfig/build_flags/build_flags.go +++ b/aconfig/build_flags/build_flags.go @@ -47,11 +47,15 @@ func buildFlagsFactory() android.Module { func (m *buildFlags) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Read the build_flags_.json file generated by soong // 'release-config' command. - srcPath := android.PathForOutput(ctx, "release-config", fmt.Sprintf("build_flags_%s.json", m.PartitionTag(ctx.DeviceConfig()))) + product := "None" + if ctx.Config().HasDeviceProduct() { + product = ctx.Config().DeviceProduct() + } + srcPath := android.PathForOutput(ctx, "release-config", fmt.Sprintf("build_flags_%s-%s.json", product, m.PartitionTag(ctx.DeviceConfig()))) outputPath := android.PathForModuleOut(ctx, outJsonFileName) // The 'release-config' command is called for every build, and generates the - // build_flags_.json file. + // build_flags_-.json file. // Update the output file only if the source file is changed. ctx.Build(pctx, android.BuildParams{ Rule: android.CpIfChanged, diff --git a/cmd/release_config/release_config/main.go b/cmd/release_config/release_config/main.go index f11147a2c..eefa842d8 100644 --- a/cmd/release_config/release_config/main.go +++ b/cmd/release_config/release_config/main.go @@ -129,7 +129,7 @@ func main() { panic(err) } } - if err = config.WritePartitionBuildFlags(outputDir); err != nil { + if err = config.WritePartitionBuildFlags(product, outputDir); err != nil { panic(err) } diff --git a/cmd/release_config/release_config_lib/release_config.go b/cmd/release_config/release_config_lib/release_config.go index 873f2fc28..7df177ce8 100644 --- a/cmd/release_config/release_config_lib/release_config.go +++ b/cmd/release_config/release_config_lib/release_config.go @@ -508,7 +508,7 @@ func (config *ReleaseConfig) WriteMakefile(outFile, targetRelease string, config return os.WriteFile(outFile, []byte(data), 0644) } -func (config *ReleaseConfig) WritePartitionBuildFlags(outDir string) error { +func (config *ReleaseConfig) WritePartitionBuildFlags(product string, outDir string) error { var err error for partition, flags := range config.PartitionBuildFlags { slices.SortFunc(flags.Flags, func(a, b *rc_proto.FlagArtifact) int { @@ -516,7 +516,7 @@ func (config *ReleaseConfig) WritePartitionBuildFlags(outDir string) error { }) // The json file name must not be modified as this is read from // build_flags_json module - if err = WriteMessage(filepath.Join(outDir, fmt.Sprintf("build_flags_%s.json", partition)), flags); err != nil { + if err = WriteMessage(filepath.Join(outDir, fmt.Sprintf("build_flags_%s-%s.json", product, partition)), flags); err != nil { return err } } -- cgit v1.2.3 From efa54cafca76b3138eb475b010a700bfd1c5427e Mon Sep 17 00:00:00 2001 From: LaMont Jones Date: Wed, 23 Apr 2025 10:25:37 -0700 Subject: Add build flag for read-only source tree When RELEASE_SRC_DIR_IS_READ_ONLY=true then configure nsjail to treat the workspace as read-only unless BUILD_BROKEN_SRC_DIR_IS_WRITABLE=true. This effectively changes the default value from `false` to `true` when the build flag is set. Bug: None Test: manual, TH Change-Id: I4de2925869225198a197aabb07054c5f5f5c3818 --- ui/build/dumpvars.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go index f9a7246f1..3f8d26f0f 100644 --- a/ui/build/dumpvars.go +++ b/ui/build/dumpvars.go @@ -300,6 +300,7 @@ func runMakeProductConfig(ctx Context, config Config) { "BUILD_BROKEN_USES_BUILD_STATIC_JAVA_LIBRARY", "BUILD_BROKEN_USES_BUILD_STATIC_LIBRARY", "RELEASE_BUILD_EXECUTION_METRICS", + "RELEASE_SRC_DIR_IS_READ_ONLY", }, exportEnvVars...), BannerVars...) makeVars, err := dumpMakeVars(ctx, config, config.Arguments(), allVars, true, "") @@ -321,7 +322,15 @@ func runMakeProductConfig(ctx Context, config Config) { config.SetNinjaArgs(strings.Fields(makeVars["NINJA_GOALS"])) config.SetTargetDevice(makeVars["TARGET_DEVICE"]) config.SetTargetDeviceDir(makeVars["TARGET_DEVICE_DIR"]) - config.sandboxConfig.SetSrcDirIsRO(makeVars["BUILD_BROKEN_SRC_DIR_IS_WRITABLE"] == "false") + if makeVars["RELEASE_SRC_DIR_IS_READ_ONLY"] == "true" { + // If the release config says source is read-only, then make it read-write only if + // BUILD_BROKEN_SRC_DIR_IS_WRITABLE=true. + config.sandboxConfig.SetSrcDirIsRO(makeVars["BUILD_BROKEN_SRC_DIR_IS_WRITABLE"] != "true") + } else { + // If the release config says source is not read-only, then make it read-only only if + // BUILD_BROKEN_SRC_DIR_IS_WRITABLE=false. + config.sandboxConfig.SetSrcDirIsRO(makeVars["BUILD_BROKEN_SRC_DIR_IS_WRITABLE"] == "false") + } config.sandboxConfig.SetSrcDirRWAllowlist(strings.Fields(makeVars["BUILD_BROKEN_SRC_DIR_RW_ALLOWLIST"])) config.SetBuildBrokenDupRules(makeVars["BUILD_BROKEN_DUP_RULES"] == "true") -- cgit v1.2.3 From 47e0757034fd2239f639b14d4f35d170fba7a50a Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Tue, 29 Apr 2025 16:09:52 -0700 Subject: Make bpfs configurable Per user request. Fixes: 413906274 Test: m nothing --no-skip-soong-tests Change-Id: I8b05a919e735c618b0b8f67c1eee705f45a4c27d --- apex/apex.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apex/apex.go b/apex/apex.go index 3ddcd8825..d7e2691ea 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -367,7 +367,7 @@ type overridableProperties struct { Prebuilts proptools.Configurable[[]string] // List of BPF programs inside this APEX bundle. - Bpfs []string + Bpfs proptools.Configurable[[]string] // Names of modules to be overridden. Listed modules can only be other binaries (in Make or // Soong). This does not completely prevent installation of the overridden binaries, but if @@ -981,7 +981,7 @@ func (a *apexBundle) OverridablePropertiesDepsMutator(ctx android.BottomUpMutato commonVariation := ctx.Config().AndroidCommonTarget.Variations() ctx.AddFarVariationDependencies(commonVariation, androidAppTag, a.overridableProperties.Apps.GetOrDefault(ctx, nil)...) - ctx.AddFarVariationDependencies(commonVariation, bpfTag, a.overridableProperties.Bpfs...) + ctx.AddFarVariationDependencies(commonVariation, bpfTag, a.overridableProperties.Bpfs.GetOrDefault(ctx, nil)...) if prebuilts := a.overridableProperties.Prebuilts.GetOrDefault(ctx, nil); len(prebuilts) > 0 { // For prebuilt_etc, use the first variant (64 on 64/32bit device, 32 on 32bit device) // regardless of the TARGET_PREFER_* setting. See b/144532908 -- cgit v1.2.3 From 71bc01688bb891ec3a4a2a2e05577915fd59baa7 Mon Sep 17 00:00:00 2001 From: Roopesh Nataraja Date: Thu, 17 Apr 2025 11:10:47 -0700 Subject: Parse BoardInitBootHeaderVersion variable to get the header_version Parse BoardInitBootHeaderVersion variable to get the header_version of init_boot and create the image. Relying on BoardBootHeaderVersion triggers creation of vendor_boot image which may not be needed. Bug: 411213637 Test: builds Change-Id: Ibeaf0828425371fe28e46aa87117fceb947fda47 --- android/variable.go | 1 + fsgen/boot_imgs.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/android/variable.go b/android/variable.go index c788688d6..8946dbe02 100644 --- a/android/variable.go +++ b/android/variable.go @@ -647,6 +647,7 @@ type PartitionVariables struct { BoardVendorBootimagePartitionSize string `json:",omitempty"` BoardInitBootimagePartitionSize string `json:",omitempty"` BoardBootHeaderVersion string `json:",omitempty"` + BoardInitBootHeaderVersion string `json:",omitempty"` TargetKernelPath string `json:",omitempty"` BoardUsesGenericKernelImage bool `json:",omitempty"` BootSecurityPatch string `json:",omitempty"` diff --git a/fsgen/boot_imgs.go b/fsgen/boot_imgs.go index 0ba0a90dd..02256c16f 100644 --- a/fsgen/boot_imgs.go +++ b/fsgen/boot_imgs.go @@ -181,7 +181,7 @@ func createInitBootImage(ctx android.LoadHookContext) bool { &filesystem.BootimgProperties{ Boot_image_type: proptools.StringPtr("init_boot"), Ramdisk_module: proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "ramdisk")), - Header_version: proptools.StringPtr(partitionVariables.BoardBootHeaderVersion), + Header_version: proptools.StringPtr(partitionVariables.BoardInitBootHeaderVersion), Security_patch: securityPatch, Partition_size: partitionSize, Use_avb: avbInfo.avbEnable, -- cgit v1.2.3 From f7f56ac5d43a88a439cf6abe7b84f5a0ef6db03a Mon Sep 17 00:00:00 2001 From: Owner Cleanup Bot Date: Wed, 30 Apr 2025 10:07:43 -0700 Subject: [owners] Remove joeo@google.com from android/team_proto/OWNERS This suggested change is automatically generated based on group memberships and affiliations. Please approve this change and vote the highest CR. This will keep the OWNERs file tidy. We ask that you do not ignore this change and approve it unless you know a reason the OWNER should remain. It can always be reverted if needed. If this change is in error, vote the lowest CR value (i.e. reject the CL) and the bot will abandon it. See the owner's recent review activity for context: https://googleplex-android-review.googlesource.com/q/joeo@google.com To report an issue, file a bug in the Infra>Codereview component. Change-Id: I3724902c574d4cd5db2dcfd49c9ecfbf06a1814c --- android/team_proto/OWNERS | 1 - 1 file changed, 1 deletion(-) diff --git a/android/team_proto/OWNERS b/android/team_proto/OWNERS index 1eb820b4c..bfbe4348b 100644 --- a/android/team_proto/OWNERS +++ b/android/team_proto/OWNERS @@ -1,4 +1,3 @@ dariofreni@google.com -joeo@google.com ronish@google.com rbraunstein@google.com -- cgit v1.2.3 From f14af61072ed366ea83b092b2d140e3a341d16f2 Mon Sep 17 00:00:00 2001 From: Owner Cleanup Bot Date: Wed, 30 Apr 2025 10:08:04 -0700 Subject: [owners] Remove joeo@google.com from OWNERS This suggested change is automatically generated based on group memberships and affiliations. Please approve this change and vote the highest CR. This will keep the OWNERs file tidy. We ask that you do not ignore this change and approve it unless you know a reason the OWNER should remain. It can always be reverted if needed. If this change is in error, vote the lowest CR value (i.e. reject the CL) and the bot will abandon it. See the owner's recent review activity for context: https://googleplex-android-review.googlesource.com/q/joeo@google.com To report an issue, file a bug in the Infra>Codereview component. Change-Id: Icef0601d62c352ce2f3f22ce55bdbc1a6aa31dab --- OWNERS | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/OWNERS b/OWNERS index 01025fb65..490c15726 100644 --- a/OWNERS +++ b/OWNERS @@ -7,11 +7,10 @@ ccross@android.com colefaust@google.com dwillemsen@google.com jihoonkang@google.com -joeo@google.com lamontjones@google.com mrziwang@google.com spandandas@google.com weiwli@google.com yudiliu@google.com -per-file build/soong/ui/build/androidmk_denylist.go = joeo@google.com, weiwli@google.com \ No newline at end of file +per-file build/soong/ui/build/androidmk_denylist.go =weiwli@google.com -- cgit v1.2.3 From 1314209d9550e6685b2e2ac8df699c1053b0a028 Mon Sep 17 00:00:00 2001 From: Jiakai Zhang Date: Wed, 30 Apr 2025 18:10:26 +0100 Subject: Propagate transitive CLC of SDK libraries. If an app depends on SDK library "foo", and "foo" depends on "bar", "bar" should be added to the CLC of the app. Bug: 414306949 Test: m --no-skip-soong-tests nothing Flag: EXEMPT bugfix Change-Id: Ief74725d48853b400f2c7dc3b03eb6a349feb7c9 --- dexpreopt/class_loader_context.go | 5 +++ java/app_test.go | 67 +++++++++++++++++++++++++++++++++++++++ java/sdk_library.go | 3 ++ 3 files changed, 75 insertions(+) diff --git a/dexpreopt/class_loader_context.go b/dexpreopt/class_loader_context.go index 7f50912b5..8658040f6 100644 --- a/dexpreopt/class_loader_context.go +++ b/dexpreopt/class_loader_context.go @@ -328,7 +328,12 @@ func (clcMap ClassLoaderContextMap) addContext(ctx android.ModuleInstallPathCont } else if clc.Host == hostPath && clc.Device == devicePath { // Ok, the same library with the same paths. Don't re-add it, but don't raise an error // either, as the same library may be reachable via different transitional dependencies. + // For the same library brought in by different dependencies, some of them don't carry all the + // fields, so we populate the fields from other dependencies when available. clc.Optional = clc.Optional && optional + if len(clc.Subcontexts) == 0 { + clc.Subcontexts = subcontexts + } return nil } else { // Fail, as someone is trying to add the same library with different paths. This likely diff --git a/java/app_test.go b/java/app_test.go index 2303de103..2af308bcb 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -15,6 +15,7 @@ package java import ( + "encoding/json" "fmt" "path/filepath" "reflect" @@ -3526,6 +3527,72 @@ func TestUsesLibraries(t *testing.T) { "--product-packages=out/soong/.intermediates/app/android_common/dexpreopt/app/product_packages.txt") } +func TestClassLoaderContext_SdkLibrary(t *testing.T) { + bp := ` + java_sdk_library { + name: "foo", + srcs: ["a.java"], + api_packages: ["foo"], + sdk_version: "current", + uses_libs: ["bar"], + } + + java_sdk_library { + name: "bar", + srcs: ["b.java"], + api_packages: ["bar"], + sdk_version: "current", + } + + android_app { + name: "app", + srcs: ["app.java"], + libs: ["foo.stubs"], + uses_libs: ["foo"], + sdk_version: "current", + } + + android_app { + name: "app2", + srcs: ["app.java"], + libs: ["foo.impl"], + uses_libs: ["foo"], + sdk_version: "current", + } + ` + + result := android.GroupFixturePreparers( + prepareForJavaTest, + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithLastReleaseApis("foo", "bar"), + ).RunTestWithBp(t, bp) + + for _, name := range []string{"app", "app2"} { + app := result.ModuleForTests(t, name, "android_common") + cmd := app.Rule("dexpreopt").RuleParams.Command + + var clc map[string]interface{} + for _, flag := range strings.Split(cmd, " ") { + if value, match := strings.CutPrefix(flag, "--context-json='"); match { + value = strings.TrimSuffix(value, "'") + if err := json.Unmarshal([]byte(value), &clc); err != nil { + t.Error(err) + return + } + } + } + + deps := clc["any"].([]interface{}) + android.AssertIntEquals(t, "", 1, len(deps)) + foo := deps[0].(map[string]interface{}) + android.AssertStringEquals(t, "", "foo", foo["Name"].(string)) + fooDeps := foo["Subcontexts"].([]interface{}) + android.AssertIntEquals(t, "", 1, len(fooDeps)) + bar := fooDeps[0].(map[string]interface{}) + android.AssertStringEquals(t, "", "bar", bar["Name"].(string)) + } +} + func TestDexpreoptBcp(t *testing.T) { t.Parallel() bp := ` diff --git a/java/sdk_library.go b/java/sdk_library.go index 92529a51c..3b5f4d4bd 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -1474,6 +1474,8 @@ func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { m += "Please see the documentation of the prebuilt_apis module type (and a usage example in prebuilts/sdk) for a convenient way to generate these." ctx.ModuleErrorf(m) } + + module.usesLibrary.deps(ctx, false) } func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { @@ -1534,6 +1536,7 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) module.bootDexJarPath = module.implLibraryInfo.BootDexJarPath module.uncompressDexState = module.implLibraryInfo.UncompressDexState module.active = module.implLibraryInfo.Active + module.classLoaderContexts = module.usesLibrary.classLoaderContextForUsesLibDeps(ctx) } module.outputFile = module.implLibraryInfo.OutputFile -- cgit v1.2.3 From 3fcc51377c669ce535abe8c0a5d7adb4402b7c64 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Wed, 30 Apr 2025 15:45:28 -0700 Subject: Remove BUILD_BROKEN_GENRULE_SANDBOXING Genrule sandboxing has been the default for a long time now, remove the flag to disable sandboxing. Bug: 414874576 Test: Presubmits Change-Id: I19d5d40faf928f5eaf1d85ed2025d0cbc61973ac --- android/config.go | 4 ---- android/variable.go | 1 - genrule/genrule.go | 3 --- genrule/genrule_test.go | 56 +++++++++---------------------------------------- 4 files changed, 10 insertions(+), 54 deletions(-) diff --git a/android/config.go b/android/config.go index aa60ab2fd..4e994f129 100644 --- a/android/config.go +++ b/android/config.go @@ -2227,10 +2227,6 @@ func (c *deviceConfig) BuildBrokenDupSysprop() bool { return c.config.productVariables.BuildBrokenDupSysprop } -func (c *deviceConfig) GenruleSandboxing() bool { - return Bool(c.config.productVariables.GenruleSandboxing) -} - func (c *deviceConfig) RequiresInsecureExecmemForSwiftshader() bool { return c.config.productVariables.RequiresInsecureExecmemForSwiftshader } diff --git a/android/variable.go b/android/variable.go index c788688d6..e01eba86d 100644 --- a/android/variable.go +++ b/android/variable.go @@ -454,7 +454,6 @@ type ProductVariables struct { BuildBrokenClangAsFlags bool `json:",omitempty"` BuildBrokenClangCFlags bool `json:",omitempty"` BuildBrokenClangProperty bool `json:",omitempty"` - GenruleSandboxing *bool `json:",omitempty"` BuildBrokenEnforceSyspropOwner bool `json:",omitempty"` BuildBrokenTrebleSyspropNeverallow bool `json:",omitempty"` BuildBrokenVendorPropertyNamespace bool `json:",omitempty"` diff --git a/genrule/genrule.go b/genrule/genrule.go index ea2fa45e4..0b9e61901 100644 --- a/genrule/genrule.go +++ b/genrule/genrule.go @@ -1042,8 +1042,5 @@ func DefaultsFactory(props ...interface{}) android.Module { } func getSandboxedRuleBuilder(ctx android.ModuleContext, r *android.RuleBuilder) *android.RuleBuilder { - if !ctx.DeviceConfig().GenruleSandboxing() { - return r.SandboxTools() - } return r.SandboxInputs() } diff --git a/genrule/genrule_test.go b/genrule/genrule_test.go index 25c87bce7..3f1ca1011 100644 --- a/genrule/genrule_test.go +++ b/genrule/genrule_test.go @@ -19,7 +19,6 @@ import ( "os" "regexp" "strconv" - "strings" "testing" "android/soong/android" @@ -436,9 +435,6 @@ func TestGenruleCmd(t *testing.T) { android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { variables.Allow_missing_dependencies = proptools.BoolPtr(test.allowMissingDependencies) }), - android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { - variables.GenruleSandboxing = proptools.BoolPtr(true) - }), android.FixtureModifyContext(func(ctx *android.TestContext) { ctx.SetAllowMissingDependencies(test.allowMissingDependencies) }), @@ -1190,7 +1186,7 @@ func TestGenruleWithGlobPaths(t *testing.T) { } } -func TestGenruleUsesOrderOnlyBuildNumberFile(t *testing.T) { +func TestGenruleUsesOrderOnlyBuildNumberOrDateFile(t *testing.T) { testCases := []struct { name string bp string @@ -1199,7 +1195,7 @@ func TestGenruleUsesOrderOnlyBuildNumberFile(t *testing.T) { expectedCommand string }{ { - name: "not allowed when not in allowlist", + name: "buld number not allowed when not in allowlist", fs: android.MockFS{ "foo/Android.bp": []byte(` genrule { @@ -1213,7 +1209,7 @@ genrule { expectedError: `Only allowlisted modules may use uses_order_only_build_number_file: true`, }, { - name: "normal", + name: "build number normal", fs: android.MockFS{ "build/soong/tests/Android.bp": []byte(` genrule { @@ -1224,44 +1220,10 @@ genrule { } `), }, - expectedCommand: `cp BUILD_NUMBER_FILE __SBOX_SANDBOX_DIR__/out/out.txt`, + expectedCommand: `cp __SBOX_SANDBOX_DIR__/out/soong/build_number.txt __SBOX_SANDBOX_DIR__/out/out.txt`, }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - fixtures := android.GroupFixturePreparers( - prepareForGenRuleTest, - android.PrepareForTestWithVisibility, - android.FixtureMergeMockFs(tc.fs), - android.FixtureModifyConfigAndContext(func(config android.Config, ctx *android.TestContext) { - config.TestProductVariables.BuildNumberFile = proptools.StringPtr("build_number.txt") - }), - ) - if tc.expectedError != "" { - fixtures = fixtures.ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(tc.expectedError)) - } - result := fixtures.RunTest(t) - - if tc.expectedError == "" { - tc.expectedCommand = strings.ReplaceAll(tc.expectedCommand, "BUILD_NUMBER_FILE", result.Config.SoongOutDir()+"/build_number.txt") - gen := result.Module("gen", "").(*Module) - android.AssertStringEquals(t, "raw commands", tc.expectedCommand, gen.rawCommands[0]) - } - }) - } -} - -func TestGenruleUsesOrderOnlyBuildDateFile(t *testing.T) { - testCases := []struct { - name string - bp string - fs android.MockFS - expectedError string - expectedCommand string - }{ { - name: "not allowed when not in allowlist", + name: "build date not allowed when not in allowlist", fs: android.MockFS{ "foo/Android.bp": []byte(` genrule { @@ -1275,7 +1237,7 @@ func TestGenruleUsesOrderOnlyBuildDateFile(t *testing.T) { expectedError: `Only allowlisted modules may use uses_order_only_build_date_file: true`, }, { - name: "normal", + name: "build date normal", fs: android.MockFS{ "build/soong/tests/Android.bp": []byte(` genrule { @@ -1286,7 +1248,7 @@ func TestGenruleUsesOrderOnlyBuildDateFile(t *testing.T) { } `), }, - expectedCommand: `cp BUILD_DATE_FILE __SBOX_SANDBOX_DIR__/out/out.txt`, + expectedCommand: `cp __SBOX_SANDBOX_DIR__/out/build_date.txt __SBOX_SANDBOX_DIR__/out/out.txt`, }, } @@ -1296,6 +1258,9 @@ func TestGenruleUsesOrderOnlyBuildDateFile(t *testing.T) { prepareForGenRuleTest, android.PrepareForTestWithVisibility, android.FixtureMergeMockFs(tc.fs), + android.FixtureModifyConfigAndContext(func(config android.Config, ctx *android.TestContext) { + config.TestProductVariables.BuildNumberFile = proptools.StringPtr("build_number.txt") + }), android.SetBuildDateFileEnvVarForTests(), ) if tc.expectedError != "" { @@ -1304,7 +1269,6 @@ func TestGenruleUsesOrderOnlyBuildDateFile(t *testing.T) { result := fixtures.RunTest(t) if tc.expectedError == "" { - tc.expectedCommand = strings.ReplaceAll(tc.expectedCommand, "BUILD_DATE_FILE", result.Config.OutDir()+"/build_date.txt") gen := result.Module("gen", "").(*Module) android.AssertStringEquals(t, "raw commands", tc.expectedCommand, gen.rawCommands[0]) } -- cgit v1.2.3 From 2d52f825796f0f87503177d73b4311a560435d0e Mon Sep 17 00:00:00 2001 From: Yu Liu Date: Fri, 18 Apr 2025 22:37:44 +0000 Subject: Auto generate GobEncode and GobDecode for structs used by InstallFilesInfo. Bug: 358427516 Test: Unit tests and compare the generated ninja and mk files. Change-Id: I764ef362eb5f413e575c777e2d071d96a1fe840f --- android/Android.bp | 3 + android/module.go | 70 +------ android/module_gob_enc.go | 143 ++++++++++++++ android/packaging.go | 68 +------ android/packaging_gob_enc.go | 218 +++++++++++++++++++++ android/paths.go | 107 ++--------- android/paths_gob_enc.go | 446 +++++++++++++++++++++++++++++++++++++++++++ cc/installer.go | 2 +- cc/test.go | 2 +- filesystem/filesystem.go | 2 +- 10 files changed, 837 insertions(+), 224 deletions(-) create mode 100644 android/module_gob_enc.go create mode 100644 android/packaging_gob_enc.go create mode 100644 android/paths_gob_enc.go diff --git a/android/Android.bp b/android/Android.bp index cefd0a597..9cb1d965b 100644 --- a/android/Android.bp +++ b/android/Android.bp @@ -75,6 +75,7 @@ bootstrap_go_package { "metrics.go", "module.go", "module_context.go", + "module_gob_enc.go", "module_info_json.go", "module_proxy.go", "mutator.go", @@ -89,8 +90,10 @@ bootstrap_go_package { "package.go", "package_ctx.go", "packaging.go", + "packaging_gob_enc.go", "path_properties.go", "paths.go", + "paths_gob_enc.go", "phony.go", "plugin.go", "prebuilt.go", diff --git a/android/module.go b/android/module.go index 221ca20cc..386df7edc 100644 --- a/android/module.go +++ b/android/module.go @@ -27,11 +27,12 @@ import ( "github.com/google/blueprint" "github.com/google/blueprint/depset" - "github.com/google/blueprint/gobtools" "github.com/google/blueprint/pathtools" "github.com/google/blueprint/proptools" ) +//go:generate go run ../../blueprint/gobtools/codegen/gob_gen.go -source module.go + var ( DeviceSharedLibrary = "shared_library" DeviceStaticLibrary = "static_library" @@ -2689,6 +2690,7 @@ func checkDistProperties(ctx *moduleContext, property string, dist *Dist) { } // katiInstall stores a request from Soong to Make to create an install rule. +// @auto-generate: gob type katiInstall struct { from Path to InstallPath @@ -2699,76 +2701,12 @@ type katiInstall struct { absFrom string } -type katiInstallGob struct { - From Path - To InstallPath - ImplicitDeps Paths - OrderOnlyDeps Paths - Executable bool - ExtraFiles *extraFilesZip - AbsFrom string -} - -func (k *katiInstall) ToGob() *katiInstallGob { - return &katiInstallGob{ - From: k.from, - To: k.to, - ImplicitDeps: k.implicitDeps, - OrderOnlyDeps: k.orderOnlyDeps, - Executable: k.executable, - ExtraFiles: k.extraFiles, - AbsFrom: k.absFrom, - } -} - -func (k *katiInstall) FromGob(data *katiInstallGob) { - k.from = data.From - k.to = data.To - k.implicitDeps = data.ImplicitDeps - k.orderOnlyDeps = data.OrderOnlyDeps - k.executable = data.Executable - k.extraFiles = data.ExtraFiles - k.absFrom = data.AbsFrom -} - -func (k *katiInstall) GobEncode() ([]byte, error) { - return gobtools.CustomGobEncode[katiInstallGob](k) -} - -func (k *katiInstall) GobDecode(data []byte) error { - return gobtools.CustomGobDecode[katiInstallGob](data, k) -} - +// @auto-generate: gob type extraFilesZip struct { zip Path dir InstallPath } -type extraFilesZipGob struct { - Zip Path - Dir InstallPath -} - -func (e *extraFilesZip) ToGob() *extraFilesZipGob { - return &extraFilesZipGob{ - Zip: e.zip, - Dir: e.dir, - } -} - -func (e *extraFilesZip) FromGob(data *extraFilesZipGob) { - e.zip = data.Zip - e.dir = data.Dir -} - -func (e *extraFilesZip) GobEncode() ([]byte, error) { - return gobtools.CustomGobEncode[extraFilesZipGob](e) -} - -func (e *extraFilesZip) GobDecode(data []byte) error { - return gobtools.CustomGobDecode[extraFilesZipGob](data, e) -} - type katiInstalls []katiInstall // BuiltInstalled returns the katiInstalls in the form used by $(call copy-many-files) in Make, a diff --git a/android/module_gob_enc.go b/android/module_gob_enc.go new file mode 100644 index 000000000..bdd8a7ec1 --- /dev/null +++ b/android/module_gob_enc.go @@ -0,0 +1,143 @@ +// Code generated by go run gob_gen.go -source module.go; DO NOT EDIT. + +package android + +import ( + "bytes" + "github.com/google/blueprint/gobtools" +) + +func (r katiInstall) GobEncode() ([]byte, error) { + buf := new(bytes.Buffer) + + var err error + + if err = gobtools.EncodeStruct(buf, &r.from); err != nil { + return nil, err + } + + if err = gobtools.EncodeStruct(buf, &r.to); err != nil { + return nil, err + } + + if err = gobtools.EncodeStruct(buf, &r.implicitDeps); err != nil { + return nil, err + } + + if err = gobtools.EncodeStruct(buf, &r.orderOnlyDeps); err != nil { + return nil, err + } + + if err = gobtools.EncodeSimple(buf, r.executable); err != nil { + return nil, err + } + + isNil6 := r.extraFiles == nil + if err = gobtools.EncodeSimple(buf, isNil6); err != nil { + return nil, err + } + if !isNil6 { + if err = gobtools.EncodeStruct(buf, &*r.extraFiles); err != nil { + return nil, err + } + } + + if err = gobtools.EncodeString(buf, r.absFrom); err != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +func (r *katiInstall) GobDecode(b []byte) error { + buf := bytes.NewReader(b) + err := r.Decode(buf) + return err +} + +func (r *katiInstall) Decode(buf *bytes.Reader) error { + var err error + + err = gobtools.DecodeStruct(buf, &r.from) + if err != nil { + return err + } + + err = gobtools.DecodeStruct(buf, &r.to) + if err != nil { + return err + } + + err = gobtools.DecodeStruct(buf, &r.implicitDeps) + if err != nil { + return err + } + + err = gobtools.DecodeStruct(buf, &r.orderOnlyDeps) + if err != nil { + return err + } + + err = gobtools.DecodeSimple[bool](buf, &r.executable) + if err != nil { + return err + } + + var isNil14 bool + if err = gobtools.DecodeSimple(buf, &isNil14); err != nil { + return err + } + if !isNil14 { + var val14 extraFilesZip + err = gobtools.DecodeStruct(buf, &val14) + if err != nil { + return err + } + r.extraFiles = &val14 + } + + err = gobtools.DecodeString(buf, &r.absFrom) + if err != nil { + return err + } + + return nil +} + +func (r extraFilesZip) GobEncode() ([]byte, error) { + buf := new(bytes.Buffer) + + var err error + + if err = gobtools.EncodeStruct(buf, &r.zip); err != nil { + return nil, err + } + + if err = gobtools.EncodeStruct(buf, &r.dir); err != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +func (r *extraFilesZip) GobDecode(b []byte) error { + buf := bytes.NewReader(b) + err := r.Decode(buf) + return err +} + +func (r *extraFilesZip) Decode(buf *bytes.Reader) error { + var err error + + err = gobtools.DecodeStruct(buf, &r.zip) + if err != nil { + return err + } + + err = gobtools.DecodeStruct(buf, &r.dir) + if err != nil { + return err + } + + return nil +} diff --git a/android/packaging.go b/android/packaging.go index 43a250343..8ab80cc16 100644 --- a/android/packaging.go +++ b/android/packaging.go @@ -20,15 +20,17 @@ import ( "sort" "github.com/google/blueprint" - "github.com/google/blueprint/gobtools" "github.com/google/blueprint/proptools" "github.com/google/blueprint/uniquelist" ) +//go:generate go run ../../blueprint/gobtools/codegen/gob_gen.go -source packaging.go + // PackagingSpec abstracts a request to place a built artifact at a certain path in a package. A // package can be the traditional .img, but isn't limited to those. Other examples could // be a new filesystem image that is a subset of system.img (e.g. for an Android-like mini OS // running on a VM), or a zip archive for some of the host tools. +// @auto-generate: gob type PackagingSpec struct { // Path relative to the root of the package relPathInPackage string @@ -80,24 +82,6 @@ type PackagingSpec struct { prebuilt bool } -type packagingSpecGob struct { - RelPathInPackage string - SrcPath Path - SymlinkTarget string - Executable bool - EffectiveLicenseFiles Paths - Partition string - SkipInstall bool - AconfigPaths Paths - ArchType ArchType - Overrides []string - Owner string - RequiresFullInstall bool - FullInstallPath InstallPath - Variation string - Prebuilt bool -} - func (p *PackagingSpec) Owner() string { return p.owner } @@ -110,52 +94,6 @@ func (p *PackagingSpec) Prebuilt() bool { return p.prebuilt } -func (p *PackagingSpec) ToGob() *packagingSpecGob { - return &packagingSpecGob{ - RelPathInPackage: p.relPathInPackage, - SrcPath: p.srcPath, - SymlinkTarget: p.symlinkTarget, - Executable: p.executable, - EffectiveLicenseFiles: p.effectiveLicenseFiles.ToSlice(), - Partition: p.partition, - SkipInstall: p.skipInstall, - AconfigPaths: p.aconfigPaths.ToSlice(), - ArchType: p.archType, - Overrides: p.overrides.ToSlice(), - Owner: p.owner, - RequiresFullInstall: p.requiresFullInstall, - FullInstallPath: p.fullInstallPath, - Variation: p.variation, - Prebuilt: p.prebuilt, - } -} - -func (p *PackagingSpec) FromGob(data *packagingSpecGob) { - p.relPathInPackage = data.RelPathInPackage - p.srcPath = data.SrcPath - p.symlinkTarget = data.SymlinkTarget - p.executable = data.Executable - p.effectiveLicenseFiles = uniquelist.Make(data.EffectiveLicenseFiles) - p.partition = data.Partition - p.skipInstall = data.SkipInstall - p.aconfigPaths = uniquelist.Make(data.AconfigPaths) - p.archType = data.ArchType - p.overrides = uniquelist.Make(data.Overrides) - p.owner = data.Owner - p.requiresFullInstall = data.RequiresFullInstall - p.fullInstallPath = data.FullInstallPath - p.variation = data.Variation - p.prebuilt = data.Prebuilt -} - -func (p *PackagingSpec) GobEncode() ([]byte, error) { - return gobtools.CustomGobEncode[packagingSpecGob](p) -} - -func (p *PackagingSpec) GobDecode(data []byte) error { - return gobtools.CustomGobDecode[packagingSpecGob](data, p) -} - func (p *PackagingSpec) Equals(other *PackagingSpec) bool { if other == nil { return false diff --git a/android/packaging_gob_enc.go b/android/packaging_gob_enc.go new file mode 100644 index 000000000..37452b888 --- /dev/null +++ b/android/packaging_gob_enc.go @@ -0,0 +1,218 @@ +// Code generated by go run gob_gen.go -source packaging.go; DO NOT EDIT. + +package android + +import ( + "bytes" + "github.com/google/blueprint/gobtools" + "github.com/google/blueprint/uniquelist" +) + +func (r PackagingSpec) GobEncode() ([]byte, error) { + buf := new(bytes.Buffer) + + var err error + + if err = gobtools.EncodeString(buf, r.relPathInPackage); err != nil { + return nil, err + } + + if err = gobtools.EncodeStruct(buf, &r.srcPath); err != nil { + return nil, err + } + + if err = gobtools.EncodeString(buf, r.symlinkTarget); err != nil { + return nil, err + } + + if err = gobtools.EncodeSimple(buf, r.executable); err != nil { + return nil, err + } + + unilst5 := r.effectiveLicenseFiles.ToSlice() + if err = gobtools.EncodeSimple(buf, int32(len(unilst5))); err != nil { + return nil, err + } + for i := 0; i < len(unilst5); i++ { + if err = gobtools.EncodeStruct(buf, &unilst5[i]); err != nil { + return nil, err + } + } + + if err = gobtools.EncodeString(buf, r.partition); err != nil { + return nil, err + } + + if err = gobtools.EncodeSimple(buf, r.skipInstall); err != nil { + return nil, err + } + + unilst9 := r.aconfigPaths.ToSlice() + if err = gobtools.EncodeSimple(buf, int32(len(unilst9))); err != nil { + return nil, err + } + for i := 0; i < len(unilst9); i++ { + if err = gobtools.EncodeStruct(buf, &unilst9[i]); err != nil { + return nil, err + } + } + + if err = gobtools.EncodeStruct(buf, &r.archType); err != nil { + return nil, err + } + + unilst12 := r.overrides.ToSlice() + if err = gobtools.EncodeSimple(buf, int32(len(unilst12))); err != nil { + return nil, err + } + for i := 0; i < len(unilst12); i++ { + if err = gobtools.EncodeString(buf, unilst12[i]); err != nil { + return nil, err + } + } + + if err = gobtools.EncodeString(buf, r.owner); err != nil { + return nil, err + } + + if err = gobtools.EncodeSimple(buf, r.requiresFullInstall); err != nil { + return nil, err + } + + if err = gobtools.EncodeStruct(buf, &r.fullInstallPath); err != nil { + return nil, err + } + + if err = gobtools.EncodeString(buf, r.variation); err != nil { + return nil, err + } + + if err = gobtools.EncodeSimple(buf, r.prebuilt); err != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +func (r *PackagingSpec) GobDecode(b []byte) error { + buf := bytes.NewReader(b) + err := r.Decode(buf) + return err +} + +func (r *PackagingSpec) Decode(buf *bytes.Reader) error { + var err error + + err = gobtools.DecodeString(buf, &r.relPathInPackage) + if err != nil { + return err + } + + err = gobtools.DecodeStruct(buf, &r.srcPath) + if err != nil { + return err + } + + err = gobtools.DecodeString(buf, &r.symlinkTarget) + if err != nil { + return err + } + + err = gobtools.DecodeSimple[bool](buf, &r.executable) + if err != nil { + return err + } + + var unilst23 []Path + var val23 int32 + err = gobtools.DecodeSimple[int32](buf, &val23) + if err != nil { + return err + } + if val23 > 0 { + unilst23 = make([]Path, val23) + for i := 0; i < int(val23); i++ { + err = gobtools.DecodeStruct(buf, &unilst23[i]) + if err != nil { + return err + } + } + } + r.effectiveLicenseFiles = uniquelist.Make(unilst23) + + err = gobtools.DecodeString(buf, &r.partition) + if err != nil { + return err + } + + err = gobtools.DecodeSimple[bool](buf, &r.skipInstall) + if err != nil { + return err + } + + var unilst27 []Path + var val27 int32 + err = gobtools.DecodeSimple[int32](buf, &val27) + if err != nil { + return err + } + if val27 > 0 { + unilst27 = make([]Path, val27) + for i := 0; i < int(val27); i++ { + err = gobtools.DecodeStruct(buf, &unilst27[i]) + if err != nil { + return err + } + } + } + r.aconfigPaths = uniquelist.Make(unilst27) + + err = gobtools.DecodeStruct(buf, &r.archType) + if err != nil { + return err + } + + var unilst30 []string + var val30 int32 + err = gobtools.DecodeSimple[int32](buf, &val30) + if err != nil { + return err + } + if val30 > 0 { + unilst30 = make([]string, val30) + for i := 0; i < int(val30); i++ { + err = gobtools.DecodeString(buf, &unilst30[i]) + if err != nil { + return err + } + } + } + r.overrides = uniquelist.Make(unilst30) + + err = gobtools.DecodeString(buf, &r.owner) + if err != nil { + return err + } + + err = gobtools.DecodeSimple[bool](buf, &r.requiresFullInstall) + if err != nil { + return err + } + + err = gobtools.DecodeStruct(buf, &r.fullInstallPath) + if err != nil { + return err + } + + err = gobtools.DecodeString(buf, &r.variation) + if err != nil { + return err + } + + err = gobtools.DecodeSimple[bool](buf, &r.prebuilt) + if err != nil { + return err + } + + return nil +} diff --git a/android/paths.go b/android/paths.go index 5dfaa8602..0c4a032d1 100644 --- a/android/paths.go +++ b/android/paths.go @@ -28,6 +28,8 @@ import ( "github.com/google/blueprint/pathtools" ) +//go:generate go run ../../blueprint/gobtools/codegen/gob_gen.go -source paths.go + var absSrcDir string // PathContext is the subset of a (Module|Singleton)Context required by the @@ -1212,36 +1214,12 @@ func (p WritablePaths) Paths() Paths { return ret } +// @auto-generate: gob type basePath struct { path string rel string } -type basePathGob struct { - Path string - Rel string -} - -func (p *basePath) ToGob() *basePathGob { - return &basePathGob{ - Path: p.path, - Rel: p.rel, - } -} - -func (p *basePath) FromGob(data *basePathGob) { - p.path = data.Path - p.rel = data.Rel -} - -func (p basePath) GobEncode() ([]byte, error) { - return gobtools.CustomGobEncode[basePathGob](&p) -} - -func (p *basePath) GobDecode(data []byte) error { - return gobtools.CustomGobDecode[basePathGob](data, p) -} - func (p basePath) Ext() string { return filepath.Ext(p.path) } @@ -1273,6 +1251,8 @@ func (p basePath) withoutRel() basePath { } // SourcePath is a Path representing a file path rooted from SrcDir +// +// @auto-generate: gob type SourcePath struct { basePath } @@ -1456,6 +1436,8 @@ func (p SourcePath) join(ctx PathContext, paths ...string) SourcePath { } // OutputPath is a Path representing an intermediates file path rooted from the build directory +// +// @auto-generate: gob type OutputPath struct { basePath @@ -1465,34 +1447,6 @@ type OutputPath struct { fullPath string } -type outputPathGob struct { - BasePath basePath - OutDir string - FullPath string -} - -func (p *OutputPath) ToGob() *outputPathGob { - return &outputPathGob{ - BasePath: p.basePath, - OutDir: p.outDir, - FullPath: p.fullPath, - } -} - -func (p *OutputPath) FromGob(data *outputPathGob) { - p.basePath = data.BasePath - p.outDir = data.OutDir - p.fullPath = data.FullPath -} - -func (p OutputPath) GobEncode() ([]byte, error) { - return gobtools.CustomGobEncode[outputPathGob](&p) -} - -func (p *OutputPath) GobDecode(data []byte) error { - return gobtools.CustomGobDecode[outputPathGob](data, p) -} - func (p OutputPath) withRel(rel string) OutputPath { p.basePath = p.basePath.withRel(rel) p.fullPath = filepath.Join(p.fullPath, rel) @@ -1532,6 +1486,7 @@ var _ WritablePath = OutputPath{} var _ objPathProvider = OutputPath{} // toolDepPath is a Path representing a dependency of the build tool. +// @auto-generate: gob type toolDepPath struct { basePath } @@ -1731,6 +1686,7 @@ func (p SourcePath) resPathWithName(ctx ModuleOutPathContext, name string) Modul } // ModuleOutPath is a Path representing a module's output directory. +// @auto-generate: gob type ModuleOutPath struct { OutputPath } @@ -1774,6 +1730,7 @@ func PathForModuleOut(ctx ModuleOutPathContext, paths ...string) ModuleOutPath { // ModuleGenPath is a Path representing the 'gen' directory in a module's output // directory. Mainly used for generated sources. +// @auto-generate: gob type ModuleGenPath struct { ModuleOutPath } @@ -1824,6 +1781,7 @@ func (p ModuleGenPath) objPathWithExt(ctx ModuleOutPathContext, subdir, ext stri // ModuleObjPath is a Path representing the 'obj' directory in a module's output // directory. Used for compiled objects. +// @auto-generate: gob type ModuleObjPath struct { ModuleOutPath } @@ -1848,6 +1806,7 @@ func PathForModuleObj(ctx ModuleOutPathContext, pathComponents ...string) Module // ModuleResPath is a a Path representing the 'res' directory in a module's // output directory. +// @auto-generate: gob type ModuleResPath struct { ModuleOutPath } @@ -1872,6 +1831,8 @@ func PathForModuleRes(ctx ModuleOutPathContext, pathComponents ...string) Module } // InstallPath is a Path representing a installed file path rooted from the build directory +// +// @auto-generate: gob type InstallPath struct { basePath @@ -1890,43 +1851,6 @@ type InstallPath struct { fullPath string } -type installPathGob struct { - BasePath basePath - SoongOutDir string - PartitionDir string - Partition string - MakePath bool - FullPath string -} - -func (p *InstallPath) ToGob() *installPathGob { - return &installPathGob{ - BasePath: p.basePath, - SoongOutDir: p.soongOutDir, - PartitionDir: p.partitionDir, - Partition: p.partition, - MakePath: p.makePath, - FullPath: p.fullPath, - } -} - -func (p *InstallPath) FromGob(data *installPathGob) { - p.basePath = data.BasePath - p.soongOutDir = data.SoongOutDir - p.partitionDir = data.PartitionDir - p.partition = data.Partition - p.makePath = data.MakePath - p.fullPath = data.FullPath -} - -func (p InstallPath) GobEncode() ([]byte, error) { - return gobtools.CustomGobEncode[installPathGob](&p) -} - -func (p *InstallPath) GobDecode(data []byte) error { - return gobtools.CustomGobDecode[installPathGob](data, p) -} - // Will panic if called from outside a test environment. func ensureTestOnly() { if PrefixInList(os.Args, "-test.") { @@ -2263,6 +2187,7 @@ func PathForPhony(ctx PathContext, phony string) WritablePath { return PhonyPath{basePath{phony, ""}} } +// @auto-generate: gob type PhonyPath struct { basePath } @@ -2293,6 +2218,7 @@ func (p PhonyPath) ReplaceExtension(ctx PathContext, ext string) OutputPath { var _ Path = PhonyPath{} var _ WritablePath = PhonyPath{} +// @auto-generate: gob type testPath struct { basePath } @@ -2538,6 +2464,7 @@ func absolutePath(path string) string { // The data file should be installed (copied from ``) to // `//`, or // `/` if RelativeInstallPath is empty. +// @auto-generate: gob type DataPath struct { // The path of the data file that should be copied into the data directory SrcPath Path diff --git a/android/paths_gob_enc.go b/android/paths_gob_enc.go new file mode 100644 index 000000000..96d47146a --- /dev/null +++ b/android/paths_gob_enc.go @@ -0,0 +1,446 @@ +// Code generated by go run gob_gen.go -source paths.go; DO NOT EDIT. + +package android + +import ( + "bytes" + "github.com/google/blueprint/gobtools" +) + +func (r basePath) GobEncode() ([]byte, error) { + buf := new(bytes.Buffer) + + var err error + + if err = gobtools.EncodeString(buf, r.path); err != nil { + return nil, err + } + + if err = gobtools.EncodeString(buf, r.rel); err != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +func (r *basePath) GobDecode(b []byte) error { + buf := bytes.NewReader(b) + err := r.Decode(buf) + return err +} + +func (r *basePath) Decode(buf *bytes.Reader) error { + var err error + + err = gobtools.DecodeString(buf, &r.path) + if err != nil { + return err + } + + err = gobtools.DecodeString(buf, &r.rel) + if err != nil { + return err + } + + return nil +} + +func (r SourcePath) GobEncode() ([]byte, error) { + buf := new(bytes.Buffer) + + var err error + + if err = gobtools.EncodeStruct(buf, &r.basePath); err != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +func (r *SourcePath) GobDecode(b []byte) error { + buf := bytes.NewReader(b) + err := r.Decode(buf) + return err +} + +func (r *SourcePath) Decode(buf *bytes.Reader) error { + var err error + + err = gobtools.DecodeStruct(buf, &r.basePath) + if err != nil { + return err + } + + return nil +} + +func (r OutputPath) GobEncode() ([]byte, error) { + buf := new(bytes.Buffer) + + var err error + + if err = gobtools.EncodeStruct(buf, &r.basePath); err != nil { + return nil, err + } + + if err = gobtools.EncodeString(buf, r.outDir); err != nil { + return nil, err + } + + if err = gobtools.EncodeString(buf, r.fullPath); err != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +func (r *OutputPath) GobDecode(b []byte) error { + buf := bytes.NewReader(b) + err := r.Decode(buf) + return err +} + +func (r *OutputPath) Decode(buf *bytes.Reader) error { + var err error + + err = gobtools.DecodeStruct(buf, &r.basePath) + if err != nil { + return err + } + + err = gobtools.DecodeString(buf, &r.outDir) + if err != nil { + return err + } + + err = gobtools.DecodeString(buf, &r.fullPath) + if err != nil { + return err + } + + return nil +} + +func (r toolDepPath) GobEncode() ([]byte, error) { + buf := new(bytes.Buffer) + + var err error + + if err = gobtools.EncodeStruct(buf, &r.basePath); err != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +func (r *toolDepPath) GobDecode(b []byte) error { + buf := bytes.NewReader(b) + err := r.Decode(buf) + return err +} + +func (r *toolDepPath) Decode(buf *bytes.Reader) error { + var err error + + err = gobtools.DecodeStruct(buf, &r.basePath) + if err != nil { + return err + } + + return nil +} + +func (r ModuleOutPath) GobEncode() ([]byte, error) { + buf := new(bytes.Buffer) + + var err error + + if err = gobtools.EncodeStruct(buf, &r.OutputPath); err != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +func (r *ModuleOutPath) GobDecode(b []byte) error { + buf := bytes.NewReader(b) + err := r.Decode(buf) + return err +} + +func (r *ModuleOutPath) Decode(buf *bytes.Reader) error { + var err error + + err = gobtools.DecodeStruct(buf, &r.OutputPath) + if err != nil { + return err + } + + return nil +} + +func (r ModuleGenPath) GobEncode() ([]byte, error) { + buf := new(bytes.Buffer) + + var err error + + if err = gobtools.EncodeStruct(buf, &r.ModuleOutPath); err != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +func (r *ModuleGenPath) GobDecode(b []byte) error { + buf := bytes.NewReader(b) + err := r.Decode(buf) + return err +} + +func (r *ModuleGenPath) Decode(buf *bytes.Reader) error { + var err error + + err = gobtools.DecodeStruct(buf, &r.ModuleOutPath) + if err != nil { + return err + } + + return nil +} + +func (r ModuleObjPath) GobEncode() ([]byte, error) { + buf := new(bytes.Buffer) + + var err error + + if err = gobtools.EncodeStruct(buf, &r.ModuleOutPath); err != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +func (r *ModuleObjPath) GobDecode(b []byte) error { + buf := bytes.NewReader(b) + err := r.Decode(buf) + return err +} + +func (r *ModuleObjPath) Decode(buf *bytes.Reader) error { + var err error + + err = gobtools.DecodeStruct(buf, &r.ModuleOutPath) + if err != nil { + return err + } + + return nil +} + +func (r ModuleResPath) GobEncode() ([]byte, error) { + buf := new(bytes.Buffer) + + var err error + + if err = gobtools.EncodeStruct(buf, &r.ModuleOutPath); err != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +func (r *ModuleResPath) GobDecode(b []byte) error { + buf := bytes.NewReader(b) + err := r.Decode(buf) + return err +} + +func (r *ModuleResPath) Decode(buf *bytes.Reader) error { + var err error + + err = gobtools.DecodeStruct(buf, &r.ModuleOutPath) + if err != nil { + return err + } + + return nil +} + +func (r InstallPath) GobEncode() ([]byte, error) { + buf := new(bytes.Buffer) + + var err error + + if err = gobtools.EncodeStruct(buf, &r.basePath); err != nil { + return nil, err + } + + if err = gobtools.EncodeString(buf, r.soongOutDir); err != nil { + return nil, err + } + + if err = gobtools.EncodeString(buf, r.partitionDir); err != nil { + return nil, err + } + + if err = gobtools.EncodeString(buf, r.partition); err != nil { + return nil, err + } + + if err = gobtools.EncodeSimple(buf, r.makePath); err != nil { + return nil, err + } + + if err = gobtools.EncodeString(buf, r.fullPath); err != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +func (r *InstallPath) GobDecode(b []byte) error { + buf := bytes.NewReader(b) + err := r.Decode(buf) + return err +} + +func (r *InstallPath) Decode(buf *bytes.Reader) error { + var err error + + err = gobtools.DecodeStruct(buf, &r.basePath) + if err != nil { + return err + } + + err = gobtools.DecodeString(buf, &r.soongOutDir) + if err != nil { + return err + } + + err = gobtools.DecodeString(buf, &r.partitionDir) + if err != nil { + return err + } + + err = gobtools.DecodeString(buf, &r.partition) + if err != nil { + return err + } + + err = gobtools.DecodeSimple[bool](buf, &r.makePath) + if err != nil { + return err + } + + err = gobtools.DecodeString(buf, &r.fullPath) + if err != nil { + return err + } + + return nil +} + +func (r PhonyPath) GobEncode() ([]byte, error) { + buf := new(bytes.Buffer) + + var err error + + if err = gobtools.EncodeStruct(buf, &r.basePath); err != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +func (r *PhonyPath) GobDecode(b []byte) error { + buf := bytes.NewReader(b) + err := r.Decode(buf) + return err +} + +func (r *PhonyPath) Decode(buf *bytes.Reader) error { + var err error + + err = gobtools.DecodeStruct(buf, &r.basePath) + if err != nil { + return err + } + + return nil +} + +func (r testPath) GobEncode() ([]byte, error) { + buf := new(bytes.Buffer) + + var err error + + if err = gobtools.EncodeStruct(buf, &r.basePath); err != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +func (r *testPath) GobDecode(b []byte) error { + buf := bytes.NewReader(b) + err := r.Decode(buf) + return err +} + +func (r *testPath) Decode(buf *bytes.Reader) error { + var err error + + err = gobtools.DecodeStruct(buf, &r.basePath) + if err != nil { + return err + } + + return nil +} + +func (r DataPath) GobEncode() ([]byte, error) { + buf := new(bytes.Buffer) + + var err error + + if err = gobtools.EncodeStruct(buf, &r.SrcPath); err != nil { + return nil, err + } + + if err = gobtools.EncodeString(buf, r.RelativeInstallPath); err != nil { + return nil, err + } + + if err = gobtools.EncodeSimple(buf, r.WithoutRel); err != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +func (r *DataPath) GobDecode(b []byte) error { + buf := bytes.NewReader(b) + err := r.Decode(buf) + return err +} + +func (r *DataPath) Decode(buf *bytes.Reader) error { + var err error + + err = gobtools.DecodeStruct(buf, &r.SrcPath) + if err != nil { + return err + } + + err = gobtools.DecodeString(buf, &r.RelativeInstallPath) + if err != nil { + return err + } + + err = gobtools.DecodeSimple[bool](buf, &r.WithoutRel) + if err != nil { + return err + } + + return nil +} diff --git a/cc/installer.go b/cc/installer.go index d7d8c6d22..99e220faa 100644 --- a/cc/installer.go +++ b/cc/installer.go @@ -108,7 +108,7 @@ func (installer *baseInstaller) installTestData(ctx ModuleContext, data []androi } func (installer *baseInstaller) installStandaloneTestDep(ctx ModuleContext, standaloneTestDep android.PackagingSpec) { - installer.installTestData(ctx, []android.DataPath{{SrcPath: standaloneTestDep.ToGob().SrcPath, RelativeInstallPath: "standalone-libs"}}) + installer.installTestData(ctx, []android.DataPath{{SrcPath: standaloneTestDep.SrcPath(), RelativeInstallPath: "standalone-libs"}}) } func (installer *baseInstaller) everInstallable() bool { diff --git a/cc/test.go b/cc/test.go index 12b9716b4..a20592892 100644 --- a/cc/test.go +++ b/cc/test.go @@ -441,7 +441,7 @@ func (test *testBinary) install(ctx ModuleContext, file android.Path) { }) for _, standaloneTestDep := range packagingSpecsBuilder.Build().ToList() { - if standaloneTestDep.ToGob().SrcPath == nil { + if standaloneTestDep.SrcPath() == nil { continue } if standaloneTestDep.SkipInstall() { diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index 2b8d7f80e..2507d2875 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -634,7 +634,7 @@ func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) { FullInstallPath: spec.FullInstallPath(), RequiresFullInstall: spec.RequiresFullInstall(), SourcePath: spec.SrcPath(), - SymlinkTarget: spec.ToGob().SymlinkTarget, + SymlinkTarget: spec.SymlinkTarget(), }) } -- cgit v1.2.3 From 08cc952b5ad95e60cf6a8b45b9290a10c1900641 Mon Sep 17 00:00:00 2001 From: Brian Ryner Date: Wed, 30 Apr 2025 19:20:45 +0000 Subject: Log anything read from cipd's stderr, and the exit status on EOF. Test: none Bug: 400695406 Change-Id: I9c9f0b9c0ede76f79eb4f990d33d790267396ead --- ui/build/cipd.go | 48 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/ui/build/cipd.go b/ui/build/cipd.go index 2a31e1784..2c3daad95 100644 --- a/ui/build/cipd.go +++ b/ui/build/cipd.go @@ -16,9 +16,13 @@ package build import ( "bufio" + "errors" + "io" "log" "path/filepath" "strings" + "sync" + "sync/atomic" ) const ( @@ -27,10 +31,12 @@ const ( ) type cipdProxy struct { - cmd *Cmd + cmd *Cmd + wg sync.WaitGroup + stopping atomic.Bool } -func startCIPDProxyServer(ctx Context, config Config) cipdProxy { +func startCIPDProxyServer(ctx Context, config Config) *cipdProxy { ctx.Status.Status("Starting CIPD proxy server...") cipdPath := filepath.Join("prebuilts/cipd", config.HostPrebuiltTag(), "cipd") @@ -39,16 +45,48 @@ func startCIPDProxyServer(ctx Context, config Config) cipdProxy { if err != nil { log.Fatal(err) } + stderr, err := cmd.StderrPipe() + if err != nil { + log.Fatal(err) + } if err := cmd.Start(); err != nil { log.Fatal(err) } + cp := cipdProxy{cmd: cmd} + cp.wg.Add(1) + go func() { + // Log any error output from cipd until it exits. + defer cp.wg.Done() + + bufReader := bufio.NewReader(stderr) + for { + l, err := bufReader.ReadString('\n') + if err != nil { + if errors.Is(err, io.EOF) { + if !cp.stopping.Load() { + err := cmd.Wait() + ctx.Printf("cipd: unexpected EOF, process exited with %v", err) + } + break + } + ctx.Fatalf("cipd: %v %v", l, err) + } + ctx.Printf("cipd: %v", l) + } + }() bufReader := bufio.NewReader(stdout) for { l, err := bufReader.ReadString('\n') + if errors.Is(err, io.EOF) { + ctx.Printf("cipd: unexpected EOF: %v\n", l) + // The stderr goroutine will handle the EOF + cp.wg.Wait() + } + if err != nil { - log.Fatal(err) + log.Fatalf("Got %v reading from cipd process", err) } if strings.HasPrefix(l, cipdProxyUrlKey) { proxyUrl := strings.TrimSpace(l[len(cipdProxyUrlKey)+1:]) @@ -57,9 +95,11 @@ func startCIPDProxyServer(ctx Context, config Config) cipdProxy { break } } - return cipdProxy{cmd: cmd} + return &cp } func (c *cipdProxy) Stop() { + c.stopping.Store(true) c.cmd.Process.Kill() + c.wg.Wait() } -- cgit v1.2.3 From 81b6b3e6c07c71d401a0aea054e2519c59f0fe34 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Wed, 30 Apr 2025 17:28:28 -0700 Subject: Rename UnbundledBuildApps to HasUnbundledBuildApps In preparation for adding an UnbundledBuildApps() function that actually returns the list of apps, for unbundled soong-only builds. Bug: 413145177 Test: Presubmits Change-Id: Iac290601089f79ee148faa504427568b493065ad --- android/config.go | 4 ++-- android/sbom.go | 2 +- cc/sdk.go | 2 +- java/android_manifest.go | 2 +- java/app.go | 2 +- java/base.go | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/android/config.go b/android/config.go index aa60ab2fd..199693031 100644 --- a/android/config.go +++ b/android/config.go @@ -1380,7 +1380,7 @@ func (c *config) UnbundledBuild() bool { // Returns true if building apps that aren't bundled with the platform. // UnbundledBuild() is always true when this is true. -func (c *config) UnbundledBuildApps() bool { +func (c *config) HasUnbundledBuildApps() bool { return len(c.productVariables.Unbundled_build_apps) > 0 } @@ -2032,7 +2032,7 @@ func (c *config) ForceApexSymlinkOptimization() bool { } func (c *config) ApexCompressionEnabled() bool { - return Bool(c.productVariables.CompressedApex) && !c.UnbundledBuildApps() + return Bool(c.productVariables.CompressedApex) && !c.HasUnbundledBuildApps() } func (c *config) DefaultApexPayloadType() string { diff --git a/android/sbom.go b/android/sbom.go index fc61c41dd..322aa2682 100644 --- a/android/sbom.go +++ b/android/sbom.go @@ -77,7 +77,7 @@ func (this *sbomSingleton) GenerateBuildActions(ctx SingletonContext) { }, }) - if !ctx.Config().UnbundledBuildApps() { + if !ctx.Config().HasUnbundledBuildApps() { // When building SBOM of products, phony rule "sbom" is for generating product SBOM in Soong. ctx.Build(pctx, BuildParams{ Rule: blueprint.Phony, diff --git a/cc/sdk.go b/cc/sdk.go index 5dd44d8b8..8f4827d6a 100644 --- a/cc/sdk.go +++ b/cc/sdk.go @@ -114,7 +114,7 @@ func (sdkTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation ccModule.Properties.PreventInstall = true } - if ctx.Config().UnbundledBuildApps() { + if ctx.Config().HasUnbundledBuildApps() { if variation == "" { // For an unbundled apps build, hide the platform variant from Make // so that other Make modules don't link against it, but against the diff --git a/java/android_manifest.go b/java/android_manifest.go index 0c77968e6..1b91babad 100644 --- a/java/android_manifest.go +++ b/java/android_manifest.go @@ -68,7 +68,7 @@ func shouldReturnFinalOrFutureInt(ctx android.ModuleContext, targetSdkVersionLev return false } // If this a module targeting an unreleased SDK (MTS or unbundled builds), return 10000 - return targetSdkVersionLevel.IsPreview() && (ctx.Config().UnbundledBuildApps() || includedInMts(ctx.Module())) + return targetSdkVersionLevel.IsPreview() && (ctx.Config().HasUnbundledBuildApps() || includedInMts(ctx.Module())) } // Helper function that returns true if android_test, android_test_helper_app, java_test are in an MTS suite. diff --git a/java/app.go b/java/app.go index 1d3de149a..bfb3c0553 100644 --- a/java/app.go +++ b/java/app.go @@ -1044,7 +1044,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { a.linter.mergedManifest = a.aapt.mergedManifestFile a.linter.manifest = a.aapt.manifestPath a.linter.resources = a.aapt.resourceFiles - a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps() + a.linter.buildModuleReportZip = ctx.Config().HasUnbundledBuildApps() dexJarFile, packageResources, javaInfo := a.dexBuildActions(ctx) diff --git a/java/base.go b/java/base.go index f584535d3..3a1913080 100644 --- a/java/base.go +++ b/java/base.go @@ -1939,7 +1939,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath j.linter.javaLanguageLevel = flags.javaVersion.String() j.linter.kotlinLanguageLevel = "1.3" j.linter.compile_data = android.PathsForModuleSrc(ctx, j.properties.Compile_data) - if !apexInfo.IsForPlatform() && ctx.Config().UnbundledBuildApps() { + if !apexInfo.IsForPlatform() && ctx.Config().HasUnbundledBuildApps() { j.linter.buildModuleReportZip = true } j.linter.lint(ctx) -- cgit v1.2.3 From b048427ecf9e976311f2cd49121c1d8b92e1e8d2 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Wed, 30 Apr 2025 17:45:16 -0700 Subject: Use static rule instead of rulebuilder in BuildSymbolsZip Minor cleanup Bug: 413145177 Test: Presubmits Change-Id: Id6b151b1ad441322f0b70ac7e59cdbb5993dcaef --- android/symbols.go | 28 +++++++++++++++++----------- android/test_suites.go | 2 +- ci_tests/ci_test_package_zip.go | 2 +- filesystem/android_device.go | 2 +- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/android/symbols.go b/android/symbols.go index 3810b2e9a..30e4607bb 100644 --- a/android/symbols.go +++ b/android/symbols.go @@ -15,11 +15,13 @@ package android import ( - "fmt" - "github.com/google/blueprint" ) +func init() { + pctx.HostBinToolVariable("symbols_map", "symbols_map") +} + var zipFiles = pctx.AndroidStaticRule("SnapshotZipFiles", blueprint.RuleParams{ Command: `${SoongZipCmd} -r $out.rsp -o $out`, CommandDeps: []string{"${SoongZipCmd}"}, @@ -27,6 +29,13 @@ var zipFiles = pctx.AndroidStaticRule("SnapshotZipFiles", blueprint.RuleParams{ RspfileContent: "$in", }) +var mergeSymbolsMapProtos = pctx.AndroidStaticRule("merge_symbol_map_protos", blueprint.RuleParams{ + Command: `${symbols_map} -merge $out @$out.rsp`, + CommandDeps: []string{"${symbols_map}"}, + Rspfile: "$out.rsp", + RspfileContent: "$in", +}) + // Provider for generating symbols.zip type SymbolicOutputInfo struct { UnstrippedOutputFile Path @@ -64,7 +73,7 @@ type symbolsContext interface { // Defines the build rules to generate the symbols.zip file and the merged elf mapping textproto // file. Modules in depModules that provide [SymbolInfosProvider] and are exported to make // will be listed in the symbols.zip and the merged proto file. -func BuildSymbolsZip(ctx symbolsContext, depModules []ModuleOrProxy, iden string, symbolsZipFile, mergedMappingProtoFile WritablePath) { +func BuildSymbolsZip(ctx symbolsContext, depModules []ModuleOrProxy, symbolsZipFile, mergedMappingProtoFile WritablePath) { var allSymbolicOutputPaths, allElfMappingProtoPaths Paths for _, mod := range depModules { if commonInfo, _ := OtherModuleProvider(ctx, mod, CommonModuleInfoProvider); commonInfo.SkipAndroidMkProcessing { @@ -84,12 +93,9 @@ func BuildSymbolsZip(ctx symbolsContext, depModules []ModuleOrProxy, iden string Output: symbolsZipFile, }) - dictMappingBuilder := NewRuleBuilder(pctx, ctx) - dictMappingBuilder.Command(). - BuiltTool("symbols_map"). - Flag("-merge"). - Output(mergedMappingProtoFile). - Inputs(allElfMappingProtoPaths) - - dictMappingBuilder.Build(fmt.Sprintf("%s_symbols_elf_dict_mapping_proto", iden), fmt.Sprintf("Building symbols mapping proto for %s", iden)) + ctx.Build(pctx, BuildParams{ + Rule: mergeSymbolsMapProtos, + Output: mergedMappingProtoFile, + Inputs: allElfMappingProtoPaths, + }) } diff --git a/android/test_suites.go b/android/test_suites.go index 3ae3b1a3c..23e0477b9 100644 --- a/android/test_suites.go +++ b/android/test_suites.go @@ -204,7 +204,7 @@ func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) { testSuiteSymbolsZipFile := pathForTestSymbols(ctx, fmt.Sprintf("%s-symbols.zip", testSuite)) testSuiteMergedMappingProtoFile := pathForTestSymbols(ctx, fmt.Sprintf("%s-symbols-mapping.textproto", testSuite)) allTestModules := files[testSuite].testModules() - BuildSymbolsZip(ctx, allTestModules, testSuite, testSuiteSymbolsZipFile, testSuiteMergedMappingProtoFile) + BuildSymbolsZip(ctx, allTestModules, testSuiteSymbolsZipFile, testSuiteMergedMappingProtoFile) ctx.DistForGoalWithFilenameTag(testSuite, testSuiteSymbolsZipFile, testSuiteSymbolsZipFile.Base()) ctx.DistForGoalWithFilenameTag(testSuite, testSuiteMergedMappingProtoFile, testSuiteMergedMappingProtoFile.Base()) diff --git a/ci_tests/ci_test_package_zip.go b/ci_tests/ci_test_package_zip.go index e4308fa02..617104ab8 100644 --- a/ci_tests/ci_test_package_zip.go +++ b/ci_tests/ci_test_package_zip.go @@ -242,7 +242,7 @@ func createOutput(ctx android.ModuleContext, pctx android.PackageContext) androi func createSymbolsZip(ctx android.ModuleContext, allModules []android.ModuleOrProxy) { symbolsZipFile := android.PathForModuleOut(ctx, "symbols.zip") symbolsMappingFile := android.PathForModuleOut(ctx, "symbols-mapping.textproto") - android.BuildSymbolsZip(ctx, allModules, ctx.ModuleName(), symbolsZipFile, symbolsMappingFile) + android.BuildSymbolsZip(ctx, allModules, symbolsZipFile, symbolsMappingFile) ctx.SetOutputFiles(android.Paths{symbolsZipFile}, ".symbols") ctx.SetOutputFiles(android.Paths{symbolsMappingFile}, ".elf_mapping") diff --git a/filesystem/android_device.go b/filesystem/android_device.go index 626c220b1..8cc1bce12 100644 --- a/filesystem/android_device.go +++ b/filesystem/android_device.go @@ -426,7 +426,7 @@ type symbolicOutputInfo struct { func (a *androidDevice) buildSymbolsZip(ctx android.ModuleContext, allInstalledModules []android.ModuleOrProxy) { a.symbolsZipFile = android.PathForModuleOut(ctx, "symbols.zip") a.symbolsMappingFile = android.PathForModuleOut(ctx, "symbols-mapping.textproto") - android.BuildSymbolsZip(ctx, allInstalledModules, ctx.ModuleName(), a.symbolsZipFile, a.symbolsMappingFile) + android.BuildSymbolsZip(ctx, allInstalledModules, a.symbolsZipFile, a.symbolsMappingFile) } func (a *androidDevice) distInstalledFiles(ctx android.ModuleContext) { -- cgit v1.2.3 From 4dd11829e886805254fe6d22d92f7062ab822e7c Mon Sep 17 00:00:00 2001 From: LaMont Jones Date: Thu, 1 May 2025 09:04:14 -0700 Subject: Disable inc_javac when partial-compile=true If inc_javac is enabled in SOONG_PARTIAL_COMPILE, and SOONG_USE_PARTIAL_COMPILE=false, there are build errors. Bug: 387798027 Test: manual Change-Id: I1452f688f9d58b020675914cb87553f9c2f95b3d --- android/config.go | 1 - 1 file changed, 1 deletion(-) diff --git a/android/config.go b/android/config.go index 2d88d434f..a96b8340e 100644 --- a/android/config.go +++ b/android/config.go @@ -435,7 +435,6 @@ var defaultPartialCompileFlags = partialCompileFlags{} var enabledPartialCompileFlags = partialCompileFlags{ Use_d8: true, Disable_stub_validation: true, - Enable_inc_javac: true, } // These are the flags when `SOONG_PARTIAL_COMPILE=all`. -- cgit v1.2.3 From aba9cfb9b72ec71e7a9cfecb2f0f585cd4191b50 Mon Sep 17 00:00:00 2001 From: Taylor Santiago Date: Thu, 1 May 2025 10:02:57 -0700 Subject: Update the sandboxSupported() arguments to be closer to wrapSandbox() arguments Change-Id: I76df58ac97a4e7058179ace616245b08fe958700 --- ui/build/sandbox_linux.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/ui/build/sandbox_linux.go b/ui/build/sandbox_linux.go index 51cbc9382..f57a7d54c 100644 --- a/ui/build/sandbox_linux.go +++ b/ui/build/sandbox_linux.go @@ -94,19 +94,24 @@ func (c *Cmd) sandboxSupported() bool { sandboxConfig.distDir = absPath(c.ctx, derefPath) } - sandboxArgs := []string{ + var sandboxArgs []string + sandboxArgs = append(sandboxArgs, "-H", "android-build", "-e", "-u", "nobody", "-g", sandboxConfig.group, - "-R", "/", + ) + sandboxArgs = append(sandboxArgs, + c.readMountArgs()..., + ) + sandboxArgs = append(sandboxArgs, // Mount tmp before srcDir // srcDir is /tmp/.* in integration tests, which is a child dir of /tmp // nsjail throws an error if a child dir is mounted before its parent "-B", "/tmp", - c.config.sandboxConfig.SrcDirMountFlag(), sandboxConfig.srcDir, - "-B", sandboxConfig.outDir, - } + c.config.sandboxConfig.SrcDirMountFlag(), c.srcDirArg(), + "-B", c.outDirArg(), + ) if _, err := os.Stat(sandboxConfig.distDir); !os.IsNotExist(err) { //Mount dist dir as read-write if it already exists -- cgit v1.2.3 From dbc2bee870c4164818be0fb1e4911b52294af29f Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Thu, 1 May 2025 11:20:53 -0700 Subject: Disable fsgen in unbundled builds Unbundled builds don't build partitions / a device, so disable fsgen. The dist artifacts of the android_device were conflicting with unbundled dist artifacts. Bug: 413145177 Test: Presubmits Change-Id: I47292cfbfed52bad2c5c04ae91c987758044620c --- fsgen/filesystem_creator.go | 20 ++++++++++++++++++++ fsgen/fsgen_mutators.go | 9 +++++++++ 2 files changed, 29 insertions(+) diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go index 033d606f2..2d5ce5a32 100644 --- a/fsgen/filesystem_creator.go +++ b/fsgen/filesystem_creator.go @@ -144,6 +144,9 @@ func filesystemCreatorFactory() android.Module { android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon) module.AddProperties(&module.properties) android.AddLoadHook(module, func(ctx android.LoadHookContext) { + if !shouldEnableFilesystemCreator(ctx) { + return + } generatedPrebuiltEtcModuleNames := createPrebuiltEtcModules(ctx) avbpubkeyGenerated := createAvbpubkeyModule(ctx) createFsGenState(ctx, generatedPrebuiltEtcModuleNames, avbpubkeyGenerated) @@ -155,6 +158,17 @@ func filesystemCreatorFactory() android.Module { return module } +func shouldEnableFilesystemCreator(ctx android.ConfigContext) bool { + if ctx.Config().HasUnbundledBuildApps() || ctx.Config().UnbundledBuild() { + // unbundled builds don't build a device. The android_device's dist artifacts + // would conflict with the dist artifacts from the unbundled singleton. + return false + } + // We create the filsystem modules even if soong-only mode isn't enabled, so we at least + // get analysis time checks running everywhere for more real-world coverage. + return true +} + func generatedPartitions(ctx android.EarlyModuleContext) allGeneratedPartitionData { partitionVars := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse @@ -1193,6 +1207,9 @@ var generatedFilesystemDepTag imageDepTagType var generatedVbmetaPartitionDepTag imageDepTagType func (f *filesystemCreator) DepsMutator(ctx android.BottomUpMutatorContext) { + if !shouldEnableFilesystemCreator(ctx) { + return + } for _, name := range ctx.Config().Get(fsGenStateOnceKey).(*FsGenState).soongGeneratedPartitions.names() { ctx.AddDependency(ctx.Module(), generatedFilesystemDepTag, name) } @@ -1202,6 +1219,9 @@ func (f *filesystemCreator) DepsMutator(ctx android.BottomUpMutatorContext) { } func (f *filesystemCreator) GenerateAndroidBuildActions(ctx android.ModuleContext) { + if !shouldEnableFilesystemCreator(ctx) { + return + } if ctx.ModuleDir() != "build/soong/fsgen" { ctx.ModuleErrorf("There can only be one soong_filesystem_creator in build/soong/fsgen") } diff --git a/fsgen/fsgen_mutators.go b/fsgen/fsgen_mutators.go index f19f266a2..e2c8fe559 100644 --- a/fsgen/fsgen_mutators.go +++ b/fsgen/fsgen_mutators.go @@ -241,6 +241,9 @@ func appendDepIfAppropriate(mctx android.BottomUpMutatorContext, deps *multilibD } func collectDepsMutator(mctx android.BottomUpMutatorContext) { + if !shouldEnableFilesystemCreator(mctx) { + return + } m := mctx.Module() if m.Target().Os.Class != android.Device { return @@ -325,6 +328,9 @@ func getBitness(archTypes []android.ArchType) (ret []string) { } func removeDepsMutator(mctx android.BottomUpMutatorContext) { + if !shouldEnableFilesystemCreator(mctx) { + return + } fsGenState := mctx.Config().Get(fsGenStateOnceKey).(*FsGenState) fsGenState.fsDepsMutex.Lock() defer fsGenState.fsDepsMutex.Unlock() @@ -332,6 +338,9 @@ func removeDepsMutator(mctx android.BottomUpMutatorContext) { } func setDepsMutator(mctx android.BottomUpMutatorContext) { + if !shouldEnableFilesystemCreator(mctx) { + return + } removeOverriddenDeps(mctx) fsGenState := mctx.Config().Get(fsGenStateOnceKey).(*FsGenState) fsDeps := fsGenState.fsDeps -- cgit v1.2.3 From 303e5d4b6b39c2b682e5c1bfe126b3828a9ff1f6 Mon Sep 17 00:00:00 2001 From: Dave Mankoff Date: Fri, 31 Jan 2025 21:02:44 +0000 Subject: Add command line arguments to the client. This is a first pass approximation of the needed command line arguments for the client, along with a simple framework for declaring and ingesting command line arguments. It includes thorough unit tests for the argument framework. More to come. Bug: 392906864 Test: atest kotlin-incremental-client-tests Ignore-AOSP-First: going in after aosp close Change-Id: I0239857dfa2b3893182f1063a1b098128a999ff3 --- PREUPLOAD.cfg | 9 + cmd/kotlinc_incremental/Android.bp | 3 + .../com/android/kotlin/compiler/client/Argument.kt | 395 +++++++++++++++++++ .../kotlin/compiler/client/BuildFileParser.kt | 104 +++++ .../src/com/android/kotlin/compiler/client/Main.kt | 96 ++++- .../com/android/kotlin/compiler/client/Options.kt | 187 +++++++++ .../tests/resources/test_build.xml | 10 + .../android/kotlin/compiler/client/ArgumentTest.kt | 434 +++++++++++++++++++++ .../kotlin/compiler/client/BuildFileParserTest.kt | 66 ++++ .../com/android/kotlin/compiler/client/MainTest.kt | 27 -- 10 files changed, 1303 insertions(+), 28 deletions(-) create mode 100644 cmd/kotlinc_incremental/src/com/android/kotlin/compiler/client/Argument.kt create mode 100644 cmd/kotlinc_incremental/src/com/android/kotlin/compiler/client/BuildFileParser.kt create mode 100644 cmd/kotlinc_incremental/src/com/android/kotlin/compiler/client/Options.kt create mode 100644 cmd/kotlinc_incremental/tests/resources/test_build.xml create mode 100644 cmd/kotlinc_incremental/tests/src/com/android/kotlin/compiler/client/ArgumentTest.kt create mode 100644 cmd/kotlinc_incremental/tests/src/com/android/kotlin/compiler/client/BuildFileParserTest.kt delete mode 100644 cmd/kotlinc_incremental/tests/src/com/android/kotlin/compiler/client/MainTest.kt diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg index 317f5c434..b89e5f8c8 100644 --- a/PREUPLOAD.cfg +++ b/PREUPLOAD.cfg @@ -1,6 +1,15 @@ [Builtin Hooks] gofmt = true bpfmt = true +ktfmt = true [Hook Scripts] do_not_use_DO_NOT_MERGE = ${REPO_ROOT}/build/soong/scripts/check_do_not_merge.sh ${PREUPLOAD_COMMIT} + +ktlint_hook = ${REPO_ROOT}/prebuilts/ktlint/ktlint.py --no-verify-format -f ${PREUPLOAD_FILES} + +[Builtin Hooks Options] +ktfmt = --kotlinlang-style --include-dirs=cmd/kotlinc_incremental + +[Tool Paths] +ktfmt = ${REPO_ROOT}/external/ktfmt/ktfmt.sh \ No newline at end of file diff --git a/cmd/kotlinc_incremental/Android.bp b/cmd/kotlinc_incremental/Android.bp index 7816553ee..9811cc1db 100644 --- a/cmd/kotlinc_incremental/Android.bp +++ b/cmd/kotlinc_incremental/Android.bp @@ -57,6 +57,9 @@ java_test_host { srcs: [ "tests/src/com/**/*.kt", ], + data: [ + "tests/resources/test_build.xml", + ], static_libs: [ "kotlin-incremental-client-lib", "junit", diff --git a/cmd/kotlinc_incremental/src/com/android/kotlin/compiler/client/Argument.kt b/cmd/kotlinc_incremental/src/com/android/kotlin/compiler/client/Argument.kt new file mode 100644 index 000000000..d59cd99e0 --- /dev/null +++ b/cmd/kotlinc_incremental/src/com/android/kotlin/compiler/client/Argument.kt @@ -0,0 +1,395 @@ +/* + * 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 com.android.kotlin.compiler.client + +import java.io.File +import javax.xml.parsers.SAXParserFactory + +abstract class Argument { + abstract val argumentName: String + abstract val helpText: String + abstract val default: T? + + var error: String? = null + protected set + + abstract fun matches(arg: String): Boolean + + abstract fun parse(arg: String, position: Iterator, opts: Options) + + abstract fun setOption(option: T, opts: Options) + + fun setupDefault(opts: Options) { + if (default != null) { + setOption(default!!, opts) + } + } +} + +abstract class NoArgument : Argument() { + override val default = null + + override fun matches(arg: String) = arg == "-$argumentName" + + override fun parse(arg: String, position: Iterator, opts: Options) { + setOption(true, opts) + } +} + +abstract class SingleArgument : Argument() { + + override fun matches(arg: String) = arg.startsWith("-$argumentName=") + + override fun parse(arg: String, position: Iterator, opts: Options) { + val splits = arg.split("=", limit = 2) + if (splits.size != 2 || splits[1].isEmpty()) { + error = "Required argument not supplied for $argumentName" + return + } + val value = stringToType(splits[1]) + setOption(value, opts) + } + + abstract fun stringToType(arg: String): T +} + +abstract class StringArgument : SingleArgument() { + override fun stringToType(arg: String): String { + return arg + } +} + +class SourcesArgument : Argument() { + override val default = null + override val argumentName = "-" + override val helpText = + """ + Everything after this is treated as a source file. + """.trimIndent() + + override fun matches(arg: String) = arg == "--" + + override fun parse(arg: String, position: Iterator, opts: Options) { + position.forEachRemaining { setOption(it, opts) } + } + + override fun setOption(option: String, opts: Options) { + opts.addSource(option) + } +} + +class BuildFileArgument : StringArgument() { + override val default = null + + override val argumentName = "build-file" + override val helpText = + """ + Build file containing sources and classpaths to be consumed by kotlinc. See + -Xbuild-file on kotlinc. + """ + .trimIndent() + + override fun setOption(option: String, opts: Options) { + opts.buildFileLocation = option + parseBuildFile(opts.buildFile!!, opts) + } + + private fun parseBuildFile(buildFile: File, opts: Options) { + val parser = BuildFileParser() + val spf = SAXParserFactory.newInstance() + val saxParser = spf.newSAXParser() + val xmlReader = saxParser.xmlReader + xmlReader.contentHandler = parser + xmlReader.parse(buildFile.absolutePath) + + opts.buildFileModuleName = parser.moduleName + opts.buildFileClassPaths = parser.classpaths + opts.buildFileSources = parser.sources + opts.buildFileJavaSources = parser.javaSources + if (parser.outputDirName != null) { + opts.outputDirName = parser.outputDirName!! + } + } +} + +class XBuildFileArgument : StringArgument() { + override val default = null + + override val argumentName = "Xbuild-file" + override val helpText = """ + Deprecated: use -build-file + """.trimIndent() + + override fun setOption(option: String, opts: Options) { + error = "Can not parser -Xbuild-file. Please use -build-file." + } +} + +class HelpArgument : NoArgument() { + override val argumentName = "h" + + override val helpText = """ + Outputs this help text. + """.trimIndent() + + override fun setOption(option: Boolean, opts: Options) {} +} + +abstract class WritableDirectoryArgument : StringArgument() { + override fun setOption(option: String, opts: Options) { + val e = isValidDirectoryForWriting(option) + if (e != null) { + error = "Invalid $argumentName option specified: $e" + } else { + setDirectory(File(option), opts) + } + } + + abstract fun setDirectory(dir: File, opts: Options) +} + +abstract class SubdirectoryArgument : StringArgument() { + override fun setOption(option: String, opts: Options) { + if (option.isBlank()) { + error = "Invalid $argumentName option specified: Must be non-empty string." + } else if (option.contains("..")) { + error = "Invalid $argumentName option specified: No path traversal allowed." + } else { + setSubDirectory(option, opts) + } + } + + abstract fun setSubDirectory(dir: String, opts: Options) +} + +class LogDirArgument : WritableDirectoryArgument() { + override val argumentName = "log-dir" + override val helpText = """ + Directory to write log output to. + """.trimIndent() + override val default = null + + override fun setDirectory(dir: File, opts: Options) { + opts.logDir = dir + } +} + +class RunFilesArgument : WritableDirectoryArgument() { + override val argumentName = "run-files-path" + override val helpText = + """ + Local directory to place lock files and other process-specific + metadata. + """ + .trimIndent() + override val default = "/tmp" + + override fun setDirectory(dir: File, opts: Options) { + opts.runFiles = dir + } +} + +class RootDirArgument : WritableDirectoryArgument() { + override val argumentName = "root-dir" + override val helpText = + """ + Base directory for the Kotlin daemon's artifacts. + Other directories - working-dir, output-dir, and build-dir - are all relative + to this directory. + This option is REQUIRED. + """ + .trimIndent() + override val default = null + + override fun setDirectory(dir: File, opts: Options) { + opts.rootDir = dir + } +} + +class WorkingDirArgument : SubdirectoryArgument() { + override val argumentName = "working-dir" + override val helpText = + """ + Stores intermediate steps used specifically for incremental compilation. + Must be maintained between compilation invocations to see + incremental speed benefits. + Relative to root-dir. + """ + .trimIndent() + override val default = "work" + + override fun setSubDirectory(dir: String, opts: Options) { + opts.workingDirName = dir + } +} + +class OutputDirArgument : SubdirectoryArgument() { + override val argumentName = "output-dir" + override val helpText = + """ + Where to output compiler results. + Relative to root-dir. + """ + .trimIndent() + override val default = "output" + + override fun setSubDirectory(dir: String, opts: Options) { + opts.outputDirName = dir + } +} + +class BuildDirArgument : SubdirectoryArgument() { + override val argumentName = "build-dir" + override val helpText = + """ + TODO: figure out what this is. Notes say: + "buildDir is the parent of destDir and workingDir" + """ + .trimIndent() + override val default = "build" + + override fun setSubDirectory(dir: String, opts: Options) { + opts.buildDirName = dir + } +} + +class BuildHistoryFileArgument : StringArgument() { + override val argumentName = "build-history" + override val helpText = + """ + Location of the build-history file used for incremental compilation. + """ + .trimIndent() + override val default = "build-history" + + override fun setOption(option: String, opts: Options) { + opts.buildHistoryFileName = option + } +} + +class ClassPathArgument : StringArgument() { + override val argumentName = "classpath" + override val helpText = + """ + List of directories and JAR/ZIP archives to search for user class files. + Colon separated: "foo.jar:bar.jar" + """ + .trimIndent() + override val default = null + + override fun setOption(option: String, opts: Options) { + val paths = option.split(":").filter { !it.isBlank() } + // TODO: validate paths? + opts.classPath.addAll(paths) + } +} + +/** + * Intercepts the -Xplugin argument of kotlinc such that we can prepend them to the front of the + * classpath. + * + * Without this, you can run into a bug where a passed in plugin can cause a plugin implementing the + * same package+classname to be loaded from a different part of the classpath than is intended. + */ +class PluginArgument : StringArgument() { + override val argumentName = "Xplugin" + override val helpText = + """ + Compiler plugins passed to kotlin. See the `-Xplugin` argument of kotlinc. + """ + .trimIndent() + override val default = null + + override fun setOption(option: String, opts: Options) { + opts.classPath.addFirst(option) + opts.passThroughArgs.add("-Xplugin=$option") + } +} + +class JvmArgument : Argument() { + override val argumentName = "-J