blob: 06ec6460776c7300a92ef7b6322d888f89247db3 [file] [log] [blame]
Dan Willemsen1e704462016-08-21 15:17:17 -07001// 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 build
16
17import (
18 "crypto/md5"
19 "fmt"
20 "io/ioutil"
Dan Willemsen71edc8b2019-01-02 12:21:18 -080021 "os"
22 "os/user"
Dan Willemsen1e704462016-08-21 15:17:17 -070023 "path/filepath"
Dan Willemsen1e704462016-08-21 15:17:17 -070024 "strings"
Dan Willemsenb82471a2018-05-17 16:37:09 -070025
Nan Zhang17f27672018-12-12 16:01:49 -080026 "android/soong/ui/metrics"
Dan Willemsenb82471a2018-05-17 16:37:09 -070027 "android/soong/ui/status"
Dan Willemsen1e704462016-08-21 15:17:17 -070028)
29
30var spaceSlashReplacer = strings.NewReplacer("/", "_", " ", "_")
31
Dan Willemsen29971232018-09-26 14:58:30 -070032const katiBuildSuffix = ""
33const katiCleanspecSuffix = "-cleanspec"
Dan Willemsenfb1271a2018-09-26 15:00:42 -070034const katiPackageSuffix = "-package"
Dan Willemsen29971232018-09-26 14:58:30 -070035
Jingwen Chenb1d30d62020-11-18 02:43:19 -050036// genKatiSuffix creates a filename suffix for kati-generated files so that we
37// can cache them based on their inputs. Such files include the generated Ninja
38// files and env.sh environment variable setup files.
39//
40// The filename suffix should encode all common changes to Kati inputs.
41// Currently that includes the TARGET_PRODUCT and kati-processed command line
42// arguments.
Dan Willemsen1e704462016-08-21 15:17:17 -070043func genKatiSuffix(ctx Context, config Config) {
Jingwen Chenb1d30d62020-11-18 02:43:19 -050044 // Construct the base suffix.
Dan Willemsen1e704462016-08-21 15:17:17 -070045 katiSuffix := "-" + config.TargetProduct()
Jingwen Chenb1d30d62020-11-18 02:43:19 -050046
47 // Append kati arguments to the suffix.
Dan Willemsen1e704462016-08-21 15:17:17 -070048 if args := config.KatiArgs(); len(args) > 0 {
49 katiSuffix += "-" + spaceSlashReplacer.Replace(strings.Join(args, "_"))
50 }
Dan Willemsen1e704462016-08-21 15:17:17 -070051
52 // If the suffix is too long, replace it with a md5 hash and write a
53 // file that contains the original suffix.
54 if len(katiSuffix) > 64 {
55 shortSuffix := "-" + fmt.Sprintf("%x", md5.Sum([]byte(katiSuffix)))
56 config.SetKatiSuffix(shortSuffix)
57
58 ctx.Verbosef("Kati ninja suffix too long: %q", katiSuffix)
59 ctx.Verbosef("Replacing with: %q", shortSuffix)
60
Dan Willemsen29971232018-09-26 14:58:30 -070061 if err := ioutil.WriteFile(strings.TrimSuffix(config.KatiBuildNinjaFile(), "ninja")+"suf", []byte(katiSuffix), 0777); err != nil {
Dan Willemsen1e704462016-08-21 15:17:17 -070062 ctx.Println("Error writing suffix file:", err)
63 }
64 } else {
65 config.SetKatiSuffix(katiSuffix)
66 }
67}
68
Jingwen Chenb1d30d62020-11-18 02:43:19 -050069// Base function to construct and run the Kati command line with additional
70// arguments, and a custom function closure to mutate the environment Kati runs
71// in.
Dan Willemsenfb1271a2018-09-26 15:00:42 -070072func runKati(ctx Context, config Config, extraSuffix string, args []string, envFunc func(*Environment)) {
Dan Willemsenf173d592017-04-27 14:28:00 -070073 executable := config.PrebuiltBuildTool("ckati")
Jingwen Chenb1d30d62020-11-18 02:43:19 -050074 // cKati arguments.
Dan Willemsen29971232018-09-26 14:58:30 -070075 args = append([]string{
Jingwen Chenb1d30d62020-11-18 02:43:19 -050076 // Instead of executing commands directly, generate a Ninja file.
Dan Willemsen1e704462016-08-21 15:17:17 -070077 "--ninja",
Jingwen Chenb1d30d62020-11-18 02:43:19 -050078 // Generate Ninja files in the output directory.
Dan Willemsen1e704462016-08-21 15:17:17 -070079 "--ninja_dir=" + config.OutDir(),
Jingwen Chenb1d30d62020-11-18 02:43:19 -050080 // Filename suffix of the generated Ninja file.
Dan Willemsen29971232018-09-26 14:58:30 -070081 "--ninja_suffix=" + config.KatiSuffix() + extraSuffix,
Jingwen Chenb1d30d62020-11-18 02:43:19 -050082 // Remove common parts at the beginning of a Ninja file, like build_dir,
83 // local_pool and _kati_always_build_. Allows Kati to be run multiple
84 // times, with generated Ninja files combined in a single invocation
85 // using 'include'.
Dan Willemsen29971232018-09-26 14:58:30 -070086 "--no_ninja_prelude",
Jingwen Chenb1d30d62020-11-18 02:43:19 -050087 // Support declaring phony outputs in AOSP Ninja.
Dan Willemsen6587bed2020-04-18 20:25:59 -070088 "--use_ninja_phony_output",
Jingwen Chenb1d30d62020-11-18 02:43:19 -050089 // Support declaring symlink outputs in AOSP Ninja.
Jingwen Chence679d22020-09-23 04:30:02 +000090 "--use_ninja_symlink_outputs",
Jingwen Chenb1d30d62020-11-18 02:43:19 -050091 // Regenerate the Ninja file if environment inputs have changed. e.g.
92 // CLI flags, .mk file timestamps, env vars, $(wildcard ..) and some
93 // $(shell ..) results.
Dan Willemsen1e704462016-08-21 15:17:17 -070094 "--regen",
Jingwen Chenb1d30d62020-11-18 02:43:19 -050095 // Skip '-include' directives starting with the specified path. Used to
96 // ignore generated .mk files.
Dan Willemsen1e704462016-08-21 15:17:17 -070097 "--ignore_optional_include=" + filepath.Join(config.OutDir(), "%.P"),
Jingwen Chenb1d30d62020-11-18 02:43:19 -050098 // Detect the use of $(shell echo ...).
Dan Willemsen1e704462016-08-21 15:17:17 -070099 "--detect_android_echo",
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500100 // Colorful ANSI-based warning and error messages.
Dan Willemsenc38d3662017-02-24 10:53:23 -0800101 "--color_warnings",
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500102 // Generate all targets, not just the top level requested ones.
Dan Willemsenc38d3662017-02-24 10:53:23 -0800103 "--gen_all_targets",
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500104 // Use the built-in emulator of GNU find for better file finding
105 // performance. Used with $(shell find ...).
Dan Willemsen29971232018-09-26 14:58:30 -0700106 "--use_find_emulator",
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500107 // Fail when the find emulator encounters problems.
Dan Willemsen418420e2017-05-30 14:07:45 -0700108 "--werror_find_emulator",
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500109 // Do not provide any built-in rules.
Dan Willemsend368d6f2018-06-15 21:53:18 -0700110 "--no_builtin_rules",
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500111 // Fail when suffix rules are used.
Dan Willemsend368d6f2018-06-15 21:53:18 -0700112 "--werror_suffix_rules",
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500113 // Fail when a real target depends on a phony target.
Dan Willemsen60977462019-04-18 09:40:15 -0700114 "--werror_real_to_phony",
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500115 // Makes real_to_phony checks assume that any top-level or leaf
116 // dependencies that does *not* have a '/' in it is a phony target.
Dan Willemsencc628902019-01-24 15:53:06 -0800117 "--top_level_phony",
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500118 // Fail when a phony target contains slashes.
119 "--werror_phony_looks_real",
120 // Fail when writing to a read-only directory.
121 "--werror_writable",
122 // Print Kati's internal statistics, such as the number of variables,
123 // implicit/explicit/suffix rules, and so on.
Dan Willemsen75d2c172017-10-12 20:46:34 -0700124 "--kati_stats",
Dan Willemsen29971232018-09-26 14:58:30 -0700125 }, args...)
126
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500127 // Generate a minimal Ninja file.
128 //
129 // Used for build_test and multiproduct_kati, which runs Kati several
130 // hundred times for different configurations to test file generation logic.
131 // These can result in generating Ninja files reaching ~1GB or more,
132 // resulting in ~hundreds of GBs of writes.
133 //
134 // Since we don't care about executing the Ninja files in these test cases,
135 // generating the Ninja file content wastes time, so skip writing any
136 // information out with --empty_ninja_file.
137 //
138 // From https://github.com/google/kati/commit/87b8da7af2c8bea28b1d8ab17679453d859f96e5
Dan Willemsenf99915f2018-10-25 22:04:42 -0700139 if config.Environment().IsEnvTrue("EMPTY_NINJA_FILE") {
140 args = append(args, "--empty_ninja_file")
141 }
142
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500143 // Apply 'local_pool' to to all rules that don't specify a pool.
Colin Cross9016b912019-11-11 14:57:42 -0800144 if config.UseRemoteBuild() {
145 args = append(args, "--default_pool=local_pool")
146 }
147
Dan Willemsen29971232018-09-26 14:58:30 -0700148 cmd := Command(ctx, config, "ckati", executable, args...)
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500149
150 // Set up the nsjail sandbox.
Dan Willemsen29971232018-09-26 14:58:30 -0700151 cmd.Sandbox = katiSandbox
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500152
153 // Set up stdout and stderr.
Dan Willemsen29971232018-09-26 14:58:30 -0700154 pipe, err := cmd.StdoutPipe()
155 if err != nil {
156 ctx.Fatalln("Error getting output pipe for ckati:", err)
157 }
158 cmd.Stderr = cmd.Stdout
159
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500160 // Apply the caller's function closure to mutate the environment variables.
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700161 envFunc(cmd.Environment)
162
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500163 // Pass on various build environment metadata to Kati.
Dan Willemsen71edc8b2019-01-02 12:21:18 -0800164 if _, ok := cmd.Environment.Get("BUILD_USERNAME"); !ok {
Dan Willemsena17ac962020-03-10 15:38:57 -0700165 username := "unknown"
166 if u, err := user.Current(); err == nil {
167 username = u.Username
168 } else {
169 ctx.Println("Failed to get current user:", err)
Dan Willemsen71edc8b2019-01-02 12:21:18 -0800170 }
Dan Willemsena17ac962020-03-10 15:38:57 -0700171 cmd.Environment.Set("BUILD_USERNAME", username)
Dan Willemsen71edc8b2019-01-02 12:21:18 -0800172 }
173
174 if _, ok := cmd.Environment.Get("BUILD_HOSTNAME"); !ok {
175 hostname, err := os.Hostname()
176 if err != nil {
Dan Willemsena17ac962020-03-10 15:38:57 -0700177 ctx.Println("Failed to read hostname:", err)
178 hostname = "unknown"
Dan Willemsen71edc8b2019-01-02 12:21:18 -0800179 }
180 cmd.Environment.Set("BUILD_HOSTNAME", hostname)
181 }
182
Dan Willemsen29971232018-09-26 14:58:30 -0700183 cmd.StartOrFatal()
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500184 // Set up the ToolStatus command line reader for Kati for a consistent UI
185 // for the user.
Dan Willemsen29971232018-09-26 14:58:30 -0700186 status.KatiReader(ctx.Status.StartTool(), pipe)
187 cmd.WaitOrFatal()
188}
189
190func runKatiBuild(ctx Context, config Config) {
Nan Zhang17f27672018-12-12 16:01:49 -0800191 ctx.BeginTrace(metrics.RunKati, "kati build")
Dan Willemsen29971232018-09-26 14:58:30 -0700192 defer ctx.EndTrace()
193
194 args := []string{
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500195 // Mark the output directory as writable.
Dan Willemsen25a56182018-08-31 20:25:32 -0700196 "--writable", config.OutDir() + "/",
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500197 // Fail when encountering implicit rules. e.g.
198 // %.foo: %.bar
199 // cp $< $@
Dan Willemsen9f435972020-05-28 15:28:00 -0700200 "--werror_implicit_rules",
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500201 // Entry point for the Kati Ninja file generation.
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -0700202 "-f", "build/make/core/main.mk",
Dan Willemsen1e704462016-08-21 15:17:17 -0700203 }
204
Dan Willemsen3d60b112018-04-04 22:25:56 -0700205 if !config.BuildBrokenDupRules() {
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500206 // Fail when redefining / duplicating a target.
Dan Willemsen3d60b112018-04-04 22:25:56 -0700207 args = append(args, "--werror_overriding_commands")
208 }
209
Dan Willemsen1e704462016-08-21 15:17:17 -0700210 args = append(args, config.KatiArgs()...)
211
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700212 args = append(args,
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500213 // Location of the Make vars .mk file generated by Soong.
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700214 "SOONG_MAKEVARS_MK="+config.SoongMakeVarsMk(),
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500215 // Location of the Android.mk file generated by Soong. This
216 // file contains Soong modules represented as Kati modules,
217 // allowing Kati modules to depend on Soong modules.
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700218 "SOONG_ANDROID_MK="+config.SoongAndroidMk(),
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500219 // Directory containing outputs for the target device.
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700220 "TARGET_DEVICE_DIR="+config.TargetDeviceDir(),
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500221 // Directory containing .mk files for packaging purposes, such as
222 // the dist.mk file, containing dist-for-goals data.
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700223 "KATI_PACKAGE_MK_DIR="+config.KatiPackageMkDir())
Dan Willemsen1e704462016-08-21 15:17:17 -0700224
Dan Willemsen2d31a442018-10-20 21:33:41 -0700225 runKati(ctx, config, katiBuildSuffix, args, func(env *Environment) {})
Dan Willemsen78428262019-12-13 18:50:24 -0800226
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500227 // compress and dist the main build ninja file.
Colin Cross8ba7d472020-06-25 11:27:52 -0700228 distGzipFile(ctx, config, config.KatiBuildNinjaFile())
229
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500230 // Cleanup steps.
Dan Willemsen78428262019-12-13 18:50:24 -0800231 cleanCopyHeaders(ctx, config)
Dan Willemsen1e775d72020-01-03 13:40:45 -0800232 cleanOldInstalledFiles(ctx, config)
Dan Willemsen78428262019-12-13 18:50:24 -0800233}
234
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500235// Clean out obsolete header files on the disk that were *not copied* during the
236// build with BUILD_COPY_HEADERS and LOCAL_COPY_HEADERS.
237//
238// These should be increasingly uncommon, as it's a deprecated feature and there
239// isn't an equivalent feature in Soong.
Dan Willemsen78428262019-12-13 18:50:24 -0800240func cleanCopyHeaders(ctx Context, config Config) {
241 ctx.BeginTrace("clean", "clean copy headers")
242 defer ctx.EndTrace()
243
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500244 // Read and parse the list of copied headers from a file in the product
245 // output directory.
Dan Willemsen78428262019-12-13 18:50:24 -0800246 data, err := ioutil.ReadFile(filepath.Join(config.ProductOut(), ".copied_headers_list"))
247 if err != nil {
248 if os.IsNotExist(err) {
249 return
250 }
251 ctx.Fatalf("Failed to read copied headers list: %v", err)
252 }
253
254 headers := strings.Fields(string(data))
255 if len(headers) < 1 {
256 ctx.Fatal("Failed to parse copied headers list: %q", string(data))
257 }
258 headerDir := headers[0]
259 headers = headers[1:]
260
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500261 // Walk the tree and remove any headers that are not in the list of copied
262 // headers in the current build.
Dan Willemsen78428262019-12-13 18:50:24 -0800263 filepath.Walk(headerDir,
264 func(path string, info os.FileInfo, err error) error {
265 if err != nil {
266 return nil
267 }
268 if info.IsDir() {
269 return nil
270 }
271 if !inList(path, headers) {
272 ctx.Printf("Removing obsolete header %q", path)
273 if err := os.Remove(path); err != nil {
274 ctx.Fatalf("Failed to remove obsolete header %q: %v", path, err)
275 }
276 }
277 return nil
278 })
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700279}
280
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500281// Clean out any previously installed files from the disk that are not installed
282// in the current build.
Dan Willemsen1e775d72020-01-03 13:40:45 -0800283func cleanOldInstalledFiles(ctx Context, config Config) {
284 ctx.BeginTrace("clean", "clean old installed files")
285 defer ctx.EndTrace()
286
287 // We shouldn't be removing files from one side of the two-step asan builds
288 var suffix string
289 if v, ok := config.Environment().Get("SANITIZE_TARGET"); ok {
290 if sanitize := strings.Fields(v); inList("address", sanitize) {
291 suffix = "_asan"
292 }
293 }
294
295 cleanOldFiles(ctx, config.ProductOut(), ".installable_files"+suffix)
296
297 cleanOldFiles(ctx, config.HostOut(), ".installable_test_files")
298}
299
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500300// Generate the Ninja file containing the packaging command lines for the dist
301// dir.
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700302func runKatiPackage(ctx Context, config Config) {
Nan Zhang17f27672018-12-12 16:01:49 -0800303 ctx.BeginTrace(metrics.RunKati, "kati package")
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700304 defer ctx.EndTrace()
305
306 args := []string{
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500307 // Mark the dist dir as writable.
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700308 "--writable", config.DistDir() + "/",
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500309 // Fail when encountering implicit rules. e.g.
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700310 "--werror_implicit_rules",
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500311 // Fail when redefining / duplicating a target.
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700312 "--werror_overriding_commands",
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500313 // Entry point.
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700314 "-f", "build/make/packaging/main.mk",
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500315 // Directory containing .mk files for packaging purposes, such as
316 // the dist.mk file, containing dist-for-goals data.
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700317 "KATI_PACKAGE_MK_DIR=" + config.KatiPackageMkDir(),
318 }
319
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500320 // Run Kati against a restricted set of environment variables.
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700321 runKati(ctx, config, katiPackageSuffix, args, func(env *Environment) {
322 env.Allow([]string{
323 // Some generic basics
324 "LANG",
325 "LC_MESSAGES",
326 "PATH",
327 "PWD",
328 "TMPDIR",
329
330 // Tool configs
Dan Willemsen70c1ff82019-08-21 14:56:13 -0700331 "ASAN_SYMBOLIZER_PATH",
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700332 "JAVA_HOME",
333 "PYTHONDONTWRITEBYTECODE",
334
335 // Build configuration
336 "ANDROID_BUILD_SHELL",
337 "DIST_DIR",
338 "OUT_DIR",
339 }...)
340
341 if config.Dist() {
342 env.Set("DIST", "true")
Dan Willemsen2d31a442018-10-20 21:33:41 -0700343 env.Set("DIST_DIR", config.DistDir())
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700344 }
345 })
Colin Cross8ba7d472020-06-25 11:27:52 -0700346
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500347 // Compress and dist the packaging Ninja file.
Colin Cross8ba7d472020-06-25 11:27:52 -0700348 distGzipFile(ctx, config, config.KatiPackageNinjaFile())
Dan Willemsen1e704462016-08-21 15:17:17 -0700349}
Dan Willemsen29f88272017-02-18 18:12:41 -0800350
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500351// Run Kati on the cleanspec files to clean the build.
Dan Willemsen59fdf962017-07-24 22:26:54 -0700352func runKatiCleanSpec(ctx Context, config Config) {
Nan Zhang17f27672018-12-12 16:01:49 -0800353 ctx.BeginTrace(metrics.RunKati, "kati cleanspec")
Dan Willemsen59fdf962017-07-24 22:26:54 -0700354 defer ctx.EndTrace()
355
Dan Willemsen29971232018-09-26 14:58:30 -0700356 runKati(ctx, config, katiCleanspecSuffix, []string{
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500357 // Fail when encountering implicit rules. e.g.
Dan Willemsen29971232018-09-26 14:58:30 -0700358 "--werror_implicit_rules",
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500359 // Fail when redefining / duplicating a target.
Dan Willemsen3d60b112018-04-04 22:25:56 -0700360 "--werror_overriding_commands",
Jingwen Chenb1d30d62020-11-18 02:43:19 -0500361 // Entry point.
Dan Willemsen59fdf962017-07-24 22:26:54 -0700362 "-f", "build/make/core/cleanbuild.mk",
Dan Willemsenfb1271a2018-09-26 15:00:42 -0700363 "SOONG_MAKEVARS_MK=" + config.SoongMakeVarsMk(),
364 "TARGET_DEVICE_DIR=" + config.TargetDeviceDir(),
Dan Willemsen2d31a442018-10-20 21:33:41 -0700365 }, func(env *Environment) {})
Dan Willemsen59fdf962017-07-24 22:26:54 -0700366}