From 331a1213b0ece32fa2af20cbe00448bddd7d242b Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 15 Aug 2018 20:40:52 -0700 Subject: [PATCH] Don't pass resources to r8 R8 complains when it gets dex files in the input jar, but some tests use dex files or dex jars as resources. Keep resources separate from classes until after r8 has been run. Test: java_test.go Test: m checkbuild Change-Id: I1d9164d60d6b054ebb138648da07d80ee769177f --- java/aar.go | 8 ++++ java/androidmk.go | 17 +++++--- java/dex.go | 1 - java/java.go | 100 +++++++++++++++++++++++++++++++++++++++++----- java/java_test.go | 2 +- 5 files changed, 109 insertions(+), 19 deletions(-) diff --git a/java/aar.go b/java/aar.go index de67da612..e90f98471 100644 --- a/java/aar.go +++ b/java/aar.go @@ -498,6 +498,14 @@ func (a *AARImport) ImplementationJars() android.Paths { return android.Paths{a.classpathFile} } +func (a *AARImport) ResourceJars() android.Paths { + return nil +} + +func (a *AARImport) ImplementationAndResourcesJars() android.Paths { + return android.Paths{a.classpathFile} +} + func (a *AARImport) AidlIncludeDirs() android.Paths { return nil } diff --git a/java/androidmk.go b/java/androidmk.go index 384d7e8e8..aebbcc802 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -25,7 +25,7 @@ import ( func (library *Library) AndroidMk() android.AndroidMkData { return android.AndroidMkData{ Class: "JAVA_LIBRARIES", - OutputFile: android.OptionalPathForPath(library.implementationJarFile), + OutputFile: android.OptionalPathForPath(library.implementationAndResourcesJar), Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk", Extra: []android.AndroidMkExtraFunc{ func(w io.Writer, outputFile android.Path) { @@ -84,14 +84,14 @@ func (library *Library) AndroidMk() android.AndroidMkData { fmt.Fprintln(w, "LOCAL_MODULE := "+name+"-hostdex") fmt.Fprintln(w, "LOCAL_IS_HOST_MODULE := true") fmt.Fprintln(w, "LOCAL_MODULE_CLASS := JAVA_LIBRARIES") - fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", library.implementationJarFile.String()) + fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", library.implementationAndResourcesJar.String()) if library.installFile == nil { fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true") } if library.dexJarFile != nil { fmt.Fprintln(w, "LOCAL_SOONG_DEX_JAR :=", library.dexJarFile.String()) } - fmt.Fprintln(w, "LOCAL_SOONG_HEADER_JAR :=", library.implementationJarFile.String()) + fmt.Fprintln(w, "LOCAL_SOONG_HEADER_JAR :=", library.headerJarFile.String()) fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES := "+strings.Join(data.Required, " ")) fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_java_prebuilt.mk") } @@ -159,8 +159,13 @@ func (binary *Binary) AndroidMk() android.AndroidMkData { if !binary.isWrapperVariant { return android.AndroidMkData{ Class: "JAVA_LIBRARIES", - OutputFile: android.OptionalPathForPath(binary.implementationJarFile), + OutputFile: android.OptionalPathForPath(binary.outputFile), Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk", + Extra: []android.AndroidMkExtraFunc{ + func(w io.Writer, outputFile android.Path) { + fmt.Fprintln(w, "LOCAL_SOONG_HEADER_JAR :=", binary.headerJarFile.String()) + }, + }, Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) { android.WriteAndroidMkData(w, data) @@ -198,8 +203,8 @@ func (app *AndroidApp) AndroidMk() android.AndroidMkData { if app.dexJarFile != nil { fmt.Fprintln(w, "LOCAL_SOONG_DEX_JAR :=", app.dexJarFile.String()) } - if app.implementationJarFile != nil { - fmt.Fprintln(w, "LOCAL_SOONG_CLASSES_JAR :=", app.implementationJarFile) + if app.implementationAndResourcesJar != nil { + fmt.Fprintln(w, "LOCAL_SOONG_CLASSES_JAR :=", app.implementationAndResourcesJar.String()) } if app.headerJarFile != nil { fmt.Fprintln(w, "LOCAL_SOONG_HEADER_JAR :=", app.headerJarFile.String()) diff --git a/java/dex.go b/java/dex.go index d0ca06e45..77a3644da 100644 --- a/java/dex.go +++ b/java/dex.go @@ -183,6 +183,5 @@ func (j *Module) compileDex(ctx android.ModuleContext, flags javaBuilderFlags, }) } - j.dexJarFile = javalibJar return javalibJar } diff --git a/java/java.go b/java/java.go index c9759d737..705704646 100644 --- a/java/java.go +++ b/java/java.go @@ -272,13 +272,22 @@ type Module struct { protoProperties android.ProtoProperties deviceProperties CompilerDeviceProperties - // header jar file suitable for inserting into the bootclasspath/classpath of another compile + // jar file containing header classes including static library dependencies, suitable for + // inserting into the bootclasspath/classpath of another compile headerJarFile android.Path - // full implementation jar file suitable for static dependency of another module compile + // jar file containing implementation classes including static library dependencies but no + // resources implementationJarFile android.Path - // output file containing classes.dex + // jar file containing only resources including from static library dependencies + resourceJar android.Path + + // jar file containing implementation classes and resources including static library + // dependencies + implementationAndResourcesJar android.Path + + // output file containing classes.dex and resources dexJarFile android.Path // output file containing uninstrumented classes that will be instrumented by jacoco @@ -287,7 +296,7 @@ type Module struct { // output file containing mapping of obfuscated names proguardDictionary android.Path - // output file suitable for installing or running + // output file of the module, which may be a classes jar or a dex jar outputFile android.Path exportAidlIncludeDirs android.Paths @@ -317,6 +326,8 @@ var _ android.SourceFileProducer = (*Module)(nil) type Dependency interface { HeaderJars() android.Paths ImplementationJars() android.Paths + ResourceJars() android.Paths + ImplementationAndResourcesJars() android.Paths AidlIncludeDirs() android.Paths ExportedSdkLibs() []string } @@ -673,7 +684,7 @@ type deps struct { processorPath classpath staticJars android.Paths staticHeaderJars android.Paths - staticJarResources android.Paths + staticResourceJars android.Paths aidlIncludeDirs android.Paths srcs android.Paths srcJars android.Paths @@ -794,10 +805,11 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { deps.classpath = append(deps.classpath, dep.HeaderJars()...) 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.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...) case annoTag: - deps.processorPath = append(deps.processorPath, dep.ImplementationJars()...) + deps.processorPath = append(deps.processorPath, dep.ImplementationAndResourcesJars()...) case frameworkResTag: if ctx.ModuleName() == "framework" { // framework.jar has a one-off dependency on the R.java and Manifest.java files @@ -817,7 +829,7 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { // Normally the package rule runs aapt, which includes the resource, // but we're not running that in our package rule so just copy in the // resource files here. - deps.staticJarResources = append(deps.staticJarResources, dep.(*AndroidApp).exportPackage) + deps.staticResourceJars = append(deps.staticResourceJars, dep.(*AndroidApp).exportPackage) } case kotlinStdlibTag: deps.kotlinStdlib = dep.HeaderJars() @@ -1149,16 +1161,27 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path if len(resArgs) > 0 { resourceJar := android.PathForModuleOut(ctx, "res", jarName) TransformResourcesToJar(ctx, resourceJar, resArgs, resDeps) + j.resourceJar = resourceJar if ctx.Failed() { return } - - jars = append(jars, resourceJar) } - // static classpath jars have the resources in them, so the resource jars aren't necessary here + if len(deps.staticResourceJars) > 0 { + var jars android.Paths + if j.resourceJar != nil { + jars = append(jars, j.resourceJar) + } + jars = append(jars, deps.staticResourceJars...) + + combinedJar := android.PathForModuleOut(ctx, "res-combined", jarName) + TransformJarsToJar(ctx, combinedJar, "for resources", jars, android.OptionalPath{}, + false, nil, nil) + j.resourceJar = combinedJar + } + jars = append(jars, deps.staticJars...) - jars = append(jars, deps.staticJarResources...) + jars = append(jars, deps.staticResourceJars...) var manifest android.OptionalPath if j.properties.Manifest != nil { @@ -1203,12 +1226,21 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path } } + // jarjar implementation jar if necessary if j.properties.Jarjar_rules != nil { jarjar_rules := android.PathForModuleSrc(ctx, *j.properties.Jarjar_rules) // Transform classes.jar into classes-jarjar.jar jarjarFile := android.PathForModuleOut(ctx, "jarjar", jarName) TransformJarJar(ctx, jarjarFile, outputFile, jarjar_rules) outputFile = jarjarFile + + // jarjar resource jar if necessary + if j.resourceJar != nil { + resourceJarJarFile := android.PathForModuleOut(ctx, "res-jarjar", jarName) + TransformJarJar(ctx, resourceJarJarFile, j.resourceJar, jarjar_rules) + j.resourceJar = resourceJarJarFile + } + if ctx.Failed() { return } @@ -1228,14 +1260,41 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path outputFile = j.instrument(ctx, flags, outputFile, jarName) } + // merge implementation jar with resources if necessary + implementationAndResourcesJar := outputFile + if j.resourceJar != nil { + jars := android.Paths{implementationAndResourcesJar, j.resourceJar} + combinedJar := android.PathForModuleOut(ctx, "withres", jarName) + TransformJarsToJar(ctx, combinedJar, "for resources", jars, android.OptionalPath{}, + false, nil, nil) + implementationAndResourcesJar = combinedJar + } + + j.implementationAndResourcesJar = implementationAndResourcesJar + if ctx.Device() && (Bool(j.properties.Installable) || Bool(j.deviceProperties.Compile_dex)) { var dexOutputFile android.ModuleOutPath dexOutputFile = j.compileDex(ctx, flags, outputFile, jarName) if ctx.Failed() { return } + + // merge dex jar with resources if necessary + if j.resourceJar != nil { + jars := android.Paths{dexOutputFile, j.resourceJar} + combinedJar := android.PathForModuleOut(ctx, "dex-withres", jarName) + TransformJarsToJar(ctx, combinedJar, "for dex resources", jars, android.OptionalPath{}, + false, nil, nil) + dexOutputFile = combinedJar + } + + j.dexJarFile = dexOutputFile + outputFile = dexOutputFile + } else { + outputFile = implementationAndResourcesJar } + ctx.CheckbuildFile(outputFile) // Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource @@ -1307,6 +1366,17 @@ func (j *Module) ImplementationJars() android.Paths { return android.Paths{j.implementationJarFile} } +func (j *Module) ResourceJars() android.Paths { + if j.resourceJar == nil { + return nil + } + return android.Paths{j.resourceJar} +} + +func (j *Module) ImplementationAndResourcesJars() android.Paths { + return android.Paths{j.implementationAndResourcesJar} +} + func (j *Module) AidlIncludeDirs() android.Paths { return j.exportAidlIncludeDirs } @@ -1625,6 +1695,14 @@ func (j *Import) ImplementationJars() android.Paths { return android.Paths{j.combinedClasspathFile} } +func (j *Import) ResourceJars() android.Paths { + return nil +} + +func (j *Import) ImplementationAndResourcesJars() android.Paths { + return android.Paths{j.combinedClasspathFile} +} + func (j *Import) AidlIncludeDirs() android.Paths { return nil } diff --git a/java/java_test.go b/java/java_test.go index 434bcc7f3..72341ee26 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -719,7 +719,7 @@ func TestResources(t *testing.T) { } `+test.extra) - foo := ctx.ModuleForTests("foo", "android_common").Output("combined/foo.jar") + foo := ctx.ModuleForTests("foo", "android_common").Output("withres/foo.jar") fooRes := ctx.ModuleForTests("foo", "android_common").Output("res/foo.jar") if !inList(fooRes.Output.String(), foo.Inputs.Strings()) {