Improve comments in java/aapt2.go

Test: N/A
Change-Id: I4b35a7c8707b9c4b173bb4587f7634e570d78674
This commit is contained in:
Jaewoong Jung 2020-11-20 17:58:27 -08:00
parent 62aa21508c
commit 60d6d57771
1 changed files with 36 additions and 4 deletions

View File

@ -25,12 +25,9 @@ import (
"android/soong/android" "android/soong/android"
) )
const AAPT2_SHARD_SIZE = 100
// Convert input resource file path to output file path. // Convert input resource file path to output file path.
// values-[config]/<file>.xml -> values-[config]_<file>.arsc.flat; // values-[config]/<file>.xml -> values-[config]_<file>.arsc.flat;
// For other resource file, just replace the last "/" with "_" and // For other resource file, just replace the last "/" with "_" and add .flat extension.
// add .flat extension.
func pathToAapt2Path(ctx android.ModuleContext, res android.Path) android.WritablePath { func pathToAapt2Path(ctx android.ModuleContext, res android.Path) android.WritablePath {
name := res.Base() name := res.Base()
@ -43,6 +40,7 @@ func pathToAapt2Path(ctx android.ModuleContext, res android.Path) android.Writab
return android.PathForModuleOut(ctx, "aapt2", subDir, name) 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 { func pathsToAapt2Paths(ctx android.ModuleContext, resPaths android.Paths) android.WritablePaths {
outPaths := make(android.WritablePaths, len(resPaths)) outPaths := make(android.WritablePaths, len(resPaths))
@ -53,6 +51,9 @@ func pathsToAapt2Paths(ctx android.ModuleContext, resPaths android.Paths) androi
return outPaths return outPaths
} }
// Shard resource files for efficiency. See aapt2Compile for details.
const AAPT2_SHARD_SIZE = 100
var aapt2CompileRule = pctx.AndroidStaticRule("aapt2Compile", var aapt2CompileRule = pctx.AndroidStaticRule("aapt2Compile",
blueprint.RuleParams{ blueprint.RuleParams{
Command: `${config.Aapt2Cmd} compile -o $outDir $cFlags $in`, Command: `${config.Aapt2Cmd} compile -o $outDir $cFlags $in`,
@ -60,14 +61,26 @@ var aapt2CompileRule = pctx.AndroidStaticRule("aapt2Compile",
}, },
"outDir", "cFlags") "outDir", "cFlags")
// aapt2Compile compiles resources and puts the results in the requested directory.
func aapt2Compile(ctx android.ModuleContext, dir android.Path, paths android.Paths, func aapt2Compile(ctx android.ModuleContext, dir android.Path, paths android.Paths,
flags []string) android.WritablePaths { 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) shards := android.ShardPaths(paths, AAPT2_SHARD_SIZE)
ret := make(android.WritablePaths, 0, len(paths)) ret := make(android.WritablePaths, 0, len(paths))
for i, shard := range shards { 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) outPaths := pathsToAapt2Paths(ctx, shard)
ret = append(ret, outPaths...) ret = append(ret, outPaths...)
@ -82,6 +95,12 @@ func aapt2Compile(ctx android.ModuleContext, dir android.Path, paths android.Pat
Inputs: shard, Inputs: shard,
Outputs: outPaths, Outputs: outPaths,
Args: map[string]string{ 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(), "outDir": android.PathForModuleOut(ctx, "aapt2", dir.String()).String(),
"cFlags": strings.Join(flags, " "), "cFlags": strings.Join(flags, " "),
}, },
@ -104,6 +123,8 @@ var aapt2CompileZipRule = pctx.AndroidStaticRule("aapt2CompileZip",
}, },
}, "cFlags", "resZipDir", "zipSyncFlags") }, "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, func aapt2CompileZip(ctx android.ModuleContext, flata android.WritablePath, zip android.Path, zipPrefix string,
flags []string) { flags []string) {
@ -163,6 +184,7 @@ func aapt2Link(ctx android.ModuleContext,
var inFlags []string var inFlags []string
if len(compiledRes) > 0 { if len(compiledRes) > 0 {
// Create a file that contains the list of all compiled resource file paths.
resFileList := android.PathForModuleOut(ctx, "aapt2", "res.list") resFileList := android.PathForModuleOut(ctx, "aapt2", "res.list")
// Write out file lists to files // Write out file lists to files
ctx.Build(pctx, android.BuildParams{ ctx.Build(pctx, android.BuildParams{
@ -174,10 +196,12 @@ func aapt2Link(ctx android.ModuleContext,
deps = append(deps, compiledRes...) deps = append(deps, compiledRes...)
deps = append(deps, resFileList) deps = append(deps, resFileList)
// aapt2 filepath arguments that start with "@" mean file-list files.
inFlags = append(inFlags, "@"+resFileList.String()) inFlags = append(inFlags, "@"+resFileList.String())
} }
if len(compiledOverlay) > 0 { if len(compiledOverlay) > 0 {
// Compiled overlay files are processed the same way as compiled resources.
overlayFileList := android.PathForModuleOut(ctx, "aapt2", "overlay.list") overlayFileList := android.PathForModuleOut(ctx, "aapt2", "overlay.list")
ctx.Build(pctx, android.BuildParams{ ctx.Build(pctx, android.BuildParams{
Rule: fileListToFileRule, Rule: fileListToFileRule,
@ -188,9 +212,11 @@ func aapt2Link(ctx android.ModuleContext,
deps = append(deps, compiledOverlay...) deps = append(deps, compiledOverlay...)
deps = append(deps, overlayFileList) deps = append(deps, overlayFileList)
// Compiled overlay files are passed over to aapt2 using -R option.
inFlags = append(inFlags, "-R", "@"+overlayFileList.String()) inFlags = append(inFlags, "-R", "@"+overlayFileList.String())
} }
// Set auxiliary outputs as implicit outputs to establish correct dependency chains.
implicitOutputs := append(splitPackages, proguardOptions, genJar, rTxt, extraPackages) implicitOutputs := append(splitPackages, proguardOptions, genJar, rTxt, extraPackages)
linkOutput := packageRes linkOutput := packageRes
@ -212,6 +238,10 @@ func aapt2Link(ctx android.ModuleContext,
Implicits: deps, Implicits: deps,
Output: linkOutput, Output: linkOutput,
ImplicitOutputs: implicitOutputs, 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{ Args: map[string]string{
"flags": strings.Join(flags, " "), "flags": strings.Join(flags, " "),
"inFlags": strings.Join(inFlags, " "), "inFlags": strings.Join(inFlags, " "),
@ -230,6 +260,8 @@ var aapt2ConvertRule = pctx.AndroidStaticRule("aapt2Convert",
CommandDeps: []string{"${config.Aapt2Cmd}"}, 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) { func aapt2Convert(ctx android.ModuleContext, out android.WritablePath, in android.Path) {
ctx.Build(pctx, android.BuildParams{ ctx.Build(pctx, android.BuildParams{
Rule: aapt2ConvertRule, Rule: aapt2ConvertRule,