diff options
Diffstat (limited to 'apex/builder.go')
-rw-r--r-- | apex/builder.go | 104 |
1 files changed, 90 insertions, 14 deletions
diff --git a/apex/builder.go b/apex/builder.go index 641aa2772..15737f8c7 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -20,12 +20,14 @@ import ( "path" "path/filepath" "runtime" + "slices" "sort" "strconv" "strings" "android/soong/aconfig" "android/soong/android" + "android/soong/dexpreopt" "android/soong/java" "github.com/google/blueprint" @@ -522,9 +524,10 @@ func markManifestTestOnly(ctx android.ModuleContext, androidManifestFile android }) } -func isVintfFragment(fi apexFile) bool { +func shouldApplyAssembleVintf(fi apexFile) bool { isVintfFragment, _ := path.Match("etc/vintf/*", fi.path()) - return isVintfFragment + _, fromVintfFragmentModule := fi.module.(*android.VintfFragmentModule) + return isVintfFragment && !fromVintfFragmentModule } func runAssembleVintf(ctx android.ModuleContext, vintfFragment android.Path) android.Path { @@ -538,6 +541,64 @@ func runAssembleVintf(ctx android.ModuleContext, vintfFragment android.Path) and return processed } +// installApexSystemServerFiles installs dexpreopt and dexjar files for system server classpath entries +// provided by the apex. They are installed here instead of in library module because there may be multiple +// variants of the library, generally one for the "main" apex and another with a different min_sdk_version +// for the Android Go version of the apex. Both variants would attempt to install to the same locations, +// and the library variants cannot determine which one should. The apex module is better equipped to determine +// if it is "selected". +// This assumes that the jars produced by different min_sdk_version values are identical, which is currently +// true but may not be true if the min_sdk_version difference between the variants spans version that changed +// the dex format. +func (a *apexBundle) installApexSystemServerFiles(ctx android.ModuleContext) { + // If performInstalls is set this module is responsible for creating the install rules. + performInstalls := a.GetOverriddenBy() == "" && !a.testApex && a.installable() + // TODO(b/234351700): Remove once ART does not have separated debug APEX, or make the selection + // explicit in the ART Android.bp files. + if ctx.Config().UseDebugArt() { + if ctx.ModuleName() == "com.android.art" { + performInstalls = false + } + } else { + if ctx.ModuleName() == "com.android.art.debug" { + performInstalls = false + } + } + + psi := android.PrebuiltSelectionInfoMap{} + ctx.VisitDirectDeps(func(am android.Module) { + if info, exists := android.OtherModuleProvider(ctx, am, android.PrebuiltSelectionInfoProvider); exists { + psi = info + } + }) + + if len(psi.GetSelectedModulesForApiDomain(ctx.ModuleName())) > 0 { + performInstalls = false + } + + for _, fi := range a.filesInfo { + for _, install := range fi.systemServerDexpreoptInstalls { + var installedFile android.InstallPath + if performInstalls { + installedFile = ctx.InstallFile(install.InstallDirOnDevice, install.InstallFileOnDevice, install.OutputPathOnHost) + } else { + // Another module created the install rules, but this module should still depend on + // the installed locations. + installedFile = install.InstallDirOnDevice.Join(ctx, install.InstallFileOnDevice) + } + a.extraInstalledFiles = append(a.extraInstalledFiles, installedFile) + a.extraInstalledPairs = append(a.extraInstalledPairs, installPair{install.OutputPathOnHost, installedFile}) + } + if performInstalls { + for _, dexJar := range fi.systemServerDexJars { + // Copy the system server dex jar to a predefined location where dex2oat will find it. + android.CopyFileRule(ctx, dexJar, + android.PathForOutput(ctx, dexpreopt.SystemServerDexjarsDir, dexJar.Base())) + } + } + } +} + // buildApex creates build rules to build an APEX using apexer. func (a *apexBundle) buildApex(ctx android.ModuleContext) { suffix := imageApexSuffix @@ -548,7 +609,7 @@ func (a *apexBundle) buildApex(ctx android.ModuleContext) { imageDir := android.PathForModuleOut(ctx, "image"+suffix) - installSymbolFiles := (ctx.Config().KatiEnabled() && a.ExportedToMake()) && a.installable() + installSymbolFiles := a.ExportedToMake() && a.installable() // set of dependency module:location mappings installMapSet := make(map[string]bool) @@ -575,7 +636,7 @@ func (a *apexBundle) buildApex(ctx android.ModuleContext) { copyCommands = append(copyCommands, "ln -sfn "+pathOnDevice+" "+destPath) } else { // Copy the file into APEX - if !a.testApex && isVintfFragment(fi) { + if !a.testApex && shouldApplyAssembleVintf(fi) { // copy the output of assemble_vintf instead of the original vintfFragment := runAssembleVintf(ctx, fi.builtFile) copyCommands = append(copyCommands, "cp -f "+vintfFragment.String()+" "+destPath) @@ -599,7 +660,7 @@ func (a *apexBundle) buildApex(ctx android.ModuleContext) { } else { if installSymbolFiles { // store installedPath. symlinks might be created if required. - installedPath = apexDir.Join(ctx, fi.installDir, fi.stem()) + installedPath = ctx.InstallFile(apexDir.Join(ctx, fi.installDir), fi.stem(), fi.builtFile) } } @@ -981,9 +1042,9 @@ func (a *apexBundle) buildApex(ctx android.ModuleContext) { a.SkipInstall() } + installDeps := slices.Concat(a.compatSymlinks, a.extraInstalledFiles) // Install to $OUT/soong/{target,host}/.../apex. - a.installedFile = ctx.InstallFile(a.installDir, a.Name()+installSuffix, a.outputFile, - a.compatSymlinks...) + a.installedFile = ctx.InstallFile(a.installDir, a.Name()+installSuffix, a.outputFile, installDeps...) // installed-files.txt is dist'ed a.installedFilesFile = a.buildInstalledFilesFile(ctx, a.outputFile, imageDir) @@ -1040,7 +1101,7 @@ func (a *apexBundle) buildApexDependencyInfo(ctx android.ModuleContext) { } depInfos := android.DepNameToDepInfoMap{} - a.WalkPayloadDepsProxy(ctx, func(ctx android.BaseModuleContext, from, to android.ModuleProxy, externalDep bool) bool { + a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from android.Module, to android.ApexModule, externalDep bool) bool { if from.Name() == to.Name() { // This can happen for cc.reuseObjTag. We are not interested in tracking this. // As soon as the dependency graph crosses the APEX boundary, don't go further. @@ -1067,10 +1128,9 @@ func (a *apexBundle) buildApexDependencyInfo(ctx android.ModuleContext) { depInfos[to.Name()] = info } else { toMinSdkVersion := "(no version)" - if info, ok := android.OtherModuleProvider(ctx, to, android.CommonModuleInfoKey); ok { - if v := info.MinSdkVersion; v != "" { - toMinSdkVersion = v - } + if info, ok := android.OtherModuleProvider(ctx, to, android.CommonModuleInfoKey); ok && + !info.MinSdkVersion.IsPlatform && info.MinSdkVersion.ApiLevel != nil { + toMinSdkVersion = info.MinSdkVersion.ApiLevel.String() } depInfos[to.Name()] = android.ApexModuleDepInfo{ To: to.Name(), @@ -1198,6 +1258,22 @@ func runApexLinkerconfigValidation(ctx android.ModuleContext, apexFile android.P return timestamp } +// Can't use PartitionTag() because PartitionTag() returns the partition this module is actually +// installed (e.g. PartitionTag() may return "system" for vendor apex when vendor is linked to /system/vendor) +func (a *apexBundle) partition() string { + if a.SocSpecific() { + return "vendor" + } else if a.DeviceSpecific() { + return "odm" + } else if a.ProductSpecific() { + return "product" + } else if a.SystemExtSpecific() { + return "system_ext" + } else { + return "system" + } +} + // Runs apex_sepolicy_tests // // $ apex-ls -Z {apex_file} > {file_contexts} @@ -1209,7 +1285,7 @@ func runApexSepolicyTests(ctx android.ModuleContext, a *apexBundle, apexFile and Input: apexFile, Output: timestamp, Args: map[string]string{ - "partition_tag": a.PartitionTag(ctx.DeviceConfig()), + "partition_tag": a.partition(), }, }) return timestamp @@ -1236,7 +1312,7 @@ func runApexHostVerifier(ctx android.ModuleContext, a *apexBundle, apexFile andr Input: apexFile, Output: timestamp, Args: map[string]string{ - "partition_tag": a.PartitionTag(ctx.DeviceConfig()), + "partition_tag": a.partition(), }, }) return timestamp |