diff options
Diffstat (limited to 'java')
| -rw-r--r-- | java/aar.go | 241 | ||||
| -rw-r--r-- | java/androidmk.go | 19 | ||||
| -rwxr-xr-x | java/app.go | 18 | ||||
| -rw-r--r-- | java/app_builder.go | 33 | ||||
| -rw-r--r-- | java/app_import.go | 49 | ||||
| -rw-r--r-- | java/app_test.go | 277 | ||||
| -rw-r--r-- | java/base.go | 63 | ||||
| -rw-r--r-- | java/builder.go | 30 | ||||
| -rw-r--r-- | java/config/config.go | 2 | ||||
| -rw-r--r-- | java/core-libraries/Android.bp | 38 | ||||
| -rw-r--r-- | java/core-libraries/TxtStubLibraries.bp | 20 | ||||
| -rw-r--r-- | java/device_host_converter.go | 2 | ||||
| -rw-r--r-- | java/device_host_converter_test.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.go | 2 | ||||
| -rw-r--r-- | java/hiddenapi_singleton.go | 4 | ||||
| -rw-r--r-- | java/java.go | 53 | ||||
| -rw-r--r-- | java/kotlin.go | 2 | ||||
| -rw-r--r-- | java/platform_bootclasspath.go | 6 |
21 files changed, 731 insertions, 142 deletions
diff --git a/java/aar.go b/java/aar.go index c9e08e2b5..180e1d726 100644 --- a/java/aar.go +++ b/java/aar.go @@ -88,28 +88,40 @@ 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 - proguardOptionsFile android.Path - 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 @@ -139,6 +151,10 @@ 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 } @@ -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") @@ -348,6 +362,19 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon 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") @@ -355,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 { @@ -374,7 +402,23 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon // of transitiveStaticLibs. transitiveStaticLibs := android.ReversePaths(staticDeps.resPackages()) - compiledOverlay = append(compiledOverlay, transitiveStaticLibs...) + 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. @@ -437,7 +481,16 @@ 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 @@ -449,7 +502,11 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon 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). @@ -461,34 +518,93 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkCon 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 { - var paths android.Paths + paths := make(android.Paths, 0, len(t)) for _, dep := range t { paths = append(paths, dep.resPackage) } - return android.FirstUniquePaths(paths) + return paths } func (t transitiveAarDeps) manifests() android.Paths { - var paths android.Paths + paths := make(android.Paths, 0, len(t)) for _, dep := range t { paths = append(paths, dep.manifest) paths = append(paths, dep.additionalManifests...) } - return android.FirstUniquePaths(paths) + 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 { - var paths android.Paths + paths := make(android.Paths, 0, len(t)) for _, dep := range t { if dep.assets.Valid() { paths = append(paths, dep.assets.Path()) @@ -613,9 +729,12 @@ func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) a.stem = proptools.StringDefault(a.overridableDeviceProperties.Stem, ctx.ModuleName()) - ctx.CheckbuildFile(a.proguardOptionsFile) - ctx.CheckbuildFile(a.exportPackage) - ctx.CheckbuildFile(a.aaptSrcJar) + 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 @@ -627,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 @@ -729,12 +863,15 @@ 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 resourcesNodesDepSet *android.DepSet[*resourcesNode] manifestsDepSet *android.DepSet[android.Path] @@ -903,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(), @@ -928,14 +1066,14 @@ 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", } @@ -948,25 +1086,35 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { _ = staticRRODirsDepSet staticDeps := transitiveAarDeps(staticResourcesNodesDepSet.ToList()) - // AAPT2 overlays are in lowest to highest priority order, reverse the topological order - // of transitiveStaticLibs. - transitiveStaticLibs := android.ReversePaths(staticDeps.resPackages()) - linkDeps = append(linkDeps, sharedLibs...) - linkDeps = append(linkDeps, transitiveStaticLibs...) + linkDeps = append(linkDeps, staticDeps.resPackages()...) linkFlags = append(linkFlags, libFlags...) - overlayRes := append(android.Paths{flata}, transitiveStaticLibs...) + overlayRes := android.Paths{flata} + + // 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, rTxt, a.extraAaptPackagesFile, + aapt2Link(ctx, a.exportPackage, srcJar, proguardOptionsFile, a.rTxt, a.extraAaptPackagesFile, linkFlags, linkDeps, nil, overlayRes, transitiveAssets, nil) + 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() @@ -981,6 +1129,8 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { _ = staticManifestsDepSet a.manifestsDepSet = manifestDepSetBuilder.Build() + a.transitiveAaptResourcePackages = staticDeps.resPackages() + a.collectTransitiveHeaderJars(ctx) ctx.SetProvider(JavaInfoProvider, JavaInfo{ HeaderJars: android.PathsIfNonNil(a.classpathFile), @@ -988,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/androidmk.go b/java/androidmk.go index 784fa29b5..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()) @@ -437,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{ @@ -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 8e4efd2b2..224bc8867 100755 --- a/java/app.go +++ b/java/app.go @@ -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() diff --git a/java/app_builder.go b/java/app_builder.go index d20a6bfe4..d397ff7f5 100644 --- a/java/app_builder.go +++ b/java/app_builder.go @@ -225,8 +225,6 @@ func BuildBundleModule(ctx android.ModuleContext, outputFile android.WritablePat }) } -const jniJarOutputPathString = "jniJarOutput.zip" - func TransformJniLibsToJar( ctx android.ModuleContext, outputFile android.WritablePath, @@ -258,7 +256,10 @@ func TransformJniLibsToJar( rule = zipRE args["implicits"] = strings.Join(deps.Strings(), ",") } - jniJarPath := android.PathForModuleOut(ctx, jniJarOutputPathString) + var jniJarPath android.WritablePath = android.PathForModuleOut(ctx, "jniJarOutput.zip") + if len(prebuiltJniPackages) == 0 { + jniJarPath = outputFile + } ctx.Build(pctx, android.BuildParams{ Rule: rule, Description: "zip jni libs", @@ -266,12 +267,26 @@ func TransformJniLibsToJar( Implicits: deps, Args: args, }) - ctx.Build(pctx, android.BuildParams{ - Rule: mergeAssetsRule, - Description: "merge prebuilt JNI packages", - Inputs: append(prebuiltJniPackages, jniJarPath), - Output: outputFile, - }) + if len(prebuiltJniPackages) > 0 { + var mergeJniJarPath android.WritablePath = android.PathForModuleOut(ctx, "mergeJniJarOutput.zip") + if !uncompressJNI { + mergeJniJarPath = outputFile + } + ctx.Build(pctx, android.BuildParams{ + Rule: mergeAssetsRule, + Description: "merge prebuilt JNI packages", + Inputs: append(prebuiltJniPackages, jniJarPath), + Output: mergeJniJarPath, + }) + + if uncompressJNI { + ctx.Build(pctx, android.BuildParams{ + Rule: uncompressEmbeddedJniLibsRule, + Input: mergeJniJarPath, + Output: outputFile, + }) + } + } } func (a *AndroidApp) generateJavaUsedByApex(ctx android.ModuleContext) { diff --git a/java/app_import.go b/java/app_import.go index e25bcd1b7..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) { @@ -384,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 c438b6cfa..8474ea7d6 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -722,7 +722,10 @@ func TestAppJavaResources(t *testing.T) { func TestAndroidResourceProcessor(t *testing.T) { testCases := []struct { - name string + name string + appUsesRP bool + directLibUsesRP bool + transitiveLibUsesRP bool dontVerifyApp bool appResources []string @@ -759,7 +762,12 @@ func TestAndroidResourceProcessor(t *testing.T) { transitiveImportImports []string }{ { - name: "legacy", + // 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{ @@ -771,7 +779,6 @@ func TestAndroidResourceProcessor(t *testing.T) { "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{ @@ -792,7 +799,6 @@ func TestAndroidResourceProcessor(t *testing.T) { "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{ @@ -814,18 +820,256 @@ func TestAndroidResourceProcessor(t *testing.T) { transitiveCombined: nil, directImportResources: nil, - directImportOverlays: []string{ - "out/soong/.intermediates/direct_import/android_common/flat-res/gen_res.flata", + 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", }, - directImportImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"}, transitiveImportResources: nil, - transitiveImportOverlays: []string{ - "out/soong/.intermediates/transitive_import/android_common/flat-res/gen_res.flata", + 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", }, - transitiveImportImports: []string{"out/soong/.intermediates/default/java/framework-res/android_common/package-res.apk"}, + + 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, }, } @@ -839,6 +1083,7 @@ func TestAndroidResourceProcessor(t *testing.T) { resource_dirs: ["app/res"], manifest: "app/AndroidManifest.xml", static_libs: ["direct", "direct_import"], + use_resource_processor: %v, } android_library { @@ -848,6 +1093,7 @@ func TestAndroidResourceProcessor(t *testing.T) { resource_dirs: ["direct/res"], manifest: "direct/AndroidManifest.xml", static_libs: ["transitive", "transitive_import"], + use_resource_processor: %v, } android_library { @@ -856,6 +1102,7 @@ func TestAndroidResourceProcessor(t *testing.T) { srcs: ["transitive/transitive.java"], resource_dirs: ["transitive/res"], manifest: "transitive/AndroidManifest.xml", + use_resource_processor: %v, } android_library_import { @@ -883,7 +1130,7 @@ func TestAndroidResourceProcessor(t *testing.T) { sdk_version: "current", aars: ["transitive_import_dep.aar"], } - `) + `, testCase.appUsesRP, testCase.directLibUsesRP, testCase.transitiveLibUsesRP) fs := android.MockFS{ "app/res/values/strings.xml": nil, @@ -1495,7 +1742,7 @@ func TestJNIABI(t *testing.T) { for _, test := range testCases { t.Run(test.name, func(t *testing.T) { app := ctx.ModuleForTests(test.name, "android_common") - jniLibZip := app.Output(jniJarOutputPathString) + jniLibZip := app.Output("jnilibs.zip") var abis []string args := strings.Fields(jniLibZip.Args["jarArgs"]) for i := 0; i < len(args); i++ { @@ -1628,7 +1875,7 @@ func TestJNIPackaging(t *testing.T) { for _, test := range testCases { t.Run(test.name, func(t *testing.T) { app := ctx.ModuleForTests(test.name, "android_common") - jniLibZip := app.MaybeOutput(jniJarOutputPathString) + jniLibZip := app.MaybeOutput("jnilibs.zip") if g, w := (jniLibZip.Rule != nil), test.packaged; g != w { t.Errorf("expected jni packaged %v, got %v", w, g) } @@ -1719,7 +1966,7 @@ func TestJNISDK(t *testing.T) { t.Run(test.name, func(t *testing.T) { app := ctx.ModuleForTests(test.name, "android_common") - jniLibZip := app.MaybeOutput(jniJarOutputPathString) + jniLibZip := app.MaybeOutput("jnilibs.zip") if len(jniLibZip.Implicits) != 1 { t.Fatalf("expected exactly one jni library, got %q", jniLibZip.Implicits.Strings()) } @@ -2739,7 +2986,7 @@ func TestStl(t *testing.T) { for _, test := range testCases { t.Run(test.name, func(t *testing.T) { app := ctx.ModuleForTests(test.name, "android_common") - jniLibZip := app.Output(jniJarOutputPathString) + jniLibZip := app.Output("jnilibs.zip") var jnis []string args := strings.Fields(jniLibZip.Args["jarArgs"]) for i := 0; i < len(args); i++ { diff --git a/java/base.go b/java/base.go index 8db716256..f5eb01c4b 100644 --- a/java/base.go +++ b/java/base.go @@ -508,6 +508,14 @@ type Module struct { // 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 { @@ -1057,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) @@ -1095,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") @@ -1140,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 @@ -1233,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 } @@ -1385,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 @@ -1477,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) @@ -1623,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, @@ -1637,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 @@ -1917,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/builder.go b/java/builder.go index be4af552b..debf49a00 100644 --- a/java/builder.go +++ b/java/builder.go @@ -42,7 +42,7 @@ 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" "$annoSrcJar" "$srcJarDir" "$out" && ` + + 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 ` + @@ -51,15 +51,18 @@ var ( `$processorpath $processor $javacFlags $bootClasspath $classpath ` + `-source $javaVersion -target $javaVersion ` + `-d $outDir -s $annoDir @$out.rsp @$srcJarDir/list ; fi ) && ` + - `$annoSrcJarTemplate${config.SoongZipCmd} -jar -o $annoSrcJar -C $annoDir -D $annoDir && ` + - `$zipTemplate${config.SoongZipCmd} -jar -o $out -C $outDir -D $outDir && ` + - `rm -rf "$srcJarDir"`, + `$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" "$outDir"`, CommandDeps: []string{ "${config.JavacCmd}", "${config.SoongZipCmd}", "${config.ZipSyncCmd}", }, CommandOrderOnly: []string{"${config.SoongJavacWrapper}"}, + Restat: true, Rspfile: "$out.rsp", RspfileContent: "$in", }, map[string]*remoteexec.REParams{ @@ -71,14 +74,14 @@ 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"}, + OutputFiles: []string{"$annoSrcJar.tmp"}, ExecStrategy: "${config.REJavacExecStrategy}", Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"}, }, @@ -268,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() { @@ -630,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/core-libraries/Android.bp b/java/core-libraries/Android.bp index eadd9c697..de9a82d09 100644 --- a/java/core-libraries/Android.bp +++ b/java/core-libraries/Android.bp @@ -146,12 +146,43 @@ java_system_modules { ], } +java_defaults { + name: "core.module_lib.stubs.defaults", + visibility: ["//visibility:private"], + sdk_version: "none", + system_modules: "none", +} + + // A stubs target containing the parts of the public SDK & @SystemApi(MODULE_LIBRARIES) API // provided by the core libraries. // // Don't use this directly, use "sdk_version: module_current". java_library { name: "core.module_lib.stubs", + defaults: [ + "core.module_lib.stubs.defaults", + ], + static_libs: [ + "core.module_lib.stubs.from-source", + ], + product_variables: { + build_from_text_stub: { + static_libs: [ + "core.module_lib.stubs.from-text", + ], + exclude_static_libs: [ + "core.module_lib.stubs.from-source", + ], + }, + }, +} + +java_library { + name: "core.module_lib.stubs.from-source", + defaults: [ + "core.module_lib.stubs.defaults", + ], static_libs: [ "art.module.public.api.stubs.module_lib", @@ -161,9 +192,6 @@ java_library { "conscrypt.module.public.api.stubs", "i18n.module.public.api.stubs", ], - sdk_version: "none", - system_modules: "none", - visibility: ["//visibility:private"], } // Produces a dist file that is used by the @@ -249,10 +277,10 @@ java_library { product_variables: { build_from_text_stub: { static_libs: [ - "stable.core.platform.api.stubs.from-text", + "legacy.core.platform.api.stubs.from-text", ], exclude_static_libs: [ - "stable.core.platform.api.stubs.from-source", + "legacy.core.platform.api.stubs.from-source", ], }, }, diff --git a/java/core-libraries/TxtStubLibraries.bp b/java/core-libraries/TxtStubLibraries.bp index 0cf0f360b..c46f8b8ea 100644 --- a/java/core-libraries/TxtStubLibraries.bp +++ b/java/core-libraries/TxtStubLibraries.bp @@ -57,19 +57,23 @@ java_library { ], } -java_library { +java_api_library { name: "core.module_lib.stubs.from-text", - static_libs: [ - "art.module.public.api.stubs.module_lib.from-text", + api_surface: "module-lib", + api_contributions: [ + "art.module.public.api.stubs.source.api.contribution", + "art.module.public.api.stubs.source.system.api.contribution", + "art.module.public.api.stubs.source.module_lib.api.contribution", - // Replace the following with the module-lib correspondence when Conscrypt or i18N module + // Add the module-lib correspondence when Conscrypt or i18N module // provides @SystemApi(MODULE_LIBRARIES). Currently, assume that only ART module provides // @SystemApi(MODULE_LIBRARIES). - "conscrypt.module.public.api.stubs.from-text", - "i18n.module.public.api.stubs.from-text", + "conscrypt.module.public.api.stubs.source.api.contribution", + "i18n.module.public.api.stubs.source.api.contribution", + ], + libs: [ + "stub-annotations", ], - sdk_version: "none", - system_modules: "none", visibility: ["//visibility:private"], } 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/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.go b/java/hiddenapi.go index d25096b15..4d08b8307 100644 --- a/java/hiddenapi.go +++ b/java/hiddenapi.go @@ -106,7 +106,7 @@ func (h *hiddenAPI) initHiddenAPI(ctx android.ModuleContext, dexJar OptionalDexJ h.uncompressDexState = uncompressedDexState // If hiddenapi processing is disabled treat this as inactive. - if ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") { + if ctx.Config().DisableHiddenApiChecks() { return } diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go index 714634f58..8ec17971a 100644 --- a/java/hiddenapi_singleton.go +++ b/java/hiddenapi_singleton.go @@ -121,8 +121,8 @@ type hiddenAPISingleton struct { // hiddenAPI singleton rules func (h *hiddenAPISingleton) GenerateBuildActions(ctx android.SingletonContext) { - // Don't run any hiddenapi rules if UNSAFE_DISABLE_HIDDENAPI_FLAGS=true - if ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") { + // Don't run any hiddenapi rules if hiddenapi checks are disabled + if ctx.Config().DisableHiddenApiChecks() { return } diff --git a/java/java.go b/java/java.go index 6388d13e3..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{}) @@ -692,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()) @@ -730,6 +737,7 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { } }) j.exportedProguardFlagFiles = android.FirstUniquePaths(j.exportedProguardFlagFiles) + } func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) { @@ -1916,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 }) } @@ -2237,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 }) } @@ -2809,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 @@ -2825,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) - } } } @@ -2847,6 +2846,7 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) javaSrcPartition := "java" protoSrcPartition := "proto" + xsdSrcPartition := "xsd" logtagSrcPartition := "logtag" aidlSrcPartition := "aidl" kotlinPartition := "kotlin" @@ -2855,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"}}, }) @@ -2862,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( @@ -2915,7 +2918,7 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) }, ) - staticDeps.Add(&bazel.Label{Label: ":" + javaAidlLibName}) + staticDeps.Append(bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + javaAidlLibName})) } var javacopts bazel.StringListAttribute //[]string @@ -2970,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 @@ -2985,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{ @@ -3155,6 +3160,7 @@ func javaBinaryHostBp2Build(ctx android.TopDownMutatorContext, m *Binary) { type javaTestHostAttributes struct { *javaCommonAttributes + Srcs bazel.LabelListAttribute Deps bazel.LabelListAttribute Runtime_deps bazel.LabelListAttribute } @@ -3191,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) } @@ -3305,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/kotlin.go b/java/kotlin.go index f28d6c737..3637e2e71 100644 --- a/java/kotlin.go +++ b/java/kotlin.go @@ -42,7 +42,7 @@ var kotlinc = pctx.AndroidRemoteStaticRule("kotlinc", android.RemoteRuleSupports ` -P plugin:org.jetbrains.kotlin.jvm.abi:outputDir=$headerClassesDir && ` + `${config.SoongZipCmd} -jar -o $out -C $classesDir -D $classesDir -write_if_changed && ` + `${config.SoongZipCmd} -jar -o $headerJar -C $headerClassesDir -D $headerClassesDir -write_if_changed && ` + - `rm -rf "$srcJarDir"`, + `rm -rf "$srcJarDir" "$classesDir" "$headerClassesDir"`, CommandDeps: []string{ "${config.KotlincCmd}", "${config.KotlinCompilerJar}", diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go index a4bba486d..ade739552 100644 --- a/java/platform_bootclasspath.go +++ b/java/platform_bootclasspath.go @@ -113,7 +113,7 @@ func (b *platformBootclasspathModule) DepsMutator(ctx android.BottomUpMutatorCon } func (b *platformBootclasspathModule) hiddenAPIDepsMutator(ctx android.BottomUpMutatorContext) { - if ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") { + if ctx.Config().DisableHiddenApiChecks() { return } @@ -275,10 +275,10 @@ func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android. bootDexJarByModule := extractBootDexJarsFromModules(ctx, modules) - // Don't run any hiddenapi rules if UNSAFE_DISABLE_HIDDENAPI_FLAGS=true. This is a performance + // Don't run any hiddenapi rules if hidden api checks are disabled. This is a performance // optimization that can be used to reduce the incremental build time but as its name suggests it // can be unsafe to use, e.g. when the changes affect anything that goes on the bootclasspath. - if ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") { + if ctx.Config().DisableHiddenApiChecks() { paths := android.OutputPaths{b.hiddenAPIFlagsCSV, b.hiddenAPIIndexCSV, b.hiddenAPIMetadataCSV} for _, path := range paths { ctx.Build(pctx, android.BuildParams{ |