diff options
Diffstat (limited to 'java')
| -rw-r--r-- | java/aar.go | 11 | ||||
| -rwxr-xr-x | java/app.go | 7 | ||||
| -rw-r--r-- | java/app_builder.go | 2 | ||||
| -rw-r--r-- | java/app_test.go | 66 | ||||
| -rw-r--r-- | java/builder.go | 2 | ||||
| -rw-r--r-- | java/dexpreopt_bootjars.go | 65 | ||||
| -rw-r--r-- | java/hiddenapi_singleton.go | 7 | ||||
| -rw-r--r-- | java/java.go | 41 |
8 files changed, 157 insertions, 44 deletions
diff --git a/java/aar.go b/java/aar.go index 1940d7f7b..3b6b34e27 100644 --- a/java/aar.go +++ b/java/aar.go @@ -407,6 +407,7 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext, classLoaderConte ctx.VisitDirectDeps(func(module android.Module) { depName := ctx.OtherModuleName(module) + depTag := ctx.OtherModuleDependencyTag(module) var exportPackage android.Path aarDep, _ := module.(AndroidLibraryDependency) @@ -414,7 +415,7 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext, classLoaderConte exportPackage = aarDep.ExportPackage() } - switch ctx.OtherModuleDependencyTag(module) { + switch depTag { case instrumentationForTag: // Nothing, instrumentationForTag is treated as libTag for javac but not for aapt2. case libTag: @@ -439,7 +440,6 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext, classLoaderConte transitiveStaticLibs = append(transitiveStaticLibs, aarDep.ExportedStaticPackages()...) transitiveStaticLibs = append(transitiveStaticLibs, exportPackage) transitiveStaticLibManifests = append(transitiveStaticLibManifests, aarDep.ExportedManifests()...) - classLoaderContexts.AddContextMap(aarDep.ClassLoaderContexts(), depName) if aarDep.ExportedAssets().Valid() { assets = append(assets, aarDep.ExportedAssets().Path()) } @@ -458,11 +458,8 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext, classLoaderConte } } - // Add nested dependencies after processing the direct dependency: if it is a <uses-library>, - // nested context is added as its subcontext, and should not be re-added at the top-level. - if dep, ok := module.(Dependency); ok { - classLoaderContexts.AddContextMap(dep.ClassLoaderContexts(), depName) - } + // Merge dep's CLC after processing the dep itself (which may add its own <uses-library>). + maybeAddCLCFromDep(module, depTag, depName, classLoaderContexts) }) deps = append(deps, sharedLibs...) diff --git a/java/app.go b/java/app.go index 4bf9d33ea..e6d9550ec 100755 --- a/java/app.go +++ b/java/app.go @@ -1400,6 +1400,13 @@ func (a *AndroidAppImport) processVariants(ctx android.LoadHookContext) { archProps := reflect.ValueOf(a.archVariants).Elem().FieldByName("Arch") archType := ctx.Config().AndroidFirstDeviceTarget.Arch.ArchType MergePropertiesFromVariant(ctx, &a.properties, archProps, archType.Name) + + if String(a.properties.Apk) == "" { + // Disable this module since the apk property is still empty after processing all matching + // variants. This likely means there is no matching variant, and the default variant doesn't + // have an apk property value either. + a.Disable() + } } func MergePropertiesFromVariant(ctx android.EarlyModuleContext, diff --git a/java/app_builder.go b/java/app_builder.go index 69e462c3d..b53c15ab4 100644 --- a/java/app_builder.go +++ b/java/app_builder.go @@ -32,7 +32,7 @@ import ( var ( Signapk, SignapkRE = remoteexec.StaticRules(pctx, "signapk", blueprint.RuleParams{ - Command: `$reTemplate${config.JavaCmd} ${config.JavaVmFlags} -Djava.library.path=$$(dirname ${config.SignapkJniLibrary}) ` + + Command: `rm -f $out && $reTemplate${config.JavaCmd} ${config.JavaVmFlags} -Djava.library.path=$$(dirname ${config.SignapkJniLibrary}) ` + `-jar ${config.SignapkCmd} $flags $certificates $in $out`, CommandDeps: []string{"${config.SignapkCmd}", "${config.SignapkJniLibrary}"}, }, diff --git a/java/app_test.go b/java/app_test.go index 6efb0dcb3..e13c6b9f0 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -2524,6 +2524,24 @@ func TestAndroidAppImport_ArchVariants(t *testing.T) { `, expected: "prebuilts/apk/app.apk", }, + { + name: "no matching arch without default", + bp: ` + android_app_import { + name: "foo", + arch: { + arm: { + apk: "prebuilts/apk/app_arm.apk", + }, + }, + presigned: true, + dex_preopt: { + enabled: true, + }, + } + `, + expected: "", + }, } jniRuleRe := regexp.MustCompile("^if \\(zipinfo (\\S+)") @@ -2531,6 +2549,12 @@ func TestAndroidAppImport_ArchVariants(t *testing.T) { ctx, _ := testJava(t, test.bp) variant := ctx.ModuleForTests("foo", "android_common") + if test.expected == "" { + if variant.Module().Enabled() { + t.Error("module should have been disabled, but wasn't") + } + continue + } jniRuleCommand := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command matches := jniRuleRe.FindStringSubmatch(jniRuleCommand) if len(matches) != 2 { @@ -2542,6 +2566,34 @@ func TestAndroidAppImport_ArchVariants(t *testing.T) { } } +func TestAndroidAppImport_overridesDisabledAndroidApp(t *testing.T) { + ctx, _ := testJava(t, ` + android_app { + name: "foo", + srcs: ["a.java"], + enabled: false, + } + + android_app_import { + name: "foo", + apk: "prebuilts/apk/app.apk", + certificate: "platform", + prefer: true, + } + `) + + variant := ctx.ModuleForTests("prebuilt_foo", "android_common") + a := variant.Module().(*AndroidAppImport) + // The prebuilt module should still be enabled and active even if the source-based counterpart + // is disabled. + if !a.prebuilt.UsePrebuilt() { + t.Errorf("prebuilt foo module is not active") + } + if !a.Enabled() { + t.Errorf("prebuilt foo module is disabled") + } +} + func TestAndroidTestImport(t *testing.T) { ctx, config := testJava(t, ` android_test_import { @@ -2730,6 +2782,13 @@ func TestUsesLibraries(t *testing.T) { } java_sdk_library { + name: "fred", + srcs: ["a.java"], + api_packages: ["fred"], + sdk_version: "current", + } + + java_sdk_library { name: "bar", srcs: ["a.java"], api_packages: ["bar"], @@ -2753,7 +2812,12 @@ func TestUsesLibraries(t *testing.T) { name: "app", srcs: ["a.java"], libs: ["qux", "quuz.stubs"], - static_libs: ["static-runtime-helper"], + static_libs: [ + "static-runtime-helper", + // statically linked component libraries should not pull their SDK libraries, + // so "fred" should not be added to class loader context + "fred.stubs", + ], uses_libs: ["foo"], sdk_version: "current", optional_uses_libs: [ diff --git a/java/builder.go b/java/builder.go index cd3524542..995160d0e 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 = remoteexec.MultiCommandStaticRules(pctx, "javac", blueprint.RuleParams{ - Command: `rm -rf "$outDir" "$annoDir" "$srcJarDir" && mkdir -p "$outDir" "$annoDir" "$srcJarDir" && ` + + Command: `rm -rf "$outDir" "$annoDir" "$srcJarDir" "$out" && 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} ` + diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index f16ddf1df..062005b5b 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -418,43 +418,53 @@ func (d *dexpreoptBootJars) GenerateBuildActions(ctx android.SingletonContext) { dumpOatRules(ctx, d.defaultBootImage) } -func isHostdex(module android.Module) bool { - if lib, ok := module.(*Library); ok { - return Bool(lib.deviceProperties.Hostdex) - } - return false -} - // Inspect this module to see if it contains a bootclasspath dex jar. // Note that the same jar may occur in multiple modules. // This logic is tested in the apex package to avoid import cycle apex <-> java. func getBootImageJar(ctx android.SingletonContext, image *bootImageConfig, module android.Module) (int, android.Path) { - // All apex Java libraries have non-installable platform variants, skip them. - if module.IsSkipInstall() { + // Ignore any module that is not listed in the boot image configuration. + name := ctx.ModuleName(module) + index := image.modules.IndexOfJar(name) + if index == -1 { return -1, nil } + // It is an error if a module configured in the boot image does not support + // accessing the dex jar. This is safe because every module that has the same + // name has to have the same module type. jar, hasJar := module.(interface{ DexJarBuildPath() android.Path }) if !hasJar { + ctx.Errorf("module %q configured in boot image %q does not support accessing dex jar", module, image.name) return -1, nil } - name := ctx.ModuleName(module) - index := image.modules.IndexOfJar(name) - if index == -1 { + // It is also an error if the module is not an ApexModule. + if _, ok := module.(android.ApexModule); !ok { + ctx.Errorf("module %q configured in boot image %q does not support being added to an apex", module, image.name) return -1, nil } - // Check that this module satisfies constraints for a particular boot image. - _, isApexModule := module.(android.ApexModule) apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo) - fromUpdatableApex := isApexModule && apexInfo.Updatable - if image.name == artBootImageName { - if isApexModule && len(apexInfo.InApexes) > 0 && allHavePrefix(apexInfo.InApexes, "com.android.art") { - // ok: found the jar in the ART apex - } else if isApexModule && apexInfo.IsForPlatform() && isHostdex(module) { - // exception (skip and continue): special "hostdex" platform variant + + // Now match the apex part of the boot image configuration. + requiredApex := image.modules.Apex(index) + if requiredApex == "platform" { + if len(apexInfo.InApexes) != 0 { + // A platform variant is required but this is for an apex so ignore it. return -1, nil + } + } else if !android.InList(requiredApex, apexInfo.InApexes) { + // An apex variant for a specific apex is required but this is the wrong apex. + return -1, nil + } + + // Check that this module satisfies any boot image specific constraints. + fromUpdatableApex := apexInfo.Updatable + + switch image.name { + case artBootImageName: + if len(apexInfo.InApexes) > 0 && allHavePrefix(apexInfo.InApexes, "com.android.art") { + // ok: found the jar in the ART apex } else if name == "jacocoagent" && ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") { // exception (skip and continue): Jacoco platform variant for a coverage build return -1, nil @@ -465,14 +475,15 @@ func getBootImageJar(ctx android.SingletonContext, image *bootImageConfig, modul // error: this jar is part of the platform or a non-updatable apex ctx.Errorf("module %q is not allowed in the ART boot image", name) } - } else if image.name == frameworkBootImageName { + + case frameworkBootImageName: if !fromUpdatableApex { // ok: this jar is part of the platform or a non-updatable apex } else { // error: this jar is part of an updatable apex ctx.Errorf("module %q from updatable apexes %q is not allowed in the framework boot image", name, apexInfo.InApexes) } - } else { + default: panic("unknown boot image: " + image.name) } @@ -495,6 +506,12 @@ func buildBootImage(ctx android.SingletonContext, image *bootImageConfig) *bootI bootDexJars := make(android.Paths, image.modules.Len()) ctx.VisitAllModules(func(module android.Module) { if i, j := getBootImageJar(ctx, image, module); i != -1 { + if existing := bootDexJars[i]; existing != nil { + ctx.Errorf("Multiple dex jars found for %s:%s - %s and %s", + image.modules.Apex(i), image.modules.Jar(i), existing, j) + return + } + bootDexJars[i] = j } }) @@ -506,7 +523,7 @@ func buildBootImage(ctx android.SingletonContext, image *bootImageConfig) *bootI m := image.modules.Jar(i) if ctx.Config().AllowMissingDependencies() { missingDeps = append(missingDeps, m) - bootDexJars[i] = android.PathForOutput(ctx, "missing") + bootDexJars[i] = android.PathForOutput(ctx, "missing/module", m, "from/apex", image.modules.Apex(i)) } else { ctx.Errorf("failed to find a dex jar path for module '%s'"+ ", note that some jars may be filtered out by module constraints", m) @@ -779,7 +796,7 @@ func bootFrameworkProfileRule(ctx android.SingletonContext, image *bootImageConf bootFrameworkProfile = path.Path() } else { missingDeps = append(missingDeps, defaultProfile) - bootFrameworkProfile = android.PathForOutput(ctx, "missing") + bootFrameworkProfile = android.PathForOutput(ctx, "missing", defaultProfile) } profile := image.dir.Join(ctx, "boot.bprof") diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go index ce8410ed4..419dc3424 100644 --- a/java/hiddenapi_singleton.go +++ b/java/hiddenapi_singleton.go @@ -177,12 +177,13 @@ func stubFlagsRule(ctx android.SingletonContext) { for moduleList, pathList := range moduleListToPathList { for i := range pathList { if pathList[i] == nil { - pathList[i] = android.PathForOutput(ctx, "missing") + moduleName := (*moduleList)[i] + pathList[i] = android.PathForOutput(ctx, "missing/module", moduleName) if ctx.Config().AllowMissingDependencies() { - missingDeps = append(missingDeps, (*moduleList)[i]) + missingDeps = append(missingDeps, moduleName) } else { ctx.Errorf("failed to find dex jar path for module %q", - (*moduleList)[i]) + moduleName) } } } diff --git a/java/java.go b/java/java.go index 3d121ccea..d44719e99 100644 --- a/java/java.go +++ b/java/java.go @@ -1081,7 +1081,6 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { switch tag { case libTag: deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...) - // names of sdk libs that are directly depended are exported j.classLoaderContexts.MaybeAddContext(ctx, dep.OptionalImplicitSdkLibrary(), dep.DexJarBuildPath(), dep.DexJarInstallPath()) case staticLibTag: @@ -1093,7 +1092,6 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars()...) case libTag, instrumentationForTag: deps.classpath = append(deps.classpath, dep.HeaderJars()...) - // sdk lib names from dependencies are re-exported j.classLoaderContexts.AddContextMap(dep.ClassLoaderContexts(), otherName) deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...) pluginJars, pluginClasses, disableTurbine := dep.ExportedPlugins() @@ -1106,8 +1104,6 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { deps.staticJars = append(deps.staticJars, dep.ImplementationJars()...) deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars()...) deps.staticResourceJars = append(deps.staticResourceJars, dep.ResourceJars()...) - // sdk lib names from dependencies are re-exported - j.classLoaderContexts.AddContextMap(dep.ClassLoaderContexts(), otherName) deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...) pluginJars, pluginClasses, disableTurbine := dep.ExportedPlugins() addPlugins(&deps, pluginJars, pluginClasses...) @@ -1182,6 +1178,9 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { deps.systemModules = &systemModules{outputDir, outputDeps} } } + + // Merge dep's CLC after processing the dep itself (which may add its own <uses-library>). + maybeAddCLCFromDep(module, tag, otherName, j.classLoaderContexts) }) return deps @@ -2815,8 +2814,6 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { switch tag { case libTag, staticLibTag: flags.classpath = append(flags.classpath, dep.HeaderJars()...) - // sdk lib names from dependencies are re-exported - j.classLoaderContexts.AddContextMap(dep.ClassLoaderContexts(), otherName) case bootClasspathTag: flags.bootClasspath = append(flags.bootClasspath, dep.HeaderJars()...) } @@ -2824,10 +2821,12 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { switch tag { case libTag: flags.classpath = append(flags.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...) - // names of sdk libs that are directly depended are exported j.classLoaderContexts.AddContext(ctx, otherName, dep.DexJarBuildPath(), dep.DexJarInstallPath()) } } + + // Merge dep's CLC after processing the dep itself (which may add its own <uses-library>). + maybeAddCLCFromDep(module, tag, otherName, j.classLoaderContexts) }) var installFile android.Path @@ -3248,3 +3247,31 @@ var Bool = proptools.Bool var BoolDefault = proptools.BoolDefault var String = proptools.String var inList = android.InList + +// Add class loader context of a given dependency to the given class loader context, provided that +// all the necessary conditions are met. +func maybeAddCLCFromDep(depModule android.Module, depTag blueprint.DependencyTag, + depName string, clcMap dexpreopt.ClassLoaderContextMap) { + + if dep, ok := depModule.(Dependency); ok { + if depTag == libTag { + // Ok, propagate <uses-library> through non-static library dependencies. + } else if depTag == staticLibTag { + // Propagate <uses-library> through static library dependencies, unless it is a + // component library (such as stubs). Component libraries have a dependency on their + // SDK library, which should not be pulled just because of a static component library. + if comp, isComp := depModule.(SdkLibraryComponentDependency); isComp { + if compName := comp.OptionalImplicitSdkLibrary(); compName != nil { + dep = nil + } + } + } else { + // Don't propagate <uses-library> for other dependency tags. + dep = nil + } + + if dep != nil { + clcMap.AddContextMap(dep.ClassLoaderContexts(), depName) + } + } +} |