blob: 0f1a3dd986acb1ca21c223bdaf037182927c678f [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 (
Dan Willemsen051133b2017-07-14 11:29:29 -070018 "bytes"
Dan Willemsen1e704462016-08-21 15:17:17 -070019 "fmt"
Dan Willemsen4e2456b2019-10-03 16:45:58 -070020 "io/ioutil"
21 "os"
Dan Willemsen1e704462016-08-21 15:17:17 -070022 "strings"
Dan Willemsenb82471a2018-05-17 16:37:09 -070023
Nan Zhang17f27672018-12-12 16:01:49 -080024 "android/soong/ui/metrics"
Dan Willemsenb82471a2018-05-17 16:37:09 -070025 "android/soong/ui/status"
Dan Willemsen1e704462016-08-21 15:17:17 -070026)
27
28// DumpMakeVars can be used to extract the values of Make variables after the
29// product configurations are loaded. This is roughly equivalent to the
30// `get_build_var` bash function.
31//
32// goals can be used to set MAKECMDGOALS, which emulates passing arguments to
33// Make without actually building them. So all the variables based on
34// MAKECMDGOALS can be read.
35//
Dan Willemsen1e704462016-08-21 15:17:17 -070036// vars is the list of variables to read. The values will be put in the
37// returned map.
Dan Willemsen6f037522018-10-21 09:20:47 -070038//
39// variables controlled by soong_ui directly are now returned without needing
40// to call into make, to retain compatibility.
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -070041func DumpMakeVars(ctx Context, config Config, goals, vars []string) (map[string]string, error) {
Dan Willemsen6f037522018-10-21 09:20:47 -070042 soongUiVars := map[string]func() string{
43 "OUT_DIR": func() string { return config.OutDir() },
44 "DIST_DIR": func() string { return config.DistDir() },
Dan Willemsenb6699a12019-10-07 15:26:26 -070045 "TMPDIR": func() string { return absPath(ctx, config.TempDir()) },
Dan Willemsen6f037522018-10-21 09:20:47 -070046 }
47
48 makeVars := make([]string, 0, len(vars))
49 for _, v := range vars {
50 if _, ok := soongUiVars[v]; !ok {
51 makeVars = append(makeVars, v)
52 }
53 }
54
55 var ret map[string]string
56 if len(makeVars) > 0 {
Patrice Arrudaae2694b2020-06-04 19:34:41 +000057 // It's not safe to use the same TMPDIR as the build, as that can be removed.
Dan Willemsen4e2456b2019-10-03 16:45:58 -070058 tmpDir, err := ioutil.TempDir("", "dumpvars")
59 if err != nil {
60 return nil, err
61 }
62 defer os.RemoveAll(tmpDir)
63
Patrice Arrudaae2694b2020-06-04 19:34:41 +000064 SetupLitePath(ctx, config, tmpDir)
Dan Willemsen4e2456b2019-10-03 16:45:58 -070065
Patrice Arrudaae2694b2020-06-04 19:34:41 +000066 ret, err = dumpMakeVars(ctx, config, goals, makeVars, false, tmpDir)
Dan Willemsen6f037522018-10-21 09:20:47 -070067 if err != nil {
68 return ret, err
69 }
70 } else {
71 ret = make(map[string]string)
72 }
73
74 for _, v := range vars {
75 if f, ok := soongUiVars[v]; ok {
76 ret[v] = f()
77 }
78 }
79
80 return ret, nil
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -070081}
82
Patrice Arrudaae2694b2020-06-04 19:34:41 +000083func dumpMakeVars(ctx Context, config Config, goals, vars []string, write_soong_vars bool, tmpDir string) (map[string]string, error) {
Nan Zhang17f27672018-12-12 16:01:49 -080084 ctx.BeginTrace(metrics.RunKati, "dumpvars")
Dan Willemsend9f6fa22016-08-21 15:17:17 -070085 defer ctx.EndTrace()
86
Cole Faust64955b32023-02-16 12:53:32 -080087 tool := ctx.Status.StartTool()
88 if write_soong_vars {
89 // only print this when write_soong_vars is true so that it's not printed when using
90 // the get_build_var command.
91 tool.Status("Running product configuration...")
92 }
93 defer tool.Finish()
94
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -070095 cmd := Command(ctx, config, "dumpvars",
Taylor Santiago3c16e612024-05-30 14:41:31 -070096 config.KatiBin(),
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -070097 "-f", "build/make/core/config.mk",
98 "--color_warnings",
Dan Willemsen0c518512018-01-09 02:09:52 -080099 "--kati_stats",
Dan Willemsen1e704462016-08-21 15:17:17 -0700100 "dump-many-vars",
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -0700101 "MAKECMDGOALS="+strings.Join(goals, " "))
102 cmd.Environment.Set("CALLED_FROM_SETUP", "true")
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -0700103 if write_soong_vars {
104 cmd.Environment.Set("WRITE_SOONG_VARIABLES", "true")
105 }
106 cmd.Environment.Set("DUMP_MANY_VARS", strings.Join(vars, " "))
Patrice Arrudaae2694b2020-06-04 19:34:41 +0000107 if tmpDir != "" {
108 cmd.Environment.Set("TMPDIR", tmpDir)
109 }
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -0700110 cmd.Sandbox = dumpvarsSandbox
Dan Willemsen0c518512018-01-09 02:09:52 -0800111 output := bytes.Buffer{}
112 cmd.Stdout = &output
113 pipe, err := cmd.StderrPipe()
Dan Willemsen1e704462016-08-21 15:17:17 -0700114 if err != nil {
Dan Willemsen0c518512018-01-09 02:09:52 -0800115 ctx.Fatalln("Error getting output pipe for ckati:", err)
Dan Willemsen1e704462016-08-21 15:17:17 -0700116 }
Dan Willemsen0c518512018-01-09 02:09:52 -0800117 cmd.StartOrFatal()
118 // TODO: error out when Stderr contains any content
Cole Faust64955b32023-02-16 12:53:32 -0800119 status.KatiReader(tool, pipe)
Dan Willemsen0c518512018-01-09 02:09:52 -0800120 cmd.WaitOrFatal()
Dan Willemsen1e704462016-08-21 15:17:17 -0700121
122 ret := make(map[string]string, len(vars))
Dan Willemsen0c518512018-01-09 02:09:52 -0800123 for _, line := range strings.Split(output.String(), "\n") {
Dan Willemsen1e704462016-08-21 15:17:17 -0700124 if len(line) == 0 {
125 continue
126 }
127
128 if key, value, ok := decodeKeyValue(line); ok {
129 if value, ok = singleUnquote(value); ok {
130 ret[key] = value
131 ctx.Verboseln(key, value)
132 } else {
133 return nil, fmt.Errorf("Failed to parse make line: %q", line)
134 }
135 } else {
136 return nil, fmt.Errorf("Failed to parse make line: %q", line)
137 }
138 }
Nan Zhang17f27672018-12-12 16:01:49 -0800139 if ctx.Metrics != nil {
LaMont Jones28c6d672025-01-14 08:53:09 -0800140 // Also include TARGET_RELEASE in the metrics. Do this first
141 // so that it gets overwritten if dumpvars ever spits it out.
142 if release, found := os.LookupEnv("TARGET_RELEASE"); found {
143 ctx.Metrics.SetMetadataMetrics(
144 map[string]string{"TARGET_RELEASE": release})
145 }
Nan Zhang17f27672018-12-12 16:01:49 -0800146 ctx.Metrics.SetMetadataMetrics(ret)
147 }
Dan Willemsen1e704462016-08-21 15:17:17 -0700148
149 return ret, nil
150}
151
Dan Willemsen051133b2017-07-14 11:29:29 -0700152// Variables to print out in the top banner
153var BannerVars = []string{
154 "PLATFORM_VERSION_CODENAME",
155 "PLATFORM_VERSION",
Sam Delmerico98a73292023-02-21 11:50:29 -0500156 "PRODUCT_SOURCE_ROOT_DIRS",
Dan Willemsen051133b2017-07-14 11:29:29 -0700157 "TARGET_PRODUCT",
158 "TARGET_BUILD_VARIANT",
Dan Willemsen051133b2017-07-14 11:29:29 -0700159 "TARGET_BUILD_APPS",
Martin Stjernholm08802332020-06-04 17:00:01 +0100160 "TARGET_BUILD_UNBUNDLED",
Dan Willemsen051133b2017-07-14 11:29:29 -0700161 "TARGET_ARCH",
162 "TARGET_ARCH_VARIANT",
163 "TARGET_CPU_VARIANT",
164 "TARGET_2ND_ARCH",
165 "TARGET_2ND_ARCH_VARIANT",
166 "TARGET_2ND_CPU_VARIANT",
Dan Willemsen051133b2017-07-14 11:29:29 -0700167 "HOST_OS",
168 "HOST_OS_EXTRA",
169 "HOST_CROSS_OS",
Dan Willemsen051133b2017-07-14 11:29:29 -0700170 "BUILD_ID",
171 "OUT_DIR",
Paul Duffin39abf8f2021-09-24 14:58:27 +0100172 "SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE",
maxwendfb0d742020-03-13 12:36:24 +0100173 "ROM_BUILDTYPE",
Dan Willemsen051133b2017-07-14 11:29:29 -0700174}
175
Joe Onorato8ae66df2025-01-29 13:21:58 -0800176func Banner(config Config, make_vars map[string]string) string {
Dan Willemsen051133b2017-07-14 11:29:29 -0700177 b := &bytes.Buffer{}
178
179 fmt.Fprintln(b, "============================================")
180 for _, name := range BannerVars {
181 if make_vars[name] != "" {
182 fmt.Fprintf(b, "%s=%s\n", name, make_vars[name])
183 }
184 }
Spandan Das670efb62025-03-20 02:37:25 +0000185 if config.skipKatiControlledByFlags {
186 fmt.Fprintf(b, "SOONG_ONLY=%t\n", config.soongOnlyRequested)
187 } else { // default for this product
188 fmt.Fprintf(b, "SOONG_ONLY=%t\n", make_vars["PRODUCT_SOONG_ONLY"] == "true")
189 }
190
Dan Willemsen051133b2017-07-14 11:29:29 -0700191 fmt.Fprint(b, "============================================")
192
193 return b.String()
194}
195
Dan Willemsen1e704462016-08-21 15:17:17 -0700196func runMakeProductConfig(ctx Context, config Config) {
197 // Variables to export into the environment of Kati/Ninja
198 exportEnvVars := []string{
199 // So that we can use the correct TARGET_PRODUCT if it's been
Dan Willemsena2a8ecb2019-07-29 15:14:11 -0700200 // modified by a buildspec.mk
Dan Willemsen1e704462016-08-21 15:17:17 -0700201 "TARGET_PRODUCT",
Dan Willemsen02781d52017-05-12 19:28:13 -0700202 "TARGET_BUILD_VARIANT",
Dan Willemsen04a16c72017-05-25 22:18:57 -0700203 "TARGET_BUILD_APPS",
Martin Stjernholm08802332020-06-04 17:00:01 +0100204 "TARGET_BUILD_UNBUNDLED",
Dan Willemsen1e704462016-08-21 15:17:17 -0700205
LaMont Jones9a912862023-11-06 22:11:08 +0000206 // Additional release config maps
207 "PRODUCT_RELEASE_CONFIG_MAPS",
208
Dan Willemsen1e704462016-08-21 15:17:17 -0700209 // compiler wrappers set up by make
210 "CC_WRAPPER",
211 "CXX_WRAPPER",
Ramy Medhat9a90fe52020-04-13 13:21:23 -0400212 "RBE_WRAPPER",
Yoshisato Yanagisawa13fd3ff2017-04-05 11:05:31 +0900213 "JAVAC_WRAPPER",
Ramy Medhat8ea054a2020-01-27 14:19:44 -0500214 "R8_WRAPPER",
215 "D8_WRAPPER",
Dan Willemsen1e704462016-08-21 15:17:17 -0700216
217 // ccache settings
218 "CCACHE_COMPILERCHECK",
219 "CCACHE_SLOPPINESS",
220 "CCACHE_BASEDIR",
221 "CCACHE_CPP2",
Yi Kong6adf2582022-04-17 15:01:06 +0800222
223 // LLVM compiler wrapper options
224 "TOOLCHAIN_RUSAGE_OUTPUT",
Dan Willemsen1e704462016-08-21 15:17:17 -0700225 }
226
Dan Willemsen1e704462016-08-21 15:17:17 -0700227 allVars := append(append([]string{
228 // Used to execute Kati and Ninja
229 "NINJA_GOALS",
230 "KATI_GOALS",
Dan Willemsen02781d52017-05-12 19:28:13 -0700231
232 // To find target/product/<DEVICE>
233 "TARGET_DEVICE",
Dan Willemsen3d60b112018-04-04 22:25:56 -0700234
Dan Willemsen6ab79db2018-05-02 00:06:28 -0700235 // So that later Kati runs can find BoardConfig.mk faster
236 "TARGET_DEVICE_DIR",
237
Dan Willemsen3d60b112018-04-04 22:25:56 -0700238 // Whether --werror_overriding_commands will work
239 "BUILD_BROKEN_DUP_RULES",
Dan Willemsenb58f1202018-06-21 10:12:53 -0700240
Dan Willemsen25e6f092019-04-09 10:22:43 -0700241 // Whether to enable the network during the build
242 "BUILD_BROKEN_USES_NETWORK",
243
Dan Willemsene3336352020-01-02 19:10:38 -0800244 // Extra environment variables to be exported to ninja
245 "BUILD_BROKEN_NINJA_USES_ENV_VARS",
246
Spandan Dasa3639e62021-05-25 19:14:02 +0000247 // Used to restrict write access to source tree
248 "BUILD_BROKEN_SRC_DIR_IS_WRITABLE",
249 "BUILD_BROKEN_SRC_DIR_RW_ALLOWLIST",
250
Spandan Das28a6f192024-07-01 21:00:25 +0000251 // Whether missing outputs should be treated as warnings
252 // instead of errors.
253 // `true` will relegate missing outputs to warnings.
254 "BUILD_BROKEN_MISSING_OUTPUTS",
255
Cole Faust3740b282025-01-21 15:59:50 -0800256 "PRODUCT_SOONG_ONLY",
257
Dan Willemsenb58f1202018-06-21 10:12:53 -0700258 // Not used, but useful to be in the soong.log
Jihoon Kang36904852022-08-12 23:02:09 +0000259 "TARGET_BUILD_TYPE",
260 "HOST_ARCH",
261 "HOST_2ND_ARCH",
262 "HOST_CROSS_ARCH",
263 "HOST_CROSS_2ND_ARCH",
264 "HOST_BUILD_TYPE",
265 "PRODUCT_SOONG_NAMESPACES",
Dan Willemsen368e5562019-04-17 14:44:33 -0700266
267 "DEFAULT_WARNING_BUILD_MODULE_TYPES",
268 "DEFAULT_ERROR_BUILD_MODULE_TYPES",
Logan Chienf9cf9ac2019-09-20 11:37:30 -0700269 "BUILD_BROKEN_PREBUILT_ELF_FILES",
Inseob Kim822fdca2019-10-11 14:55:33 +0900270 "BUILD_BROKEN_TREBLE_SYSPROP_NEVERALLOW",
Dan Willemsen368e5562019-04-17 14:44:33 -0700271 "BUILD_BROKEN_USES_BUILD_COPY_HEADERS",
272 "BUILD_BROKEN_USES_BUILD_EXECUTABLE",
273 "BUILD_BROKEN_USES_BUILD_FUZZ_TEST",
274 "BUILD_BROKEN_USES_BUILD_HEADER_LIBRARY",
Dan Willemsen368e5562019-04-17 14:44:33 -0700275 "BUILD_BROKEN_USES_BUILD_HOST_EXECUTABLE",
Dan Willemsen368e5562019-04-17 14:44:33 -0700276 "BUILD_BROKEN_USES_BUILD_HOST_JAVA_LIBRARY",
Dan Willemsen368e5562019-04-17 14:44:33 -0700277 "BUILD_BROKEN_USES_BUILD_HOST_PREBUILT",
278 "BUILD_BROKEN_USES_BUILD_HOST_SHARED_LIBRARY",
Dan Willemsen368e5562019-04-17 14:44:33 -0700279 "BUILD_BROKEN_USES_BUILD_HOST_STATIC_LIBRARY",
Dan Willemsen368e5562019-04-17 14:44:33 -0700280 "BUILD_BROKEN_USES_BUILD_JAVA_LIBRARY",
281 "BUILD_BROKEN_USES_BUILD_MULTI_PREBUILT",
Dan Willemsen368e5562019-04-17 14:44:33 -0700282 "BUILD_BROKEN_USES_BUILD_NATIVE_TEST",
283 "BUILD_BROKEN_USES_BUILD_NOTICE_FILE",
284 "BUILD_BROKEN_USES_BUILD_PACKAGE",
285 "BUILD_BROKEN_USES_BUILD_PHONY_PACKAGE",
286 "BUILD_BROKEN_USES_BUILD_PREBUILT",
287 "BUILD_BROKEN_USES_BUILD_RRO_PACKAGE",
288 "BUILD_BROKEN_USES_BUILD_SHARED_LIBRARY",
Dan Willemsen368e5562019-04-17 14:44:33 -0700289 "BUILD_BROKEN_USES_BUILD_STATIC_JAVA_LIBRARY",
290 "BUILD_BROKEN_USES_BUILD_STATIC_LIBRARY",
LaMont Jones8490ffb2024-11-14 16:42:54 -0800291 "RELEASE_BUILD_EXECUTION_METRICS",
Dan Willemsen051133b2017-07-14 11:29:29 -0700292 }, exportEnvVars...), BannerVars...)
Dan Willemsen1e704462016-08-21 15:17:17 -0700293
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800294 makeVars, err := dumpMakeVars(ctx, config, config.Arguments(), allVars, true, "")
Dan Willemsen1e704462016-08-21 15:17:17 -0700295 if err != nil {
296 ctx.Fatalln("Error dumping make vars:", err)
297 }
298
Dan Willemsen1e704462016-08-21 15:17:17 -0700299 // Populate the environment
Joe Onorato8ae66df2025-01-29 13:21:58 -0800300 env := config.Environment()
Dan Willemsen1e704462016-08-21 15:17:17 -0700301 for _, name := range exportEnvVars {
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800302 if makeVars[name] == "" {
Dan Willemsen1e704462016-08-21 15:17:17 -0700303 env.Unset(name)
304 } else {
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800305 env.Set(name, makeVars[name])
Dan Willemsen1e704462016-08-21 15:17:17 -0700306 }
307 }
308
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800309 config.SetKatiArgs(strings.Fields(makeVars["KATI_GOALS"]))
310 config.SetNinjaArgs(strings.Fields(makeVars["NINJA_GOALS"]))
311 config.SetTargetDevice(makeVars["TARGET_DEVICE"])
312 config.SetTargetDeviceDir(makeVars["TARGET_DEVICE_DIR"])
Spandan Dasa3639e62021-05-25 19:14:02 +0000313 config.sandboxConfig.SetSrcDirIsRO(makeVars["BUILD_BROKEN_SRC_DIR_IS_WRITABLE"] == "false")
314 config.sandboxConfig.SetSrcDirRWAllowlist(strings.Fields(makeVars["BUILD_BROKEN_SRC_DIR_RW_ALLOWLIST"]))
Dan Willemsen3d60b112018-04-04 22:25:56 -0700315
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800316 config.SetBuildBrokenDupRules(makeVars["BUILD_BROKEN_DUP_RULES"] == "true")
317 config.SetBuildBrokenUsesNetwork(makeVars["BUILD_BROKEN_USES_NETWORK"] == "true")
318 config.SetBuildBrokenNinjaUsesEnvVars(strings.Fields(makeVars["BUILD_BROKEN_NINJA_USES_ENV_VARS"]))
Sam Delmerico98a73292023-02-21 11:50:29 -0500319 config.SetSourceRootDirs(strings.Fields(makeVars["PRODUCT_SOURCE_ROOT_DIRS"]))
Spandan Das28a6f192024-07-01 21:00:25 +0000320 config.SetBuildBrokenMissingOutputs(makeVars["BUILD_BROKEN_MISSING_OUTPUTS"] == "true")
Cole Faust3740b282025-01-21 15:59:50 -0800321
322 if !config.skipKatiControlledByFlags {
323 if makeVars["PRODUCT_SOONG_ONLY"] == "true" {
Joe Onorato8ae66df2025-01-29 13:21:58 -0800324 config.soongOnlyRequested = true
Cole Faust3740b282025-01-21 15:59:50 -0800325 config.skipKati = true
326 config.skipKatiNinja = true
327 }
328 }
Joe Onorato8ae66df2025-01-29 13:21:58 -0800329
330 // Print the banner like make did
331 if !env.IsEnvTrue("ANDROID_QUIET_BUILD") {
332 fmt.Fprintln(ctx.Writer, Banner(config, makeVars))
333 }
Dan Willemsen1e704462016-08-21 15:17:17 -0700334}