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()) {