Merge "Revert "Rename DexJar interface method to DexJarBuildPath.""
diff --git a/apex/apex.go b/apex/apex.go
index d3c5df0..8fd80fc 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1650,7 +1650,8 @@
}
type javaDependency interface {
- java.Dependency
+ DexJar() android.Path
+ JacocoReportClassesFile() android.Path
Stem() string
}
@@ -1977,23 +1978,16 @@
ctx.PropertyErrorf("binaries", "%q is neither cc_binary, (embedded) py_binary, (host) blueprint_go_binary, (host) bootstrap_go_binary, nor sh_binary", depName)
}
case javaLibTag:
- if javaLib, ok := child.(*java.Library); ok {
- af := apexFileForJavaLibrary(ctx, javaLib, javaLib)
- if !af.Ok() {
- ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
- } else {
- filesInfo = append(filesInfo, af)
- return true // track transitive dependencies
- }
- } else if sdkLib, ok := child.(*java.SdkLibrary); ok {
- af := apexFileForJavaLibrary(ctx, sdkLib, sdkLib)
+ switch child.(type) {
+ case *java.Library, *java.SdkLibrary, *java.DexImport:
+ af := apexFileForJavaLibrary(ctx, child.(javaDependency), child.(android.Module))
if !af.Ok() {
ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
return false
}
filesInfo = append(filesInfo, af)
return true // track transitive dependencies
- } else {
+ default:
ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child))
}
case androidAppTag:
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 779119c..e45cd00 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -329,7 +329,10 @@
binaries: ["foo",],
}
},
- java_libs: ["myjar"],
+ java_libs: [
+ "myjar",
+ "myjar_dex",
+ ],
}
apex {
@@ -438,6 +441,15 @@
],
}
+ dex_import {
+ name: "myjar_dex",
+ jars: ["prebuilt.jar"],
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
+ }
+
java_library {
name: "myotherjar",
srcs: ["foo/bar/MyClass.java"],
@@ -473,6 +485,7 @@
// Ensure that apex variant is created for the direct dep
ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_myapex")
ensureListContains(t, ctx.ModuleVariantsForTests("myjar"), "android_common_myapex")
+ ensureListContains(t, ctx.ModuleVariantsForTests("myjar_dex"), "android_common_myapex")
// Ensure that apex variant is created for the indirect dep
ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_myapex")
@@ -482,6 +495,7 @@
ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
ensureContains(t, copyCmds, "image.apex/lib64/mylib2.so")
ensureContains(t, copyCmds, "image.apex/javalib/myjar_stem.jar")
+ ensureContains(t, copyCmds, "image.apex/javalib/myjar_dex.jar")
// .. but not for java libs
ensureNotContains(t, copyCmds, "image.apex/javalib/myotherjar.jar")
ensureNotContains(t, copyCmds, "image.apex/javalib/msharedjar.jar")
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index 98850e5..0148161 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -50,6 +50,8 @@
UpdatableSystemServerJars []string // jars within apex that are loaded into system server
SpeedApps []string // apps that should be speed optimized
+ BrokenSuboptimalOrderOfSystemServerJars bool // if true, sub-optimal order does not cause a build error
+
PreoptFlags []string // global dex2oat flags that should be used if no module-specific dex2oat flags are specified
DefaultCompilerFilter string // default compiler filter to pass to dex2oat, overridden by --compiler-filter= in module-specific dex2oat flags
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index 5275e8f..8e65ca6 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -314,6 +314,8 @@
dexPathHost := SystemServerDexJarHostPath(ctx, module.Name)
rule.Command().Text("mkdir -p").Flag(filepath.Dir(dexPathHost.String()))
rule.Command().Text("cp -f").Input(module.DexPath).Output(dexPathHost)
+
+ checkSystemServerOrder(ctx, jarIndex)
} else {
// Pass special class loader context to skip the classpath and collision check.
// This will get removed once LOCAL_USES_LIBRARIES is enforced.
@@ -607,6 +609,29 @@
}
}
+// Check the order of jars on the system server classpath and give a warning/error if a jar precedes
+// one of its dependencies. This is not an error, but a missed optimization, as dexpreopt won't
+// have the dependency jar in the class loader context, and it won't be able to resolve any
+// references to its classes and methods.
+func checkSystemServerOrder(ctx android.PathContext, jarIndex int) {
+ mctx, isModule := ctx.(android.ModuleContext)
+ if isModule {
+ config := GetGlobalConfig(ctx)
+ jars := NonUpdatableSystemServerJars(ctx, config)
+ mctx.WalkDeps(func(dep android.Module, parent android.Module) bool {
+ depIndex := android.IndexList(dep.Name(), jars)
+ if jarIndex < depIndex && !config.BrokenSuboptimalOrderOfSystemServerJars {
+ jar := jars[jarIndex]
+ dep := jars[depIndex]
+ mctx.ModuleErrorf("non-optimal order of jars on the system server classpath:"+
+ " '%s' precedes its dependency '%s', so dexpreopt is unable to resolve any"+
+ " references from '%s' to '%s'.\n", jar, dep, jar, dep)
+ }
+ return true
+ })
+ }
+}
+
func contains(l []string, s string) bool {
for _, e := range l {
if e == s {
diff --git a/java/androidmk.go b/java/androidmk.go
index 6eb22fd..62cf169 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -69,7 +69,26 @@
if !library.ApexModuleBase.AvailableFor(android.AvailableToPlatform) {
hideFromMake = true
}
- if !hideFromMake {
+ if hideFromMake {
+ // May still need to add some additional dependencies. This will be called
+ // once for the platform variant (even if it is not being used) and once each
+ // for the APEX specific variants. In order to avoid adding the dependency
+ // multiple times only add it for the platform variant.
+ checkedModulePaths := library.additionalCheckedModules
+ if library.IsForPlatform() && len(checkedModulePaths) != 0 {
+ mainEntries = android.AndroidMkEntries{
+ Class: "FAKE",
+ // Need at least one output file in order for this to take effect.
+ OutputFile: android.OptionalPathForPath(checkedModulePaths[0]),
+ Include: "$(BUILD_PHONY_PACKAGE)",
+ ExtraEntries: []android.AndroidMkExtraEntriesFunc{
+ func(entries *android.AndroidMkEntries) {
+ entries.AddStrings("LOCAL_ADDITIONAL_CHECKED_MODULE", checkedModulePaths.Strings()...)
+ },
+ },
+ }
+ }
+ } else {
mainEntries = android.AndroidMkEntries{
Class: "JAVA_LIBRARIES",
DistFile: android.OptionalPathForPath(library.distFile),
@@ -104,6 +123,10 @@
entries.AddStrings("LOCAL_EXPORT_SDK_LIBRARIES", library.exportedSdkLibs...)
+ if len(library.additionalCheckedModules) != 0 {
+ entries.AddStrings("LOCAL_ADDITIONAL_CHECKED_MODULE", library.additionalCheckedModules.Strings()...)
+ }
+
if library.proguardDictionary != nil {
entries.SetPath("LOCAL_SOONG_PROGUARD_DICT", library.proguardDictionary)
}
diff --git a/java/builder.go b/java/builder.go
index 640dba9..a27e5c3 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -206,7 +206,7 @@
blueprint.RuleParams{
Command: "rm -f $out && " +
"${config.PackageCheckCmd} $in $packages && " +
- "cp $in $out",
+ "touch $out",
CommandDeps: []string{"${config.PackageCheckCmd}"},
},
"packages")
@@ -547,9 +547,8 @@
})
}
-func CheckJarPackages(ctx android.ModuleContext, classesJar android.Path, permittedPackages []string) android.ModuleOutPath {
- outputFile := android.PathForModuleOut(ctx, "package-check", classesJar.Base())
-
+func CheckJarPackages(ctx android.ModuleContext, outputFile android.WritablePath,
+ classesJar android.Path, permittedPackages []string) {
ctx.Build(pctx, android.BuildParams{
Rule: packageCheck,
Description: "packageCheck",
@@ -559,8 +558,6 @@
"packages": strings.Join(permittedPackages, " "),
},
})
-
- return outputFile
}
func TransformJetifier(ctx android.ModuleContext, outputFile android.WritablePath,
diff --git a/java/java.go b/java/java.go
index 09df2ad..eaf0fe9 100644
--- a/java/java.go
+++ b/java/java.go
@@ -463,6 +463,9 @@
// expanded Jarjar_rules
expandJarjarRules android.Path
+ // list of additional targets for checkbuild
+ additionalCheckedModules android.Paths
+
// Extra files generated by the module type to be added as java resources.
extraResources android.Paths
@@ -1518,10 +1521,10 @@
// Check package restrictions if necessary.
if len(j.properties.Permitted_packages) > 0 {
- // Check packages and copy input to package-checked file.
- // Use the file copied after a successful package check as the output file for this
- // module so that any dependencies on this module will trigger the package check.
- outputFile = CheckJarPackages(ctx, outputFile, j.properties.Permitted_packages)
+ // Check packages and copy to package-checked file.
+ pkgckFile := android.PathForModuleOut(ctx, "package-check.stamp")
+ CheckJarPackages(ctx, pkgckFile, outputFile, j.properties.Permitted_packages)
+ j.additionalCheckedModules = append(j.additionalCheckedModules, pkgckFile)
if ctx.Failed() {
return
@@ -2688,6 +2691,10 @@
return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name())
}
+func (a *DexImport) JacocoReportClassesFile() android.Path {
+ return nil
+}
+
func (j *DexImport) IsInstallable() bool {
return true
}