blob: 5553bfdf889e6771d8efadc1392078ff496682cd [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"
Colin Crossb69301e2017-12-01 10:48:26 -080019 "sort"
Colin Cross3bc7ffa2017-11-22 16:19:37 -080020 "strconv"
21 "strings"
22
23 "github.com/google/blueprint"
24
25 "android/soong/android"
26)
27
28const AAPT2_SHARD_SIZE = 100
29
30// Convert input resource file path to output file path.
31// values-[config]/<file>.xml -> values-[config]_<file>.arsc.flat;
32// For other resource file, just replace the last "/" with "_" and
33// add .flat extension.
34func pathToAapt2Path(ctx android.ModuleContext, res android.Path) android.WritablePath {
35
36 name := res.Base()
37 subDir := filepath.Dir(res.String())
38 subDir, lastDir := filepath.Split(subDir)
39 if strings.HasPrefix(lastDir, "values") {
40 name = strings.TrimSuffix(name, ".xml") + ".arsc"
41 }
42 name = lastDir + "_" + name + ".flat"
43 return android.PathForModuleOut(ctx, "aapt2", subDir, name)
44}
45
46func pathsToAapt2Paths(ctx android.ModuleContext, resPaths android.Paths) android.WritablePaths {
47 outPaths := make(android.WritablePaths, len(resPaths))
48
49 for i, res := range resPaths {
50 outPaths[i] = pathToAapt2Path(ctx, res)
51 }
52
53 return outPaths
54}
55
56var aapt2CompileRule = pctx.AndroidStaticRule("aapt2Compile",
57 blueprint.RuleParams{
Colin Cross44f06682017-11-29 00:17:36 -080058 Command: `${config.Aapt2Cmd} compile -o $outDir $cFlags --legacy $in`,
Colin Cross3bc7ffa2017-11-22 16:19:37 -080059 CommandDeps: []string{"${config.Aapt2Cmd}"},
60 },
61 "outDir", "cFlags")
62
63func aapt2Compile(ctx android.ModuleContext, dir android.Path, paths android.Paths) android.WritablePaths {
64 shards := shardPaths(paths, AAPT2_SHARD_SIZE)
65
66 ret := make(android.WritablePaths, 0, len(paths))
67
68 for i, shard := range shards {
69 outPaths := pathsToAapt2Paths(ctx, shard)
70 ret = append(ret, outPaths...)
71
72 shardDesc := ""
73 if i != 0 {
74 shardDesc = " " + strconv.Itoa(i+1)
75 }
76
77 ctx.Build(pctx, android.BuildParams{
78 Rule: aapt2CompileRule,
79 Description: "aapt2 compile " + dir.String() + shardDesc,
80 Inputs: shard,
81 Outputs: outPaths,
82 Args: map[string]string{
83 "outDir": android.PathForModuleOut(ctx, "aapt2", dir.String()).String(),
Colin Crossfabb6082018-02-20 17:22:23 -080084 // Always set --pseudo-localize, it will be stripped out later for release
85 // builds that don't want it.
Colin Cross3bc7ffa2017-11-22 16:19:37 -080086 "cFlags": "--pseudo-localize",
87 },
88 })
89 }
90
Colin Crossb69301e2017-12-01 10:48:26 -080091 sort.Slice(ret, func(i, j int) bool {
92 return ret[i].String() < ret[j].String()
93 })
Colin Cross3bc7ffa2017-11-22 16:19:37 -080094 return ret
95}
96
Colin Crossfabb6082018-02-20 17:22:23 -080097func aapt2CompileDirs(ctx android.ModuleContext, flata android.WritablePath, dirs android.Paths, deps android.Paths) {
98 ctx.Build(pctx, android.BuildParams{
99 Rule: aapt2CompileRule,
100 Description: "aapt2 compile dirs",
101 Implicits: deps,
102 Output: flata,
103 Args: map[string]string{
104 "outDir": flata.String(),
105 // Always set --pseudo-localize, it will be stripped out later for release
106 // builds that don't want it.
107 "cFlags": "--pseudo-localize " + android.JoinWithPrefix(dirs.Strings(), "--dir "),
108 },
109 })
110}
111
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800112var aapt2LinkRule = pctx.AndroidStaticRule("aapt2Link",
113 blueprint.RuleParams{
Colin Cross78e3cb02018-10-17 15:42:59 -0700114 Command: `rm -rf $genDir && ` +
115 `${config.Aapt2Cmd} link -o $out $flags --java $genDir --proguard $proguardOptions ` +
Colin Crossa97c5d32018-03-28 14:58:31 -0700116 `--output-text-symbols ${rTxt} $inFlags && ` +
Colin Cross66f78822018-05-02 12:58:28 -0700117 `${config.SoongZipCmd} -write_if_changed -jar -o $genJar -C $genDir -D $genDir &&` +
118 `${config.ExtractJarPackagesCmd} -i $genJar -o $extraPackages --prefix '--extra-packages '`,
119
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800120 CommandDeps: []string{
Colin Cross44f06682017-11-29 00:17:36 -0800121 "${config.Aapt2Cmd}",
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800122 "${config.SoongZipCmd}",
Colin Cross66f78822018-05-02 12:58:28 -0700123 "${config.ExtractJarPackagesCmd}",
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800124 },
125 Restat: true,
126 },
Colin Cross66f78822018-05-02 12:58:28 -0700127 "flags", "inFlags", "proguardOptions", "genDir", "genJar", "rTxt", "extraPackages")
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800128
129var fileListToFileRule = pctx.AndroidStaticRule("fileListToFile",
130 blueprint.RuleParams{
131 Command: `cp $out.rsp $out`,
132 Rspfile: "$out.rsp",
133 RspfileContent: "$in",
134 })
135
136func aapt2Link(ctx android.ModuleContext,
Colin Cross66f78822018-05-02 12:58:28 -0700137 packageRes, genJar, proguardOptions, rTxt, extraPackages android.WritablePath,
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800138 flags []string, deps android.Paths,
139 compiledRes, compiledOverlay android.Paths) {
140
141 genDir := android.PathForModuleGen(ctx, "aapt2", "R")
142
143 var inFlags []string
144
145 if len(compiledRes) > 0 {
146 resFileList := android.PathForModuleOut(ctx, "aapt2", "res.list")
147 // Write out file lists to files
148 ctx.Build(pctx, android.BuildParams{
149 Rule: fileListToFileRule,
150 Description: "resource file list",
151 Inputs: compiledRes,
152 Output: resFileList,
153 })
154
155 deps = append(deps, compiledRes...)
156 deps = append(deps, resFileList)
157 inFlags = append(inFlags, "@"+resFileList.String())
158 }
159
160 if len(compiledOverlay) > 0 {
161 overlayFileList := android.PathForModuleOut(ctx, "aapt2", "overlay.list")
162 ctx.Build(pctx, android.BuildParams{
163 Rule: fileListToFileRule,
164 Description: "overlay resource file list",
165 Inputs: compiledOverlay,
166 Output: overlayFileList,
167 })
168
169 deps = append(deps, compiledOverlay...)
170 deps = append(deps, overlayFileList)
171 inFlags = append(inFlags, "-R", "@"+overlayFileList.String())
172 }
173
174 ctx.Build(pctx, android.BuildParams{
175 Rule: aapt2LinkRule,
176 Description: "aapt2 link",
177 Implicits: deps,
178 Output: packageRes,
Colin Cross66f78822018-05-02 12:58:28 -0700179 ImplicitOutputs: android.WritablePaths{proguardOptions, genJar, rTxt, extraPackages},
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800180 Args: map[string]string{
181 "flags": strings.Join(flags, " "),
182 "inFlags": strings.Join(inFlags, " "),
183 "proguardOptions": proguardOptions.String(),
184 "genDir": genDir.String(),
185 "genJar": genJar.String(),
Colin Crossa97c5d32018-03-28 14:58:31 -0700186 "rTxt": rTxt.String(),
Colin Cross66f78822018-05-02 12:58:28 -0700187 "extraPackages": extraPackages.String(),
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800188 },
189 })
190}