summaryrefslogtreecommitdiff
path: root/apex/builder.go
diff options
context:
space:
mode:
Diffstat (limited to 'apex/builder.go')
-rw-r--r--apex/builder.go104
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