blob: 1925e87b99796eeaf70cda7ff0300824cc865883 [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() },
45 }
46
47 makeVars := make([]string, 0, len(vars))
48 for _, v := range vars {
49 if _, ok := soongUiVars[v]; !ok {
50 makeVars = append(makeVars, v)
51 }
52 }
53
54 var ret map[string]string
55 if len(makeVars) > 0 {
Dan Willemsen4e2456b2019-10-03 16:45:58 -070056 tmpDir, err := ioutil.TempDir("", "dumpvars")
57 if err != nil {
58 return nil, err
59 }
60 defer os.RemoveAll(tmpDir)
61
62 // It's not safe to use the same TMPDIR as the build, as that can be removed.
63 config.Environment().Set("TMPDIR", tmpDir)
64
65 SetupLitePath(ctx, config)
66
Dan Willemsen6f037522018-10-21 09:20:47 -070067 ret, err = dumpMakeVars(ctx, config, goals, makeVars, false)
68 if err != nil {
69 return ret, err
70 }
71 } else {
72 ret = make(map[string]string)
73 }
74
75 for _, v := range vars {
76 if f, ok := soongUiVars[v]; ok {
77 ret[v] = f()
78 }
79 }
80
81 return ret, nil
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -070082}
83
84func dumpMakeVars(ctx Context, config Config, goals, vars []string, write_soong_vars bool) (map[string]string, error) {
Nan Zhang17f27672018-12-12 16:01:49 -080085 ctx.BeginTrace(metrics.RunKati, "dumpvars")
Dan Willemsend9f6fa22016-08-21 15:17:17 -070086 defer ctx.EndTrace()
87
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -070088 cmd := Command(ctx, config, "dumpvars",
89 config.PrebuiltBuildTool("ckati"),
90 "-f", "build/make/core/config.mk",
91 "--color_warnings",
Dan Willemsen0c518512018-01-09 02:09:52 -080092 "--kati_stats",
Dan Willemsen1e704462016-08-21 15:17:17 -070093 "dump-many-vars",
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -070094 "MAKECMDGOALS="+strings.Join(goals, " "))
95 cmd.Environment.Set("CALLED_FROM_SETUP", "true")
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -070096 if write_soong_vars {
97 cmd.Environment.Set("WRITE_SOONG_VARIABLES", "true")
98 }
99 cmd.Environment.Set("DUMP_MANY_VARS", strings.Join(vars, " "))
100 cmd.Sandbox = dumpvarsSandbox
Dan Willemsen0c518512018-01-09 02:09:52 -0800101 output := bytes.Buffer{}
102 cmd.Stdout = &output
103 pipe, err := cmd.StderrPipe()
Dan Willemsen1e704462016-08-21 15:17:17 -0700104 if err != nil {
Dan Willemsen0c518512018-01-09 02:09:52 -0800105 ctx.Fatalln("Error getting output pipe for ckati:", err)
Dan Willemsen1e704462016-08-21 15:17:17 -0700106 }
Dan Willemsen0c518512018-01-09 02:09:52 -0800107 cmd.StartOrFatal()
108 // TODO: error out when Stderr contains any content
Dan Willemsenb82471a2018-05-17 16:37:09 -0700109 status.KatiReader(ctx.Status.StartTool(), pipe)
Dan Willemsen0c518512018-01-09 02:09:52 -0800110 cmd.WaitOrFatal()
Dan Willemsen1e704462016-08-21 15:17:17 -0700111
112 ret := make(map[string]string, len(vars))
Dan Willemsen0c518512018-01-09 02:09:52 -0800113 for _, line := range strings.Split(output.String(), "\n") {
Dan Willemsen1e704462016-08-21 15:17:17 -0700114 if len(line) == 0 {
115 continue
116 }
117
118 if key, value, ok := decodeKeyValue(line); ok {
119 if value, ok = singleUnquote(value); ok {
120 ret[key] = value
121 ctx.Verboseln(key, value)
122 } else {
123 return nil, fmt.Errorf("Failed to parse make line: %q", line)
124 }
125 } else {
126 return nil, fmt.Errorf("Failed to parse make line: %q", line)
127 }
128 }
Nan Zhang17f27672018-12-12 16:01:49 -0800129 if ctx.Metrics != nil {
130 ctx.Metrics.SetMetadataMetrics(ret)
131 }
Dan Willemsen1e704462016-08-21 15:17:17 -0700132
133 return ret, nil
134}
135
Dan Willemsen051133b2017-07-14 11:29:29 -0700136// Variables to print out in the top banner
137var BannerVars = []string{
138 "PLATFORM_VERSION_CODENAME",
139 "PLATFORM_VERSION",
140 "TARGET_PRODUCT",
141 "TARGET_BUILD_VARIANT",
142 "TARGET_BUILD_TYPE",
143 "TARGET_BUILD_APPS",
144 "TARGET_ARCH",
145 "TARGET_ARCH_VARIANT",
146 "TARGET_CPU_VARIANT",
147 "TARGET_2ND_ARCH",
148 "TARGET_2ND_ARCH_VARIANT",
149 "TARGET_2ND_CPU_VARIANT",
150 "HOST_ARCH",
151 "HOST_2ND_ARCH",
152 "HOST_OS",
153 "HOST_OS_EXTRA",
154 "HOST_CROSS_OS",
155 "HOST_CROSS_ARCH",
156 "HOST_CROSS_2ND_ARCH",
157 "HOST_BUILD_TYPE",
158 "BUILD_ID",
159 "OUT_DIR",
160 "AUX_OS_VARIANT_LIST",
161 "TARGET_BUILD_PDK",
162 "PDK_FUSION_PLATFORM_ZIP",
Jeff Gaston088e29e2017-11-29 16:47:17 -0800163 "PRODUCT_SOONG_NAMESPACES",
Dan Willemsen051133b2017-07-14 11:29:29 -0700164}
165
166func Banner(make_vars map[string]string) string {
167 b := &bytes.Buffer{}
168
169 fmt.Fprintln(b, "============================================")
170 for _, name := range BannerVars {
171 if make_vars[name] != "" {
172 fmt.Fprintf(b, "%s=%s\n", name, make_vars[name])
173 }
174 }
175 fmt.Fprint(b, "============================================")
176
177 return b.String()
178}
179
Dan Willemsen1e704462016-08-21 15:17:17 -0700180func runMakeProductConfig(ctx Context, config Config) {
181 // Variables to export into the environment of Kati/Ninja
182 exportEnvVars := []string{
183 // So that we can use the correct TARGET_PRODUCT if it's been
Dan Willemsena2a8ecb2019-07-29 15:14:11 -0700184 // modified by a buildspec.mk
Dan Willemsen1e704462016-08-21 15:17:17 -0700185 "TARGET_PRODUCT",
Dan Willemsen02781d52017-05-12 19:28:13 -0700186 "TARGET_BUILD_VARIANT",
Dan Willemsen04a16c72017-05-25 22:18:57 -0700187 "TARGET_BUILD_APPS",
Dan Willemsen1e704462016-08-21 15:17:17 -0700188
189 // compiler wrappers set up by make
190 "CC_WRAPPER",
191 "CXX_WRAPPER",
Yoshisato Yanagisawa13fd3ff2017-04-05 11:05:31 +0900192 "JAVAC_WRAPPER",
Dan Willemsen1e704462016-08-21 15:17:17 -0700193
194 // ccache settings
195 "CCACHE_COMPILERCHECK",
196 "CCACHE_SLOPPINESS",
197 "CCACHE_BASEDIR",
198 "CCACHE_CPP2",
199 }
200
Dan Willemsen1e704462016-08-21 15:17:17 -0700201 allVars := append(append([]string{
202 // Used to execute Kati and Ninja
203 "NINJA_GOALS",
204 "KATI_GOALS",
Dan Willemsen02781d52017-05-12 19:28:13 -0700205
206 // To find target/product/<DEVICE>
207 "TARGET_DEVICE",
Dan Willemsen3d60b112018-04-04 22:25:56 -0700208
Dan Willemsen6ab79db2018-05-02 00:06:28 -0700209 // So that later Kati runs can find BoardConfig.mk faster
210 "TARGET_DEVICE_DIR",
211
Dan Willemsen3d60b112018-04-04 22:25:56 -0700212 // Whether --werror_overriding_commands will work
213 "BUILD_BROKEN_DUP_RULES",
Dan Willemsenb58f1202018-06-21 10:12:53 -0700214
Dan Willemsen25e6f092019-04-09 10:22:43 -0700215 // Whether to enable the network during the build
216 "BUILD_BROKEN_USES_NETWORK",
217
Dan Willemsenb58f1202018-06-21 10:12:53 -0700218 // Not used, but useful to be in the soong.log
Steven Moreland00020282019-03-07 09:27:27 -0800219 "BOARD_VNDK_VERSION",
Dan Willemsen368e5562019-04-17 14:44:33 -0700220
221 "DEFAULT_WARNING_BUILD_MODULE_TYPES",
222 "DEFAULT_ERROR_BUILD_MODULE_TYPES",
Logan Chienf9cf9ac2019-09-20 11:37:30 -0700223 "BUILD_BROKEN_PREBUILT_ELF_FILES",
Dan Willemsen368e5562019-04-17 14:44:33 -0700224 "BUILD_BROKEN_USES_BUILD_AUX_EXECUTABLE",
225 "BUILD_BROKEN_USES_BUILD_AUX_STATIC_LIBRARY",
226 "BUILD_BROKEN_USES_BUILD_COPY_HEADERS",
227 "BUILD_BROKEN_USES_BUILD_EXECUTABLE",
228 "BUILD_BROKEN_USES_BUILD_FUZZ_TEST",
229 "BUILD_BROKEN_USES_BUILD_HEADER_LIBRARY",
230 "BUILD_BROKEN_USES_BUILD_HOST_DALVIK_JAVA_LIBRARY",
231 "BUILD_BROKEN_USES_BUILD_HOST_DALVIK_STATIC_JAVA_LIBRARY",
232 "BUILD_BROKEN_USES_BUILD_HOST_EXECUTABLE",
233 "BUILD_BROKEN_USES_BUILD_HOST_FUZZ_TEST",
234 "BUILD_BROKEN_USES_BUILD_HOST_JAVA_LIBRARY",
235 "BUILD_BROKEN_USES_BUILD_HOST_NATIVE_TEST",
236 "BUILD_BROKEN_USES_BUILD_HOST_PREBUILT",
237 "BUILD_BROKEN_USES_BUILD_HOST_SHARED_LIBRARY",
Dan Willemsen368e5562019-04-17 14:44:33 -0700238 "BUILD_BROKEN_USES_BUILD_HOST_STATIC_LIBRARY",
239 "BUILD_BROKEN_USES_BUILD_HOST_STATIC_TEST_LIBRARY",
240 "BUILD_BROKEN_USES_BUILD_HOST_TEST_CONFIG",
241 "BUILD_BROKEN_USES_BUILD_JAVA_LIBRARY",
242 "BUILD_BROKEN_USES_BUILD_MULTI_PREBUILT",
243 "BUILD_BROKEN_USES_BUILD_NATIVE_BENCHMARK",
244 "BUILD_BROKEN_USES_BUILD_NATIVE_TEST",
245 "BUILD_BROKEN_USES_BUILD_NOTICE_FILE",
246 "BUILD_BROKEN_USES_BUILD_PACKAGE",
247 "BUILD_BROKEN_USES_BUILD_PHONY_PACKAGE",
248 "BUILD_BROKEN_USES_BUILD_PREBUILT",
249 "BUILD_BROKEN_USES_BUILD_RRO_PACKAGE",
250 "BUILD_BROKEN_USES_BUILD_SHARED_LIBRARY",
Dan Willemsen368e5562019-04-17 14:44:33 -0700251 "BUILD_BROKEN_USES_BUILD_STATIC_JAVA_LIBRARY",
252 "BUILD_BROKEN_USES_BUILD_STATIC_LIBRARY",
253 "BUILD_BROKEN_USES_BUILD_STATIC_TEST_LIBRARY",
254 "BUILD_BROKEN_USES_BUILD_TARGET_TEST_CONFIG",
Dan Willemsen051133b2017-07-14 11:29:29 -0700255 }, exportEnvVars...), BannerVars...)
Dan Willemsen1e704462016-08-21 15:17:17 -0700256
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -0700257 make_vars, err := dumpMakeVars(ctx, config, config.Arguments(), allVars, true)
Dan Willemsen1e704462016-08-21 15:17:17 -0700258 if err != nil {
259 ctx.Fatalln("Error dumping make vars:", err)
260 }
261
Sasha Smundakc0c9ef92019-01-23 09:52:57 -0800262 env := config.Environment()
Dan Willemsen1e704462016-08-21 15:17:17 -0700263 // Print the banner like make does
Sasha Smundakc0c9ef92019-01-23 09:52:57 -0800264 if !env.IsEnvTrue("ANDROID_QUIET_BUILD") {
Colin Cross097ed2a2019-06-08 21:48:58 -0700265 fmt.Fprintln(ctx.Writer, Banner(make_vars))
Sasha Smundakc0c9ef92019-01-23 09:52:57 -0800266 }
Dan Willemsen1e704462016-08-21 15:17:17 -0700267
268 // Populate the environment
Dan Willemsen1e704462016-08-21 15:17:17 -0700269 for _, name := range exportEnvVars {
270 if make_vars[name] == "" {
271 env.Unset(name)
272 } else {
273 env.Set(name, make_vars[name])
274 }
275 }
276
277 config.SetKatiArgs(strings.Fields(make_vars["KATI_GOALS"]))
278 config.SetNinjaArgs(strings.Fields(make_vars["NINJA_GOALS"]))
Dan Willemsen02781d52017-05-12 19:28:13 -0700279 config.SetTargetDevice(make_vars["TARGET_DEVICE"])
Dan Willemsen6ab79db2018-05-02 00:06:28 -0700280 config.SetTargetDeviceDir(make_vars["TARGET_DEVICE_DIR"])
Dan Willemsen3d60b112018-04-04 22:25:56 -0700281
Dan Willemsenfa42f3c2018-06-15 21:54:47 -0700282 config.SetPdkBuild(make_vars["TARGET_BUILD_PDK"] == "true")
Dan Willemsen9dc69a42018-06-22 13:18:06 -0700283 config.SetBuildBrokenDupRules(make_vars["BUILD_BROKEN_DUP_RULES"] == "true")
Dan Willemsen25e6f092019-04-09 10:22:43 -0700284 config.SetBuildBrokenUsesNetwork(make_vars["BUILD_BROKEN_USES_NETWORK"] == "true")
Dan Willemsen1e704462016-08-21 15:17:17 -0700285}