blob: ce307fe79b506ecd6dd6e3c64c47841b569a0799 [file] [log] [blame]
Colin Cross3bc7ffa2017-11-22 16:19:37 -08001// Copyright 2017 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
15package java
16
17import (
18 "path/filepath"
19 "strconv"
20 "strings"
21
22 "github.com/google/blueprint"
23
24 "android/soong/android"
25)
26
27const AAPT2_SHARD_SIZE = 100
28
29// Convert input resource file path to output file path.
30// values-[config]/<file>.xml -> values-[config]_<file>.arsc.flat;
31// For other resource file, just replace the last "/" with "_" and
32// add .flat extension.
33func pathToAapt2Path(ctx android.ModuleContext, res android.Path) android.WritablePath {
34
35 name := res.Base()
36 subDir := filepath.Dir(res.String())
37 subDir, lastDir := filepath.Split(subDir)
38 if strings.HasPrefix(lastDir, "values") {
39 name = strings.TrimSuffix(name, ".xml") + ".arsc"
40 }
41 name = lastDir + "_" + name + ".flat"
42 return android.PathForModuleOut(ctx, "aapt2", subDir, name)
43}
44
45func pathsToAapt2Paths(ctx android.ModuleContext, resPaths android.Paths) android.WritablePaths {
46 outPaths := make(android.WritablePaths, len(resPaths))
47
48 for i, res := range resPaths {
49 outPaths[i] = pathToAapt2Path(ctx, res)
50 }
51
52 return outPaths
53}
54
55var aapt2CompileRule = pctx.AndroidStaticRule("aapt2Compile",
56 blueprint.RuleParams{
57 Command: `${config.Aapt2Cmd compile -o $outDir $cFlags --legacy $in`,
58 CommandDeps: []string{"${config.Aapt2Cmd}"},
59 },
60 "outDir", "cFlags")
61
62func aapt2Compile(ctx android.ModuleContext, dir android.Path, paths android.Paths) android.WritablePaths {
63 shards := shardPaths(paths, AAPT2_SHARD_SIZE)
64
65 ret := make(android.WritablePaths, 0, len(paths))
66
67 for i, shard := range shards {
68 outPaths := pathsToAapt2Paths(ctx, shard)
69 ret = append(ret, outPaths...)
70
71 shardDesc := ""
72 if i != 0 {
73 shardDesc = " " + strconv.Itoa(i+1)
74 }
75
76 ctx.Build(pctx, android.BuildParams{
77 Rule: aapt2CompileRule,
78 Description: "aapt2 compile " + dir.String() + shardDesc,
79 Inputs: shard,
80 Outputs: outPaths,
81 Args: map[string]string{
82 "outDir": android.PathForModuleOut(ctx, "aapt2", dir.String()).String(),
83 "cFlags": "--pseudo-localize",
84 },
85 })
86 }
87
88 return ret
89}
90
91var aapt2LinkRule = pctx.AndroidStaticRule("aapt2Link",
92 blueprint.RuleParams{
93 Command: `$aapt2Cmd link -o $out $flags --java $genDir --proguard $proguardOptions $inFlags && ` +
94 `${config.SoongZipCmd} -write_if_changed -jar -o $genJar -C $genDir -D $genDir`,
95 CommandDeps: []string{
96 "$aapt2Cmd",
97 "${config.SoongZipCmd}",
98 },
99 Restat: true,
100 },
101 "flags", "inFlags", "proguardOptions", "genDir", "genJar")
102
103var fileListToFileRule = pctx.AndroidStaticRule("fileListToFile",
104 blueprint.RuleParams{
105 Command: `cp $out.rsp $out`,
106 Rspfile: "$out.rsp",
107 RspfileContent: "$in",
108 })
109
110func aapt2Link(ctx android.ModuleContext,
111 packageRes, genJar, proguardOptions android.WritablePath,
112 flags []string, deps android.Paths,
113 compiledRes, compiledOverlay android.Paths) {
114
115 genDir := android.PathForModuleGen(ctx, "aapt2", "R")
116
117 var inFlags []string
118
119 if len(compiledRes) > 0 {
120 resFileList := android.PathForModuleOut(ctx, "aapt2", "res.list")
121 // Write out file lists to files
122 ctx.Build(pctx, android.BuildParams{
123 Rule: fileListToFileRule,
124 Description: "resource file list",
125 Inputs: compiledRes,
126 Output: resFileList,
127 })
128
129 deps = append(deps, compiledRes...)
130 deps = append(deps, resFileList)
131 inFlags = append(inFlags, "@"+resFileList.String())
132 }
133
134 if len(compiledOverlay) > 0 {
135 overlayFileList := android.PathForModuleOut(ctx, "aapt2", "overlay.list")
136 ctx.Build(pctx, android.BuildParams{
137 Rule: fileListToFileRule,
138 Description: "overlay resource file list",
139 Inputs: compiledOverlay,
140 Output: overlayFileList,
141 })
142
143 deps = append(deps, compiledOverlay...)
144 deps = append(deps, overlayFileList)
145 inFlags = append(inFlags, "-R", "@"+overlayFileList.String())
146 }
147
148 ctx.Build(pctx, android.BuildParams{
149 Rule: aapt2LinkRule,
150 Description: "aapt2 link",
151 Implicits: deps,
152 Output: packageRes,
153 ImplicitOutputs: android.WritablePaths{proguardOptions, genJar},
154 Args: map[string]string{
155 "flags": strings.Join(flags, " "),
156 "inFlags": strings.Join(inFlags, " "),
157 "proguardOptions": proguardOptions.String(),
158 "genDir": genDir.String(),
159 "genJar": genJar.String(),
160 },
161 })
162}