diff options
Diffstat (limited to 'java')
| -rw-r--r-- | java/Android.bp | 1 | ||||
| -rw-r--r-- | java/aar.go | 462 | ||||
| -rw-r--r-- | java/android_manifest_test.go | 103 | ||||
| -rw-r--r-- | java/androidmk.go | 31 | ||||
| -rwxr-xr-x | java/app.go | 54 | ||||
| -rw-r--r-- | java/app_import.go | 65 | ||||
| -rw-r--r-- | java/app_test.go | 528 | ||||
| -rw-r--r-- | java/base.go | 90 | ||||
| -rw-r--r-- | java/bootclasspath.go | 5 | ||||
| -rw-r--r-- | java/bootclasspath_fragment.go | 268 | ||||
| -rw-r--r-- | java/bootclasspath_fragment_test.go | 35 | ||||
| -rw-r--r-- | java/builder.go | 53 | ||||
| -rw-r--r-- | java/config/config.go | 2 | ||||
| -rw-r--r-- | java/device_host_converter.go | 2 | ||||
| -rw-r--r-- | java/device_host_converter_test.go | 3 | ||||
| -rw-r--r-- | java/dexpreopt_bootjars.go | 327 | ||||
| -rw-r--r-- | java/dexpreopt_config.go | 93 | ||||
| -rw-r--r-- | java/dexpreopt_config_test.go | 20 | ||||
| -rw-r--r-- | java/dexpreopt_config_testing.go | 188 | ||||
| -rw-r--r-- | java/droidstubs.go | 3 | ||||
| -rw-r--r-- | java/fuzz_test.go | 4 | ||||
| -rw-r--r-- | java/generated_java_library.go | 4 | ||||
| -rw-r--r-- | java/generated_java_library_test.go | 3 | ||||
| -rw-r--r-- | java/hiddenapi_modular.go | 1 | ||||
| -rw-r--r-- | java/hiddenapi_singleton.go | 2 | ||||
| -rw-r--r-- | java/java.go | 108 | ||||
| -rw-r--r-- | java/java_test.go | 19 | ||||
| -rw-r--r-- | java/platform_bootclasspath.go | 85 |
28 files changed, 1873 insertions, 686 deletions
diff --git a/java/Android.bp b/java/Android.bp index e07986975..4450c4275 100644 --- a/java/Android.bp +++ b/java/Android.bp @@ -80,6 +80,7 @@ bootstrap_go_package { ], testSrcs: [ "aar_test.go", + "android_manifest_test.go", "androidmk_test.go", "app_import_test.go", "app_set_test.go", diff --git a/java/aar.go b/java/aar.go index 29e86e678..180e1d726 100644 --- a/java/aar.go +++ b/java/aar.go @@ -31,10 +31,9 @@ import ( type AndroidLibraryDependency interface { LibraryDependency ExportPackage() android.Path - ExportedRRODirs() []rroDir - ExportedStaticPackages() android.Paths - ExportedManifests() android.Paths - ExportedAssets() android.OptionalPath + ResourcesNodeDepSet() *android.DepSet[*resourcesNode] + RRODirsDepSet() *android.DepSet[rroDir] + ManifestsDepSet() *android.DepSet[android.Path] SetRROEnforcedForDependent(enforce bool) IsRROEnforced(ctx android.BaseModuleContext) bool } @@ -89,35 +88,49 @@ type aaptProperties struct { // do not include AndroidManifest from dependent libraries Dont_merge_manifests *bool + // If use_resource_processor is set, use Bazel's resource processor instead of aapt2 to generate R.class files. + // The resource processor produces more optimal R.class files that only list resources in the package of the + // library that provided them, as opposed to aapt2 which produces R.java files for every package containing + // every resource. Using the resource processor can provide significant build time speedups, but requires + // fixing the module to use the correct package to reference each resource, and to avoid having any other + // libraries in the tree that use the same package name. Defaults to false, but will default to true in the + // future. + Use_resource_processor *bool + // true if RRO is enforced for any of the dependent modules RROEnforcedForDependent bool `blueprint:"mutated"` } type aapt struct { - aaptSrcJar android.Path - exportPackage android.Path - manifestPath android.Path - transitiveManifestPaths android.Paths - proguardOptionsFile android.Path - rroDirs []rroDir - rTxt android.Path - extraAaptPackagesFile android.Path - mergedManifestFile android.Path - noticeFile android.OptionalPath - assetPackage android.OptionalPath - isLibrary bool - defaultManifestVersion string - useEmbeddedNativeLibs bool - useEmbeddedDex bool - usesNonSdkApis bool - hasNoCode bool - LoggingParent string - resourceFiles android.Paths + aaptSrcJar android.Path + transitiveAaptRJars android.Paths + transitiveAaptResourcePackages android.Paths + exportPackage android.Path + manifestPath android.Path + proguardOptionsFile android.Path + rTxt android.Path + rJar android.Path + extraAaptPackagesFile android.Path + mergedManifestFile android.Path + noticeFile android.OptionalPath + assetPackage android.OptionalPath + isLibrary bool + defaultManifestVersion string + useEmbeddedNativeLibs bool + useEmbeddedDex bool + usesNonSdkApis bool + hasNoCode bool + LoggingParent string + resourceFiles android.Paths splitNames []string splits []split aaptProperties aaptProperties + + resourcesNodesDepSet *android.DepSet[*resourcesNode] + rroDirsDepSet *android.DepSet[rroDir] + manifestsDepSet *android.DepSet[android.Path] } type split struct { @@ -138,20 +151,23 @@ func propagateRROEnforcementMutator(ctx android.TopDownMutatorContext) { } } +func (a *aapt) useResourceProcessorBusyBox() bool { + return BoolDefault(a.aaptProperties.Use_resource_processor, false) +} + func (a *aapt) ExportPackage() android.Path { return a.exportPackage } - -func (a *aapt) ExportedRRODirs() []rroDir { - return a.rroDirs +func (a *aapt) ResourcesNodeDepSet() *android.DepSet[*resourcesNode] { + return a.resourcesNodesDepSet } -func (a *aapt) ExportedManifests() android.Paths { - return a.transitiveManifestPaths +func (a *aapt) RRODirsDepSet() *android.DepSet[rroDir] { + return a.rroDirsDepSet } -func (a *aapt) ExportedAssets() android.OptionalPath { - return a.assetPackage +func (a *aapt) ManifestsDepSet() *android.DepSet[android.Path] { + return a.manifestsDepSet } func (a *aapt) SetRROEnforcedForDependent(enforce bool) { @@ -175,8 +191,6 @@ func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext android.SdkConte // Flags specified in Android.bp linkFlags = append(linkFlags, a.aaptProperties.Aaptflags...) - linkFlags = append(linkFlags, "--no-static-lib-packages") - // Find implicit or explicit asset and resource dirs assetDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Asset_dirs, "assets") resourceDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Resource_dirs, "res") @@ -291,7 +305,7 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon classLoaderContexts dexpreopt.ClassLoaderContextMap, excludedLibs []string, enforceDefaultTargetSdkVersion bool, extraLinkFlags ...string) { - transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, assetPackages, libDeps, libFlags := + staticResourcesNodesDepSet, staticRRODirsDepSet, staticManifestsDepSet, sharedDeps, libFlags := aaptLibs(ctx, sdkContext, classLoaderContexts) // Exclude any libraries from the supplied list. @@ -314,13 +328,20 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon EnforceDefaultTargetSdkVersion: enforceDefaultTargetSdkVersion, }) + staticDeps := transitiveAarDeps(staticResourcesNodesDepSet.ToList()) + // Add additional manifest files to transitive manifests. additionalManifests := android.PathsForModuleSrc(ctx, a.aaptProperties.Additional_manifests) - a.transitiveManifestPaths = append(android.Paths{manifestPath}, additionalManifests...) - a.transitiveManifestPaths = append(a.transitiveManifestPaths, transitiveStaticLibManifests...) - - if len(a.transitiveManifestPaths) > 1 && !Bool(a.aaptProperties.Dont_merge_manifests) { - a.mergedManifestFile = manifestMerger(ctx, a.transitiveManifestPaths[0], a.transitiveManifestPaths[1:], a.isLibrary) + transitiveManifestPaths := append(android.Paths{manifestPath}, additionalManifests...) + // TODO(b/288358614): Soong has historically not merged manifests from dependencies of android_library_import + // modules. Merging manifests from dependencies could remove the need for pom2bp to generate the "-nodeps" copies + // of androidx libraries, but doing so triggers errors due to errors introduced by existing dependencies of + // android_library_import modules. If this is fixed, staticManifestsDepSet can be dropped completely in favor of + // staticResourcesNodesDepSet.manifests() + transitiveManifestPaths = append(transitiveManifestPaths, staticManifestsDepSet.ToList()...) + + if len(transitiveManifestPaths) > 1 && !Bool(a.aaptProperties.Dont_merge_manifests) { + a.mergedManifestFile = manifestMerger(ctx, transitiveManifestPaths[0], transitiveManifestPaths[1:], a.isLibrary) if !a.isLibrary { // Only use the merged manifest for applications. For libraries, the transitive closure of manifests // will be propagated to the final application and merged there. The merged manifest for libraries is @@ -333,14 +354,27 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon compileFlags, linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, resZips := a.aapt2Flags(ctx, sdkContext, manifestPath) - rroDirs = append(rroDirs, staticRRODirs...) linkFlags = append(linkFlags, libFlags...) - linkDeps = append(linkDeps, libDeps...) + linkDeps = append(linkDeps, sharedDeps...) + linkDeps = append(linkDeps, staticDeps.resPackages()...) linkFlags = append(linkFlags, extraLinkFlags...) if a.isLibrary { linkFlags = append(linkFlags, "--static-lib") } + if a.isLibrary && a.useResourceProcessorBusyBox() { + // When building an android_library using ResourceProcessorBusyBox the resources are merged into + // package-res.apk with --merge-only, but --no-static-lib-packages is not used so that R.txt only + // contains resources from this library. + linkFlags = append(linkFlags, "--merge-only") + } else { + // When building and app or when building an android_library without ResourceProcessorBusyBox + // --no-static-lib-packages is used to put all the resources into the app. If ResourceProcessorBusyBox + // is used then the app's R.txt will be post-processed along with the R.txt files from dependencies to + // sort resources into the right packages in R.class. + linkFlags = append(linkFlags, "--no-static-lib-packages") + } + packageRes := android.PathForModuleOut(ctx, "package-res.apk") // the subdir "android" is required to be filtered by package names srcJar := android.PathForModuleGen(ctx, "android", "R.srcjar") @@ -348,6 +382,7 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon rTxt := android.PathForModuleOut(ctx, "R.txt") // This file isn't used by Soong, but is generated for exporting extraPackages := android.PathForModuleOut(ctx, "extra_packages") + var transitiveRJars android.Paths var compiledResDirs []android.Paths for _, dir := range resDirs { @@ -363,7 +398,27 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon var compiledRes, compiledOverlay android.Paths - compiledOverlay = append(compiledOverlay, transitiveStaticLibs...) + // AAPT2 overlays are in lowest to highest priority order, reverse the topological order + // of transitiveStaticLibs. + transitiveStaticLibs := android.ReversePaths(staticDeps.resPackages()) + + if a.isLibrary && a.useResourceProcessorBusyBox() { + // When building an android_library with ResourceProcessorBusyBox enabled treat static library dependencies + // as imports. The resources from dependencies will not be merged into this module's package-res.apk, and + // instead modules depending on this module will reference package-res.apk from all transitive static + // dependencies. + for _, staticDep := range staticDeps { + linkDeps = append(linkDeps, staticDep.resPackage) + linkFlags = append(linkFlags, "-I "+staticDep.resPackage.String()) + if staticDep.usedResourceProcessor { + transitiveRJars = append(transitiveRJars, staticDep.rJar) + } + } + } else { + // When building an app or building a library without ResourceProcessorBusyBox enabled all static + // dependencies are compiled into this module's package-res.apk as overlays. + compiledOverlay = append(compiledOverlay, transitiveStaticLibs...) + } if len(transitiveStaticLibs) > 0 { // If we are using static android libraries, every source file becomes an overlay. @@ -404,12 +459,18 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon }) } + // No need to specify assets from dependencies to aapt2Link for libraries, all transitive assets will be + // provided to the final app aapt2Link step. + var transitiveAssets android.Paths + if !a.isLibrary { + transitiveAssets = android.ReverseSliceInPlace(staticDeps.assets()) + } aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile, rTxt, extraPackages, - linkFlags, linkDeps, compiledRes, compiledOverlay, assetPackages, splitPackages) + linkFlags, linkDeps, compiledRes, compiledOverlay, transitiveAssets, splitPackages) // Extract assets from the resource package output so that they can be used later in aapt2link // for modules that depend on this one. - if android.PrefixInList(linkFlags, "-A ") || len(assetPackages) > 0 { + if android.PrefixInList(linkFlags, "-A ") { assets := android.PathForModuleOut(ctx, "assets.zip") ctx.Build(pctx, android.BuildParams{ Rule: extractAssetsRule, @@ -420,21 +481,142 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon a.assetPackage = android.OptionalPathForPath(assets) } + if a.useResourceProcessorBusyBox() { + rJar := android.PathForModuleOut(ctx, "busybox/R.jar") + resourceProcessorBusyBoxGenerateBinaryR(ctx, rTxt, a.mergedManifestFile, rJar, staticDeps, a.isLibrary) + transitiveRJars = append(transitiveRJars, rJar) + a.rJar = rJar + } + a.aaptSrcJar = srcJar + a.transitiveAaptRJars = transitiveRJars + a.transitiveAaptResourcePackages = staticDeps.resPackages() a.exportPackage = packageRes a.manifestPath = manifestPath a.proguardOptionsFile = proguardOptionsFile - a.rroDirs = rroDirs a.extraAaptPackagesFile = extraPackages a.rTxt = rTxt a.splits = splits + a.resourcesNodesDepSet = android.NewDepSetBuilder[*resourcesNode](android.TOPOLOGICAL). + Direct(&resourcesNode{ + resPackage: a.exportPackage, + manifest: a.manifestPath, + additionalManifests: additionalManifests, + rTxt: a.rTxt, + rJar: a.rJar, + assets: a.assetPackage, + + usedResourceProcessor: a.useResourceProcessorBusyBox(), + }). + Transitive(staticResourcesNodesDepSet).Build() + a.rroDirsDepSet = android.NewDepSetBuilder[rroDir](android.TOPOLOGICAL). + Direct(rroDirs...). + Transitive(staticRRODirsDepSet).Build() + a.manifestsDepSet = android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL). + Direct(a.manifestPath). + DirectSlice(additionalManifests). + Transitive(staticManifestsDepSet).Build() +} + +var resourceProcessorBusyBox = pctx.AndroidStaticRule("resourceProcessorBusyBox", + blueprint.RuleParams{ + Command: "${config.JavaCmd} -cp ${config.ResourceProcessorBusyBox} " + + "com.google.devtools.build.android.ResourceProcessorBusyBox --tool=GENERATE_BINARY_R -- @${out}.args && " + + "if cmp -s ${out}.tmp ${out} ; then rm ${out}.tmp ; else mv ${out}.tmp ${out}; fi", + CommandDeps: []string{"${config.ResourceProcessorBusyBox}"}, + Rspfile: "${out}.args", + RspfileContent: "--primaryRTxt ${rTxt} --primaryManifest ${manifest} --classJarOutput ${out}.tmp ${args}", + Restat: true, + }, "rTxt", "manifest", "args") + +// resourceProcessorBusyBoxGenerateBinaryR converts the R.txt file produced by aapt2 into R.class files +// using Bazel's ResourceProcessorBusyBox tool, which is faster than compiling the R.java files and +// supports producing classes for static dependencies that only include resources from that dependency. +func resourceProcessorBusyBoxGenerateBinaryR(ctx android.ModuleContext, rTxt, manifest android.Path, + rJar android.WritablePath, transitiveDeps transitiveAarDeps, isLibrary bool) { + + var args []string + var deps android.Paths + + if !isLibrary { + // When compiling an app, pass all R.txt and AndroidManifest.xml from transitive static library dependencies + // to ResourceProcessorBusyBox so that it can regenerate R.class files with the final resource IDs for each + // package. + args, deps = transitiveDeps.resourceProcessorDeps() + } else { + // When compiling a library don't pass any dependencies as it only needs to generate an R.class file for this + // library. Pass --finalFields=false so that the R.class file contains non-final fields so they don't get + // inlined into the library before the final IDs are assigned during app compilation. + args = append(args, "--finalFields=false") + } + + deps = append(deps, rTxt, manifest) + + ctx.Build(pctx, android.BuildParams{ + Rule: resourceProcessorBusyBox, + Output: rJar, + Implicits: deps, + Description: "ResourceProcessorBusyBox", + Args: map[string]string{ + "rTxt": rTxt.String(), + "manifest": manifest.String(), + "args": strings.Join(args, " "), + }, + }) +} + +type resourcesNode struct { + resPackage android.Path + manifest android.Path + additionalManifests android.Paths + rTxt android.Path + rJar android.Path + assets android.OptionalPath + + usedResourceProcessor bool +} + +type transitiveAarDeps []*resourcesNode + +func (t transitiveAarDeps) resPackages() android.Paths { + paths := make(android.Paths, 0, len(t)) + for _, dep := range t { + paths = append(paths, dep.resPackage) + } + return paths +} + +func (t transitiveAarDeps) manifests() android.Paths { + paths := make(android.Paths, 0, len(t)) + for _, dep := range t { + paths = append(paths, dep.manifest) + paths = append(paths, dep.additionalManifests...) + } + return paths +} + +func (t transitiveAarDeps) resourceProcessorDeps() (args []string, deps android.Paths) { + for _, dep := range t { + args = append(args, "--library="+dep.rTxt.String()+","+dep.manifest.String()) + deps = append(deps, dep.rTxt, dep.manifest) + } + return args, deps +} + +func (t transitiveAarDeps) assets() android.Paths { + paths := make(android.Paths, 0, len(t)) + for _, dep := range t { + if dep.assets.Valid() { + paths = append(paths, dep.assets.Path()) + } + } + return paths } // aaptLibs collects libraries from dependencies and sdk_version and converts them into paths func aaptLibs(ctx android.ModuleContext, sdkContext android.SdkContext, classLoaderContexts dexpreopt.ClassLoaderContextMap) ( - transitiveStaticLibs, transitiveStaticLibManifests android.Paths, staticRRODirs []rroDir, assets, deps android.Paths, flags []string) { - - var sharedLibs android.Paths + staticResourcesNodes *android.DepSet[*resourcesNode], staticRRODirs *android.DepSet[rroDir], + staticManifests *android.DepSet[android.Path], sharedLibs android.Paths, flags []string) { if classLoaderContexts == nil { // Not all callers need to compute class loader context, those who don't just pass nil. @@ -447,6 +629,10 @@ func aaptLibs(ctx android.ModuleContext, sdkContext android.SdkContext, classLoa sharedLibs = append(sharedLibs, sdkDep.jars...) } + var resourcesNodeDepSets []*android.DepSet[*resourcesNode] + rroDirsDepSetBuilder := android.NewDepSetBuilder[rroDir](android.TOPOLOGICAL) + manifestsDepSetBuilder := android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL) + ctx.VisitDirectDeps(func(module android.Module) { depTag := ctx.OtherModuleDependencyTag(module) @@ -469,32 +655,28 @@ func aaptLibs(ctx android.ModuleContext, sdkContext android.SdkContext, classLoa } case staticLibTag: if exportPackage != nil { - transitiveStaticLibs = append(transitiveStaticLibs, aarDep.ExportedStaticPackages()...) - transitiveStaticLibs = append(transitiveStaticLibs, exportPackage) - transitiveStaticLibManifests = append(transitiveStaticLibManifests, aarDep.ExportedManifests()...) - if aarDep.ExportedAssets().Valid() { - assets = append(assets, aarDep.ExportedAssets().Path()) - } - - outer: - for _, d := range aarDep.ExportedRRODirs() { - for _, e := range staticRRODirs { - if d.path == e.path { - continue outer - } - } - staticRRODirs = append(staticRRODirs, d) - } + resourcesNodeDepSets = append(resourcesNodeDepSets, aarDep.ResourcesNodeDepSet()) + rroDirsDepSetBuilder.Transitive(aarDep.RRODirsDepSet()) + manifestsDepSetBuilder.Transitive(aarDep.ManifestsDepSet()) } } addCLCFromDep(ctx, module, classLoaderContexts) }) - deps = append(deps, sharedLibs...) - deps = append(deps, transitiveStaticLibs...) + // AAPT2 overlays are in lowest to highest priority order, the topological order will be reversed later. + // Reverse the dependency order now going into the depset so that it comes out in order after the second + // reverse later. + // NOTE: this is legacy and probably incorrect behavior, for most other cases (e.g. conflicting classes in + // dependencies) the highest priority dependency is listed first, but for resources the highest priority + // dependency has to be listed last. + staticResourcesNodes = android.NewDepSet(android.TOPOLOGICAL, nil, + android.ReverseSliceInPlace(resourcesNodeDepSets)) - if len(transitiveStaticLibs) > 0 { + staticRRODirs = rroDirsDepSetBuilder.Build() + staticManifests = manifestsDepSetBuilder.Build() + + if len(staticResourcesNodes.ToList()) > 0 { flags = append(flags, "--auto-add-overlay") } @@ -502,10 +684,7 @@ func aaptLibs(ctx android.ModuleContext, sdkContext android.SdkContext, classLoa flags = append(flags, "-I "+sharedLib.String()) } - transitiveStaticLibs = android.FirstUniquePaths(transitiveStaticLibs) - transitiveStaticLibManifests = android.FirstUniquePaths(transitiveStaticLibManifests) - - return transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, assets, deps, flags + return staticResourcesNodes, staticRRODirs, staticManifests, sharedLibs, flags } type AndroidLibrary struct { @@ -516,8 +695,6 @@ type AndroidLibrary struct { androidLibraryProperties androidLibraryProperties aarFile android.WritablePath - - exportedStaticPackages android.Paths } var _ android.OutputFileProducer = (*AndroidLibrary)(nil) @@ -532,10 +709,6 @@ func (a *AndroidLibrary) OutputFiles(tag string) (android.Paths, error) { } } -func (a *AndroidLibrary) ExportedStaticPackages() android.Paths { - return a.exportedStaticPackages -} - var _ AndroidLibraryDependency = (*AndroidLibrary)(nil) func (a *AndroidLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { @@ -554,9 +727,14 @@ func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) a.hideApexVariantFromMake = !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform() - ctx.CheckbuildFile(a.proguardOptionsFile) - ctx.CheckbuildFile(a.exportPackage) - ctx.CheckbuildFile(a.aaptSrcJar) + a.stem = proptools.StringDefault(a.overridableDeviceProperties.Stem, ctx.ModuleName()) + + ctx.CheckbuildFile(a.aapt.proguardOptionsFile) + ctx.CheckbuildFile(a.aapt.exportPackage) + ctx.CheckbuildFile(a.aapt.aaptSrcJar) + if a.useResourceProcessorBusyBox() { + ctx.CheckbuildFile(a.aapt.rJar) + } // apps manifests are handled by aapt, don't let Module see them a.properties.Manifest = nil @@ -568,7 +746,22 @@ func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles, a.proguardOptionsFile) - a.Module.compile(ctx, a.aaptSrcJar) + var extraSrcJars android.Paths + var extraCombinedJars android.Paths + var extraClasspathJars android.Paths + if a.useResourceProcessorBusyBox() { + // When building a library with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox for this + // library and each of the transitive static android_library dependencies has already created an + // R.class file for the appropriate package. Add all of those R.class files to the classpath. + extraClasspathJars = a.transitiveAaptRJars + } else { + // When building a library without ResourceProcessorBusyBox the aapt2 rule creates R.srcjar containing + // R.java files for the library's package and the packages from all transitive static android_library + // dependencies. Compile the srcjar alongside the rest of the sources. + extraSrcJars = android.Paths{a.aapt.aaptSrcJar} + } + + a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars) a.aarFile = android.PathForModuleOut(ctx, ctx.ModuleName()+".aar") var res android.Paths @@ -579,19 +772,15 @@ func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) a.exportedProguardFlagFiles = append(a.exportedProguardFlagFiles, android.PathsForModuleSrc(ctx, a.dexProperties.Optimize.Proguard_flags_files)...) + ctx.VisitDirectDeps(func(m android.Module) { if ctx.OtherModuleDependencyTag(m) == staticLibTag { if lib, ok := m.(LibraryDependency); ok { a.exportedProguardFlagFiles = append(a.exportedProguardFlagFiles, lib.ExportedProguardFlagFiles()...) } - if alib, ok := m.(AndroidLibraryDependency); ok { - a.exportedStaticPackages = append(a.exportedStaticPackages, alib.ExportPackage()) - a.exportedStaticPackages = append(a.exportedStaticPackages, alib.ExportedStaticPackages()...) - } } }) a.exportedProguardFlagFiles = android.FirstUniquePaths(a.exportedProguardFlagFiles) - a.exportedStaticPackages = android.FirstUniquePaths(a.exportedStaticPackages) prebuiltJniPackages := android.Paths{} ctx.VisitDirectDeps(func(module android.Module) { @@ -674,14 +863,18 @@ type AARImport struct { properties AARImportProperties - classpathFile android.WritablePath - proguardFlags android.WritablePath - exportPackage android.WritablePath - extraAaptPackagesFile android.WritablePath - manifest android.WritablePath - assetsPackage android.WritablePath + classpathFile android.WritablePath + proguardFlags android.WritablePath + exportPackage android.WritablePath + transitiveAaptResourcePackages android.Paths + extraAaptPackagesFile android.WritablePath + manifest android.WritablePath + assetsPackage android.WritablePath + rTxt android.WritablePath + rJar android.WritablePath - exportedStaticPackages android.Paths + resourcesNodesDepSet *android.DepSet[*resourcesNode] + manifestsDepSet *android.DepSet[android.Path] hideApexVariantFromMake bool @@ -738,25 +931,20 @@ var _ AndroidLibraryDependency = (*AARImport)(nil) func (a *AARImport) ExportPackage() android.Path { return a.exportPackage } - func (a *AARImport) ExportedProguardFlagFiles() android.Paths { return android.Paths{a.proguardFlags} } -func (a *AARImport) ExportedRRODirs() []rroDir { - return nil -} - -func (a *AARImport) ExportedStaticPackages() android.Paths { - return a.exportedStaticPackages +func (a *AARImport) ResourcesNodeDepSet() *android.DepSet[*resourcesNode] { + return a.resourcesNodesDepSet } -func (a *AARImport) ExportedManifests() android.Paths { - return android.Paths{a.manifest} +func (a *AARImport) RRODirsDepSet() *android.DepSet[rroDir] { + return android.NewDepSet[rroDir](android.TOPOLOGICAL, nil, nil) } -func (a *AARImport) ExportedAssets() android.OptionalPath { - return android.OptionalPathForPath(a.assetsPackage) +func (a *AARImport) ManifestsDepSet() *android.DepSet[android.Path] { + return a.manifestsDepSet } // RRO enforcement is not available on aar_import since its RRO dirs are not @@ -852,12 +1040,13 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.classpathFile = extractedAARDir.Join(ctx, "classes-combined.jar") a.proguardFlags = extractedAARDir.Join(ctx, "proguard.txt") a.manifest = extractedAARDir.Join(ctx, "AndroidManifest.xml") + aarRTxt := extractedAARDir.Join(ctx, "R.txt") a.assetsPackage = android.PathForModuleOut(ctx, "assets.zip") ctx.Build(pctx, android.BuildParams{ Rule: unzipAAR, Input: a.aarPath, - Outputs: android.WritablePaths{a.classpathFile, a.proguardFlags, a.manifest, a.assetsPackage}, + Outputs: android.WritablePaths{a.classpathFile, a.proguardFlags, a.manifest, a.assetsPackage, aarRTxt}, Description: "unzip AAR", Args: map[string]string{ "outDir": extractedAARDir.String(), @@ -877,46 +1066,70 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { // the subdir "android" is required to be filtered by package names srcJar := android.PathForModuleGen(ctx, "android", "R.srcjar") proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options") - rTxt := android.PathForModuleOut(ctx, "R.txt") + a.rTxt = android.PathForModuleOut(ctx, "R.txt") a.extraAaptPackagesFile = android.PathForModuleOut(ctx, "extra_packages") var linkDeps android.Paths linkFlags := []string{ "--static-lib", - "--no-static-lib-packages", + "--merge-only", "--auto-add-overlay", } linkFlags = append(linkFlags, "--manifest "+a.manifest.String()) linkDeps = append(linkDeps, a.manifest) - transitiveStaticLibs, staticLibManifests, staticRRODirs, transitiveAssets, libDeps, libFlags := + staticResourcesNodesDepSet, staticRRODirsDepSet, staticManifestsDepSet, sharedLibs, libFlags := aaptLibs(ctx, android.SdkContext(a), nil) - _ = staticLibManifests - _ = staticRRODirs + _ = staticRRODirsDepSet + staticDeps := transitiveAarDeps(staticResourcesNodesDepSet.ToList()) - linkDeps = append(linkDeps, libDeps...) + linkDeps = append(linkDeps, sharedLibs...) + linkDeps = append(linkDeps, staticDeps.resPackages()...) linkFlags = append(linkFlags, libFlags...) - overlayRes := append(android.Paths{flata}, transitiveStaticLibs...) + overlayRes := android.Paths{flata} - aapt2Link(ctx, a.exportPackage, srcJar, proguardOptionsFile, rTxt, a.extraAaptPackagesFile, + // Treat static library dependencies of static libraries as imports. + transitiveStaticLibs := staticDeps.resPackages() + linkDeps = append(linkDeps, transitiveStaticLibs...) + for _, staticLib := range transitiveStaticLibs { + linkFlags = append(linkFlags, "-I "+staticLib.String()) + } + + transitiveAssets := android.ReverseSliceInPlace(staticDeps.assets()) + aapt2Link(ctx, a.exportPackage, srcJar, proguardOptionsFile, a.rTxt, a.extraAaptPackagesFile, linkFlags, linkDeps, nil, overlayRes, transitiveAssets, nil) - // Merge this import's assets with its dependencies' assets (if there are any). - if len(transitiveAssets) > 0 { - mergedAssets := android.PathForModuleOut(ctx, "merged-assets.zip") - inputZips := append(android.Paths{a.assetsPackage}, transitiveAssets...) - ctx.Build(pctx, android.BuildParams{ - Rule: mergeAssetsRule, - Inputs: inputZips, - Output: mergedAssets, - Description: "merge assets from dependencies and self", - }) - a.assetsPackage = mergedAssets - } + a.rJar = android.PathForModuleOut(ctx, "busybox/R.jar") + resourceProcessorBusyBoxGenerateBinaryR(ctx, a.rTxt, a.manifest, a.rJar, nil, true) + + resourcesNodesDepSetBuilder := android.NewDepSetBuilder[*resourcesNode](android.TOPOLOGICAL) + resourcesNodesDepSetBuilder.Direct(&resourcesNode{ + resPackage: a.exportPackage, + manifest: a.manifest, + rTxt: a.rTxt, + rJar: a.rJar, + assets: android.OptionalPathForPath(a.assetsPackage), + + usedResourceProcessor: true, + }) + resourcesNodesDepSetBuilder.Transitive(staticResourcesNodesDepSet) + a.resourcesNodesDepSet = resourcesNodesDepSetBuilder.Build() + + manifestDepSetBuilder := android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL).Direct(a.manifest) + // TODO(b/288358614): Soong has historically not merged manifests from dependencies of android_library_import + // modules. Merging manifests from dependencies could remove the need for pom2bp to generate the "-nodeps" copies + // of androidx libraries, but doing so triggers errors due to errors introduced by existing dependencies of + // android_library_import modules. If this is fixed, AndroidLibraryDependency.ManifestsDepSet can be dropped + // completely in favor of AndroidLibraryDependency.ResourceNodesDepSet.manifest + //manifestDepSetBuilder.Transitive(transitiveStaticDeps.manifests) + _ = staticManifestsDepSet + a.manifestsDepSet = manifestDepSetBuilder.Build() + + a.transitiveAaptResourcePackages = staticDeps.resPackages() a.collectTransitiveHeaderJars(ctx) ctx.SetProvider(JavaInfoProvider, JavaInfo{ @@ -925,6 +1138,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { TransitiveStaticLibsHeaderJars: a.transitiveStaticLibsHeaderJars, ImplementationAndResourcesJars: android.PathsIfNonNil(a.classpathFile), ImplementationJars: android.PathsIfNonNil(a.classpathFile), + // TransitiveAconfigFiles: // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts }) if proptools.Bool(a.properties.Extract_jni) { diff --git a/java/android_manifest_test.go b/java/android_manifest_test.go new file mode 100644 index 000000000..b12d77896 --- /dev/null +++ b/java/android_manifest_test.go @@ -0,0 +1,103 @@ +// Copyright 2023 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 java + +import ( + "android/soong/android" + "testing" +) + +func TestManifestMerger(t *testing.T) { + bp := ` + android_app { + name: "app", + sdk_version: "current", + srcs: ["app/app.java"], + resource_dirs: ["app/res"], + manifest: "app/AndroidManifest.xml", + additional_manifests: ["app/AndroidManifest2.xml"], + static_libs: ["direct", "direct_import"], + } + + android_library { + name: "direct", + sdk_version: "current", + srcs: ["direct/direct.java"], + resource_dirs: ["direct/res"], + manifest: "direct/AndroidManifest.xml", + additional_manifests: ["direct/AndroidManifest2.xml"], + static_libs: ["transitive", "transitive_import"], + } + + android_library { + name: "transitive", + sdk_version: "current", + srcs: ["transitive/transitive.java"], + resource_dirs: ["transitive/res"], + manifest: "transitive/AndroidManifest.xml", + additional_manifests: ["transitive/AndroidManifest2.xml"], + } + + android_library_import { + name: "direct_import", + sdk_version: "current", + aars: ["direct_import.aar"], + static_libs: ["direct_import_dep"], + } + + android_library_import { + name: "direct_import_dep", + sdk_version: "current", + aars: ["direct_import_dep.aar"], + } + + android_library_import { + name: "transitive_import", + sdk_version: "current", + aars: ["transitive_import.aar"], + static_libs: ["transitive_import_dep"], + } + + android_library_import { + name: "transitive_import_dep", + sdk_version: "current", + aars: ["transitive_import_dep.aar"], + } + ` + + result := android.GroupFixturePreparers( + PrepareForTestWithJavaDefaultModules, + PrepareForTestWithOverlayBuildComponents, + ).RunTestWithBp(t, bp) + + manifestMergerRule := result.ModuleForTests("app", "android_common").Rule("manifestMerger") + android.AssertPathRelativeToTopEquals(t, "main manifest", + "out/soong/.intermediates/app/android_common/manifest_fixer/AndroidManifest.xml", + manifestMergerRule.Input) + android.AssertPathsRelativeToTopEquals(t, "lib manifests", + []string{ + "app/AndroidManifest2.xml", + "out/soong/.intermediates/direct/android_common/manifest_fixer/AndroidManifest.xml", + "direct/AndroidManifest2.xml", + "out/soong/.intermediates/transitive/android_common/manifest_fixer/AndroidManifest.xml", + "transitive/AndroidManifest2.xml", + "out/soong/.intermediates/transitive_import/android_common/aar/AndroidManifest.xml", + "out/soong/.intermediates/direct_import/android_common/aar/AndroidManifest.xml", + // TODO(b/288358614): Soong has historically not merged manifests from dependencies of + // android_library_import modules. + + }, + manifestMergerRule.Implicits) +} diff --git a/java/androidmk.go b/java/androidmk.go index 9c21633fb..82505e9e3 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -123,6 +123,8 @@ func (library *Library) AndroidMkEntries() []android.AndroidMkEntries { if library.dexpreopter.configPath != nil { entries.SetPath("LOCAL_SOONG_DEXPREOPT_CONFIG", library.dexpreopter.configPath) } + + entries.SetOptionalPaths("LOCAL_ACONFIG_FILES", library.getTransitiveAconfigFiles().ToList()) }, }, }) @@ -220,6 +222,7 @@ func (prebuilt *Import) AndroidMkEntries() []android.AndroidMkEntries { entries.SetPath("LOCAL_SOONG_CLASSES_JAR", prebuilt.combinedClasspathFile) entries.SetString("LOCAL_SDK_VERSION", prebuilt.sdkVersion.String()) entries.SetString("LOCAL_MODULE_STEM", prebuilt.Stem()) + // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts }, }, }} @@ -244,6 +247,7 @@ func (prebuilt *DexImport) AndroidMkEntries() []android.AndroidMkEntries { entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", prebuilt.dexpreopter.builtInstalled) } entries.SetString("LOCAL_MODULE_STEM", prebuilt.Stem()) + // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts }, }, }} @@ -265,10 +269,12 @@ func (prebuilt *AARImport) AndroidMkEntries() []android.AndroidMkEntries { entries.SetPath("LOCAL_SOONG_HEADER_JAR", prebuilt.classpathFile) entries.SetPath("LOCAL_SOONG_CLASSES_JAR", prebuilt.classpathFile) entries.SetPath("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE", prebuilt.exportPackage) + entries.SetPaths("LOCAL_SOONG_TRANSITIVE_RES_PACKAGES", prebuilt.transitiveAaptResourcePackages) entries.SetPath("LOCAL_SOONG_EXPORT_PROGUARD_FLAGS", prebuilt.proguardFlags) entries.SetPath("LOCAL_SOONG_STATIC_LIBRARY_EXTRA_PACKAGES", prebuilt.extraAaptPackagesFile) entries.SetPath("LOCAL_FULL_MANIFEST_FILE", prebuilt.manifest) entries.SetString("LOCAL_SDK_VERSION", prebuilt.sdkVersion.String()) + // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts }, }, }} @@ -295,6 +301,7 @@ func (binary *Binary) AndroidMkEntries() []android.AndroidMkEntries { if len(binary.dexpreopter.builtInstalled) > 0 { entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", binary.dexpreopter.builtInstalled) } + entries.SetOptionalPaths("LOCAL_ACONFIG_FILES", binary.getTransitiveAconfigFiles().ToList()) }, }, ExtraFooters: []android.AndroidMkExtraFootersFunc{ @@ -340,6 +347,9 @@ func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries { // App module names can be overridden. entries.SetString("LOCAL_MODULE", app.installApkName) entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", app.appProperties.PreventInstall) + if app.headerJarFile != nil { + entries.SetPath("LOCAL_SOONG_HEADER_JAR", app.headerJarFile) + } entries.SetPath("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE", app.exportPackage) if app.dexJarFile.IsSet() { entries.SetPath("LOCAL_SOONG_DEX_JAR", app.dexJarFile.Path()) @@ -368,8 +378,13 @@ func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries { filterRRO := func(filter overlayType) android.Paths { var paths android.Paths - for _, d := range app.rroDirs { + seen := make(map[android.Path]bool) + for _, d := range app.rroDirsDepSet.ToList() { if d.overlayType == filter { + if seen[d.path] { + continue + } + seen[d.path] = true paths = append(paths, d.path) } } @@ -432,6 +447,10 @@ func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries { } entries.SetOptionalPaths("LOCAL_SOONG_LINT_REPORTS", app.linter.reports) + + if app.Name() != "framework-res" { + entries.SetOptionalPaths("LOCAL_ACONFIG_FILES", app.getTransitiveAconfigFiles().ToList()) + } }, }, ExtraFooters: []android.AndroidMkExtraFootersFunc{ @@ -450,11 +469,6 @@ func (a *AndroidApp) getOverriddenPackages() []string { if len(a.overridableAppProperties.Overrides) > 0 { overridden = append(overridden, a.overridableAppProperties.Overrides...) } - // When APK name is overridden via PRODUCT_PACKAGE_NAME_OVERRIDES - // ensure that the original name is overridden. - if a.Stem() != a.installApkName { - overridden = append(overridden, a.Stem()) - } return overridden } @@ -508,10 +522,12 @@ func (a *AndroidLibrary) AndroidMkEntries() []android.AndroidMkEntries { } entries.SetPath("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE", a.exportPackage) + entries.SetPaths("LOCAL_SOONG_TRANSITIVE_RES_PACKAGES", a.transitiveAaptResourcePackages) entries.SetPath("LOCAL_SOONG_STATIC_LIBRARY_EXTRA_PACKAGES", a.extraAaptPackagesFile) entries.SetPath("LOCAL_FULL_MANIFEST_FILE", a.mergedManifestFile) entries.AddStrings("LOCAL_SOONG_EXPORT_PROGUARD_FLAGS", a.exportedProguardFlagFiles.Strings()...) entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", true) + entries.SetOptionalPaths("LOCAL_ACONFIG_FILES", a.getTransitiveAconfigFiles().ToList()) }) return entriesList @@ -684,6 +700,7 @@ func (a *AndroidAppImport) AndroidMkEntries() []android.AndroidMkEntries { if Bool(a.properties.Export_package_resources) { entries.SetPath("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE", a.outputFile) } + // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts }, }, }} @@ -717,6 +734,7 @@ func (r *RuntimeResourceOverlay) AndroidMkEntries() []android.AndroidMkEntries { entries.SetString("LOCAL_CERTIFICATE", r.certificate.AndroidMkString()) entries.SetPath("LOCAL_MODULE_PATH", r.installDir) entries.AddStrings("LOCAL_OVERRIDES_PACKAGES", r.properties.Overrides...) + // TODO: LOCAL_ACONFIG_FILES -- Might eventually need aconfig flags? }, }, }} @@ -734,6 +752,7 @@ func (apkSet *AndroidAppSet) AndroidMkEntries() []android.AndroidMkEntries { entries.SetPath("LOCAL_APK_SET_INSTALL_FILE", apkSet.PackedAdditionalOutputs()) entries.SetPath("LOCAL_APKCERTS_FILE", apkSet.apkcertsFile) entries.AddStrings("LOCAL_OVERRIDES_PACKAGES", apkSet.properties.Overrides...) + // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts -- Both declarations and values }, }, }, diff --git a/java/app.go b/java/app.go index d9272e4fc..224bc8867 100755 --- a/java/app.go +++ b/java/app.go @@ -204,8 +204,8 @@ func (a *AndroidApp) ExportedProguardFlagFiles() android.Paths { return nil } -func (a *AndroidApp) ExportedStaticPackages() android.Paths { - return nil +func (a *AndroidApp) ResourcesNodeDepSet() *android.DepSet[*resourcesNode] { + return a.aapt.resourcesNodesDepSet } func (a *AndroidApp) OutputFile() android.Path { @@ -521,7 +521,23 @@ func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path { a.dexpreopter.preventInstall = a.appProperties.PreventInstall if ctx.ModuleName() != "framework-res" { - a.Module.compile(ctx, a.aaptSrcJar) + var extraSrcJars android.Paths + var extraClasspathJars android.Paths + var extraCombinedJars android.Paths + if a.useResourceProcessorBusyBox() { + // When building an app with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox has already + // created R.class files that provide IDs for resources in busybox/R.jar. Pass that file in the + // classpath when compiling everything else, and add it to the final classes jar. + extraClasspathJars = android.Paths{a.aapt.rJar} + extraCombinedJars = android.Paths{a.aapt.rJar} + } else { + // When building an app without ResourceProcessorBusyBox the aapt2 rule creates R.srcjar containing + // R.java files for the app's package and the packages from all transitive static android_library + // dependencies. Compile the srcjar alongside the rest of the sources. + extraSrcJars = android.Paths{a.aapt.aaptSrcJar} + } + + a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars) } return a.dexJarFile.PathOrNil() @@ -666,8 +682,17 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx) a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex) + // Unlike installApkName, a.stem should respect base module name for override_android_app. + // Therefore, use ctx.ModuleName() instead of a.Name(). + a.stem = proptools.StringDefault(a.overridableDeviceProperties.Stem, ctx.ModuleName()) + // Check if the install APK name needs to be overridden. - a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(a.Stem()) + // Both android_app and override_android_app module are expected to possess + // its module bound apk path. However, override_android_app inherits ctx.ModuleName() + // from the base module. Therefore, use a.Name() which represents + // the module name for both android_app and override_android_app. + a.installApkName = ctx.DeviceConfig().OverridePackageNameFor( + proptools.StringDefault(a.overridableDeviceProperties.Stem, a.Name())) if ctx.ModuleName() == "framework-res" { // framework-res.apk is installed as system/framework/framework-res.apk @@ -1571,7 +1596,9 @@ func androidAppCertificateBp2Build(ctx android.TopDownMutatorContext, module *An } type manifestValueAttribute struct { - MinSdkVersion *string + MinSdkVersion *string + MaxSdkVersion *string + TargetSdkVersion *string } type bazelAndroidAppAttributes struct { @@ -1601,12 +1628,25 @@ func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) { // MinSdkVersion(ctx) calls SdkVersion(ctx) if no value for min_sdk_version is set minSdkVersion := a.MinSdkVersion(ctx) if !minSdkVersion.IsPreview() && !minSdkVersion.IsInvalid() { - minSdkStr, err := minSdkVersion.EffectiveVersionString(ctx) - if err == nil { + if minSdkStr, err := minSdkVersion.EffectiveVersionString(ctx); err == nil { manifestValues.MinSdkVersion = &minSdkStr } } + maxSdkVersion := a.MaxSdkVersion(ctx) + if !maxSdkVersion.IsPreview() && !maxSdkVersion.IsInvalid() { + if maxSdkStr, err := maxSdkVersion.EffectiveVersionString(ctx); err == nil { + manifestValues.MaxSdkVersion = &maxSdkStr + } + } + + targetSdkVersion := a.TargetSdkVersion(ctx) + if !targetSdkVersion.IsPreview() && !targetSdkVersion.IsInvalid() { + if targetSdkStr, err := targetSdkVersion.EffectiveVersionString(ctx); err == nil { + manifestValues.TargetSdkVersion = &targetSdkStr + } + } + appAttrs := &bazelAndroidAppAttributes{ // TODO(b/209576404): handle package name override by product variable PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES Custom_package: a.overridableAppProperties.Package_name, diff --git a/java/app_import.go b/java/app_import.go index 842721728..ad1765e9d 100644 --- a/java/app_import.go +++ b/java/app_import.go @@ -51,9 +51,9 @@ var ( Description: "Uncompress dex files", }) - checkJniAndDexLibsAreUncompressedRule = pctx.AndroidStaticRule("check-jni-and-dex-libs-are-uncompressed", blueprint.RuleParams{ + checkDexLibsAreUncompressedRule = pctx.AndroidStaticRule("check-dex-libs-are-uncompressed", blueprint.RuleParams{ // grep -v ' stor ' will search for lines that don't have ' stor '. stor means the file is stored uncompressed - Command: "if (zipinfo $in 'lib/*.so' '*.dex' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then " + + Command: "if (zipinfo $in '*.dex' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then " + "echo $in: Contains compressed JNI libraries and/or dex files >&2;" + "exit 1; " + "else " + @@ -61,6 +61,17 @@ var ( "fi", Description: "Check for compressed JNI libs or dex files", }) + + checkJniLibsAreUncompressedRule = pctx.AndroidStaticRule("check-jni-libs-are-uncompressed", blueprint.RuleParams{ + // grep -v ' stor ' will search for lines that don't have ' stor '. stor means the file is stored uncompressed + Command: "if (zipinfo $in 'lib/*.so' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then " + + "echo $in: Contains compressed JNI libraries >&2;" + + "exit 1; " + + "else " + + "touch $out; " + + "fi", + Description: "Check for compressed JNI libs or dex files", + }) ) func RegisterAppImportBuildComponents(ctx android.RegistrationContext) { @@ -335,11 +346,19 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext // Sign or align the package if package has not been preprocessed if proptools.Bool(a.properties.Preprocessed) { - output := srcApk + var output android.WritablePath if !proptools.Bool(a.properties.Skip_preprocessed_apk_checks) { - writableOutput := android.PathForModuleOut(ctx, "validated-prebuilt", apkFilename) - a.validatePreprocessedApk(ctx, srcApk, writableOutput) - output = writableOutput + output = android.PathForModuleOut(ctx, "validated-prebuilt", apkFilename) + a.validatePreprocessedApk(ctx, srcApk, output) + } else { + // If using the input APK unmodified, still make a copy of it so that the output filename has the + // right basename. + output = android.PathForModuleOut(ctx, apkFilename) + ctx.Build(pctx, android.BuildParams{ + Rule: android.Cp, + Input: srcApk, + Output: output, + }) } a.outputFile = output a.certificate = PresignedCertificate @@ -376,26 +395,40 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext } func (a *AndroidAppImport) validatePreprocessedApk(ctx android.ModuleContext, srcApk android.Path, dstApk android.WritablePath) { + var validations android.Paths + alignmentStamp := android.PathForModuleOut(ctx, "validated-prebuilt", "alignment.stamp") ctx.Build(pctx, android.BuildParams{ Rule: checkZipAlignment, Input: srcApk, Output: alignmentStamp, }) - compressionStamp := android.PathForModuleOut(ctx, "validated-prebuilt", "compression.stamp") + + validations = append(validations, alignmentStamp) + jniCompressionStamp := android.PathForModuleOut(ctx, "validated-prebuilt", "jni_compression.stamp") ctx.Build(pctx, android.BuildParams{ - Rule: checkJniAndDexLibsAreUncompressedRule, + Rule: checkJniLibsAreUncompressedRule, Input: srcApk, - Output: compressionStamp, + Output: jniCompressionStamp, }) + validations = append(validations, jniCompressionStamp) + + if a.Privileged() { + // It's ok for non-privileged apps to have compressed dex files, see go/gms-uncompressed-jni-slides + dexCompressionStamp := android.PathForModuleOut(ctx, "validated-prebuilt", "dex_compression.stamp") + ctx.Build(pctx, android.BuildParams{ + Rule: checkDexLibsAreUncompressedRule, + Input: srcApk, + Output: dexCompressionStamp, + }) + validations = append(validations, dexCompressionStamp) + } + ctx.Build(pctx, android.BuildParams{ - Rule: android.Cp, - Input: srcApk, - Output: dstApk, - Validations: []android.Path{ - alignmentStamp, - compressionStamp, - }, + Rule: android.Cp, + Input: srcApk, + Output: dstApk, + Validations: validations, }) } diff --git a/java/app_test.go b/java/app_test.go index 0f98416d2..4627ff6fc 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -599,7 +599,7 @@ func TestLibraryAssets(t *testing.T) { android_library { name: "lib3", sdk_version: "current", - static_libs: ["lib4"], + static_libs: ["lib4", "import"], } android_library { @@ -607,6 +607,12 @@ func TestLibraryAssets(t *testing.T) { sdk_version: "current", asset_dirs: ["assets_b"], } + + android_library_import { + name: "import", + sdk_version: "current", + aars: ["import.aar"], + } ` testCases := []struct { @@ -616,11 +622,12 @@ func TestLibraryAssets(t *testing.T) { }{ { name: "foo", - // lib1 has its own asset. lib3 doesn't have any, but provides lib4's transitively. + // lib1 has its own assets. lib3 doesn't have any, but lib4 and import have assets. assetPackages: []string{ "out/soong/.intermediates/foo/android_common/aapt2/package-res.apk", "out/soong/.intermediates/lib1/android_common/assets.zip", - "out/soong/.intermediates/lib3/android_common/assets.zip", + "out/soong/.intermediates/lib4/android_common/assets.zip", + "out/soong/.intermediates/import/android_common/assets.zip", }, }, { @@ -632,10 +639,6 @@ func TestLibraryAssets(t *testing.T) { }, { name: "lib3", - assetPackages: []string{ - "out/soong/.intermediates/lib3/android_common/aapt2/package-res.apk", - "out/soong/.intermediates/lib4/android_common/assets.zip", - }, }, { name: "lib4", @@ -717,7 +720,514 @@ func TestAppJavaResources(t *testing.T) { } } -func TestAndroidResources(t *testing.T) { +func TestAndroidResourceProcessor(t *testing.T) { + testCases := []struct { + name string + appUsesRP bool + directLibUsesRP bool + transitiveLibUsesRP bool + + dontVerifyApp bool + appResources []string + appOverlays []string + appImports []string + appSrcJars []string + appClasspath []string + appCombined []string + + dontVerifyDirect bool + directResources []string + directOverlays []string + directImports []string + directSrcJars []string + directClasspath []string + directCombined []string + + dontVerifyTransitive bool + transitiveResources []string + transitiveOverlays []string + transitiveImports []string + transitiveSrcJars []string + transitiveClasspath []string + transitiveCombined []string + + dontVerifyDirectImport bool + directImportResources []string + directImportOverlays []string + directImportImports []string + + dontVerifyTransitiveImport bool + transitiveImportResources []string + transitiveImportOverlays []string + transitiveImportImports []string + }{ + { + // Test with all modules set to use_resource_processor: false (except android_library_import modules, + // which always use resource processor). + name: "legacy", + appUsesRP: false, + directLibUsesRP: false, + transitiveLibUsesRP: false, + + appResources: nil, + appOverlays: []string{ + "out/soong/.intermediates/transitive/android_common/package-res.apk", + "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk", + "out/soong/.intermediates/transitive_import/android_common/package-res.apk", + "out/soong/.intermediates/direct/android_common/package-res.apk", + "out/soong/.intermediates/direct_import_dep/android_common/package-res.apk", + "out/soong/.intermediates/direct_import/android_common/package-res.apk", + "out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat", + }, + appImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"}, + appSrcJars: []string{"out/soong/.intermediates/app/android_common/gen/android/R.srcjar"}, + appClasspath: []string{ + "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", + "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar", + "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar", + }, + appCombined: []string{ + "out/soong/.intermediates/app/android_common/javac/app.jar", + "out/soong/.intermediates/direct/android_common/combined/direct.jar", + "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar", + }, + + directResources: nil, + directOverlays: []string{ + "out/soong/.intermediates/transitive/android_common/package-res.apk", + "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk", + "out/soong/.intermediates/transitive_import/android_common/package-res.apk", + "out/soong/.intermediates/direct/android_common/aapt2/direct/res/values_strings.arsc.flat", + }, + directImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"}, + directSrcJars: []string{"out/soong/.intermediates/direct/android_common/gen/android/R.srcjar"}, + directClasspath: []string{ + "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", + "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar", + "out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar", + }, + directCombined: []string{ + "out/soong/.intermediates/direct/android_common/javac/direct.jar", + "out/soong/.intermediates/transitive/android_common/javac/transitive.jar", + "out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar", + }, + + transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"}, + transitiveOverlays: nil, + transitiveImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"}, + transitiveSrcJars: []string{"out/soong/.intermediates/transitive/android_common/gen/android/R.srcjar"}, + transitiveClasspath: []string{"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar"}, + transitiveCombined: nil, + + directImportResources: nil, + directImportOverlays: []string{"out/soong/.intermediates/direct_import/android_common/flat-res/gen_res.flata"}, + directImportImports: []string{ + "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk", + "out/soong/.intermediates/direct_import_dep/android_common/package-res.apk", + }, + + transitiveImportResources: nil, + transitiveImportOverlays: []string{"out/soong/.intermediates/transitive_import/android_common/flat-res/gen_res.flata"}, + transitiveImportImports: []string{ + "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk", + "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk", + }, + }, + { + // Test with all modules set to use_resource_processor: true. + name: "resource_processor", + appUsesRP: true, + directLibUsesRP: true, + transitiveLibUsesRP: true, + + appResources: nil, + appOverlays: []string{ + "out/soong/.intermediates/transitive/android_common/package-res.apk", + "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk", + "out/soong/.intermediates/transitive_import/android_common/package-res.apk", + "out/soong/.intermediates/direct/android_common/package-res.apk", + "out/soong/.intermediates/direct_import_dep/android_common/package-res.apk", + "out/soong/.intermediates/direct_import/android_common/package-res.apk", + "out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat", + }, + appImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"}, + appSrcJars: nil, + appClasspath: []string{ + "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", + "out/soong/.intermediates/app/android_common/busybox/R.jar", + "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar", + "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar", + }, + appCombined: []string{ + "out/soong/.intermediates/app/android_common/busybox/R.jar", + "out/soong/.intermediates/app/android_common/javac/app.jar", + "out/soong/.intermediates/direct/android_common/combined/direct.jar", + "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar", + }, + + directResources: nil, + directOverlays: []string{"out/soong/.intermediates/direct/android_common/aapt2/direct/res/values_strings.arsc.flat"}, + directImports: []string{ + "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk", + "out/soong/.intermediates/transitive_import/android_common/package-res.apk", + "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk", + "out/soong/.intermediates/transitive/android_common/package-res.apk", + }, + directSrcJars: nil, + directClasspath: []string{ + "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", + "out/soong/.intermediates/transitive_import/android_common/busybox/R.jar", + "out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar", + "out/soong/.intermediates/transitive/android_common/busybox/R.jar", + "out/soong/.intermediates/direct/android_common/busybox/R.jar", + "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar", + "out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar", + }, + directCombined: []string{ + "out/soong/.intermediates/direct/android_common/javac/direct.jar", + "out/soong/.intermediates/transitive/android_common/javac/transitive.jar", + "out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar", + }, + + transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"}, + transitiveOverlays: nil, + transitiveImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"}, + transitiveSrcJars: nil, + transitiveClasspath: []string{ + "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", + "out/soong/.intermediates/transitive/android_common/busybox/R.jar", + }, + transitiveCombined: nil, + + directImportResources: nil, + directImportOverlays: []string{"out/soong/.intermediates/direct_import/android_common/flat-res/gen_res.flata"}, + directImportImports: []string{ + "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk", + "out/soong/.intermediates/direct_import_dep/android_common/package-res.apk", + }, + + transitiveImportResources: nil, + transitiveImportOverlays: []string{"out/soong/.intermediates/transitive_import/android_common/flat-res/gen_res.flata"}, + transitiveImportImports: []string{ + "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk", + "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk", + }, + }, { + // Test an app building with resource processor enabled but with dependencies built without + // resource processor. + name: "app_resource_processor", + appUsesRP: true, + directLibUsesRP: false, + transitiveLibUsesRP: false, + + appResources: nil, + appOverlays: []string{ + "out/soong/.intermediates/transitive/android_common/package-res.apk", + "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk", + "out/soong/.intermediates/transitive_import/android_common/package-res.apk", + "out/soong/.intermediates/direct/android_common/package-res.apk", + "out/soong/.intermediates/direct_import_dep/android_common/package-res.apk", + "out/soong/.intermediates/direct_import/android_common/package-res.apk", + "out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat", + }, + appImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"}, + appSrcJars: nil, + appClasspath: []string{ + "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", + // R.jar has to come before direct.jar + "out/soong/.intermediates/app/android_common/busybox/R.jar", + "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar", + "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar", + }, + appCombined: []string{ + "out/soong/.intermediates/app/android_common/busybox/R.jar", + "out/soong/.intermediates/app/android_common/javac/app.jar", + "out/soong/.intermediates/direct/android_common/combined/direct.jar", + "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar", + }, + + dontVerifyDirect: true, + dontVerifyTransitive: true, + dontVerifyDirectImport: true, + dontVerifyTransitiveImport: true, + }, + { + // Test an app building without resource processor enabled but with a dependency built with + // resource processor. + name: "app_dependency_lib_resource_processor", + appUsesRP: false, + directLibUsesRP: true, + transitiveLibUsesRP: false, + + appOverlays: []string{ + "out/soong/.intermediates/transitive/android_common/package-res.apk", + "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk", + "out/soong/.intermediates/transitive_import/android_common/package-res.apk", + "out/soong/.intermediates/direct/android_common/package-res.apk", + "out/soong/.intermediates/direct_import_dep/android_common/package-res.apk", + "out/soong/.intermediates/direct_import/android_common/package-res.apk", + "out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat", + }, + appImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"}, + appSrcJars: []string{"out/soong/.intermediates/app/android_common/gen/android/R.srcjar"}, + appClasspath: []string{ + "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", + "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar", + "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar", + }, + appCombined: []string{ + "out/soong/.intermediates/app/android_common/javac/app.jar", + "out/soong/.intermediates/direct/android_common/combined/direct.jar", + "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar", + }, + + directResources: nil, + directOverlays: []string{"out/soong/.intermediates/direct/android_common/aapt2/direct/res/values_strings.arsc.flat"}, + directImports: []string{ + "out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk", + "out/soong/.intermediates/transitive_import/android_common/package-res.apk", + "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk", + "out/soong/.intermediates/transitive/android_common/package-res.apk", + }, + directSrcJars: nil, + directClasspath: []string{ + "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", + "out/soong/.intermediates/transitive_import/android_common/busybox/R.jar", + "out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar", + "out/soong/.intermediates/direct/android_common/busybox/R.jar", + "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar", + "out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar", + }, + directCombined: []string{ + "out/soong/.intermediates/direct/android_common/javac/direct.jar", + "out/soong/.intermediates/transitive/android_common/javac/transitive.jar", + "out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar", + }, + + dontVerifyTransitive: true, + dontVerifyDirectImport: true, + dontVerifyTransitiveImport: true, + }, + { + // Test a library building without resource processor enabled but with a dependency built with + // resource processor. + name: "lib_dependency_lib_resource_processor", + appUsesRP: false, + directLibUsesRP: false, + transitiveLibUsesRP: true, + + appOverlays: []string{ + "out/soong/.intermediates/transitive/android_common/package-res.apk", + "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk", + "out/soong/.intermediates/transitive_import/android_common/package-res.apk", + "out/soong/.intermediates/direct/android_common/package-res.apk", + "out/soong/.intermediates/direct_import_dep/android_common/package-res.apk", + "out/soong/.intermediates/direct_import/android_common/package-res.apk", + "out/soong/.intermediates/app/android_common/aapt2/app/res/values_strings.arsc.flat", + }, + appImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"}, + appSrcJars: []string{"out/soong/.intermediates/app/android_common/gen/android/R.srcjar"}, + appClasspath: []string{ + "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", + "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar", + "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar", + }, + appCombined: []string{ + "out/soong/.intermediates/app/android_common/javac/app.jar", + "out/soong/.intermediates/direct/android_common/combined/direct.jar", + "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar", + }, + + directResources: nil, + directOverlays: []string{ + "out/soong/.intermediates/transitive/android_common/package-res.apk", + "out/soong/.intermediates/transitive_import_dep/android_common/package-res.apk", + "out/soong/.intermediates/transitive_import/android_common/package-res.apk", + "out/soong/.intermediates/direct/android_common/aapt2/direct/res/values_strings.arsc.flat", + }, + directImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"}, + directSrcJars: []string{"out/soong/.intermediates/direct/android_common/gen/android/R.srcjar"}, + directClasspath: []string{ + "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", + "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar", + "out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar", + }, + directCombined: []string{ + "out/soong/.intermediates/direct/android_common/javac/direct.jar", + "out/soong/.intermediates/transitive/android_common/javac/transitive.jar", + "out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar", + }, + + transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"}, + transitiveOverlays: nil, + transitiveImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"}, + transitiveSrcJars: nil, + transitiveClasspath: []string{ + "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", + "out/soong/.intermediates/transitive/android_common/busybox/R.jar", + }, + transitiveCombined: nil, + + dontVerifyDirectImport: true, + dontVerifyTransitiveImport: true, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + bp := fmt.Sprintf(` + android_app { + name: "app", + sdk_version: "current", + srcs: ["app/app.java"], + resource_dirs: ["app/res"], + manifest: "app/AndroidManifest.xml", + static_libs: ["direct", "direct_import"], + use_resource_processor: %v, + } + + android_library { + name: "direct", + sdk_version: "current", + srcs: ["direct/direct.java"], + resource_dirs: ["direct/res"], + manifest: "direct/AndroidManifest.xml", + static_libs: ["transitive", "transitive_import"], + use_resource_processor: %v, + } + + android_library { + name: "transitive", + sdk_version: "current", + srcs: ["transitive/transitive.java"], + resource_dirs: ["transitive/res"], + manifest: "transitive/AndroidManifest.xml", + use_resource_processor: %v, + } + + android_library_import { + name: "direct_import", + sdk_version: "current", + aars: ["direct_import.aar"], + static_libs: ["direct_import_dep"], + } + + android_library_import { + name: "direct_import_dep", + sdk_version: "current", + aars: ["direct_import_dep.aar"], + } + + android_library_import { + name: "transitive_import", + sdk_version: "current", + aars: ["transitive_import.aar"], + static_libs: ["transitive_import_dep"], + } + + android_library_import { + name: "transitive_import_dep", + sdk_version: "current", + aars: ["transitive_import_dep.aar"], + } + `, testCase.appUsesRP, testCase.directLibUsesRP, testCase.transitiveLibUsesRP) + + fs := android.MockFS{ + "app/res/values/strings.xml": nil, + "direct/res/values/strings.xml": nil, + "transitive/res/values/strings.xml": nil, + } + + result := android.GroupFixturePreparers( + PrepareForTestWithJavaDefaultModules, + PrepareForTestWithOverlayBuildComponents, + fs.AddToFixture(), + ).RunTestWithBp(t, bp) + + type aaptInfo struct { + resources, overlays, imports, srcJars, classpath, combined android.Paths + } + + getAaptInfo := func(moduleName string) (aaptInfo aaptInfo) { + mod := result.ModuleForTests(moduleName, "android_common") + resourceListRule := mod.MaybeOutput("aapt2/res.list") + overlayListRule := mod.MaybeOutput("aapt2/overlay.list") + aaptRule := mod.Rule("aapt2Link") + javacRule := mod.MaybeRule("javac") + combinedRule := mod.MaybeOutput("combined/" + moduleName + ".jar") + + aaptInfo.resources = resourceListRule.Inputs + aaptInfo.overlays = overlayListRule.Inputs + + aaptFlags := strings.Split(aaptRule.Args["flags"], " ") + for i, flag := range aaptFlags { + if flag == "-I" && i+1 < len(aaptFlags) { + aaptInfo.imports = append(aaptInfo.imports, android.PathForTesting(aaptFlags[i+1])) + } + } + + if len(javacRule.Args["srcJars"]) > 0 { + aaptInfo.srcJars = android.PathsForTesting(strings.Split(javacRule.Args["srcJars"], " ")...) + } + + if len(javacRule.Args["classpath"]) > 0 { + classpathArg := strings.TrimPrefix(javacRule.Args["classpath"], "-classpath ") + aaptInfo.classpath = android.PathsForTesting(strings.Split(classpathArg, ":")...) + } + + aaptInfo.combined = combinedRule.Inputs + return + } + + app := getAaptInfo("app") + direct := getAaptInfo("direct") + transitive := getAaptInfo("transitive") + directImport := getAaptInfo("direct_import") + transitiveImport := getAaptInfo("transitive_import") + + if !testCase.dontVerifyApp { + android.AssertPathsRelativeToTopEquals(t, "app resources", testCase.appResources, app.resources) + android.AssertPathsRelativeToTopEquals(t, "app overlays", testCase.appOverlays, app.overlays) + android.AssertPathsRelativeToTopEquals(t, "app imports", testCase.appImports, app.imports) + android.AssertPathsRelativeToTopEquals(t, "app srcjars", testCase.appSrcJars, app.srcJars) + android.AssertPathsRelativeToTopEquals(t, "app classpath", testCase.appClasspath, app.classpath) + android.AssertPathsRelativeToTopEquals(t, "app combined", testCase.appCombined, app.combined) + } + + if !testCase.dontVerifyDirect { + android.AssertPathsRelativeToTopEquals(t, "direct resources", testCase.directResources, direct.resources) + android.AssertPathsRelativeToTopEquals(t, "direct overlays", testCase.directOverlays, direct.overlays) + android.AssertPathsRelativeToTopEquals(t, "direct imports", testCase.directImports, direct.imports) + android.AssertPathsRelativeToTopEquals(t, "direct srcjars", testCase.directSrcJars, direct.srcJars) + android.AssertPathsRelativeToTopEquals(t, "direct classpath", testCase.directClasspath, direct.classpath) + android.AssertPathsRelativeToTopEquals(t, "direct combined", testCase.directCombined, direct.combined) + } + + if !testCase.dontVerifyTransitive { + android.AssertPathsRelativeToTopEquals(t, "transitive resources", testCase.transitiveResources, transitive.resources) + android.AssertPathsRelativeToTopEquals(t, "transitive overlays", testCase.transitiveOverlays, transitive.overlays) + android.AssertPathsRelativeToTopEquals(t, "transitive imports", testCase.transitiveImports, transitive.imports) + android.AssertPathsRelativeToTopEquals(t, "transitive srcjars", testCase.transitiveSrcJars, transitive.srcJars) + android.AssertPathsRelativeToTopEquals(t, "transitive classpath", testCase.transitiveClasspath, transitive.classpath) + android.AssertPathsRelativeToTopEquals(t, "transitive combined", testCase.transitiveCombined, transitive.combined) + } + + if !testCase.dontVerifyDirectImport { + android.AssertPathsRelativeToTopEquals(t, "direct_import resources", testCase.directImportResources, directImport.resources) + android.AssertPathsRelativeToTopEquals(t, "direct_import overlays", testCase.directImportOverlays, directImport.overlays) + android.AssertPathsRelativeToTopEquals(t, "direct_import imports", testCase.directImportImports, directImport.imports) + } + + if !testCase.dontVerifyTransitiveImport { + android.AssertPathsRelativeToTopEquals(t, "transitive_import resources", testCase.transitiveImportResources, transitiveImport.resources) + android.AssertPathsRelativeToTopEquals(t, "transitive_import overlays", testCase.transitiveImportOverlays, transitiveImport.overlays) + android.AssertPathsRelativeToTopEquals(t, "transitive_import imports", testCase.transitiveImportImports, transitiveImport.imports) + } + }) + } +} + +func TestAndroidResourceOverlays(t *testing.T) { testCases := []struct { name string enforceRROTargets []string @@ -943,7 +1453,7 @@ func TestAndroidResources(t *testing.T) { overlayFiles = resourceListToFiles(module, android.PathsRelativeToTop(overlayList.Inputs)) } - for _, d := range module.Module().(AndroidLibraryDependency).ExportedRRODirs() { + for _, d := range module.Module().(AndroidLibraryDependency).RRODirsDepSet().ToList() { var prefix string if d.overlayType == device { prefix = "device:" diff --git a/java/base.go b/java/base.go index f2ad5c2cf..f5eb01c4b 100644 --- a/java/base.go +++ b/java/base.go @@ -21,6 +21,7 @@ import ( "strings" "android/soong/ui/metrics/bp2build_metrics_proto" + "github.com/google/blueprint/pathtools" "github.com/google/blueprint/proptools" @@ -500,6 +501,21 @@ type Module struct { maxSdkVersion android.ApiLevel sourceExtensions []string + + annoSrcJars android.Paths + + // output file name based on Stem property. + // This should be set in every ModuleWithStem's GenerateAndroidBuildActions + // or the module should override Stem(). + stem string + + // Aconfig "cache files" that went directly into this module. Transitive ones are + // tracked via JavaInfo.TransitiveAconfigFiles + // TODO: Extract to something standalone to propagate tags via GeneratedJavaLibraryModule + aconfigIntermediates android.Paths + + // Aconfig files for all transitive deps. Also exposed via JavaInfo + transitiveAconfigFiles *android.DepSet[android.Path] } func (j *Module) CheckStableSdkVersion(ctx android.BaseModuleContext) error { @@ -1049,7 +1065,7 @@ func (module *Module) addGeneratedSrcJars(path android.Path) { module.properties.Generated_srcjars = append(module.properties.Generated_srcjars, path) } -func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { +func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspathJars, extraCombinedJars android.Paths) { j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs) deps := j.collectDeps(ctx) @@ -1087,9 +1103,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { srcJars := srcFiles.FilterByExt(".srcjar") srcJars = append(srcJars, deps.srcJars...) - if aaptSrcJar != nil { - srcJars = append(srcJars, aaptSrcJar) - } + srcJars = append(srcJars, extraSrcJars...) srcJars = append(srcJars, j.properties.Generated_srcjars...) srcFiles = srcFiles.FilterOutByExt(".srcjar") @@ -1097,7 +1111,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { j.expandJarjarRules = android.PathForModuleSrc(ctx, *j.properties.Jarjar_rules) } - jarName := ctx.ModuleName() + ".jar" + jarName := j.Stem() + ".jar" var uniqueJavaFiles android.Paths set := make(map[string]bool) @@ -1132,6 +1146,11 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { var kotlinJars android.Paths var kotlinHeaderJars android.Paths + // Prepend extraClasspathJars to classpath so that the resource processor R.jar comes before + // any dependencies so that it can override any non-final R classes from dependencies with the + // final R classes from the app. + flags.classpath = append(android.CopyOf(extraClasspathJars), flags.classpath...) + if srcFiles.HasExt(".kt") { // When using kotlin sources turbine is used to generate annotation processor sources, // including for annotation processors that generate API, so we can use turbine for @@ -1225,8 +1244,9 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { // allow for the use of annotation processors that do function correctly // with sharding enabled. See: b/77284273. } + extraJars := append(android.CopyOf(extraCombinedJars), kotlinHeaderJars...) headerJarFileWithoutDepsOrJarjar, j.headerJarFile = - j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName, kotlinHeaderJars) + j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName, extraJars) if ctx.Failed() { return } @@ -1255,8 +1275,9 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { // this module, or else we could have duplicated errorprone messages. errorproneFlags := enableErrorproneFlags(flags) errorprone := android.PathForModuleOut(ctx, "errorprone", jarName) + errorproneAnnoSrcJar := android.PathForModuleOut(ctx, "errorprone", "anno.srcjar") - transformJavaToClasses(ctx, errorprone, -1, uniqueJavaFiles, srcJars, errorproneFlags, nil, + transformJavaToClasses(ctx, errorprone, -1, uniqueJavaFiles, srcJars, errorproneAnnoSrcJar, errorproneFlags, nil, "errorprone", "errorprone") extraJarDeps = append(extraJarDeps, errorprone) @@ -1376,6 +1397,8 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { jars = append(jars, servicesJar) } + jars = append(android.CopyOf(extraCombinedJars), jars...) + // Combine the classes built from sources, any manifests, and any static libraries into // classes.jar. If there is only one input jar this step will be skipped. var outputFile android.OutputPath @@ -1468,7 +1491,13 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { j.implementationJarFile = outputFile if j.headerJarFile == nil { - j.headerJarFile = j.implementationJarFile + // If this module couldn't generate a header jar (for example due to api generating annotation processors) + // then use the implementation jar. Run it through zip2zip first to remove any files in META-INF/services + // so that javac on modules that depend on this module don't pick up annotation processors (which may be + // missing their implementations) from META-INF/services/javax.annotation.processing.Processor. + headerJarFile := android.PathForModuleOut(ctx, "javac-header", jarName) + convertImplementationJarToHeaderJar(ctx, j.implementationJarFile, headerJarFile) + j.headerJarFile = headerJarFile } // enforce syntax check to jacoco filters for any build (http://b/183622051) @@ -1614,6 +1643,8 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { ctx.CheckbuildFile(outputFile) + j.collectTransitiveAconfigFiles(ctx) + ctx.SetProvider(JavaInfoProvider, JavaInfo{ HeaderJars: android.PathsIfNonNil(j.headerJarFile), TransitiveLibsHeaderJars: j.transitiveLibsHeaderJars, @@ -1628,6 +1659,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { ExportedPluginClasses: j.exportedPluginClasses, ExportedPluginDisableTurbine: j.exportedDisableTurbine, JacocoReportClassesFile: j.jacocoReportClassesFile, + TransitiveAconfigFiles: j.transitiveAconfigFiles, }) // Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource @@ -1657,13 +1689,15 @@ func (j *Module) compileJavaClasses(ctx android.ModuleContext, jarName string, i srcFiles, srcJars android.Paths, flags javaBuilderFlags, extraJarDeps android.Paths) android.WritablePath { kzipName := pathtools.ReplaceExtension(jarName, "kzip") + annoSrcJar := android.PathForModuleOut(ctx, "javac", "anno.srcjar") if idx >= 0 { kzipName = strings.TrimSuffix(jarName, filepath.Ext(jarName)) + strconv.Itoa(idx) + ".kzip" + annoSrcJar = android.PathForModuleOut(ctx, "javac", "anno-"+strconv.Itoa(idx)+".srcjar") jarName += strconv.Itoa(idx) } classes := android.PathForModuleOut(ctx, "javac", jarName).OutputPath - TransformJavaToClasses(ctx, classes, idx, srcFiles, srcJars, flags, extraJarDeps) + TransformJavaToClasses(ctx, classes, idx, srcFiles, srcJars, annoSrcJar, flags, extraJarDeps) if ctx.Config().EmitXrefRules() { extractionFile := android.PathForModuleOut(ctx, kzipName) @@ -1671,6 +1705,10 @@ func (j *Module) compileJavaClasses(ctx android.ModuleContext, jarName string, i j.kytheFiles = append(j.kytheFiles, extractionFile) } + if len(flags.processorPath) > 0 { + j.annoSrcJars = append(j.annoSrcJars, annoSrcJar) + } + return classes } @@ -1850,6 +1888,7 @@ func (j *Module) IDEInfo(dpInfo *android.IdeInfo) { dpInfo.Paths = append(dpInfo.Paths, j.modulePaths...) dpInfo.Static_libs = append(dpInfo.Static_libs, j.properties.Static_libs...) dpInfo.Libs = append(dpInfo.Libs, j.properties.Libs...) + dpInfo.SrcJars = append(dpInfo.SrcJars, j.annoSrcJars.Strings()...) } func (j *Module) CompilerDeps() []string { @@ -1887,7 +1926,10 @@ func (j *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersi } func (j *Module) Stem() string { - return proptools.StringDefault(j.overridableDeviceProperties.Stem, j.Name()) + if j.stem == "" { + panic("Stem() called before stem property was set") + } + return j.stem } func (j *Module) JacocoReportClassesFile() android.Path { @@ -1898,6 +1940,34 @@ func (j *Module) IsInstallable() bool { return Bool(j.properties.Installable) } +func (j *Module) collectTransitiveAconfigFiles(ctx android.ModuleContext) { + // Aconfig files from this module + mine := j.aconfigIntermediates + + // Aconfig files from transitive dependencies + fromDeps := []*android.DepSet[android.Path]{} + ctx.VisitDirectDeps(func(module android.Module) { + dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo) + if dep.TransitiveAconfigFiles != nil { + fromDeps = append(fromDeps, dep.TransitiveAconfigFiles) + } + }) + + // DepSet containing aconfig files myself and from dependencies + j.transitiveAconfigFiles = android.NewDepSet(android.POSTORDER, mine, fromDeps) +} + +func (j *Module) AddAconfigIntermediate(path android.Path) { + j.aconfigIntermediates = append(j.aconfigIntermediates, path) +} + +func (j *Module) getTransitiveAconfigFiles() *android.DepSet[android.Path] { + if j.transitiveAconfigFiles == nil { + panic(fmt.Errorf("java.Moduile: getTransitiveAconfigFiles called before collectTransitiveAconfigFiles module=%s", j.Name())) + } + return j.transitiveAconfigFiles +} + type sdkLinkType int const ( diff --git a/java/bootclasspath.go b/java/bootclasspath.go index f4cef7fa6..c7dc3afae 100644 --- a/java/bootclasspath.go +++ b/java/bootclasspath.go @@ -77,7 +77,7 @@ func addDependencyOntoApexVariants(ctx android.BottomUpMutatorContext, propertyN // Use gatherApexModulePairDepsWithTag to retrieve the dependencies. func addDependencyOntoApexModulePair(ctx android.BottomUpMutatorContext, apex string, name string, tag blueprint.DependencyTag) { var variations []blueprint.Variation - if apex != "platform" && apex != "system_ext" { + if !android.IsConfiguredJarForPlatform(apex) { // Pick the correct apex variant. variations = []blueprint.Variation{ {Mutator: "apex", Variation: apex}, @@ -185,6 +185,9 @@ var _ android.ExcludeFromVisibilityEnforcementTag = bootclasspathDependencyTag{} // The tag used for dependencies onto bootclasspath_fragments. var bootclasspathFragmentDepTag = bootclasspathDependencyTag{name: "fragment"} +// The tag used for dependencies onto platform_bootclasspath. +var platformBootclasspathDepTag = bootclasspathDependencyTag{name: "platform"} + // BootclasspathNestedAPIProperties defines properties related to the API provided by parts of the // bootclasspath that are nested within the main BootclasspathAPIProperties. type BootclasspathNestedAPIProperties struct { diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go index 50429b07a..dcc2dece7 100644 --- a/java/bootclasspath_fragment.go +++ b/java/bootclasspath_fragment.go @@ -242,7 +242,7 @@ type BootclasspathFragmentModule struct { modulePaths []string // Path to the boot image profile. - profilePath android.Path + profilePath android.WritablePath } // commonBootclasspathFragment defines the methods that are implemented by both source and prebuilt @@ -256,16 +256,6 @@ type commonBootclasspathFragment interface { // versioned sdk. produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, fragments []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput - // produceBootImageFiles will attempt to produce rules to create the boot image files at the paths - // predefined in the bootImageConfig. - // - // If it could not create the files then it will return nil. Otherwise, it will return a map from - // android.ArchType to the predefined paths of the boot image files. - produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageOutputs - - // getImageName returns the `image_name` property of this fragment. - getImageName() *string - // getProfilePath returns the path to the boot image profile. getProfilePath() android.Path } @@ -295,9 +285,6 @@ func bootclasspathFragmentFactory() android.Module { return } } - - // Initialize the contents property from the image_name. - bootclasspathFragmentInitContentsFromImage(ctx, m) }) return m } @@ -308,9 +295,7 @@ func testBootclasspathFragmentFactory() android.Module { return m } -// bootclasspathFragmentInitContentsFromImage will initialize the contents property from the image_name if -// necessary. -func bootclasspathFragmentInitContentsFromImage(ctx android.EarlyModuleContext, m *BootclasspathFragmentModule) { +func (m *BootclasspathFragmentModule) bootclasspathFragmentPropertyCheck(ctx android.EarlyModuleContext) { contents := m.properties.Contents if len(contents) == 0 { ctx.PropertyErrorf("contents", "required property is missing") @@ -332,6 +317,18 @@ func bootclasspathFragmentInitContentsFromImage(ctx android.EarlyModuleContext, // too early in the Soong processing for that to work. global := dexpreopt.GetGlobalConfig(ctx) modules := global.ArtApexJars + configuredJars := modules.CopyOfJars() + + // Skip the check if the configured jars list is empty as that is a common configuration when + // building targets that do not result in a system image. + if len(configuredJars) == 0 { + return + } + + if !reflect.DeepEqual(configuredJars, contents) { + ctx.ModuleErrorf("inconsistency in specification of contents. ArtApexJars configuration specifies %#v, contents property specifies %#v", + configuredJars, contents) + } // Make sure that the apex specified in the configuration is consistent and is one for which // this boot image is available. @@ -357,42 +354,11 @@ func bootclasspathFragmentInitContentsFromImage(ctx android.EarlyModuleContext, } } -// bootclasspathImageNameContentsConsistencyCheck checks that the configuration that applies to this -// module (if any) matches the contents. -// -// This should be a noop as if image_name="art" then the contents will be set from the ArtApexJars -// config by bootclasspathFragmentInitContentsFromImage so it will be guaranteed to match. However, -// in future this will not be the case. -func (b *BootclasspathFragmentModule) bootclasspathImageNameContentsConsistencyCheck(ctx android.BaseModuleContext) { - imageName := proptools.String(b.properties.Image_name) - if imageName == "art" { - // Get the configuration for the art apex jars. - modules := b.getImageConfig(ctx).modules - configuredJars := modules.CopyOfJars() - - // Skip the check if the configured jars list is empty as that is a common configuration when - // building targets that do not result in a system image. - if len(configuredJars) == 0 { - return - } - - contents := b.properties.Contents - if !reflect.DeepEqual(configuredJars, contents) { - ctx.ModuleErrorf("inconsistency in specification of contents. ArtApexJars configuration specifies %#v, contents property specifies %#v", - configuredJars, contents) - } - } -} - var BootclasspathFragmentApexContentInfoProvider = blueprint.NewProvider(BootclasspathFragmentApexContentInfo{}) // BootclasspathFragmentApexContentInfo contains the bootclasspath_fragments contributions to the // apex contents. type BootclasspathFragmentApexContentInfo struct { - // The configured modules, will be empty if this is from a bootclasspath_fragment that does not - // set image_name: "art". - modules android.ConfiguredJarList - // Map from the base module name (without prebuilt_ prefix) of a fragment's contents module to the // hidden API encoded dex jar path. contentModuleDexJarPaths bootDexJarByModule @@ -405,10 +371,6 @@ type BootclasspathFragmentApexContentInfo struct { profileInstallPathInApex string } -func (i BootclasspathFragmentApexContentInfo) Modules() android.ConfiguredJarList { - return i.modules -} - // 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. @@ -503,7 +465,7 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo // unused prebuilt that was created without instrumentation from breaking an instrumentation // build. if isActiveModule(ctx.Module()) { - b.bootclasspathImageNameContentsConsistencyCheck(ctx) + b.bootclasspathFragmentPropertyCheck(ctx) } // Generate classpaths.proto config @@ -523,34 +485,15 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo fragments := gatherApexModulePairDepsWithTag(ctx, bootclasspathFragmentDepTag) - // Verify that the image_name specified on a bootclasspath_fragment is valid even if this is a - // prebuilt which will not use the image config. - imageConfig := b.getImageConfig(ctx) - // Perform hidden API processing. hiddenAPIOutput := b.generateHiddenAPIBuildActions(ctx, contents, fragments) - var bootImageFiles bootImageOutputs - if imageConfig != nil { - // Delegate the production of the boot image files to a module type specific method. - common := ctx.Module().(commonBootclasspathFragment) - bootImageFiles = common.produceBootImageFiles(ctx, imageConfig) - b.profilePath = bootImageFiles.profile - - if shouldCopyBootFilesToPredefinedLocations(ctx, imageConfig) { - // Zip the boot image files up, if available. This will generate the zip file in a - // predefined location. - buildBootImageZipInPredefinedLocation(ctx, imageConfig, bootImageFiles.byArch) - - // Copy the dex jars of this fragment's content modules to their predefined locations. - copyBootJarsToPredefinedLocations(ctx, hiddenAPIOutput.EncodedBootDexFilesByModule, imageConfig.dexPathsByModule) - } - } - - // A prebuilt fragment cannot contribute to an apex. - if !android.IsModulePrebuilt(ctx.Module()) { - // Provide the apex content info. - b.provideApexContentInfo(ctx, imageConfig, hiddenAPIOutput, bootImageFiles) + if android.IsModulePrebuilt(ctx.Module()) { + b.profilePath = ctx.Module().(*PrebuiltBootclasspathFragmentModule).produceBootImageProfile(ctx) + } else { + b.profilePath = b.produceBootImageProfileFromSource(ctx, contents, hiddenAPIOutput.EncodedBootDexFilesByModule) + // Provide the apex content info. A prebuilt fragment cannot contribute to an apex. + b.provideApexContentInfo(ctx, hiddenAPIOutput, b.profilePath) } // In order for information about bootclasspath_fragment modules to be added to module-info.json @@ -564,45 +507,37 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo } } -// shouldCopyBootFilesToPredefinedLocations determines whether the current module should copy boot -// files, e.g. boot dex jars or boot image files, to the predefined location expected by the rest -// of the build. -// -// This ensures that only a single module will copy its files to the image configuration. -func shouldCopyBootFilesToPredefinedLocations(ctx android.ModuleContext, imageConfig *bootImageConfig) bool { - // Bootclasspath fragment modules that are for the platform do not produce boot related files. - apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) - if apexInfo.IsForPlatform() { - return false +// getProfileProviderApex returns the name of the apex that provides a boot image profile, or an +// 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.Module()) { + return "" } - // If the image configuration has no modules specified then it means that the build has been - // configured to build something other than a boot image, e.g. an sdk, so do not try and copy the - // files. - if imageConfig.modules.Len() == 0 { - return false + // Bootclasspath fragment modules that are for the platform do not produce boot related files. + apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) + for _, apex := range apexInfo.InApexVariants { + if isProfileProviderApex(ctx, apex) { + return apex + } } - // Only copy files from the module that is preferred. - return isActiveModule(ctx.Module()) + return "" } // provideApexContentInfo creates, initializes and stores the apex content info for use by other // modules. -func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleContext, imageConfig *bootImageConfig, hiddenAPIOutput *HiddenAPIOutput, bootImageFiles bootImageOutputs) { +func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleContext, hiddenAPIOutput *HiddenAPIOutput, profile android.WritablePath) { // Construct the apex content info from the config. info := BootclasspathFragmentApexContentInfo{ // Populate the apex content info with paths to the dex jars. contentModuleDexJarPaths: hiddenAPIOutput.EncodedBootDexFilesByModule, } - if imageConfig != nil { - info.modules = imageConfig.modules - global := dexpreopt.GetGlobalConfig(ctx) - if !global.DisableGenerateProfile { - info.profilePathOnHost = bootImageFiles.profile - info.profileInstallPathInApex = imageConfig.profileInstallPathInApex - } + if profile != nil { + info.profilePathOnHost = profile + info.profileInstallPathInApex = profileInstallPathInApex } // Make the apex content info available for other modules. @@ -623,12 +558,12 @@ func (b *BootclasspathFragmentModule) generateClasspathProtoBuildActions(ctx and } func (b *BootclasspathFragmentModule) configuredJars(ctx android.ModuleContext) android.ConfiguredJarList { + global := dexpreopt.GetGlobalConfig(ctx) + if "art" == proptools.String(b.properties.Image_name) { - return b.getImageConfig(ctx).modules + return global.ArtApexJars } - global := dexpreopt.GetGlobalConfig(ctx) - possibleUpdatableModules := gatherPossibleApexModuleNamesAndStems(ctx, b.properties.Contents, bootclasspathFragmentContentDepTag) jars, unknown := global.ApexBootJars.Filter(possibleUpdatableModules) @@ -654,25 +589,6 @@ func (b *BootclasspathFragmentModule) configuredJars(ctx android.ModuleContext) return jars } -func (b *BootclasspathFragmentModule) getImageConfig(ctx android.EarlyModuleContext) *bootImageConfig { - // Get a map of the image configs that are supported. - imageConfigs := genBootImageConfigs(ctx) - - // Retrieve the config for this image. - imageNamePtr := b.properties.Image_name - if imageNamePtr == nil { - return nil - } - - imageName := *imageNamePtr - imageConfig := imageConfigs[imageName] - if imageConfig == nil { - ctx.PropertyErrorf("image_name", "Unknown image name %q, expected one of %s", imageName, strings.Join(android.SortedKeys(imageConfigs), ", ")) - return nil - } - return imageConfig -} - // generateHiddenAPIBuildActions generates all the hidden API related build rules. func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, contents []android.Module, fragments []android.Module) *HiddenAPIOutput { @@ -855,48 +771,22 @@ func (b *BootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleC return output } -// produceBootImageFiles builds the boot image files from the source if it is required. -func (b *BootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageOutputs { - // Only generate the boot image if the configuration does not skip it. - return b.generateBootImageBuildActions(ctx, imageConfig) -} - -// generateBootImageBuildActions generates ninja rules to create the boot image if required for this -// module. -// -// If it could not create the files then it will return nil. Otherwise, it will return a map from -// android.ArchType to the predefined paths of the boot image files. -func (b *BootclasspathFragmentModule) generateBootImageBuildActions(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageOutputs { - global := dexpreopt.GetGlobalConfig(ctx) - if !shouldBuildBootImages(ctx.Config(), global) { - return bootImageOutputs{} - } - - // Bootclasspath fragment modules that are for the platform do not produce a boot image. - apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) - if apexInfo.IsForPlatform() { - return bootImageOutputs{} +// 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 { + apex := b.getProfileProviderApex(ctx) + if apex == "" { + return nil } - // Build a profile for the image config and then use that to build the boot image. - profile := bootImageProfileRule(ctx, imageConfig) - - // If dexpreopt of boot image jars should be skipped, generate only a profile. - if SkipDexpreoptBootJars(ctx) { - return bootImageOutputs{ - profile: profile, - } + dexPaths := make(android.Paths, 0, len(contents)) + dexLocations := make([]string, 0, len(contents)) + for _, module := range contents { + dexPaths = append(dexPaths, modules[module.Name()]) + dexLocations = append(dexLocations, filepath.Join("/", "apex", apex, "javalib", module.Name() + ".jar")) } - // Build boot image files for the host variants. - buildBootImageVariantsForBuildOs(ctx, imageConfig, profile) - - // Build boot image files for the android variants. - bootImageFiles := buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile) - - // Return the boot image files for the android variants for inclusion in an APEX and to be zipped - // up for the dist. - return bootImageFiles + // Build a profile for the modules in this fragment. + return bootImageProfileRuleCommon(ctx, b.Name(), dexPaths, dexLocations) } func (b *BootclasspathFragmentModule) AndroidMkEntries() []android.AndroidMkEntries { @@ -919,10 +809,6 @@ func (b *BootclasspathFragmentModule) AndroidMkEntries() []android.AndroidMkEntr return entriesList } -func (b *BootclasspathFragmentModule) getImageName() *string { - return b.properties.Image_name -} - func (b *BootclasspathFragmentModule) getProfilePath() android.Path { return b.profilePath } @@ -1192,39 +1078,19 @@ func (module *PrebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx an return &output } -// produceBootImageFiles extracts the boot image files from the APEX if available. -func (module *PrebuiltBootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageOutputs { - if !shouldCopyBootFilesToPredefinedLocations(ctx, imageConfig) { - return bootImageOutputs{} +// produceBootImageProfile extracts the boot image profile from the APEX if available. +func (module *PrebuiltBootclasspathFragmentModule) produceBootImageProfile(ctx android.ModuleContext) android.WritablePath { + // This module does not provide a boot image profile. + if module.getProfileProviderApex(ctx) == "" { + return nil } di := android.FindDeapexerProviderForModule(ctx) if di == nil { - return bootImageOutputs{} // An error has been reported by FindDeapexerProviderForModule. + return nil // An error has been reported by FindDeapexerProviderForModule. } - profile := (android.WritablePath)(nil) - if imageConfig.profileInstallPathInApex != "" { - profile = di.PrebuiltExportPath(imageConfig.profileInstallPathInApex) - } - - // Build the boot image files for the host variants. These are always built from the dex files - // provided by the contents of this module as prebuilt versions of the host boot image files are - // not available, i.e. there is no host specific prebuilt apex containing them. This has to be - // built without a profile as the prebuilt modules do not provide a profile. - buildBootImageVariantsForBuildOs(ctx, imageConfig, profile) - - if profile == nil && imageConfig.isProfileGuided() { - ctx.ModuleErrorf("Unable to produce boot image files: profiles not found in the prebuilt apex") - return bootImageOutputs{} - } - // Build boot image files for the android variants from the dex files provided by the contents - // of this module. - return buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile) -} - -func (b *PrebuiltBootclasspathFragmentModule) getImageName() *string { - return b.properties.Image_name + return di.PrebuiltExportPath(profileInstallPathInApex) } func (b *PrebuiltBootclasspathFragmentModule) getProfilePath() android.Path { @@ -1239,14 +1105,10 @@ var _ commonBootclasspathFragment = (*PrebuiltBootclasspathFragmentModule)(nil) // If there is no image config associated with this fragment then it returns nil. Otherwise, it // returns the files that are listed in the image config. func (module *PrebuiltBootclasspathFragmentModule) RequiredFilesFromPrebuiltApex(ctx android.BaseModuleContext) []string { - imageConfig := module.getImageConfig(ctx) - if imageConfig != nil { - files := []string{} - if imageConfig.profileInstallPathInApex != "" { - // Add the boot image profile. - files = append(files, imageConfig.profileInstallPathInApex) + for _, apex := range module.ApexProperties.Apex_available { + if isProfileProviderApex(ctx, apex) { + return []string{profileInstallPathInApex} } - return files } return nil } @@ -1262,9 +1124,5 @@ func prebuiltBootclasspathFragmentFactory() android.Module { android.InitApexModule(m) android.InitAndroidArchModule(m, android.HostAndDeviceSupported, android.MultilibCommon) - // Initialize the contents property from the image_name. - android.AddLoadHook(m, func(ctx android.LoadHookContext) { - bootclasspathFragmentInitContentsFromImage(ctx, &m.BootclasspathFragmentModule) - }) return m } diff --git a/java/bootclasspath_fragment_test.go b/java/bootclasspath_fragment_test.go index 2541f14ff..888caad16 100644 --- a/java/bootclasspath_fragment_test.go +++ b/java/bootclasspath_fragment_test.go @@ -40,6 +40,12 @@ func TestBootclasspathFragment_UnknownImageName(t *testing.T) { image_name: "unknown", contents: ["foo"], } + + java_library { + name: "foo", + srcs: ["foo.java"], + installable: true, + } `) } @@ -53,6 +59,11 @@ func TestPrebuiltBootclasspathFragment_UnknownImageName(t *testing.T) { image_name: "unknown", contents: ["foo"], } + + java_import { + name: "foo", + jars: ["foo.jar"], + } `) } @@ -72,6 +83,18 @@ func TestBootclasspathFragmentInconsistentArtConfiguration_Platform(t *testing.T "apex", ], } + + java_library { + name: "foo", + srcs: ["foo.java"], + installable: true, + } + + java_library { + name: "bar", + srcs: ["bar.java"], + installable: true, + } `) } @@ -92,6 +115,18 @@ func TestBootclasspathFragmentInconsistentArtConfiguration_ApexMixture(t *testin "apex2", ], } + + java_library { + name: "foo", + srcs: ["foo.java"], + installable: true, + } + + java_library { + name: "bar", + srcs: ["bar.java"], + installable: true, + } `) } diff --git a/java/builder.go b/java/builder.go index c4395e91d..afbd69ee4 100644 --- a/java/builder.go +++ b/java/builder.go @@ -42,7 +42,8 @@ var ( // TODO(b/143658984): goma can't handle the --system argument to javac. javac, javacRE = pctx.MultiCommandRemoteStaticRules("javac", blueprint.RuleParams{ - Command: `rm -rf "$outDir" "$annoDir" "$srcJarDir" "$out" && mkdir -p "$outDir" "$annoDir" "$srcJarDir" && ` + + Command: `rm -rf "$outDir" "$annoDir" "$annoSrcJar.tmp" "$srcJarDir" "$out.tmp" && ` + + `mkdir -p "$outDir" "$annoDir" "$srcJarDir" && ` + `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` + `(if [ -s $srcJarDir/list ] || [ -s $out.rsp ] ; then ` + `${config.SoongJavacWrapper} $javaTemplate${config.JavacCmd} ` + @@ -50,7 +51,10 @@ var ( `$processorpath $processor $javacFlags $bootClasspath $classpath ` + `-source $javaVersion -target $javaVersion ` + `-d $outDir -s $annoDir @$out.rsp @$srcJarDir/list ; fi ) && ` + - `$zipTemplate${config.SoongZipCmd} -jar -o $out -C $outDir -D $outDir && ` + + `$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 && ` + `rm -rf "$srcJarDir"`, CommandDeps: []string{ "${config.JavacCmd}", @@ -58,6 +62,7 @@ var ( "${config.ZipSyncCmd}", }, CommandOrderOnly: []string{"${config.SoongJavacWrapper}"}, + Restat: true, Rspfile: "$out.rsp", RspfileContent: "$in", }, map[string]*remoteexec.REParams{ @@ -69,12 +74,19 @@ var ( "$zipTemplate": &remoteexec.REParams{ Labels: map[string]string{"type": "tool", "name": "soong_zip"}, Inputs: []string{"${config.SoongZipCmd}", "$outDir"}, - OutputFiles: []string{"$out"}, + 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", "srcJars", "srcJarDir", - "outDir", "annoDir", "javaVersion"}, nil) + "outDir", "annoDir", "annoSrcJar", "javaVersion"}, nil) _ = pctx.VariableFunc("kytheCorpus", func(ctx android.PackageVarContext) string { return ctx.Config().XrefCorpusName() }) @@ -259,6 +271,12 @@ var ( Description: "Check zip alignment", }, ) + + convertImplementationJarToHeaderJarRule = pctx.AndroidStaticRule("convertImplementationJarToHeaderJar", + blueprint.RuleParams{ + Command: `${config.Zip2ZipCmd} -i ${in} -o ${out} -x 'META-INF/services/**/*'`, + CommandDeps: []string{"${config.Zip2ZipCmd}"}, + }) ) func init() { @@ -312,7 +330,7 @@ func DefaultJavaBuilderFlags() javaBuilderFlags { } func TransformJavaToClasses(ctx android.ModuleContext, outputFile android.WritablePath, shardIdx int, - srcFiles, srcJars android.Paths, flags javaBuilderFlags, deps android.Paths) { + srcFiles, srcJars android.Paths, annoSrcJar android.WritablePath, flags javaBuilderFlags, deps android.Paths) { // Compile java sources into .class files desc := "javac" @@ -320,7 +338,7 @@ func TransformJavaToClasses(ctx android.ModuleContext, outputFile android.Writab desc += strconv.Itoa(shardIdx) } - transformJavaToClasses(ctx, outputFile, shardIdx, srcFiles, srcJars, flags, deps, "javac", desc) + transformJavaToClasses(ctx, outputFile, shardIdx, srcFiles, srcJars, annoSrcJar, flags, deps, "javac", desc) } // Emits the rule to generate Xref input file (.kzip file) for the given set of source files and source jars @@ -494,7 +512,7 @@ func TurbineApt(ctx android.ModuleContext, outputSrcJar, outputResJar android.Wr // suffix will be appended to various intermediate files and directories to avoid collisions when // this function is called twice in the same module directory. func transformJavaToClasses(ctx android.ModuleContext, outputFile android.WritablePath, - shardIdx int, srcFiles, srcJars android.Paths, + shardIdx int, srcFiles, srcJars android.Paths, annoSrcJar android.WritablePath, flags javaBuilderFlags, deps android.Paths, intermediatesDir, desc string) { @@ -541,11 +559,12 @@ func transformJavaToClasses(ctx android.ModuleContext, outputFile android.Writab rule = javacRE } ctx.Build(pctx, android.BuildParams{ - Rule: rule, - Description: desc, - Output: outputFile, - Inputs: srcFiles, - Implicits: deps, + Rule: rule, + Description: desc, + Output: outputFile, + ImplicitOutput: annoSrcJar, + Inputs: srcFiles, + Implicits: deps, Args: map[string]string{ "javacFlags": flags.javacFlags, "bootClasspath": bootClasspath, @@ -556,6 +575,7 @@ func transformJavaToClasses(ctx android.ModuleContext, outputFile android.Writab "srcJarDir": android.PathForModuleOut(ctx, intermediatesDir, srcJarDir).String(), "outDir": android.PathForModuleOut(ctx, intermediatesDir, outDir).String(), "annoDir": android.PathForModuleOut(ctx, intermediatesDir, annoDir).String(), + "annoSrcJar": annoSrcJar.String(), "javaVersion": flags.javaVersion.String(), }, }) @@ -619,6 +639,15 @@ func TransformJarsToJar(ctx android.ModuleContext, outputFile android.WritablePa }) } +func convertImplementationJarToHeaderJar(ctx android.ModuleContext, implementationJarFile android.Path, + headerJarFile android.WritablePath) { + ctx.Build(pctx, android.BuildParams{ + Rule: convertImplementationJarToHeaderJarRule, + Input: implementationJarFile, + Output: headerJarFile, + }) +} + func TransformJarJar(ctx android.ModuleContext, outputFile android.WritablePath, classesJar android.Path, rulesFile android.Path) { ctx.Build(pctx, android.BuildParams{ diff --git a/java/config/config.go b/java/config/config.go index 195dae16b..83c27d309 100644 --- a/java/config/config.go +++ b/java/config/config.go @@ -148,6 +148,8 @@ func init() { pctx.SourcePathVariable("JavaKytheExtractorJar", "prebuilts/build-tools/common/framework/javac_extractor.jar") pctx.SourcePathVariable("Ziptime", "prebuilts/build-tools/${hostPrebuiltTag}/bin/ziptime") + pctx.SourcePathVariable("ResourceProcessorBusyBox", "prebuilts/bazel/common/android_tools/android_tools/all_android_tools_deploy.jar") + pctx.HostBinToolVariable("GenKotlinBuildFileCmd", "gen-kotlin-build-file") pctx.SourcePathVariable("JarArgsCmd", "build/soong/scripts/jar-args.sh") diff --git a/java/device_host_converter.go b/java/device_host_converter.go index 3581040f8..5460dc993 100644 --- a/java/device_host_converter.go +++ b/java/device_host_converter.go @@ -143,6 +143,8 @@ func (d *DeviceHostConverter) GenerateAndroidBuildActions(ctx android.ModuleCont ResourceJars: d.resourceJars, SrcJarArgs: d.srcJarArgs, SrcJarDeps: d.srcJarDeps, + // TODO: Not sure if aconfig flags that have been moved between device and host variants + // make sense. }) } diff --git a/java/device_host_converter_test.go b/java/device_host_converter_test.go index 3c9a0f3f1..3413da03d 100644 --- a/java/device_host_converter_test.go +++ b/java/device_host_converter_test.go @@ -135,6 +135,7 @@ func TestHostForDevice(t *testing.T) { hostModule := ctx.ModuleForTests("host_module", config.BuildOSCommonTarget.String()) hostJavac := hostModule.Output("javac/host_module.jar") + hostJavacHeader := hostModule.Output("javac-header/host_module.jar") hostRes := hostModule.Output("res/host_module.jar") hostImportModule := ctx.ModuleForTests("host_import_module", config.BuildOSCommonTarget.String()) @@ -148,7 +149,7 @@ func TestHostForDevice(t *testing.T) { // check classpath of device module with dependency on host_for_device_module expectedClasspath := "-classpath " + strings.Join(android.Paths{ - hostJavac.Output, + hostJavacHeader.Output, hostImportCombined.Output, }.Strings(), ":") diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index 2b0f57e82..003f2de22 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -16,7 +16,6 @@ package java import ( "path/filepath" - "sort" "strings" "android/soong/android" @@ -224,6 +223,11 @@ var artApexNames = []string{ "com.google.android.art.testing", } +var ( + dexpreoptBootJarDepTag = bootclasspathDependencyTag{name: "dexpreopt-boot-jar"} + dexBootJarsFragmentsKey = android.NewOnceKey("dexBootJarsFragments") +) + func init() { RegisterDexpreoptBootJarsComponents(android.InitRegistrationContext) } @@ -241,6 +245,9 @@ type bootImageConfig struct { // Image name (used in directory names and ninja rule names). name string + // If the module with the given name exists, this config is enabled. + enabledIfExists string + // Basename of the image: the resulting filenames are <stem>[-<jar>].{art,oat,vdex}. stem string @@ -257,10 +264,6 @@ type bootImageConfig struct { // the location is relative to "/". installDir string - // Install path of the boot image profile if it needs to be installed in the APEX, or empty if not - // needed. - profileInstallPathInApex string - // A list of (location, jar) pairs for the Java modules in this image. modules android.ConfiguredJarList @@ -296,10 +299,9 @@ type bootImageConfig struct { // The "--single-image" argument. singleImage bool - // Profiles imported from other boot image configs. Each element must represent a - // `bootclasspath_fragment` of an APEX (i.e., the `name` field of each element must refer to the - // `image_name` property of a `bootclasspath_fragment`). - profileImports []*bootImageConfig + // Profiles imported from APEXes, in addition to the profile at the default path. Each entry must + // be the name of an APEX module. + profileImports []string } // Target-dependent description of a boot image. @@ -384,7 +386,7 @@ func (image bootImageConfig) moduleName(ctx android.PathContext, idx int) string m := image.modules.Jar(idx) name := image.stem if idx != 0 || image.extends != nil { - name += "-" + android.ModuleStem(m) + name += "-" + android.ModuleStem(ctx.Config(), image.modules.Apex(idx), m) } return name } @@ -458,18 +460,26 @@ func (image *bootImageConfig) isProfileGuided() bool { return image.compilerFilter == "speed-profile" } +func (image *bootImageConfig) isEnabled(ctx android.BaseModuleContext) bool { + return ctx.OtherModuleExists(image.enabledIfExists) +} + func dexpreoptBootJarsFactory() android.SingletonModule { m := &dexpreoptBootJars{} - android.InitAndroidModule(m) + android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon) return m } func RegisterDexpreoptBootJarsComponents(ctx android.RegistrationContext) { ctx.RegisterParallelSingletonModuleType("dex_bootjars", dexpreoptBootJarsFactory) + ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) { + ctx.BottomUp("dex_bootjars_deps", DexpreoptBootJarsMutator).Parallel() + }) } func SkipDexpreoptBootJars(ctx android.PathContext) bool { - return dexpreopt.GetGlobalConfig(ctx).DisablePreoptBootImages + global := dexpreopt.GetGlobalConfig(ctx) + return global.DisablePreoptBootImages || !shouldBuildBootImages(ctx.Config(), global) } // Singleton module for generating boot image build rules. @@ -492,39 +502,90 @@ type dexpreoptBootJars struct { dexpreoptConfigForMake android.WritablePath } -// Provide paths to boot images for use by modules that depend upon them. -// -// The build rules are created in GenerateSingletonBuildActions(). -func (d *dexpreoptBootJars) GenerateAndroidBuildActions(ctx android.ModuleContext) { - // Placeholder for now. -} - -// Generate build rules for boot images. -func (d *dexpreoptBootJars) GenerateSingletonBuildActions(ctx android.SingletonContext) { - if dexpreopt.GetCachedGlobalSoongConfig(ctx) == nil { - // No module has enabled dexpreopting, so we assume there will be no boot image to make. +func DexpreoptBootJarsMutator(ctx android.BottomUpMutatorContext) { + if _, ok := ctx.Module().(*dexpreoptBootJars); !ok { return } - archType := ctx.Config().Targets[android.Android][0].Arch.ArchType - d.dexpreoptConfigForMake = android.PathForOutput(ctx, toDexpreoptDirName(archType), "dexpreopt.config") - writeGlobalConfigForMake(ctx, d.dexpreoptConfigForMake) - global := dexpreopt.GetGlobalConfig(ctx) - if !shouldBuildBootImages(ctx.Config(), global) { - return + if dexpreopt.IsDex2oatNeeded(ctx) { + // Add a dependency onto the dex2oat tool which is needed for creating the boot image. The + // path is retrieved from the dependency by GetGlobalSoongConfig(ctx). + dexpreopt.RegisterToolDeps(ctx) } - defaultImageConfig := defaultBootImageConfig(ctx) - d.defaultBootImage = defaultImageConfig imageConfigs := genBootImageConfigs(ctx) - d.otherImages = make([]*bootImageConfig, 0, len(imageConfigs)-1) for _, config := range imageConfigs { - if config != defaultImageConfig { + if !config.isEnabled(ctx) { + continue + } + // For accessing the boot jars. + addDependenciesOntoBootImageModules(ctx, config.modules, dexpreoptBootJarDepTag) + } + + if ctx.OtherModuleExists("platform-bootclasspath") { + // For accessing all bootclasspath fragments. + addDependencyOntoApexModulePair(ctx, "platform", "platform-bootclasspath", platformBootclasspathDepTag) + } else if ctx.OtherModuleExists("art-bootclasspath-fragment") { + // For accessing the ART bootclasspath fragment on a thin manifest (e.g., master-art) where + // platform-bootclasspath doesn't exist. + addDependencyOntoApexModulePair(ctx, "com.android.art", "art-bootclasspath-fragment", bootclasspathFragmentDepTag) + } +} + +func gatherBootclasspathFragments(ctx android.ModuleContext) map[string]android.Module { + return ctx.Config().Once(dexBootJarsFragmentsKey, func() interface{} { + fragments := make(map[string]android.Module) + ctx.WalkDeps(func(child, parent android.Module) bool { + if !isActiveModule(child) { + return false + } + tag := ctx.OtherModuleDependencyTag(child) + if tag == platformBootclasspathDepTag { + return true + } + if tag == bootclasspathFragmentDepTag { + apexInfo := ctx.OtherModuleProvider(child, android.ApexInfoProvider).(android.ApexInfo) + for _, apex := range apexInfo.InApexVariants { + fragments[apex] = child + } + return false + } + return false + }) + return fragments + }).(map[string]android.Module) +} + +func getBootclasspathFragmentByApex(ctx android.ModuleContext, apexName string) android.Module { + return gatherBootclasspathFragments(ctx)[apexName] +} + +// GenerateAndroidBuildActions generates the build rules for boot images. +func (d *dexpreoptBootJars) GenerateAndroidBuildActions(ctx android.ModuleContext) { + imageConfigs := genBootImageConfigs(ctx) + d.defaultBootImage = defaultBootImageConfig(ctx) + d.otherImages = make([]*bootImageConfig, 0, len(imageConfigs)-1) + for _, name := range getImageNames() { + config := imageConfigs[name] + if config != d.defaultBootImage { d.otherImages = append(d.otherImages, config) } + if !config.isEnabled(ctx) { + continue + } + generateBootImage(ctx, config) + if config == d.defaultBootImage { + bootFrameworkProfileRule(ctx, config) + } } } +// GenerateSingletonBuildActions generates build rules for the dexpreopt config for Make. +func (d *dexpreoptBootJars) GenerateSingletonBuildActions(ctx android.SingletonContext) { + d.dexpreoptConfigForMake = android.PathForOutput(ctx, getDexpreoptDirName(ctx), "dexpreopt.config") + writeGlobalConfigForMake(ctx, d.dexpreoptConfigForMake) +} + // shouldBuildBootImages determines whether boot images should be built. func shouldBuildBootImages(config android.Config, global *dexpreopt.GlobalConfig) bool { // Skip recompiling the boot image for the second sanitization phase. We'll get separate paths @@ -537,6 +598,101 @@ func shouldBuildBootImages(config android.Config, global *dexpreopt.GlobalConfig return true } +func generateBootImage(ctx android.ModuleContext, imageConfig *bootImageConfig) { + apexJarModulePairs := getModulesForImage(ctx, imageConfig) + + // Copy module dex jars to their predefined locations. + bootDexJarsByModule := extractEncodedDexJarsFromModulesOrBootclasspathFragments(ctx, apexJarModulePairs) + copyBootJarsToPredefinedLocations(ctx, bootDexJarsByModule, imageConfig.dexPathsByModule) + + // Build a profile for the image config from the profile at the default path. The profile will + // then be used along with profiles imported from APEXes to build the boot image. + profile := bootImageProfileRule(ctx, imageConfig) + + // If dexpreopt of boot image jars should be skipped, stop after generating a profile. + if SkipDexpreoptBootJars(ctx) { + return + } + + // Build boot image files for the android variants. + androidBootImageFiles := buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile) + + // Zip the android variant boot image files up. + buildBootImageZipInPredefinedLocation(ctx, imageConfig, androidBootImageFiles.byArch) + + // Build boot image files for the host variants. There are use directly by ART host side tests. + buildBootImageVariantsForBuildOs(ctx, imageConfig, profile) + + // Create a `dump-oat-<image-name>` rule that runs `oatdump` for debugging purposes. + dumpOatRules(ctx, imageConfig) +} + +type apexJarModulePair struct { + apex string + jarModule android.Module +} + +func getModulesForImage(ctx android.ModuleContext, imageConfig *bootImageConfig) []apexJarModulePair { + modules := make([]apexJarModulePair, 0, imageConfig.modules.Len()) + for i := 0; i < imageConfig.modules.Len(); i++ { + found := false + for _, module := range gatherApexModulePairDepsWithTag(ctx, dexpreoptBootJarDepTag) { + name := android.RemoveOptionalPrebuiltPrefix(module.Name()) + if name == imageConfig.modules.Jar(i) { + modules = append(modules, apexJarModulePair{ + apex: imageConfig.modules.Apex(i), + jarModule: module, + }) + found = true + break + } + } + if !found && !ctx.Config().AllowMissingDependencies() { + ctx.ModuleErrorf( + "Boot image '%s' module '%s' not added as a dependency of dex_bootjars", + imageConfig.name, + imageConfig.modules.Jar(i)) + return []apexJarModulePair{} + } + } + return modules +} + +// extractEncodedDexJarsFromModulesOrBootclasspathFragments gets the hidden API encoded dex jars for +// the given modules. +func extractEncodedDexJarsFromModulesOrBootclasspathFragments(ctx android.ModuleContext, apexJarModulePairs []apexJarModulePair) bootDexJarByModule { + encodedDexJarsByModuleName := bootDexJarByModule{} + for _, pair := range apexJarModulePairs { + var path android.Path + if android.IsConfiguredJarForPlatform(pair.apex) || android.IsModulePrebuilt(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 + // APEX. In practice, they are the same when we are building from a full source tree, but they + // are different when we are building from a thin manifest (e.g., master-art), where there is + // no monolithic hidden API files at all. + path = retrieveEncodedBootDexJarFromModule(ctx, pair.jarModule) + } else { + // Use exactly the same jar that is packed into the APEX. + fragment := getBootclasspathFragmentByApex(ctx, pair.apex) + if fragment == nil { + 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(), + pair.apex) + } + bootclasspathFragmentInfo := ctx.OtherModuleProvider(fragment, BootclasspathFragmentApexContentInfoProvider).(BootclasspathFragmentApexContentInfo) + jar, err := bootclasspathFragmentInfo.DexBootJarPathForContentModule(pair.jarModule) + if err != nil { + ctx.ModuleErrorf("%s", err) + } + path = jar + } + encodedDexJarsByModuleName.addPath(pair.jarModule, path) + } + return encodedDexJarsByModuleName +} + // copyBootJarsToPredefinedLocations generates commands that will copy boot jars to predefined // paths in the global config. func copyBootJarsToPredefinedLocations(ctx android.ModuleContext, srcBootDexJarsByModule bootDexJarByModule, dstBootJarsByModule map[string]android.WritablePath) { @@ -687,10 +843,12 @@ func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, p rule.Command().Text("rm").Flag("-f"). Flag(symbolsDir.Join(ctx, "*.art").String()). Flag(symbolsDir.Join(ctx, "*.oat").String()). + Flag(symbolsDir.Join(ctx, "*.vdex").String()). Flag(symbolsDir.Join(ctx, "*.invocation").String()) rule.Command().Text("rm").Flag("-f"). Flag(outputDir.Join(ctx, "*.art").String()). Flag(outputDir.Join(ctx, "*.oat").String()). + Flag(outputDir.Join(ctx, "*.vdex").String()). Flag(outputDir.Join(ctx, "*.invocation").String()) cmd := rule.Command() @@ -712,36 +870,31 @@ func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, p Flag("--runtime-arg").FlagWithArg("-Xms", global.Dex2oatImageXms). Flag("--runtime-arg").FlagWithArg("-Xmx", global.Dex2oatImageXmx) - if profile != nil { - cmd.FlagWithInput("--profile-file=", profile) - } - - fragments := make(map[string]commonBootclasspathFragment) - ctx.VisitDirectDepsWithTag(bootclasspathFragmentDepTag, func(child android.Module) { - fragment := child.(commonBootclasspathFragment) - if fragment.getImageName() != nil && android.IsModulePreferred(child) { - fragments[*fragment.getImageName()] = fragment + if image.isProfileGuided() && !global.DisableGenerateProfile { + if profile != nil { + cmd.FlagWithInput("--profile-file=", profile) } - }) - for _, profileImport := range image.profileImports { - fragment := fragments[profileImport.name] - if fragment == nil { - ctx.ModuleErrorf("Boot image config '%[1]s' imports profile from '%[2]s', but a "+ - "bootclasspath_fragment with image name '%[2]s' doesn't exist or is not added as a "+ - "dependency of '%[1]s'", - image.name, - profileImport.name) - return bootImageVariantOutputs{} - } - if fragment.getProfilePath() == nil { - ctx.ModuleErrorf("Boot image config '%[1]s' imports profile from '%[2]s', but '%[2]s' "+ - "doesn't provide a profile", - image.name, - profileImport.name) - return bootImageVariantOutputs{} + for _, apex := range image.profileImports { + fragment := getBootclasspathFragmentByApex(ctx, apex) + if fragment == nil { + ctx.ModuleErrorf("Boot image config '%[1]s' 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", + image.name, + apex) + return bootImageVariantOutputs{} + } + importedProfile := fragment.(commonBootclasspathFragment).getProfilePath() + if importedProfile == nil { + ctx.ModuleErrorf("Boot image config '%[1]s' imports profile from '%[2]s', but '%[2]s' "+ + "doesn't provide a profile", + image.name, + apex) + return bootImageVariantOutputs{} + } + cmd.FlagWithInput("--profile-file=", importedProfile) } - cmd.FlagWithInput("--profile-file=", fragment.getProfilePath()) } dirtyImageFile := "frameworks/base/config/dirty-image-objects" @@ -885,11 +1038,7 @@ 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.` -func bootImageProfileRule(ctx android.ModuleContext, image *bootImageConfig) android.WritablePath { - if !image.isProfileGuided() { - return nil - } - +func bootImageProfileRuleCommon(ctx android.ModuleContext, name string, dexFiles android.Paths, dexLocations []string) android.WritablePath { globalSoong := dexpreopt.GetGlobalSoongConfig(ctx) global := dexpreopt.GetGlobalConfig(ctx) @@ -916,28 +1065,39 @@ func bootImageProfileRule(ctx android.ModuleContext, image *bootImageConfig) and if path := android.ExistentPathForSource(ctx, extraProfile); path.Valid() { profiles = append(profiles, path.Path()) } - bootImageProfile := image.dir.Join(ctx, "boot-image-profile.txt") + bootImageProfile := android.PathForModuleOut(ctx, name, "boot-image-profile.txt") rule.Command().Text("cat").Inputs(profiles).Text(">").Output(bootImageProfile) - profile := image.dir.Join(ctx, "boot.prof") + profile := android.PathForModuleOut(ctx, name, "boot.prof") rule.Command(). Text(`ANDROID_LOG_TAGS="*:e"`). Tool(globalSoong.Profman). Flag("--output-profile-type=boot"). FlagWithInput("--create-profile-from=", bootImageProfile). - FlagForEachInput("--apk=", image.dexPathsDeps.Paths()). - FlagForEachArg("--dex-location=", image.getAnyAndroidVariant().dexLocationsDeps). + FlagForEachInput("--apk=", dexFiles). + FlagForEachArg("--dex-location=", dexLocations). FlagWithOutput("--reference-profile-file=", profile) + rule.Build("bootJarsProfile_"+name, "profile boot jars "+name) + + return profile +} + +func bootImageProfileRule(ctx android.ModuleContext, image *bootImageConfig) android.WritablePath { + if !image.isProfileGuided() { + return nil + } + + profile := bootImageProfileRuleCommon(ctx, image.name, image.dexPathsDeps.Paths(), image.getAnyAndroidVariant().dexLocationsDeps) + if image == defaultBootImageConfig(ctx) { + rule := android.NewRuleBuilder(pctx, ctx) rule.Install(profile, "/system/etc/boot-image.prof") image.profileInstalls = append(image.profileInstalls, rule.Installs()...) image.profileLicenseMetadataFile = android.OptionalPathForPath(ctx.LicenseMetadataFile()) } - rule.Build("bootJarsProfile", "profile boot jars") - return profile } @@ -976,6 +1136,8 @@ func bootFrameworkProfileRule(ctx android.ModuleContext, image *bootImageConfig) func dumpOatRules(ctx android.ModuleContext, image *bootImageConfig) { var allPhonies android.Paths + name := image.name + global := dexpreopt.GetGlobalConfig(ctx) for _, image := range image.variants { arch := image.target.Arch.ArchType suffix := arch.String() @@ -984,36 +1146,39 @@ func dumpOatRules(ctx android.ModuleContext, image *bootImageConfig) { suffix = "host-" + suffix } // Create a rule to call oatdump. - output := android.PathForOutput(ctx, "boot."+suffix+".oatdump.txt") + output := android.PathForOutput(ctx, name+"."+suffix+".oatdump.txt") rule := android.NewRuleBuilder(pctx, ctx) imageLocationsOnHost, _ := image.imageLocations() - rule.Command(). + cmd := rule.Command(). BuiltTool("oatdump"). FlagWithInputList("--runtime-arg -Xbootclasspath:", image.dexPathsDeps.Paths(), ":"). FlagWithList("--runtime-arg -Xbootclasspath-locations:", image.dexLocationsDeps, ":"). FlagWithArg("--image=", strings.Join(imageLocationsOnHost, ":")).Implicits(image.imagesDeps.Paths()). FlagWithOutput("--output=", output). FlagWithArg("--instruction-set=", arch.String()) - rule.Build("dump-oat-boot-"+suffix, "dump oat boot "+arch.String()) + if global.EnableUffdGc && image.target.Os == android.Android { + cmd.Flag("--runtime-arg").Flag("-Xgc:CMC") + } + rule.Build("dump-oat-"+name+"-"+suffix, "dump oat "+name+" "+arch.String()) // Create a phony rule that depends on the output file and prints the path. - phony := android.PathForPhony(ctx, "dump-oat-boot-"+suffix) + phony := android.PathForPhony(ctx, "dump-oat-"+name+"-"+suffix) rule = android.NewRuleBuilder(pctx, ctx) rule.Command(). Implicit(output). ImplicitOutput(phony). Text("echo").FlagWithArg("Output in ", output.String()) - rule.Build("phony-dump-oat-boot-"+suffix, "dump oat boot "+arch.String()) + rule.Build("phony-dump-oat-"+name+"-"+suffix, "dump oat "+name+" "+arch.String()) allPhonies = append(allPhonies, phony) } - phony := android.PathForPhony(ctx, "dump-oat-boot") + phony := android.PathForPhony(ctx, "dump-oat-"+name) ctx.Build(pctx, android.BuildParams{ Rule: android.Phony, Output: phony, Inputs: allPhonies, - Description: "dump-oat-boot", + Description: "dump-oat-"+name, }) } @@ -1048,11 +1213,9 @@ func (d *dexpreoptBootJars) MakeVars(ctx android.MakeVarsContext) { ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_FILES", strings.Join(dexPaths.Strings(), " ")) ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS", strings.Join(dexLocations, " ")) - var imageNames []string // The primary ART boot image is exposed to Make for testing (gtests) and benchmarking // (golem) purposes. for _, current := range append(d.otherImages, image) { - imageNames = append(imageNames, current.name) for _, variant := range current.variants { suffix := "" if variant.target.Os.Class == android.Host { @@ -1073,8 +1236,6 @@ func (d *dexpreoptBootJars) MakeVars(ctx android.MakeVarsContext) { ctx.Strict("DEXPREOPT_IMAGE_LOCATIONS_ON_DEVICE"+current.name, strings.Join(imageLocationsOnDevice, ":")) ctx.Strict("DEXPREOPT_IMAGE_ZIP_"+current.name, current.zip.String()) } - // Ensure determinism. - sort.Strings(imageNames) - ctx.Strict("DEXPREOPT_IMAGE_NAMES", strings.Join(imageNames, " ")) + ctx.Strict("DEXPREOPT_IMAGE_NAMES", strings.Join(getImageNames(), " ")) } } diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go index 28f50d7e3..0f4bd9b34 100644 --- a/java/dexpreopt_config.go +++ b/java/dexpreopt_config.go @@ -40,57 +40,67 @@ func dexpreoptTargets(ctx android.PathContext) []android.Target { } var ( - bootImageConfigKey = android.NewOnceKey("bootImageConfig") - bootImageConfigRawKey = android.NewOnceKey("bootImageConfigRaw") - artBootImageName = "art" - frameworkBootImageName = "boot" - mainlineBootImageName = "mainline" - bootImageStem = "boot" + bootImageConfigKey = android.NewOnceKey("bootImageConfig") + bootImageConfigRawKey = android.NewOnceKey("bootImageConfigRaw") + frameworkBootImageName = "boot" + mainlineBootImageName = "mainline" + bootImageStem = "boot" + profileInstallPathInApex = "etc/boot-image.prof" ) +// getImageNames returns an ordered list of image names. The order doesn't matter but needs to be +// deterministic. The names listed here must match the map keys returned by genBootImageConfigs. +func getImageNames() []string { + return []string{"art", "boot", "mainline"} +} + func genBootImageConfigRaw(ctx android.PathContext) map[string]*bootImageConfig { return ctx.Config().Once(bootImageConfigRawKey, func() interface{} { global := dexpreopt.GetGlobalConfig(ctx) - artModules := global.ArtApexJars - frameworkModules := global.BootJars // This includes `artModules`. + artBootImageName := "art" // Keep this local to avoid accidental references. + frameworkModules := global.BootJars // This includes `global.ArtApexJars`. mainlineBcpModules := global.ApexBootJars frameworkSubdir := "system/framework" - // ART config for the primary boot image in the ART apex. - // It includes the Core Libraries. + profileImports := []string{"com.android.art"} + + // ART boot image for testing only. Do not rely on it to make any build-time decision. artCfg := bootImageConfig{ - name: artBootImageName, - stem: bootImageStem, - installDir: "apex/art_boot_images/javalib", - profileInstallPathInApex: "etc/boot-image.prof", - modules: artModules, - preloadedClassesFile: "art/build/boot/preloaded-classes", - compilerFilter: "speed-profile", - singleImage: false, + name: artBootImageName, + enabledIfExists: "art-bootclasspath-fragment", + stem: bootImageStem, + installDir: "apex/art_boot_images/javalib", + modules: global.TestOnlyArtBootImageJars, + preloadedClassesFile: "art/build/boot/preloaded-classes", + compilerFilter: "speed-profile", + singleImage: false, + profileImports: profileImports, } // Framework config for the boot image extension. // It includes framework libraries and depends on the ART config. frameworkCfg := bootImageConfig{ name: frameworkBootImageName, + enabledIfExists: "platform-bootclasspath", stem: bootImageStem, installDir: frameworkSubdir, modules: frameworkModules, preloadedClassesFile: "frameworks/base/config/preloaded-classes", compilerFilter: "speed-profile", singleImage: false, - profileImports: []*bootImageConfig{&artCfg}, + profileImports: profileImports, } mainlineCfg := bootImageConfig{ - extends: &frameworkCfg, - name: mainlineBootImageName, - stem: bootImageStem, - installDir: frameworkSubdir, - modules: mainlineBcpModules, - compilerFilter: "verify", - singleImage: true, + extends: &frameworkCfg, + name: mainlineBootImageName, + enabledIfExists: "platform-bootclasspath", + stem: bootImageStem, + installDir: frameworkSubdir, + modules: mainlineBcpModules, + compilerFilter: "verify", + singleImage: true, } return map[string]*bootImageConfig{ @@ -105,8 +115,7 @@ func genBootImageConfigRaw(ctx android.PathContext) map[string]*bootImageConfig func genBootImageConfigs(ctx android.PathContext) map[string]*bootImageConfig { return ctx.Config().Once(bootImageConfigKey, func() interface{} { targets := dexpreoptTargets(ctx) - archType := ctx.Config().Targets[android.Android][0].Arch.ArchType - deviceDir := android.PathForOutput(ctx, toDexpreoptDirName(archType)) + deviceDir := android.PathForOutput(ctx, getDexpreoptDirName(ctx)) configs := genBootImageConfigRaw(ctx) @@ -181,10 +190,6 @@ func calculateDepsRecursive(c *bootImageConfig, targets []android.Target, visite } } -func artBootImageConfig(ctx android.PathContext) *bootImageConfig { - return genBootImageConfigs(ctx)[artBootImageName] -} - func defaultBootImageConfig(ctx android.PathContext) *bootImageConfig { return genBootImageConfigs(ctx)[frameworkBootImageName] } @@ -193,6 +198,18 @@ func mainlineBootImageConfig(ctx android.PathContext) *bootImageConfig { return genBootImageConfigs(ctx)[mainlineBootImageName] } +// isProfileProviderApex returns true if this apex provides a boot image profile. +func isProfileProviderApex(ctx android.PathContext, apexName string) bool { + for _, config := range genBootImageConfigs(ctx) { + for _, profileImport := range config.profileImports { + if profileImport == apexName { + return true + } + } + } + return false +} + // Apex boot config allows to access build/install paths of apex boot jars without going // through the usual trouble of registering dependencies on those modules and extracting build paths // from those dependencies. @@ -218,8 +235,7 @@ var updatableBootConfigKey = android.NewOnceKey("apexBootConfig") func GetApexBootConfig(ctx android.PathContext) apexBootConfig { return ctx.Config().Once(updatableBootConfigKey, func() interface{} { apexBootJars := dexpreopt.GetGlobalConfig(ctx).ApexBootJars - archType := ctx.Config().Targets[android.Android][0].Arch.ArchType - dir := android.PathForOutput(ctx, toDexpreoptDirName(archType), "apex_bootjars") + dir := android.PathForOutput(ctx, getDexpreoptDirName(ctx), "apex_bootjars") dexPaths := apexBootJars.BuildPaths(ctx, dir) dexPathsByModuleName := apexBootJars.BuildPathsByModule(ctx, dir) @@ -258,6 +274,11 @@ func dexpreoptConfigMakevars(ctx android.MakeVarsContext) { ctx.Strict("DEXPREOPT_BOOT_JARS_MODULES", strings.Join(defaultBootImageConfig(ctx).modules.CopyOfApexJarPairs(), ":")) } -func toDexpreoptDirName(arch android.ArchType) string { - return "dexpreopt_" + arch.String() +func getDexpreoptDirName(ctx android.PathContext) string { + prefix := "dexpreopt_" + targets := ctx.Config().Targets[android.Android] + if len(targets) > 0 { + return prefix+targets[0].Arch.ArchType.String() + } + return prefix+"unknown_target" } diff --git a/java/dexpreopt_config_test.go b/java/dexpreopt_config_test.go index cd7f295c8..44d2127fd 100644 --- a/java/dexpreopt_config_test.go +++ b/java/dexpreopt_config_test.go @@ -16,6 +16,7 @@ package java import ( "runtime" + "sort" "testing" "android/soong/android" @@ -35,3 +36,22 @@ func TestBootImageConfig(t *testing.T) { CheckFrameworkBootImageConfig(t, result) CheckMainlineBootImageConfig(t, result) } + +func TestImageNames(t *testing.T) { + result := android.GroupFixturePreparers( + PrepareForBootImageConfigTest, + ).RunTest(t) + + names := getImageNames() + sort.Strings(names) + + ctx := &android.TestPathContext{TestResult: result} + configs := genBootImageConfigs(ctx) + namesFromConfigs := make([]string, 0, len(configs)) + for name, _ := range configs { + namesFromConfigs = append(namesFromConfigs, name) + } + sort.Strings(namesFromConfigs) + + android.AssertArrayString(t, "getImageNames vs genBootImageConfigs", names, namesFromConfigs) +} diff --git a/java/dexpreopt_config_testing.go b/java/dexpreopt_config_testing.go index 6f3aa2be8..176c251fd 100644 --- a/java/dexpreopt_config_testing.go +++ b/java/dexpreopt_config_testing.go @@ -29,6 +29,7 @@ import ( "testing" "android/soong/android" + "android/soong/dexpreopt" ) // PrepareForBootImageConfigTest is the minimal set of preparers that are needed to be able to use @@ -36,7 +37,17 @@ import ( var PrepareForBootImageConfigTest = android.GroupFixturePreparers( android.PrepareForTestWithArchMutator, android.PrepareForTestAccessingMakeVars, + PrepareForTestWithDexpreopt, FixtureConfigureBootJars("com.android.art:core1", "com.android.art:core2", "platform:framework"), + dexpreopt.FixtureSetTestOnlyArtBootImageJars("com.android.art:core1", "com.android.art:core2", "platform:extra1"), + android.FixtureAddTextFile("extra1/Android.bp", ` + java_library { + name: "extra1", + srcs: ["extra1.java"], + installable: true, + } + `), + android.FixtureAddFile("extra1/extra1.java", nil), ) var PrepareApexBootJarConfigs = FixtureConfigureApexBootJars( @@ -44,18 +55,18 @@ var PrepareApexBootJarConfigs = FixtureConfigureApexBootJars( var PrepareApexBootJarConfigsAndModules = android.GroupFixturePreparers( PrepareApexBootJarConfigs, - prepareApexBootJarModule("com.android.foo", "framework-foo"), - prepareApexBootJarModule("com.android.bar", "framework-bar"), + PrepareApexBootJarModule("com.android.foo", "framework-foo"), + PrepareApexBootJarModule("com.android.bar", "framework-bar"), ) var ApexBootJarFragmentsForPlatformBootclasspath = fmt.Sprintf(` { apex: "%[1]s", - module: "%[1]s-bootclasspathfragment", + module: "%[1]s-bootclasspath-fragment", }, { apex: "%[2]s", - module: "%[2]s-bootclasspathfragment", + module: "%[2]s-bootclasspath-fragment", }, `, "com.android.foo", "com.android.bar") @@ -64,15 +75,22 @@ var ApexBootJarDexJarPaths = []string{ "out/soong/.intermediates/packages/modules/com.android.foo/framework-foo/android_common_apex10000/aligned/framework-foo.jar", } -func prepareApexBootJarModule(apexName string, moduleName string) android.FixturePreparer { +func PrepareApexBootJarModule(apexName string, moduleName string) android.FixturePreparer { moduleSourceDir := fmt.Sprintf("packages/modules/%s", apexName) + fragmentName := apexName+"-bootclasspath-fragment" + imageNameProp := "" + if apexName == "com.android.art" { + fragmentName = "art-bootclasspath-fragment" + imageNameProp = `image_name: "art",` + } + return android.GroupFixturePreparers( android.FixtureAddTextFile(moduleSourceDir+"/Android.bp", fmt.Sprintf(` apex { name: "%[1]s", key: "%[1]s.key", bootclasspath_fragments: [ - "%[1]s-bootclasspathfragment", + "%[3]s", ], updatable: false, } @@ -84,7 +102,8 @@ func prepareApexBootJarModule(apexName string, moduleName string) android.Fixtur } bootclasspath_fragment { - name: "%[1]s-bootclasspathfragment", + name: "%[3]s", + %[4]s contents: ["%[2]s"], apex_available: ["%[1]s"], hidden_api: { @@ -100,7 +119,7 @@ func prepareApexBootJarModule(apexName string, moduleName string) android.Fixtur compile_dex: true, apex_available: ["%[1]s"], } - `, apexName, moduleName)), + `, apexName, moduleName, fragmentName, imageNameProp)), android.FixtureMergeMockFs(android.MockFS{ fmt.Sprintf("%s/apex_manifest.json", moduleSourceDir): nil, fmt.Sprintf("%s/%s.avbpubkey", moduleSourceDir, apexName): nil, @@ -192,7 +211,7 @@ func CheckArtBootImageConfig(t *testing.T, result *android.TestResult) { // getArtImageConfig gets the ART bootImageConfig that was created during the test. func getArtImageConfig(result *android.TestResult) *bootImageConfig { pathCtx := &android.TestPathContext{TestResult: result} - imageConfig := artBootImageConfig(pathCtx) + imageConfig := genBootImageConfigs(pathCtx)["art"] return imageConfig } @@ -210,15 +229,15 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b symbolsDir: "out/soong/dexpreopt_arm64/dex_artjars_unstripped", installDir: "apex/art_boot_images/javalib", profileInstallPathInApex: "etc/boot-image.prof", - modules: android.CreateTestConfiguredJarList([]string{"com.android.art:core1", "com.android.art:core2"}), - dexPaths: []string{"out/soong/dexpreopt_arm64/dex_artjars_input/core1.jar", "out/soong/dexpreopt_arm64/dex_artjars_input/core2.jar"}, - dexPathsDeps: []string{"out/soong/dexpreopt_arm64/dex_artjars_input/core1.jar", "out/soong/dexpreopt_arm64/dex_artjars_input/core2.jar"}, + modules: android.CreateTestConfiguredJarList([]string{"com.android.art:core1", "com.android.art:core2", "platform:extra1"}), + dexPaths: []string{"out/soong/dexpreopt_arm64/dex_artjars_input/core1.jar", "out/soong/dexpreopt_arm64/dex_artjars_input/core2.jar", "out/soong/dexpreopt_arm64/dex_artjars_input/extra1.jar"}, + dexPathsDeps: []string{"out/soong/dexpreopt_arm64/dex_artjars_input/core1.jar", "out/soong/dexpreopt_arm64/dex_artjars_input/core2.jar", "out/soong/dexpreopt_arm64/dex_artjars_input/extra1.jar"}, zip: "out/soong/dexpreopt_arm64/dex_artjars/art.zip", variants: []*expectedVariant{ { archType: android.Arm64, - dexLocations: []string{"/apex/com.android.art/javalib/core1.jar", "/apex/com.android.art/javalib/core2.jar"}, - dexLocationsDeps: []string{"/apex/com.android.art/javalib/core1.jar", "/apex/com.android.art/javalib/core2.jar"}, + dexLocations: []string{"/apex/com.android.art/javalib/core1.jar", "/apex/com.android.art/javalib/core2.jar", "/system/framework/extra1.jar"}, + dexLocationsDeps: []string{"/apex/com.android.art/javalib/core1.jar", "/apex/com.android.art/javalib/core2.jar", "/system/framework/extra1.jar"}, imagePathOnHost: "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art", imagePathOnDevice: "/apex/art_boot_images/javalib/arm64/boot.art", imagesDeps: []string{ @@ -228,6 +247,9 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.art", "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.oat", "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.vdex", + "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-extra1.art", + "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-extra1.oat", + "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-extra1.vdex", }, installs: []normalizedInstall{ { @@ -246,6 +268,14 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b from: "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.oat", to: "/apex/art_boot_images/javalib/arm64/boot-core2.oat", }, + { + from: "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-extra1.art", + to: "/apex/art_boot_images/javalib/arm64/boot-extra1.art", + }, + { + from: "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-extra1.oat", + to: "/apex/art_boot_images/javalib/arm64/boot-extra1.oat", + }, }, vdexInstalls: []normalizedInstall{ { @@ -256,6 +286,10 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b from: "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.vdex", to: "/apex/art_boot_images/javalib/arm64/boot-core2.vdex", }, + { + from: "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-extra1.vdex", + to: "/apex/art_boot_images/javalib/arm64/boot-extra1.vdex", + }, }, unstrippedInstalls: []normalizedInstall{ { @@ -266,13 +300,17 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b from: "out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot-core2.oat", to: "/apex/art_boot_images/javalib/arm64/boot-core2.oat", }, + { + from: "out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot-extra1.oat", + to: "/apex/art_boot_images/javalib/arm64/boot-extra1.oat", + }, }, licenseMetadataFile: expectedLicenseMetadataFile, }, { archType: android.Arm, - dexLocations: []string{"/apex/com.android.art/javalib/core1.jar", "/apex/com.android.art/javalib/core2.jar"}, - dexLocationsDeps: []string{"/apex/com.android.art/javalib/core1.jar", "/apex/com.android.art/javalib/core2.jar"}, + dexLocations: []string{"/apex/com.android.art/javalib/core1.jar", "/apex/com.android.art/javalib/core2.jar", "/system/framework/extra1.jar"}, + dexLocationsDeps: []string{"/apex/com.android.art/javalib/core1.jar", "/apex/com.android.art/javalib/core2.jar", "/system/framework/extra1.jar"}, imagePathOnHost: "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art", imagePathOnDevice: "/apex/art_boot_images/javalib/arm/boot.art", imagesDeps: []string{ @@ -282,6 +320,9 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.art", "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.oat", "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.vdex", + "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-extra1.art", + "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-extra1.oat", + "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-extra1.vdex", }, installs: []normalizedInstall{ { @@ -300,6 +341,14 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b from: "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.oat", to: "/apex/art_boot_images/javalib/arm/boot-core2.oat", }, + { + from: "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-extra1.art", + to: "/apex/art_boot_images/javalib/arm/boot-extra1.art", + }, + { + from: "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-extra1.oat", + to: "/apex/art_boot_images/javalib/arm/boot-extra1.oat", + }, }, vdexInstalls: []normalizedInstall{ { @@ -310,6 +359,10 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b from: "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.vdex", to: "/apex/art_boot_images/javalib/arm/boot-core2.vdex", }, + { + from: "out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-extra1.vdex", + to: "/apex/art_boot_images/javalib/arm/boot-extra1.vdex", + }, }, unstrippedInstalls: []normalizedInstall{ { @@ -320,13 +373,17 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b from: "out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot-core2.oat", to: "/apex/art_boot_images/javalib/arm/boot-core2.oat", }, + { + from: "out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot-extra1.oat", + to: "/apex/art_boot_images/javalib/arm/boot-extra1.oat", + }, }, licenseMetadataFile: expectedLicenseMetadataFile, }, { archType: android.X86_64, - dexLocations: []string{"host/linux-x86/apex/com.android.art/javalib/core1.jar", "host/linux-x86/apex/com.android.art/javalib/core2.jar"}, - dexLocationsDeps: []string{"host/linux-x86/apex/com.android.art/javalib/core1.jar", "host/linux-x86/apex/com.android.art/javalib/core2.jar"}, + dexLocations: []string{"host/linux-x86/apex/com.android.art/javalib/core1.jar", "host/linux-x86/apex/com.android.art/javalib/core2.jar", "host/linux-x86/system/framework/extra1.jar"}, + dexLocationsDeps: []string{"host/linux-x86/apex/com.android.art/javalib/core1.jar", "host/linux-x86/apex/com.android.art/javalib/core2.jar", "host/linux-x86/system/framework/extra1.jar"}, imagePathOnHost: "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art", imagePathOnDevice: "/apex/art_boot_images/javalib/x86_64/boot.art", imagesDeps: []string{ @@ -336,6 +393,9 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.art", "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat", "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.vdex", + "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-extra1.art", + "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-extra1.oat", + "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-extra1.vdex", }, installs: []normalizedInstall{ { @@ -352,6 +412,13 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b from: "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat", to: "/apex/art_boot_images/javalib/x86_64/boot-core2.oat", }, + { + from: "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-extra1.art", + to: "/apex/art_boot_images/javalib/x86_64/boot-extra1.art", + }, { + from: "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-extra1.oat", + to: "/apex/art_boot_images/javalib/x86_64/boot-extra1.oat", + }, }, vdexInstalls: []normalizedInstall{ { @@ -362,6 +429,10 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b from: "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.vdex", to: "/apex/art_boot_images/javalib/x86_64/boot-core2.vdex", }, + { + from: "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-extra1.vdex", + to: "/apex/art_boot_images/javalib/x86_64/boot-extra1.vdex", + }, }, unstrippedInstalls: []normalizedInstall{ { @@ -372,13 +443,17 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b from: "out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat", to: "/apex/art_boot_images/javalib/x86_64/boot-core2.oat", }, + { + from: "out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-extra1.oat", + to: "/apex/art_boot_images/javalib/x86_64/boot-extra1.oat", + }, }, licenseMetadataFile: expectedLicenseMetadataFile, }, { archType: android.X86, - dexLocations: []string{"host/linux-x86/apex/com.android.art/javalib/core1.jar", "host/linux-x86/apex/com.android.art/javalib/core2.jar"}, - dexLocationsDeps: []string{"host/linux-x86/apex/com.android.art/javalib/core1.jar", "host/linux-x86/apex/com.android.art/javalib/core2.jar"}, + dexLocations: []string{"host/linux-x86/apex/com.android.art/javalib/core1.jar", "host/linux-x86/apex/com.android.art/javalib/core2.jar", "host/linux-x86/system/framework/extra1.jar"}, + dexLocationsDeps: []string{"host/linux-x86/apex/com.android.art/javalib/core1.jar", "host/linux-x86/apex/com.android.art/javalib/core2.jar", "host/linux-x86/system/framework/extra1.jar"}, imagePathOnHost: "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art", imagePathOnDevice: "/apex/art_boot_images/javalib/x86/boot.art", imagesDeps: []string{ @@ -388,6 +463,9 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.art", "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat", "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.vdex", + "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.art", + "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.oat", + "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.vdex", }, installs: []normalizedInstall{ { @@ -404,6 +482,13 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b from: "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat", to: "/apex/art_boot_images/javalib/x86/boot-core2.oat", }, + { + from: "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.art", + to: "/apex/art_boot_images/javalib/x86/boot-extra1.art", + }, { + from: "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.oat", + to: "/apex/art_boot_images/javalib/x86/boot-extra1.oat", + }, }, vdexInstalls: []normalizedInstall{ { @@ -414,6 +499,10 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b from: "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.vdex", to: "/apex/art_boot_images/javalib/x86/boot-core2.vdex", }, + { + from: "out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.vdex", + to: "/apex/art_boot_images/javalib/x86/boot-extra1.vdex", + }, }, unstrippedInstalls: []normalizedInstall{ { @@ -424,6 +513,10 @@ func checkArtBootImageConfig(t *testing.T, result *android.TestResult, mutated b from: "out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat", to: "/apex/art_boot_images/javalib/x86/boot-core2.oat", }, + { + from: "out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.oat", + to: "/apex/art_boot_images/javalib/x86/boot-extra1.oat", + }, }, licenseMetadataFile: expectedLicenseMetadataFile, }, @@ -805,8 +898,8 @@ func checkFrameworkBootImageConfig(t *testing.T, result *android.TestResult, mut }, }, profileInstalls: []normalizedInstall{ + {from: "out/soong/.intermediates/default/java/dex_bootjars/android_common/boot/boot.prof", to: "/system/etc/boot-image.prof"}, {from: "out/soong/dexpreopt_arm64/dex_bootjars/boot.bprof", to: "/system/etc/boot-image.bprof"}, - {from: "out/soong/dexpreopt_arm64/dex_bootjars/boot.prof", to: "/system/etc/boot-image.prof"}, }, profileLicenseMetadataFile: expectedLicenseMetadataFile, } @@ -1136,7 +1229,6 @@ func nestedCheckBootImageConfig(t *testing.T, imageConfig *bootImageConfig, expe android.AssertPathRelativeToTopEquals(t, "dir", expected.dir, imageConfig.dir) android.AssertPathRelativeToTopEquals(t, "symbolsDir", expected.symbolsDir, imageConfig.symbolsDir) android.AssertStringEquals(t, "installDir", expected.installDir, imageConfig.installDir) - android.AssertStringEquals(t, "profileInstallPathInApex", expected.profileInstallPathInApex, imageConfig.profileInstallPathInApex) android.AssertDeepEquals(t, "modules", expected.modules, imageConfig.modules) android.AssertPathsRelativeToTopEquals(t, "dexPaths", expected.dexPaths, imageConfig.dexPaths.Paths()) android.AssertPathsRelativeToTopEquals(t, "dexPathsDeps", expected.dexPathsDeps, imageConfig.dexPathsDeps.Paths()) @@ -1195,10 +1287,10 @@ DEXPREOPT_BOOTCLASSPATH_DEX_FILES=out/soong/dexpreopt_arm64/dex_bootjars_input/c DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS=/apex/com.android.art/javalib/core1.jar /apex/com.android.art/javalib/core2.jar /system/framework/framework.jar DEXPREOPT_BOOT_JARS_MODULES=com.android.art:core1:com.android.art:core2:platform:framework DEXPREOPT_GEN=out/host/linux-x86/bin/dexpreopt_gen -DEXPREOPT_IMAGE_BUILT_INSTALLED_art_arm=out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art:/apex/art_boot_images/javalib/arm/boot.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.oat:/apex/art_boot_images/javalib/arm/boot.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.art:/apex/art_boot_images/javalib/arm/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.oat:/apex/art_boot_images/javalib/arm/boot-core2.oat -DEXPREOPT_IMAGE_BUILT_INSTALLED_art_arm64=out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art:/apex/art_boot_images/javalib/arm64/boot.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.oat:/apex/art_boot_images/javalib/arm64/boot.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.art:/apex/art_boot_images/javalib/arm64/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.oat:/apex/art_boot_images/javalib/arm64/boot-core2.oat -DEXPREOPT_IMAGE_BUILT_INSTALLED_art_host_x86=out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art:/apex/art_boot_images/javalib/x86/boot.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat:/apex/art_boot_images/javalib/x86/boot.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.art:/apex/art_boot_images/javalib/x86/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat:/apex/art_boot_images/javalib/x86/boot-core2.oat -DEXPREOPT_IMAGE_BUILT_INSTALLED_art_host_x86_64=out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art:/apex/art_boot_images/javalib/x86_64/boot.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.oat:/apex/art_boot_images/javalib/x86_64/boot.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.art:/apex/art_boot_images/javalib/x86_64/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat:/apex/art_boot_images/javalib/x86_64/boot-core2.oat +DEXPREOPT_IMAGE_BUILT_INSTALLED_art_arm=out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art:/apex/art_boot_images/javalib/arm/boot.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.oat:/apex/art_boot_images/javalib/arm/boot.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.art:/apex/art_boot_images/javalib/arm/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.oat:/apex/art_boot_images/javalib/arm/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-extra1.art:/apex/art_boot_images/javalib/arm/boot-extra1.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-extra1.oat:/apex/art_boot_images/javalib/arm/boot-extra1.oat +DEXPREOPT_IMAGE_BUILT_INSTALLED_art_arm64=out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art:/apex/art_boot_images/javalib/arm64/boot.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.oat:/apex/art_boot_images/javalib/arm64/boot.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.art:/apex/art_boot_images/javalib/arm64/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.oat:/apex/art_boot_images/javalib/arm64/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-extra1.art:/apex/art_boot_images/javalib/arm64/boot-extra1.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-extra1.oat:/apex/art_boot_images/javalib/arm64/boot-extra1.oat +DEXPREOPT_IMAGE_BUILT_INSTALLED_art_host_x86=out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art:/apex/art_boot_images/javalib/x86/boot.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat:/apex/art_boot_images/javalib/x86/boot.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.art:/apex/art_boot_images/javalib/x86/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat:/apex/art_boot_images/javalib/x86/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.art:/apex/art_boot_images/javalib/x86/boot-extra1.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.oat:/apex/art_boot_images/javalib/x86/boot-extra1.oat +DEXPREOPT_IMAGE_BUILT_INSTALLED_art_host_x86_64=out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art:/apex/art_boot_images/javalib/x86_64/boot.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.oat:/apex/art_boot_images/javalib/x86_64/boot.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.art:/apex/art_boot_images/javalib/x86_64/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat:/apex/art_boot_images/javalib/x86_64/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-extra1.art:/apex/art_boot_images/javalib/x86_64/boot-extra1.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-extra1.oat:/apex/art_boot_images/javalib/x86_64/boot-extra1.oat DEXPREOPT_IMAGE_BUILT_INSTALLED_boot_arm=out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot.art:/system/framework/arm/boot.art out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot.oat:/system/framework/arm/boot.oat out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot-core2.art:/system/framework/arm/boot-core2.art out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot-core2.oat:/system/framework/arm/boot-core2.oat out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot-framework.art:/system/framework/arm/boot-framework.art out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot-framework.oat:/system/framework/arm/boot-framework.oat DEXPREOPT_IMAGE_BUILT_INSTALLED_boot_arm64=out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot.art:/system/framework/arm64/boot.art out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot.oat:/system/framework/arm64/boot.oat out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot-core2.art:/system/framework/arm64/boot-core2.art out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot-core2.oat:/system/framework/arm64/boot-core2.oat out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot-framework.art:/system/framework/arm64/boot-framework.art out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot-framework.oat:/system/framework/arm64/boot-framework.oat DEXPREOPT_IMAGE_BUILT_INSTALLED_boot_host_x86=out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot.art:/system/framework/x86/boot.art out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot.oat:/system/framework/x86/boot.oat out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot-core2.art:/system/framework/x86/boot-core2.art out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot-core2.oat:/system/framework/x86/boot-core2.oat out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.art:/system/framework/x86/boot-framework.art out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.oat:/system/framework/x86/boot-framework.oat @@ -1207,10 +1299,10 @@ DEXPREOPT_IMAGE_BUILT_INSTALLED_mainline_arm=out/soong/dexpreopt_arm64/dex_mainl DEXPREOPT_IMAGE_BUILT_INSTALLED_mainline_arm64=out/soong/dexpreopt_arm64/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.art:/system/framework/arm64/boot-framework-foo.art out/soong/dexpreopt_arm64/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.oat:/system/framework/arm64/boot-framework-foo.oat DEXPREOPT_IMAGE_BUILT_INSTALLED_mainline_host_x86=out/soong/dexpreopt_arm64/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.art:/system/framework/x86/boot-framework-foo.art out/soong/dexpreopt_arm64/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.oat:/system/framework/x86/boot-framework-foo.oat DEXPREOPT_IMAGE_BUILT_INSTALLED_mainline_host_x86_64=out/soong/dexpreopt_arm64/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.art:/system/framework/x86_64/boot-framework-foo.art out/soong/dexpreopt_arm64/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.oat:/system/framework/x86_64/boot-framework-foo.oat -DEXPREOPT_IMAGE_DEPS_art_arm=out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.vdex -DEXPREOPT_IMAGE_DEPS_art_arm64=out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.vdex -DEXPREOPT_IMAGE_DEPS_art_host_x86=out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.vdex -DEXPREOPT_IMAGE_DEPS_art_host_x86_64=out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.vdex +DEXPREOPT_IMAGE_DEPS_art_arm=out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.vdex out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-extra1.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-extra1.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-extra1.vdex +DEXPREOPT_IMAGE_DEPS_art_arm64=out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.vdex out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-extra1.art out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-extra1.oat out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-extra1.vdex +DEXPREOPT_IMAGE_DEPS_art_host_x86=out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.vdex out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.vdex +DEXPREOPT_IMAGE_DEPS_art_host_x86_64=out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.vdex out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-extra1.art out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-extra1.oat out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-extra1.vdex DEXPREOPT_IMAGE_DEPS_boot_arm=out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot.art out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot.oat out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot.vdex out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot-core2.art out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot-core2.oat out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot-core2.vdex out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot-framework.art out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot-framework.oat out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot-framework.vdex DEXPREOPT_IMAGE_DEPS_boot_arm64=out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot.art out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot.oat out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot.vdex out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot-core2.art out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot-core2.oat out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot-core2.vdex out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot-framework.art out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot-framework.oat out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot-framework.vdex DEXPREOPT_IMAGE_DEPS_boot_host_x86=out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot.art out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot.oat out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot.vdex out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot-core2.art out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot-core2.oat out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot-core2.vdex out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.art out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.oat out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.vdex @@ -1223,14 +1315,14 @@ DEXPREOPT_IMAGE_LICENSE_METADATA_art_arm=%[1]s DEXPREOPT_IMAGE_LICENSE_METADATA_art_arm64=%[1]s DEXPREOPT_IMAGE_LICENSE_METADATA_art_host_x86=%[1]s DEXPREOPT_IMAGE_LICENSE_METADATA_art_host_x86_64=%[1]s -DEXPREOPT_IMAGE_LICENSE_METADATA_boot_arm=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic -DEXPREOPT_IMAGE_LICENSE_METADATA_boot_arm64=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic -DEXPREOPT_IMAGE_LICENSE_METADATA_boot_host_x86=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic -DEXPREOPT_IMAGE_LICENSE_METADATA_boot_host_x86_64=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic -DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_arm=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic -DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_arm64=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic -DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_host_x86=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic -DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_host_x86_64=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic +DEXPREOPT_IMAGE_LICENSE_METADATA_boot_arm=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic +DEXPREOPT_IMAGE_LICENSE_METADATA_boot_arm64=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic +DEXPREOPT_IMAGE_LICENSE_METADATA_boot_host_x86=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic +DEXPREOPT_IMAGE_LICENSE_METADATA_boot_host_x86_64=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic +DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_arm=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic +DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_arm64=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic +DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_host_x86=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic +DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_host_x86_64=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic DEXPREOPT_IMAGE_LOCATIONS_ON_DEVICEart=/apex/art_boot_images/javalib/boot.art DEXPREOPT_IMAGE_LOCATIONS_ON_DEVICEboot=/system/framework/boot.art DEXPREOPT_IMAGE_LOCATIONS_ON_DEVICEmainline=/system/framework/boot.art:/system/framework/boot-framework-foo.art @@ -1238,12 +1330,12 @@ DEXPREOPT_IMAGE_LOCATIONS_ON_HOSTart=out/soong/dexpreopt_arm64/dex_artjars/andro DEXPREOPT_IMAGE_LOCATIONS_ON_HOSTboot=out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/boot.art DEXPREOPT_IMAGE_LOCATIONS_ON_HOSTmainline=out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/boot.art:out/soong/dexpreopt_arm64/dex_mainlinejars/android/system/framework/boot-framework-foo.art DEXPREOPT_IMAGE_NAMES=art boot mainline -DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED=out/soong/dexpreopt_arm64/dex_bootjars/boot.bprof:/system/etc/boot-image.bprof out/soong/dexpreopt_arm64/dex_bootjars/boot.prof:/system/etc/boot-image.prof -DEXPREOPT_IMAGE_PROFILE_LICENSE_METADATA=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic -DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_arm=out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot.oat:/apex/art_boot_images/javalib/arm/boot.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot-core2.oat:/apex/art_boot_images/javalib/arm/boot-core2.oat -DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_arm64=out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot.oat:/apex/art_boot_images/javalib/arm64/boot.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot-core2.oat:/apex/art_boot_images/javalib/arm64/boot-core2.oat -DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_host_x86=out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat:/apex/art_boot_images/javalib/x86/boot.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat:/apex/art_boot_images/javalib/x86/boot-core2.oat -DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_host_x86_64=out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.oat:/apex/art_boot_images/javalib/x86_64/boot.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat:/apex/art_boot_images/javalib/x86_64/boot-core2.oat +DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED=out/soong/.intermediates/default/java/dex_bootjars/android_common/boot/boot.prof:/system/etc/boot-image.prof out/soong/dexpreopt_arm64/dex_bootjars/boot.bprof:/system/etc/boot-image.bprof +DEXPREOPT_IMAGE_PROFILE_LICENSE_METADATA=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic +DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_arm=out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot.oat:/apex/art_boot_images/javalib/arm/boot.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot-core2.oat:/apex/art_boot_images/javalib/arm/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot-extra1.oat:/apex/art_boot_images/javalib/arm/boot-extra1.oat +DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_arm64=out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot.oat:/apex/art_boot_images/javalib/arm64/boot.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot-core2.oat:/apex/art_boot_images/javalib/arm64/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot-extra1.oat:/apex/art_boot_images/javalib/arm64/boot-extra1.oat +DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_host_x86=out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat:/apex/art_boot_images/javalib/x86/boot.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat:/apex/art_boot_images/javalib/x86/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.oat:/apex/art_boot_images/javalib/x86/boot-extra1.oat +DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_host_x86_64=out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.oat:/apex/art_boot_images/javalib/x86_64/boot.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat:/apex/art_boot_images/javalib/x86_64/boot-core2.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-extra1.oat:/apex/art_boot_images/javalib/x86_64/boot-extra1.oat DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_boot_arm=out/soong/dexpreopt_arm64/dex_bootjars_unstripped/android/system/framework/arm/boot.oat:/system/framework/arm/boot.oat out/soong/dexpreopt_arm64/dex_bootjars_unstripped/android/system/framework/arm/boot-core2.oat:/system/framework/arm/boot-core2.oat out/soong/dexpreopt_arm64/dex_bootjars_unstripped/android/system/framework/arm/boot-framework.oat:/system/framework/arm/boot-framework.oat DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_boot_arm64=out/soong/dexpreopt_arm64/dex_bootjars_unstripped/android/system/framework/arm64/boot.oat:/system/framework/arm64/boot.oat out/soong/dexpreopt_arm64/dex_bootjars_unstripped/android/system/framework/arm64/boot-core2.oat:/system/framework/arm64/boot-core2.oat out/soong/dexpreopt_arm64/dex_bootjars_unstripped/android/system/framework/arm64/boot-framework.oat:/system/framework/arm64/boot-framework.oat DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_boot_host_x86=out/soong/dexpreopt_arm64/dex_bootjars_unstripped/linux_glibc/system/framework/x86/boot.oat:/system/framework/x86/boot.oat out/soong/dexpreopt_arm64/dex_bootjars_unstripped/linux_glibc/system/framework/x86/boot-core2.oat:/system/framework/x86/boot-core2.oat out/soong/dexpreopt_arm64/dex_bootjars_unstripped/linux_glibc/system/framework/x86/boot-framework.oat:/system/framework/x86/boot-framework.oat @@ -1252,10 +1344,10 @@ DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_mainline_arm=out/soong/dexpreopt_arm6 DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_mainline_arm64=out/soong/dexpreopt_arm64/dex_mainlinejars_unstripped/android/system/framework/arm64/boot-framework-foo.oat:/system/framework/arm64/boot-framework-foo.oat DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_mainline_host_x86=out/soong/dexpreopt_arm64/dex_mainlinejars_unstripped/linux_glibc/system/framework/x86/boot-framework-foo.oat:/system/framework/x86/boot-framework-foo.oat DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_mainline_host_x86_64=out/soong/dexpreopt_arm64/dex_mainlinejars_unstripped/linux_glibc/system/framework/x86_64/boot-framework-foo.oat:/system/framework/x86_64/boot-framework-foo.oat -DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_arm=out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.vdex:/apex/art_boot_images/javalib/arm/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.vdex:/apex/art_boot_images/javalib/arm/boot-core2.vdex -DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_arm64=out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.vdex:/apex/art_boot_images/javalib/arm64/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.vdex:/apex/art_boot_images/javalib/arm64/boot-core2.vdex -DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_host_x86=out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.vdex:/apex/art_boot_images/javalib/x86/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.vdex:/apex/art_boot_images/javalib/x86/boot-core2.vdex -DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_host_x86_64=out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.vdex:/apex/art_boot_images/javalib/x86_64/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.vdex:/apex/art_boot_images/javalib/x86_64/boot-core2.vdex +DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_arm=out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.vdex:/apex/art_boot_images/javalib/arm/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.vdex:/apex/art_boot_images/javalib/arm/boot-core2.vdex out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-extra1.vdex:/apex/art_boot_images/javalib/arm/boot-extra1.vdex +DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_arm64=out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.vdex:/apex/art_boot_images/javalib/arm64/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.vdex:/apex/art_boot_images/javalib/arm64/boot-core2.vdex out/soong/dexpreopt_arm64/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-extra1.vdex:/apex/art_boot_images/javalib/arm64/boot-extra1.vdex +DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_host_x86=out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.vdex:/apex/art_boot_images/javalib/x86/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.vdex:/apex/art_boot_images/javalib/x86/boot-core2.vdex out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-extra1.vdex:/apex/art_boot_images/javalib/x86/boot-extra1.vdex +DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_host_x86_64=out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.vdex:/apex/art_boot_images/javalib/x86_64/boot.vdex out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.vdex:/apex/art_boot_images/javalib/x86_64/boot-core2.vdex out/soong/dexpreopt_arm64/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-extra1.vdex:/apex/art_boot_images/javalib/x86_64/boot-extra1.vdex DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_boot_arm=out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot.vdex:/system/framework/arm/boot.vdex out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot-core2.vdex:/system/framework/arm/boot-core2.vdex out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm/boot-framework.vdex:/system/framework/arm/boot-framework.vdex DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_boot_arm64=out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot.vdex:/system/framework/arm64/boot.vdex out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot-core2.vdex:/system/framework/arm64/boot-core2.vdex out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot-framework.vdex:/system/framework/arm64/boot-framework.vdex DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_boot_host_x86=out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot.vdex:/system/framework/x86/boot.vdex out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot-core2.vdex:/system/framework/x86/boot-core2.vdex out/soong/dexpreopt_arm64/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.vdex:/system/framework/x86/boot-framework.vdex diff --git a/java/droidstubs.go b/java/droidstubs.go index 151c94a43..bb2388f96 100644 --- a/java/droidstubs.go +++ b/java/droidstubs.go @@ -525,8 +525,7 @@ func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersi cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":") } - cmd.Flag("--no-banner"). - Flag("--color"). + cmd.Flag("--color"). Flag("--quiet"). Flag("--format=v2"). FlagWithArg("--repeat-errors-max ", "10"). diff --git a/java/fuzz_test.go b/java/fuzz_test.go index dd1e96b3e..f29c91327 100644 --- a/java/fuzz_test.go +++ b/java/fuzz_test.go @@ -71,8 +71,8 @@ func TestJavaFuzz(t *testing.T) { } baz := result.ModuleForTests("baz", osCommonTarget).Rule("javac").Output.String() - barOut := filepath.Join("out", "soong", ".intermediates", "bar", osCommonTarget, "javac", "bar.jar") - bazOut := filepath.Join("out", "soong", ".intermediates", "baz", osCommonTarget, "javac", "baz.jar") + barOut := filepath.Join("out", "soong", ".intermediates", "bar", osCommonTarget, "javac-header", "bar.jar") + bazOut := filepath.Join("out", "soong", ".intermediates", "baz", osCommonTarget, "javac-header", "baz.jar") android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], barOut) android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], bazOut) diff --git a/java/generated_java_library.go b/java/generated_java_library.go index 1b3de9fe0..f9baa85e4 100644 --- a/java/generated_java_library.go +++ b/java/generated_java_library.go @@ -30,7 +30,7 @@ type GeneratedJavaLibraryCallbacks interface { // Called from inside GenerateAndroidBuildActions. Add the build rules to // make the srcjar, and return the path to it. - GenerateSourceJarBuildActions(ctx android.ModuleContext) android.Path + GenerateSourceJarBuildActions(module *GeneratedJavaLibraryModule, ctx android.ModuleContext) android.Path } // GeneratedJavaLibraryModuleFactory provides a utility for modules that are generated @@ -88,7 +88,7 @@ func (module *GeneratedJavaLibraryModule) GenerateAndroidBuildActions(ctx androi checkPropertyEmpty(ctx, module, "plugins", module.Library.properties.Plugins) checkPropertyEmpty(ctx, module, "exported_plugins", module.Library.properties.Exported_plugins) - srcJarPath := module.callbacks.GenerateSourceJarBuildActions(ctx) + srcJarPath := module.callbacks.GenerateSourceJarBuildActions(module, ctx) module.Library.properties.Generated_srcjars = append(module.Library.properties.Generated_srcjars, srcJarPath) module.Library.GenerateAndroidBuildActions(ctx) } diff --git a/java/generated_java_library_test.go b/java/generated_java_library_test.go index 68f1f7edd..7f52fd108 100644 --- a/java/generated_java_library_test.go +++ b/java/generated_java_library_test.go @@ -36,7 +36,8 @@ type JavaGenLibTestCallbacks struct { func (callbacks *JavaGenLibTestCallbacks) DepsMutator(module *GeneratedJavaLibraryModule, ctx android.BottomUpMutatorContext) { } -func (callbacks *JavaGenLibTestCallbacks) GenerateSourceJarBuildActions(ctx android.ModuleContext) android.Path { +func (callbacks *JavaGenLibTestCallbacks) GenerateSourceJarBuildActions(module *GeneratedJavaLibraryModule, ctx android.ModuleContext) android.Path { + module.AddAconfigIntermediate(android.PathForOutput(ctx, "aconfig_cache_file")) return android.PathForOutput(ctx, "blah.srcjar") } diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go index c6b921bb2..f31f5d1a8 100644 --- a/java/hiddenapi_modular.go +++ b/java/hiddenapi_modular.go @@ -1236,7 +1236,6 @@ func buildRuleToGenerateRemovedDexSignatures(ctx android.ModuleContext, suffix s rule := android.NewRuleBuilder(pctx, ctx) rule.Command(). BuiltTool("metalava"). - Flag("--no-banner"). Inputs(removedTxtFiles). FlagWithOutput("--dex-api ", output) rule.Build("modular-hiddenapi-removed-dex-signatures"+suffix, "modular hiddenapi removed dex signatures"+suffix) diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go index d4ee4fc9f..714634f58 100644 --- a/java/hiddenapi_singleton.go +++ b/java/hiddenapi_singleton.go @@ -166,7 +166,7 @@ func isModuleInConfiguredList(ctx android.BaseModuleContext, module android.Modu // Now match the apex part of the boot image configuration. requiredApex := configuredBootJars.Apex(index) - if requiredApex == "platform" || requiredApex == "system_ext" { + if android.IsConfiguredJarForPlatform(requiredApex) { if len(apexInfo.InApexVariants) != 0 { // A platform variant is required but this is for an apex so ignore it. return false diff --git a/java/java.go b/java/java.go index 50d48ab6d..f29f7383a 100644 --- a/java/java.go +++ b/java/java.go @@ -274,7 +274,14 @@ type JavaInfo struct { // instrumented by jacoco. JacocoReportClassesFile android.Path - // TODO: Add device config declarations here? + // set of aconfig flags for all transitive libs deps + // TODO(joeo): It would be nice if this were over in the aconfig package instead of here. + // In order to do that, generated_java_library would need a way doing + // collectTransitiveAconfigFiles with one of the callbacks, and having that automatically + // propagated. If we were to clean up more of the stuff on JavaInfo that's not part of + // core java rules (e.g. AidlIncludeDirs), then maybe adding more framework to do that would be + // worth it. + TransitiveAconfigFiles *android.DepSet[android.Path] } var JavaInfoProvider = blueprint.NewProvider(JavaInfo{}) @@ -676,6 +683,8 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.minSdkVersion = j.MinSdkVersion(ctx) j.maxSdkVersion = j.MaxSdkVersion(ctx) + j.stem = proptools.StringDefault(j.overridableDeviceProperties.Stem, ctx.ModuleName()) + apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) if !apexInfo.IsForPlatform() { j.hideApexVariantFromMake = true @@ -690,7 +699,7 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex j.classLoaderContexts = j.usesLibrary.classLoaderContextForUsesLibDeps(ctx) } - j.compile(ctx, nil) + j.compile(ctx, nil, nil, nil) // Collect the module directory for IDE info in java/jdeps.go. j.modulePaths = append(j.modulePaths, ctx.ModuleDir()) @@ -728,6 +737,7 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { } }) j.exportedProguardFlagFiles = android.FirstUniquePaths(j.exportedProguardFlagFiles) + } func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) { @@ -1468,6 +1478,8 @@ func (j *Binary) HostToolPath() android.OptionalPath { } func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) { + j.stem = proptools.StringDefault(j.overridableDeviceProperties.Stem, ctx.ModuleName()) + if ctx.Arch().ArchType == android.Common { // Compile the jar if j.binaryProperties.Main_class != nil { @@ -1716,8 +1728,7 @@ func metalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder, FlagWithArg("-encoding ", "UTF-8"). FlagWithInputList("--source-files ", srcs, " ") - cmd.Flag("--no-banner"). - Flag("--color"). + cmd.Flag("--color"). Flag("--quiet"). Flag("--format=v2"). Flag("--include-annotations"). @@ -1878,8 +1889,10 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { flags.javacFlags = strings.Join(al.properties.Javacflags, " ") flags.classpath = classpath(classPaths) + annoSrcJar := android.PathForModuleOut(ctx, ctx.ModuleName(), "anno.srcjar") + TransformJavaToClasses(ctx, al.stubsJarWithoutStaticLibs, 0, android.Paths{}, - android.Paths{al.stubsSrcJar}, flags, android.Paths{}) + android.Paths{al.stubsSrcJar}, annoSrcJar, flags, android.Paths{}) } builder := android.NewRuleBuilder(pctx, ctx) @@ -1911,6 +1924,7 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { ImplementationAndResourcesJars: android.PathsIfNonNil(al.stubsJar), ImplementationJars: android.PathsIfNonNil(al.stubsJar), AidlIncludeDirs: android.Paths{}, + // No aconfig libraries on api libraries }) } @@ -2232,6 +2246,7 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { ImplementationAndResourcesJars: android.PathsIfNonNil(j.combinedClasspathFile), ImplementationJars: android.PathsIfNonNil(j.combinedClasspathFile), AidlIncludeDirs: j.exportAidlIncludeDirs, + // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts }) } @@ -2652,7 +2667,7 @@ func (ks *kytheExtractJavaSingleton) GenerateBuildActions(ctx android.SingletonC var Bool = proptools.Bool var BoolDefault = proptools.BoolDefault var String = proptools.String -var inList = android.InList +var inList = android.InList[string] // Add class loader context (CLC) of a given dependency to the current CLC. func addCLCFromDep(ctx android.ModuleContext, depModule android.Module, @@ -2766,11 +2781,12 @@ func (m *Library) convertJavaResourcesAttributes(ctx android.TopDownMutatorConte type javaCommonAttributes struct { *javaResourcesAttributes *kotlinAttributes - Srcs bazel.LabelListAttribute - Plugins bazel.LabelListAttribute - Javacopts bazel.StringListAttribute - Sdk_version bazel.StringAttribute - Java_version bazel.StringAttribute + Srcs bazel.LabelListAttribute + Plugins bazel.LabelListAttribute + Javacopts bazel.StringListAttribute + Sdk_version bazel.StringAttribute + Java_version bazel.StringAttribute + Errorprone_force_enable bazel.BoolAttribute } type javaDependencyLabels struct { @@ -2803,12 +2819,8 @@ type bp2BuildJavaInfo struct { hasKotlin bool } -// Replaces //a/b/my_xsd_config with //a/b/my_xsd_config-java -func xsdConfigJavaTarget(ctx android.BazelConversionPathContext, mod blueprint.Module) string { - callback := func(xsd android.XsdConfigBp2buildTargets) string { - return xsd.JavaBp2buildTargetName() - } - return android.XsdConfigBp2buildTarget(ctx, mod, callback) +func javaXsdTargetName(xsd android.XsdConfigBp2buildTargets) string { + return xsd.JavaBp2buildTargetName() } // convertLibraryAttrsBp2Build returns a javaCommonAttributes struct with @@ -2819,21 +2831,14 @@ func xsdConfigJavaTarget(ctx android.BazelConversionPathContext, mod blueprint.M func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) (*javaCommonAttributes, *bp2BuildJavaInfo) { var srcs bazel.LabelListAttribute var deps bazel.LabelListAttribute - var staticDeps bazel.LabelList + var staticDeps bazel.LabelListAttribute archVariantProps := m.GetArchVariantProperties(ctx, &CommonProperties{}) for axis, configToProps := range archVariantProps { for config, _props := range configToProps { if archProps, ok := _props.(*CommonProperties); ok { - srcsNonXsd, srcsXsd := android.PartitionXsdSrcs(ctx, archProps.Srcs) - excludeSrcsNonXsd, _ := android.PartitionXsdSrcs(ctx, archProps.Exclude_srcs) - archSrcs := android.BazelLabelForModuleSrcExcludes(ctx, srcsNonXsd, excludeSrcsNonXsd) + archSrcs := android.BazelLabelForModuleSrcExcludes(ctx, archProps.Srcs, archProps.Exclude_srcs) srcs.SetSelectValue(axis, config, archSrcs) - - // Add to static deps - xsdJavaConfigLibraryLabels := android.BazelLabelForModuleDepsWithFn(ctx, srcsXsd, xsdConfigJavaTarget) - staticDeps.Append(xsdJavaConfigLibraryLabels) - } } } @@ -2841,6 +2846,7 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) javaSrcPartition := "java" protoSrcPartition := "proto" + xsdSrcPartition := "xsd" logtagSrcPartition := "logtag" aidlSrcPartition := "aidl" kotlinPartition := "kotlin" @@ -2849,6 +2855,7 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) logtagSrcPartition: bazel.LabelPartition{Extensions: []string{".logtags", ".logtag"}}, protoSrcPartition: android.ProtoSrcLabelPartition, aidlSrcPartition: android.AidlSrcLabelPartition, + xsdSrcPartition: bazel.LabelPartition{LabelMapper: android.XsdLabelMapper(javaXsdTargetName)}, kotlinPartition: bazel.LabelPartition{Extensions: []string{".kt"}}, }) @@ -2856,6 +2863,8 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) kotlinSrcs := srcPartitions[kotlinPartition] javaSrcs.Append(kotlinSrcs) + staticDeps.Append(srcPartitions[xsdSrcPartition]) + if !srcPartitions[logtagSrcPartition].IsEmpty() { logtagsLibName := m.Name() + "_logtags" ctx.CreateBazelTargetModule( @@ -2909,29 +2918,38 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) }, ) - staticDeps.Add(&bazel.Label{Label: ":" + javaAidlLibName}) + staticDeps.Append(bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + javaAidlLibName})) } - var javacopts []string + var javacopts bazel.StringListAttribute //[]string + plugins := bazel.MakeLabelListAttribute( + android.BazelLabelForModuleDeps(ctx, m.properties.Plugins), + ) if m.properties.Javacflags != nil { - javacopts = append(javacopts, m.properties.Javacflags...) + javacopts = bazel.MakeStringListAttribute(m.properties.Javacflags) } epEnabled := m.properties.Errorprone.Enabled - //TODO(b/227504307) add configuration that depends on RUN_ERROR_PRONE environment variable - if Bool(epEnabled) { - javacopts = append(javacopts, m.properties.Errorprone.Javacflags...) + epJavacflags := m.properties.Errorprone.Javacflags + var errorproneForceEnable bazel.BoolAttribute + if epEnabled == nil { + //TODO(b/227504307) add configuration that depends on RUN_ERROR_PRONE environment variable + } else if *epEnabled { + plugins.Append(bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, m.properties.Errorprone.Extra_check_modules))) + javacopts.Append(bazel.MakeStringListAttribute(epJavacflags)) + errorproneForceEnable.Value = epEnabled + } else { + javacopts.Append(bazel.MakeStringListAttribute([]string{"-XepDisableAllChecks"})) } commonAttrs := &javaCommonAttributes{ Srcs: javaSrcs, javaResourcesAttributes: m.convertJavaResourcesAttributes(ctx), - Plugins: bazel.MakeLabelListAttribute( - android.BazelLabelForModuleDeps(ctx, m.properties.Plugins), - ), - Javacopts: bazel.MakeStringListAttribute(javacopts), - Java_version: bazel.StringAttribute{Value: m.properties.Java_version}, - Sdk_version: bazel.StringAttribute{Value: m.deviceProperties.Sdk_version}, + Plugins: plugins, + Javacopts: javacopts, + Java_version: bazel.StringAttribute{Value: m.properties.Java_version}, + Sdk_version: bazel.StringAttribute{Value: m.deviceProperties.Sdk_version}, + Errorprone_force_enable: errorproneForceEnable, } for axis, configToProps := range archVariantProps { @@ -2955,7 +2973,9 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) // by protoc are included directly in the resulting JAR. Thus upstream dependencies // that depend on a java_library with proto sources can link directly to the protobuf API, // and so this should be a static dependency. - staticDeps.Add(protoDepLabel) + if protoDepLabel != nil { + staticDeps.Append(bazel.MakeSingleLabelListAttribute(*protoDepLabel)) + } depLabels := &javaDependencyLabels{} depLabels.Deps = deps @@ -2970,7 +2990,7 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) } } } - depLabels.StaticDeps.Value.Append(staticDeps) + depLabels.StaticDeps.Append(staticDeps) hasKotlin := !kotlinSrcs.IsEmpty() commonAttrs.kotlinAttributes = &kotlinAttributes{ @@ -3140,6 +3160,7 @@ func javaBinaryHostBp2Build(ctx android.TopDownMutatorContext, m *Binary) { type javaTestHostAttributes struct { *javaCommonAttributes + Srcs bazel.LabelListAttribute Deps bazel.LabelListAttribute Runtime_deps bazel.LabelListAttribute } @@ -3176,8 +3197,10 @@ func javaTestHostBp2Build(ctx android.TopDownMutatorContext, m *TestHost) { hasKotlin: bp2BuildInfo.hasKotlin, } libName := createLibraryTarget(ctx, libInfo) - attrs.Runtime_deps.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + libName}}) + attrs.Srcs = commonAttrs.Srcs + attrs.Deps = deps + attrs.Runtime_deps.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + libName}}) // Create the BazelTargetModule. ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs) } @@ -3290,7 +3313,8 @@ func (i *Import) ProcessBazelQueryResponse(ctx android.ModuleContext) { HeaderJars: android.PathsIfNonNil(i.combinedClasspathFile), ImplementationAndResourcesJars: android.PathsIfNonNil(i.combinedClasspathFile), ImplementationJars: android.PathsIfNonNil(i.combinedClasspathFile), - //TODO(b/240308299) include AIDL information from Bazel + // TODO(b/240308299) include AIDL information from Bazel + // TODO: aconfig files? }) i.maybeInstall(ctx, jarName, outputFile) diff --git a/java/java_test.go b/java/java_test.go index 473830464..dd9867704 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -2351,3 +2351,22 @@ func TestJavaExcludeStaticLib(t *testing.T) { `stable.core.platform.api.stubs`, }) } + +func TestJavaLibraryWithResourcesStem(t *testing.T) { + ctx, _ := testJavaWithFS(t, ` + java_library { + name: "foo", + java_resource_dirs: ["test-jar"], + stem: "test", + } + `, + map[string][]byte{ + "test-jar/test/resource.txt": nil, + }) + + m := ctx.ModuleForTests("foo", "android_common") + outputs := fmt.Sprint(m.AllOutputs()) + if !strings.Contains(outputs, "test.jar") { + t.Errorf("Module output does not contain expected jar %s", "test.jar") + } +} diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go index 0d4db7ca1..a4bba486d 100644 --- a/java/platform_bootclasspath.go +++ b/java/platform_bootclasspath.go @@ -123,15 +123,15 @@ func (b *platformBootclasspathModule) hiddenAPIDepsMutator(ctx android.BottomUpM } func (b *platformBootclasspathModule) BootclasspathDepsMutator(ctx android.BottomUpMutatorContext) { - // Add dependencies on all the modules configured in the "art" boot image. - artImageConfig := genBootImageConfigs(ctx)[artBootImageName] - addDependenciesOntoBootImageModules(ctx, artImageConfig.modules, platformBootclasspathArtBootJarDepTag) + // Add dependencies on all the ART jars. + global := dexpreopt.GetGlobalConfig(ctx) + addDependenciesOntoBootImageModules(ctx, global.ArtApexJars, platformBootclasspathArtBootJarDepTag) - // Add dependencies on all the non-updatable module configured in the "boot" boot image. That does - // not include modules configured in the "art" boot image. + // Add dependencies on all the non-updatable jars, which are on the platform or in non-updatable + // APEXes. addDependenciesOntoBootImageModules(ctx, b.platformJars(ctx), platformBootclasspathBootJarDepTag) - // Add dependencies on all the apex jars. + // Add dependencies on all the updatable jars, except the ART jars. apexJars := dexpreopt.GetGlobalConfig(ctx).ApexBootJars addDependenciesOntoBootImageModules(ctx, apexJars, platformBootclasspathApexBootJarDepTag) @@ -186,7 +186,6 @@ func (b *platformBootclasspathModule) GenerateAndroidBuildActions(ctx android.Mo bootDexJarByModule := b.generateHiddenAPIBuildActions(ctx, b.configuredModules, b.fragments) buildRuleForBootJarsPackageCheck(ctx, bootDexJarByModule) - b.generateBootImageBuildActions(ctx) b.copyApexBootJarsForAppsDexpreopt(ctx, apexModules) } @@ -218,7 +217,8 @@ func (b *platformBootclasspathModule) configuredJars(ctx android.ModuleContext) } func (b *platformBootclasspathModule) platformJars(ctx android.PathContext) android.ConfiguredJarList { - return defaultBootImageConfig(ctx).modules.RemoveList(artBootImageConfig(ctx).modules) + global := dexpreopt.GetGlobalConfig(ctx) + return global.BootJars.RemoveList(global.ArtApexJars) } // checkPlatformModules ensures that the non-updatable modules supplied are not part of an @@ -399,78 +399,9 @@ func (b *platformBootclasspathModule) generateHiddenApiMakeVars(ctx android.Make ctx.Strict("INTERNAL_PLATFORM_HIDDENAPI_FLAGS", b.hiddenAPIFlagsCSV.String()) } -// generateBootImageBuildActions generates ninja rules related to the boot image creation. -func (b *platformBootclasspathModule) generateBootImageBuildActions(ctx android.ModuleContext) { - // Force the GlobalSoongConfig to be created and cached for use by the dex_bootjars - // GenerateSingletonBuildActions method as it cannot create it for itself. - dexpreopt.GetGlobalSoongConfig(ctx) - - global := dexpreopt.GetGlobalConfig(ctx) - if !shouldBuildBootImages(ctx.Config(), global) { - return - } - - frameworkBootImageConfig := defaultBootImageConfig(ctx) - bootFrameworkProfileRule(ctx, frameworkBootImageConfig) - b.generateBootImage(ctx, frameworkBootImageName) - b.generateBootImage(ctx, mainlineBootImageName) - dumpOatRules(ctx, frameworkBootImageConfig) -} - -func (b *platformBootclasspathModule) generateBootImage(ctx android.ModuleContext, imageName string) { - imageConfig := genBootImageConfigs(ctx)[imageName] - - modules := b.getModulesForImage(ctx, imageConfig) - - // Copy module dex jars to their predefined locations. - bootDexJarsByModule := extractEncodedDexJarsFromModules(ctx, modules) - copyBootJarsToPredefinedLocations(ctx, bootDexJarsByModule, imageConfig.dexPathsByModule) - - // Build a profile for the image config and then use that to build the boot image. - profile := bootImageProfileRule(ctx, imageConfig) - - // If dexpreopt of boot image jars should be skipped, generate only a profile. - global := dexpreopt.GetGlobalConfig(ctx) - if global.DisablePreoptBootImages { - return - } - - // Build boot image files for the android variants. - androidBootImageFiles := buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile) - - // Zip the android variant boot image files up. - buildBootImageZipInPredefinedLocation(ctx, imageConfig, androidBootImageFiles.byArch) - - // Build boot image files for the host variants. There are use directly by ART host side tests. - buildBootImageVariantsForBuildOs(ctx, imageConfig, profile) -} - // Copy apex module dex jars to their predefined locations. They will be used for dexpreopt for apps. func (b *platformBootclasspathModule) copyApexBootJarsForAppsDexpreopt(ctx android.ModuleContext, apexModules []android.Module) { config := GetApexBootConfig(ctx) apexBootDexJarsByModule := extractEncodedDexJarsFromModules(ctx, apexModules) copyBootJarsToPredefinedLocations(ctx, apexBootDexJarsByModule, config.dexPathsByModule) } - -func (b *platformBootclasspathModule) getModulesForImage(ctx android.ModuleContext, imageConfig *bootImageConfig) []android.Module { - modules := make([]android.Module, 0, imageConfig.modules.Len()) - for i := 0; i < imageConfig.modules.Len(); i++ { - found := false - for _, module := range b.configuredModules { - name := android.RemoveOptionalPrebuiltPrefix(module.Name()) - if name == imageConfig.modules.Jar(i) { - modules = append(modules, module) - found = true - break - } - } - if !found && !ctx.Config().AllowMissingDependencies() { - ctx.ModuleErrorf( - "Boot image '%s' module '%s' not added as a dependency of platform_bootclasspath", - imageConfig.name, - imageConfig.modules.Jar(i)) - return []android.Module{} - } - } - return modules -} |