6431ca7a3a
AAPT2 ignores assets in overlay resource inputs, so separate rules are required to extract and merge assets from dependencies. Test: app_test.go Test: Added assets to Settings-core for testing Test: Confirmed Settings.apk contains them with this change. Fixes: 146655310 Change-Id: Iab8bc61b719541dae64f0e3502bc9cb45a353687
240 lines
7.3 KiB
Go
240 lines
7.3 KiB
Go
// Copyright 2017 Google Inc. All rights reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package java
|
|
|
|
import (
|
|
"path/filepath"
|
|
"sort"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/google/blueprint"
|
|
|
|
"android/soong/android"
|
|
)
|
|
|
|
const AAPT2_SHARD_SIZE = 100
|
|
|
|
// Convert input resource file path to output file path.
|
|
// values-[config]/<file>.xml -> values-[config]_<file>.arsc.flat;
|
|
// 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()
|
|
subDir := filepath.Dir(res.String())
|
|
subDir, lastDir := filepath.Split(subDir)
|
|
if strings.HasPrefix(lastDir, "values") {
|
|
name = strings.TrimSuffix(name, ".xml") + ".arsc"
|
|
}
|
|
name = lastDir + "_" + name + ".flat"
|
|
return android.PathForModuleOut(ctx, "aapt2", subDir, name)
|
|
}
|
|
|
|
func pathsToAapt2Paths(ctx android.ModuleContext, resPaths android.Paths) android.WritablePaths {
|
|
outPaths := make(android.WritablePaths, len(resPaths))
|
|
|
|
for i, res := range resPaths {
|
|
outPaths[i] = pathToAapt2Path(ctx, res)
|
|
}
|
|
|
|
return outPaths
|
|
}
|
|
|
|
var aapt2CompileRule = pctx.AndroidStaticRule("aapt2Compile",
|
|
blueprint.RuleParams{
|
|
Command: `${config.Aapt2Cmd} compile -o $outDir $cFlags $in`,
|
|
CommandDeps: []string{"${config.Aapt2Cmd}"},
|
|
},
|
|
"outDir", "cFlags")
|
|
|
|
func aapt2Compile(ctx android.ModuleContext, dir android.Path, paths android.Paths,
|
|
flags []string) android.WritablePaths {
|
|
|
|
shards := android.ShardPaths(paths, AAPT2_SHARD_SIZE)
|
|
|
|
ret := make(android.WritablePaths, 0, len(paths))
|
|
|
|
for i, shard := range shards {
|
|
outPaths := pathsToAapt2Paths(ctx, shard)
|
|
ret = append(ret, outPaths...)
|
|
|
|
shardDesc := ""
|
|
if i != 0 {
|
|
shardDesc = " " + strconv.Itoa(i+1)
|
|
}
|
|
|
|
ctx.Build(pctx, android.BuildParams{
|
|
Rule: aapt2CompileRule,
|
|
Description: "aapt2 compile " + dir.String() + shardDesc,
|
|
Inputs: shard,
|
|
Outputs: outPaths,
|
|
Args: map[string]string{
|
|
"outDir": android.PathForModuleOut(ctx, "aapt2", dir.String()).String(),
|
|
"cFlags": strings.Join(flags, " "),
|
|
},
|
|
})
|
|
}
|
|
|
|
sort.Slice(ret, func(i, j int) bool {
|
|
return ret[i].String() < ret[j].String()
|
|
})
|
|
return ret
|
|
}
|
|
|
|
var aapt2CompileZipRule = pctx.AndroidStaticRule("aapt2CompileZip",
|
|
blueprint.RuleParams{
|
|
Command: `${config.ZipSyncCmd} -d $resZipDir $zipSyncFlags $in && ` +
|
|
`${config.Aapt2Cmd} compile -o $out $cFlags --dir $resZipDir`,
|
|
CommandDeps: []string{
|
|
"${config.Aapt2Cmd}",
|
|
"${config.ZipSyncCmd}",
|
|
},
|
|
}, "cFlags", "resZipDir", "zipSyncFlags")
|
|
|
|
func aapt2CompileZip(ctx android.ModuleContext, flata android.WritablePath, zip android.Path, zipPrefix string,
|
|
flags []string) {
|
|
|
|
if zipPrefix != "" {
|
|
zipPrefix = "--zip-prefix " + zipPrefix
|
|
}
|
|
ctx.Build(pctx, android.BuildParams{
|
|
Rule: aapt2CompileZipRule,
|
|
Description: "aapt2 compile zip",
|
|
Input: zip,
|
|
Output: flata,
|
|
Args: map[string]string{
|
|
"cFlags": strings.Join(flags, " "),
|
|
"resZipDir": android.PathForModuleOut(ctx, "aapt2", "reszip", flata.Base()).String(),
|
|
"zipSyncFlags": zipPrefix,
|
|
},
|
|
})
|
|
}
|
|
|
|
var aapt2LinkRule = pctx.AndroidStaticRule("aapt2Link",
|
|
blueprint.RuleParams{
|
|
Command: `rm -rf $genDir && ` +
|
|
`${config.Aapt2Cmd} link -o $out $flags --java $genDir --proguard $proguardOptions ` +
|
|
`--output-text-symbols ${rTxt} $inFlags && ` +
|
|
`${config.SoongZipCmd} -write_if_changed -jar -o $genJar -C $genDir -D $genDir &&` +
|
|
`${config.ExtractJarPackagesCmd} -i $genJar -o $extraPackages --prefix '--extra-packages '`,
|
|
|
|
CommandDeps: []string{
|
|
"${config.Aapt2Cmd}",
|
|
"${config.SoongZipCmd}",
|
|
"${config.ExtractJarPackagesCmd}",
|
|
},
|
|
Restat: true,
|
|
},
|
|
"flags", "inFlags", "proguardOptions", "genDir", "genJar", "rTxt", "extraPackages")
|
|
|
|
var fileListToFileRule = pctx.AndroidStaticRule("fileListToFile",
|
|
blueprint.RuleParams{
|
|
Command: `cp $out.rsp $out`,
|
|
Rspfile: "$out.rsp",
|
|
RspfileContent: "$in",
|
|
})
|
|
|
|
var mergeAssetsRule = pctx.AndroidStaticRule("mergeAssets",
|
|
blueprint.RuleParams{
|
|
Command: `${config.MergeZipsCmd} ${out} ${in}`,
|
|
CommandDeps: []string{"${config.MergeZipsCmd}"},
|
|
})
|
|
|
|
func aapt2Link(ctx android.ModuleContext,
|
|
packageRes, genJar, proguardOptions, rTxt, extraPackages android.WritablePath,
|
|
flags []string, deps android.Paths,
|
|
compiledRes, compiledOverlay, assetPackages android.Paths, splitPackages android.WritablePaths) {
|
|
|
|
genDir := android.PathForModuleGen(ctx, "aapt2", "R")
|
|
|
|
var inFlags []string
|
|
|
|
if len(compiledRes) > 0 {
|
|
resFileList := android.PathForModuleOut(ctx, "aapt2", "res.list")
|
|
// Write out file lists to files
|
|
ctx.Build(pctx, android.BuildParams{
|
|
Rule: fileListToFileRule,
|
|
Description: "resource file list",
|
|
Inputs: compiledRes,
|
|
Output: resFileList,
|
|
})
|
|
|
|
deps = append(deps, compiledRes...)
|
|
deps = append(deps, resFileList)
|
|
inFlags = append(inFlags, "@"+resFileList.String())
|
|
}
|
|
|
|
if len(compiledOverlay) > 0 {
|
|
overlayFileList := android.PathForModuleOut(ctx, "aapt2", "overlay.list")
|
|
ctx.Build(pctx, android.BuildParams{
|
|
Rule: fileListToFileRule,
|
|
Description: "overlay resource file list",
|
|
Inputs: compiledOverlay,
|
|
Output: overlayFileList,
|
|
})
|
|
|
|
deps = append(deps, compiledOverlay...)
|
|
deps = append(deps, overlayFileList)
|
|
inFlags = append(inFlags, "-R", "@"+overlayFileList.String())
|
|
}
|
|
|
|
implicitOutputs := append(splitPackages, proguardOptions, genJar, rTxt, extraPackages)
|
|
linkOutput := packageRes
|
|
|
|
// AAPT2 ignores assets in overlays. Merge them after linking.
|
|
if len(assetPackages) > 0 {
|
|
linkOutput = android.PathForModuleOut(ctx, "aapt2", "package-res.apk")
|
|
inputZips := append(android.Paths{linkOutput}, assetPackages...)
|
|
ctx.Build(pctx, android.BuildParams{
|
|
Rule: mergeAssetsRule,
|
|
Inputs: inputZips,
|
|
Output: packageRes,
|
|
Description: "merge assets from dependencies",
|
|
})
|
|
}
|
|
|
|
ctx.Build(pctx, android.BuildParams{
|
|
Rule: aapt2LinkRule,
|
|
Description: "aapt2 link",
|
|
Implicits: deps,
|
|
Output: linkOutput,
|
|
ImplicitOutputs: implicitOutputs,
|
|
Args: map[string]string{
|
|
"flags": strings.Join(flags, " "),
|
|
"inFlags": strings.Join(inFlags, " "),
|
|
"proguardOptions": proguardOptions.String(),
|
|
"genDir": genDir.String(),
|
|
"genJar": genJar.String(),
|
|
"rTxt": rTxt.String(),
|
|
"extraPackages": extraPackages.String(),
|
|
},
|
|
})
|
|
}
|
|
|
|
var aapt2ConvertRule = pctx.AndroidStaticRule("aapt2Convert",
|
|
blueprint.RuleParams{
|
|
Command: `${config.Aapt2Cmd} convert --output-format proto $in -o $out`,
|
|
CommandDeps: []string{"${config.Aapt2Cmd}"},
|
|
})
|
|
|
|
func aapt2Convert(ctx android.ModuleContext, out android.WritablePath, in android.Path) {
|
|
ctx.Build(pctx, android.BuildParams{
|
|
Rule: aapt2ConvertRule,
|
|
Input: in,
|
|
Output: out,
|
|
Description: "convert to proto",
|
|
})
|
|
}
|