From 60d6d57771a50030556c918508d9921d284351ba Mon Sep 17 00:00:00 2001 From: Jaewoong Jung Date: Fri, 20 Nov 2020 17:58:27 -0800 Subject: [PATCH] Improve comments in java/aapt2.go Test: N/A Change-Id: I4b35a7c8707b9c4b173bb4587f7634e570d78674 --- java/aapt2.go | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/java/aapt2.go b/java/aapt2.go index 04e4de52c..5346ddf89 100644 --- a/java/aapt2.go +++ b/java/aapt2.go @@ -25,12 +25,9 @@ import ( "android/soong/android" ) -const AAPT2_SHARD_SIZE = 100 - // Convert input resource file path to output file path. // values-[config]/.xml -> values-[config]_.arsc.flat; -// For other resource file, just replace the last "/" with "_" and -// add .flat extension. +// For other resource file, just replace the last "/" with "_" and add .flat extension. func pathToAapt2Path(ctx android.ModuleContext, res android.Path) android.WritablePath { name := res.Base() @@ -43,6 +40,7 @@ func pathToAapt2Path(ctx android.ModuleContext, res android.Path) android.Writab return android.PathForModuleOut(ctx, "aapt2", subDir, name) } +// pathsToAapt2Paths Calls pathToAapt2Path on each entry of the given Paths, i.e. []Path. func pathsToAapt2Paths(ctx android.ModuleContext, resPaths android.Paths) android.WritablePaths { outPaths := make(android.WritablePaths, len(resPaths)) @@ -53,6 +51,9 @@ func pathsToAapt2Paths(ctx android.ModuleContext, resPaths android.Paths) androi return outPaths } +// Shard resource files for efficiency. See aapt2Compile for details. +const AAPT2_SHARD_SIZE = 100 + var aapt2CompileRule = pctx.AndroidStaticRule("aapt2Compile", blueprint.RuleParams{ Command: `${config.Aapt2Cmd} compile -o $outDir $cFlags $in`, @@ -60,14 +61,26 @@ var aapt2CompileRule = pctx.AndroidStaticRule("aapt2Compile", }, "outDir", "cFlags") +// aapt2Compile compiles resources and puts the results in the requested directory. func aapt2Compile(ctx android.ModuleContext, dir android.Path, paths android.Paths, flags []string) android.WritablePaths { + // Shard the input paths so that they can be processed in parallel. If we shard them into too + // small chunks, the additional cost of spinning up aapt2 outweighs the performance gain. The + // current shard size, 100, seems to be a good balance between the added cost and the gain. + // The aapt2 compile actions are trivially short, but each action in ninja takes on the order of + // ~10 ms to run. frameworks/base/core/res/res has >10k resource files, so compiling each one + // with an individual action could take 100 CPU seconds. Sharding them reduces the overhead of + // starting actions by a factor of 100, at the expense of recompiling more files when one + // changes. Since the individual compiles are trivial it's a good tradeoff. shards := android.ShardPaths(paths, AAPT2_SHARD_SIZE) ret := make(android.WritablePaths, 0, len(paths)) for i, shard := range shards { + // This should be kept in sync with pathToAapt2Path. The aapt2 compile command takes an + // output directory path, but not output file paths. So, outPaths is just where we expect + // the output files will be located. outPaths := pathsToAapt2Paths(ctx, shard) ret = append(ret, outPaths...) @@ -82,6 +95,12 @@ func aapt2Compile(ctx android.ModuleContext, dir android.Path, paths android.Pat Inputs: shard, Outputs: outPaths, Args: map[string]string{ + // The aapt2 compile command takes an output directory path, but not output file paths. + // outPaths specified above is only used for dependency management purposes. In order for + // the outPaths values to match the actual outputs from aapt2, the dir parameter value + // must be a common prefix path of the paths values, and the top-level path segment used + // below, "aapt2", must always be kept in sync with the one in pathToAapt2Path. + // TODO(b/174505750): Make this easier and robust to use. "outDir": android.PathForModuleOut(ctx, "aapt2", dir.String()).String(), "cFlags": strings.Join(flags, " "), }, @@ -104,6 +123,8 @@ var aapt2CompileZipRule = pctx.AndroidStaticRule("aapt2CompileZip", }, }, "cFlags", "resZipDir", "zipSyncFlags") +// Unzips the given compressed file and compiles the resource source files in it. The zipPrefix +// parameter points to the subdirectory in the zip file where the resource files are located. func aapt2CompileZip(ctx android.ModuleContext, flata android.WritablePath, zip android.Path, zipPrefix string, flags []string) { @@ -163,6 +184,7 @@ func aapt2Link(ctx android.ModuleContext, var inFlags []string if len(compiledRes) > 0 { + // Create a file that contains the list of all compiled resource file paths. resFileList := android.PathForModuleOut(ctx, "aapt2", "res.list") // Write out file lists to files ctx.Build(pctx, android.BuildParams{ @@ -174,10 +196,12 @@ func aapt2Link(ctx android.ModuleContext, deps = append(deps, compiledRes...) deps = append(deps, resFileList) + // aapt2 filepath arguments that start with "@" mean file-list files. inFlags = append(inFlags, "@"+resFileList.String()) } if len(compiledOverlay) > 0 { + // Compiled overlay files are processed the same way as compiled resources. overlayFileList := android.PathForModuleOut(ctx, "aapt2", "overlay.list") ctx.Build(pctx, android.BuildParams{ Rule: fileListToFileRule, @@ -188,9 +212,11 @@ func aapt2Link(ctx android.ModuleContext, deps = append(deps, compiledOverlay...) deps = append(deps, overlayFileList) + // Compiled overlay files are passed over to aapt2 using -R option. inFlags = append(inFlags, "-R", "@"+overlayFileList.String()) } + // Set auxiliary outputs as implicit outputs to establish correct dependency chains. implicitOutputs := append(splitPackages, proguardOptions, genJar, rTxt, extraPackages) linkOutput := packageRes @@ -212,6 +238,10 @@ func aapt2Link(ctx android.ModuleContext, Implicits: deps, Output: linkOutput, ImplicitOutputs: implicitOutputs, + // Note the absence of splitPackages. The caller is supposed to compose and provide --split flag + // values via the flags parameter when it wants to split outputs. + // TODO(b/174509108): Perhaps we can process it in this func while keeping the code reasonably + // tidy. Args: map[string]string{ "flags": strings.Join(flags, " "), "inFlags": strings.Join(inFlags, " "), @@ -230,6 +260,8 @@ var aapt2ConvertRule = pctx.AndroidStaticRule("aapt2Convert", CommandDeps: []string{"${config.Aapt2Cmd}"}, }) +// Converts xml files and resource tables (resources.arsc) in the given jar/apk file to a proto +// format. The proto definition is available at frameworks/base/tools/aapt2/Resources.proto. func aapt2Convert(ctx android.ModuleContext, out android.WritablePath, in android.Path) { ctx.Build(pctx, android.BuildParams{ Rule: aapt2ConvertRule,