app_builder.go 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. // Copyright 2015 Google Inc. All rights reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package java
  15. // This file generates the final rules for compiling all Java. All properties related to
  16. // compiling should have been translated into javaBuilderFlags or another argument to the Transform*
  17. // functions.
  18. import (
  19. "path/filepath"
  20. "strings"
  21. "github.com/google/blueprint"
  22. "github.com/google/blueprint/proptools"
  23. "android/soong/android"
  24. "android/soong/remoteexec"
  25. )
  26. var (
  27. Signapk, SignapkRE = pctx.RemoteStaticRules("signapk",
  28. blueprint.RuleParams{
  29. Command: `rm -f $out && $reTemplate${config.JavaCmd} ${config.JavaVmFlags} -Djava.library.path=$$(dirname ${config.SignapkJniLibrary}) ` +
  30. `-jar ${config.SignapkCmd} $flags $certificates $in $out`,
  31. CommandDeps: []string{"${config.SignapkCmd}", "${config.SignapkJniLibrary}"},
  32. },
  33. &remoteexec.REParams{Labels: map[string]string{"type": "tool", "name": "signapk"},
  34. ExecStrategy: "${config.RESignApkExecStrategy}",
  35. Inputs: []string{"${config.SignapkCmd}", "$in", "$$(dirname ${config.SignapkJniLibrary})", "$implicits"},
  36. OutputFiles: []string{"$outCommaList"},
  37. ToolchainInputs: []string{"${config.JavaCmd}"},
  38. Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
  39. }, []string{"flags", "certificates"}, []string{"implicits", "outCommaList"})
  40. )
  41. var combineApk = pctx.AndroidStaticRule("combineApk",
  42. blueprint.RuleParams{
  43. Command: `${config.MergeZipsCmd} $out $in`,
  44. CommandDeps: []string{"${config.MergeZipsCmd}"},
  45. })
  46. func CreateAndSignAppPackage(ctx android.ModuleContext, outputFile android.WritablePath,
  47. packageFile, jniJarFile, dexJarFile android.Path, certificates []Certificate, deps android.Paths, v4SignatureFile android.WritablePath, lineageFile android.Path, rotationMinSdkVersion string, shrinkResources bool) {
  48. unsignedApkName := strings.TrimSuffix(outputFile.Base(), ".apk") + "-unsigned.apk"
  49. unsignedApk := android.PathForModuleOut(ctx, unsignedApkName)
  50. var inputs android.Paths
  51. if dexJarFile != nil {
  52. inputs = append(inputs, dexJarFile)
  53. }
  54. inputs = append(inputs, packageFile)
  55. if jniJarFile != nil {
  56. inputs = append(inputs, jniJarFile)
  57. }
  58. ctx.Build(pctx, android.BuildParams{
  59. Rule: combineApk,
  60. Inputs: inputs,
  61. Output: unsignedApk,
  62. Implicits: deps,
  63. })
  64. if shrinkResources {
  65. shrunkenApk := android.PathForModuleOut(ctx, "resource-shrunken", unsignedApk.Base())
  66. ShrinkResources(ctx, unsignedApk, shrunkenApk)
  67. unsignedApk = shrunkenApk
  68. }
  69. SignAppPackage(ctx, outputFile, unsignedApk, certificates, v4SignatureFile, lineageFile, rotationMinSdkVersion)
  70. }
  71. func SignAppPackage(ctx android.ModuleContext, signedApk android.WritablePath, unsignedApk android.Path, certificates []Certificate, v4SignatureFile android.WritablePath, lineageFile android.Path, rotationMinSdkVersion string) {
  72. var certificateArgs []string
  73. var deps android.Paths
  74. for _, c := range certificates {
  75. certificateArgs = append(certificateArgs, c.Pem.String(), c.Key.String())
  76. deps = append(deps, c.Pem, c.Key)
  77. }
  78. outputFiles := android.WritablePaths{signedApk}
  79. var flags []string
  80. if v4SignatureFile != nil {
  81. outputFiles = append(outputFiles, v4SignatureFile)
  82. flags = append(flags, "--enable-v4")
  83. }
  84. if lineageFile != nil {
  85. flags = append(flags, "--lineage", lineageFile.String())
  86. deps = append(deps, lineageFile)
  87. }
  88. if rotationMinSdkVersion != "" {
  89. flags = append(flags, "--rotation-min-sdk-version", rotationMinSdkVersion)
  90. }
  91. rule := Signapk
  92. args := map[string]string{
  93. "certificates": strings.Join(certificateArgs, " "),
  94. "flags": strings.Join(flags, " "),
  95. }
  96. if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_SIGNAPK") {
  97. rule = SignapkRE
  98. args["implicits"] = strings.Join(deps.Strings(), ",")
  99. args["outCommaList"] = strings.Join(outputFiles.Strings(), ",")
  100. }
  101. ctx.Build(pctx, android.BuildParams{
  102. Rule: rule,
  103. Description: "signapk",
  104. Outputs: outputFiles,
  105. Input: unsignedApk,
  106. Implicits: deps,
  107. Args: args,
  108. })
  109. }
  110. var buildAAR = pctx.AndroidStaticRule("buildAAR",
  111. blueprint.RuleParams{
  112. Command: `rm -rf ${outDir} && mkdir -p ${outDir} && ` +
  113. `cp ${manifest} ${outDir}/AndroidManifest.xml && ` +
  114. `cp ${classesJar} ${outDir}/classes.jar && ` +
  115. `cp ${rTxt} ${outDir}/R.txt && ` +
  116. `${config.SoongZipCmd} -jar -o $out -C ${outDir} -D ${outDir}`,
  117. CommandDeps: []string{"${config.SoongZipCmd}"},
  118. },
  119. "manifest", "classesJar", "rTxt", "outDir")
  120. func BuildAAR(ctx android.ModuleContext, outputFile android.WritablePath,
  121. classesJar, manifest, rTxt android.Path, res android.Paths) {
  122. // TODO(ccross): uniquify and copy resources with dependencies
  123. deps := android.Paths{manifest, rTxt}
  124. classesJarPath := ""
  125. if classesJar != nil {
  126. deps = append(deps, classesJar)
  127. classesJarPath = classesJar.String()
  128. }
  129. ctx.Build(pctx, android.BuildParams{
  130. Rule: buildAAR,
  131. Description: "aar",
  132. Implicits: deps,
  133. Output: outputFile,
  134. Args: map[string]string{
  135. "manifest": manifest.String(),
  136. "classesJar": classesJarPath,
  137. "rTxt": rTxt.String(),
  138. "outDir": android.PathForModuleOut(ctx, "aar").String(),
  139. },
  140. })
  141. }
  142. var buildBundleModule = pctx.AndroidStaticRule("buildBundleModule",
  143. blueprint.RuleParams{
  144. Command: `${config.MergeZipsCmd} ${out} ${in}`,
  145. CommandDeps: []string{"${config.MergeZipsCmd}"},
  146. })
  147. var bundleMungePackage = pctx.AndroidStaticRule("bundleMungePackage",
  148. blueprint.RuleParams{
  149. Command: `${config.Zip2ZipCmd} -i ${in} -o ${out} AndroidManifest.xml:manifest/AndroidManifest.xml resources.pb "res/**/*" "assets/**/*"`,
  150. CommandDeps: []string{"${config.Zip2ZipCmd}"},
  151. })
  152. var bundleMungeDexJar = pctx.AndroidStaticRule("bundleMungeDexJar",
  153. blueprint.RuleParams{
  154. Command: `${config.Zip2ZipCmd} -i ${in} -o ${out} "classes*.dex:dex/" && ` +
  155. `${config.Zip2ZipCmd} -i ${in} -o ${resJar} -x "classes*.dex" "**/*:root/"`,
  156. CommandDeps: []string{"${config.Zip2ZipCmd}"},
  157. }, "resJar")
  158. // Builds an app into a module suitable for input to bundletool
  159. func BuildBundleModule(ctx android.ModuleContext, outputFile android.WritablePath,
  160. packageFile, jniJarFile, dexJarFile android.Path) {
  161. protoResJarFile := android.PathForModuleOut(ctx, "package-res.pb.apk")
  162. aapt2Convert(ctx, protoResJarFile, packageFile, "proto")
  163. var zips android.Paths
  164. mungedPackage := android.PathForModuleOut(ctx, "bundle", "apk.zip")
  165. ctx.Build(pctx, android.BuildParams{
  166. Rule: bundleMungePackage,
  167. Input: protoResJarFile,
  168. Output: mungedPackage,
  169. Description: "bundle apk",
  170. })
  171. zips = append(zips, mungedPackage)
  172. if dexJarFile != nil {
  173. mungedDexJar := android.PathForModuleOut(ctx, "bundle", "dex.zip")
  174. mungedResJar := android.PathForModuleOut(ctx, "bundle", "res.zip")
  175. ctx.Build(pctx, android.BuildParams{
  176. Rule: bundleMungeDexJar,
  177. Input: dexJarFile,
  178. Output: mungedDexJar,
  179. ImplicitOutput: mungedResJar,
  180. Description: "bundle dex",
  181. Args: map[string]string{
  182. "resJar": mungedResJar.String(),
  183. },
  184. })
  185. zips = append(zips, mungedDexJar, mungedResJar)
  186. }
  187. if jniJarFile != nil {
  188. zips = append(zips, jniJarFile)
  189. }
  190. ctx.Build(pctx, android.BuildParams{
  191. Rule: buildBundleModule,
  192. Inputs: zips,
  193. Output: outputFile,
  194. Description: "bundle",
  195. })
  196. }
  197. const jniJarOutputPathString = "jniJarOutput.zip"
  198. func TransformJniLibsToJar(
  199. ctx android.ModuleContext,
  200. outputFile android.WritablePath,
  201. jniLibs []jniLib,
  202. prebuiltJniPackages android.Paths,
  203. uncompressJNI bool) {
  204. var deps android.Paths
  205. jarArgs := []string{
  206. "-j", // junk paths, they will be added back with -P arguments
  207. }
  208. if uncompressJNI {
  209. jarArgs = append(jarArgs, "-L", "0")
  210. }
  211. for _, j := range jniLibs {
  212. deps = append(deps, j.path)
  213. jarArgs = append(jarArgs,
  214. "-P", targetToJniDir(j.target),
  215. "-f", j.path.String())
  216. }
  217. rule := zip
  218. args := map[string]string{
  219. "jarArgs": strings.Join(proptools.NinjaAndShellEscapeList(jarArgs), " "),
  220. }
  221. if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_ZIP") {
  222. rule = zipRE
  223. args["implicits"] = strings.Join(deps.Strings(), ",")
  224. }
  225. jniJarPath := android.PathForModuleOut(ctx, jniJarOutputPathString)
  226. ctx.Build(pctx, android.BuildParams{
  227. Rule: rule,
  228. Description: "zip jni libs",
  229. Output: jniJarPath,
  230. Implicits: deps,
  231. Args: args,
  232. })
  233. ctx.Build(pctx, android.BuildParams{
  234. Rule: mergeAssetsRule,
  235. Description: "merge prebuilt JNI packages",
  236. Inputs: append(prebuiltJniPackages, jniJarPath),
  237. Output: outputFile,
  238. })
  239. }
  240. func (a *AndroidApp) generateJavaUsedByApex(ctx android.ModuleContext) {
  241. javaApiUsedByOutputFile := android.PathForModuleOut(ctx, a.installApkName+"_using.xml")
  242. javaUsedByRule := android.NewRuleBuilder(pctx, ctx)
  243. javaUsedByRule.Command().
  244. Tool(android.PathForSource(ctx, "build/soong/scripts/gen_java_usedby_apex.sh")).
  245. BuiltTool("dexdeps").
  246. Output(javaApiUsedByOutputFile).
  247. Input(a.Library.Module.outputFile)
  248. javaUsedByRule.Build("java_usedby_list", "Generate Java APIs used by Apex")
  249. a.javaApiUsedByOutputFile = javaApiUsedByOutputFile
  250. }
  251. func targetToJniDir(target android.Target) string {
  252. return filepath.Join("lib", target.Arch.Abi[0])
  253. }