blob: 1ab855d021468ce2e56ebac2406d29bfc4a45733 [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 Willemsen1e704462016-08-21 15:17:17 -070020 "strings"
Dan Willemsenb82471a2018-05-17 16:37:09 -070021
Nan Zhang17f27672018-12-12 16:01:49 -080022 "android/soong/ui/metrics"
Dan Willemsenb82471a2018-05-17 16:37:09 -070023 "android/soong/ui/status"
Dan Willemsen1e704462016-08-21 15:17:17 -070024)
25
26// DumpMakeVars can be used to extract the values of Make variables after the
27// product configurations are loaded. This is roughly equivalent to the
28// `get_build_var` bash function.
29//
30// goals can be used to set MAKECMDGOALS, which emulates passing arguments to
31// Make without actually building them. So all the variables based on
32// MAKECMDGOALS can be read.
33//
Dan Willemsen1e704462016-08-21 15:17:17 -070034// vars is the list of variables to read. The values will be put in the
35// returned map.
Dan Willemsen6f037522018-10-21 09:20:47 -070036//
37// variables controlled by soong_ui directly are now returned without needing
38// to call into make, to retain compatibility.
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -070039func DumpMakeVars(ctx Context, config Config, goals, vars []string) (map[string]string, error) {
Dan Willemsen6f037522018-10-21 09:20:47 -070040 soongUiVars := map[string]func() string{
41 "OUT_DIR": func() string { return config.OutDir() },
42 "DIST_DIR": func() string { return config.DistDir() },
43 }
44
45 makeVars := make([]string, 0, len(vars))
46 for _, v := range vars {
47 if _, ok := soongUiVars[v]; !ok {
48 makeVars = append(makeVars, v)
49 }
50 }
51
52 var ret map[string]string
53 if len(makeVars) > 0 {
54 var err error
55 ret, err = dumpMakeVars(ctx, config, goals, makeVars, false)
56 if err != nil {
57 return ret, err
58 }
59 } else {
60 ret = make(map[string]string)
61 }
62
63 for _, v := range vars {
64 if f, ok := soongUiVars[v]; ok {
65 ret[v] = f()
66 }
67 }
68
69 return ret, nil
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -070070}
71
72func dumpMakeVars(ctx Context, config Config, goals, vars []string, write_soong_vars bool) (map[string]string, error) {
Nan Zhang17f27672018-12-12 16:01:49 -080073 ctx.BeginTrace(metrics.RunKati, "dumpvars")
Dan Willemsend9f6fa22016-08-21 15:17:17 -070074 defer ctx.EndTrace()
75
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -070076 cmd := Command(ctx, config, "dumpvars",
77 config.PrebuiltBuildTool("ckati"),
78 "-f", "build/make/core/config.mk",
79 "--color_warnings",
Dan Willemsen0c518512018-01-09 02:09:52 -080080 "--kati_stats",
Dan Willemsen1e704462016-08-21 15:17:17 -070081 "dump-many-vars",
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -070082 "MAKECMDGOALS="+strings.Join(goals, " "))
83 cmd.Environment.Set("CALLED_FROM_SETUP", "true")
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -070084 if write_soong_vars {
85 cmd.Environment.Set("WRITE_SOONG_VARIABLES", "true")
86 }
87 cmd.Environment.Set("DUMP_MANY_VARS", strings.Join(vars, " "))
88 cmd.Sandbox = dumpvarsSandbox
Dan Willemsen0c518512018-01-09 02:09:52 -080089 output := bytes.Buffer{}
90 cmd.Stdout = &output
91 pipe, err := cmd.StderrPipe()
Dan Willemsen1e704462016-08-21 15:17:17 -070092 if err != nil {
Dan Willemsen0c518512018-01-09 02:09:52 -080093 ctx.Fatalln("Error getting output pipe for ckati:", err)
Dan Willemsen1e704462016-08-21 15:17:17 -070094 }
Dan Willemsen0c518512018-01-09 02:09:52 -080095 cmd.StartOrFatal()
96 // TODO: error out when Stderr contains any content
Dan Willemsenb82471a2018-05-17 16:37:09 -070097 status.KatiReader(ctx.Status.StartTool(), pipe)
Dan Willemsen0c518512018-01-09 02:09:52 -080098 cmd.WaitOrFatal()
Dan Willemsen1e704462016-08-21 15:17:17 -070099
100 ret := make(map[string]string, len(vars))
Dan Willemsen0c518512018-01-09 02:09:52 -0800101 for _, line := range strings.Split(output.String(), "\n") {
Dan Willemsen1e704462016-08-21 15:17:17 -0700102 if len(line) == 0 {
103 continue
104 }
105
106 if key, value, ok := decodeKeyValue(line); ok {
107 if value, ok = singleUnquote(value); ok {
108 ret[key] = value
109 ctx.Verboseln(key, value)
110 } else {
111 return nil, fmt.Errorf("Failed to parse make line: %q", line)
112 }
113 } else {
114 return nil, fmt.Errorf("Failed to parse make line: %q", line)
115 }
116 }
Nan Zhang17f27672018-12-12 16:01:49 -0800117 if ctx.Metrics != nil {
118 ctx.Metrics.SetMetadataMetrics(ret)
119 }
Dan Willemsen1e704462016-08-21 15:17:17 -0700120
121 return ret, nil
122}
123
Dan Willemsen051133b2017-07-14 11:29:29 -0700124// Variables to print out in the top banner
125var BannerVars = []string{
126 "PLATFORM_VERSION_CODENAME",
127 "PLATFORM_VERSION",
128 "TARGET_PRODUCT",
129 "TARGET_BUILD_VARIANT",
130 "TARGET_BUILD_TYPE",
131 "TARGET_BUILD_APPS",
132 "TARGET_ARCH",
133 "TARGET_ARCH_VARIANT",
134 "TARGET_CPU_VARIANT",
135 "TARGET_2ND_ARCH",
136 "TARGET_2ND_ARCH_VARIANT",
137 "TARGET_2ND_CPU_VARIANT",
138 "HOST_ARCH",
139 "HOST_2ND_ARCH",
140 "HOST_OS",
141 "HOST_OS_EXTRA",
142 "HOST_CROSS_OS",
143 "HOST_CROSS_ARCH",
144 "HOST_CROSS_2ND_ARCH",
145 "HOST_BUILD_TYPE",
146 "BUILD_ID",
147 "OUT_DIR",
148 "AUX_OS_VARIANT_LIST",
149 "TARGET_BUILD_PDK",
150 "PDK_FUSION_PLATFORM_ZIP",
Jeff Gaston088e29e2017-11-29 16:47:17 -0800151 "PRODUCT_SOONG_NAMESPACES",
Dan Willemsen051133b2017-07-14 11:29:29 -0700152}
153
154func Banner(make_vars map[string]string) string {
155 b := &bytes.Buffer{}
156
157 fmt.Fprintln(b, "============================================")
158 for _, name := range BannerVars {
159 if make_vars[name] != "" {
160 fmt.Fprintf(b, "%s=%s\n", name, make_vars[name])
161 }
162 }
163 fmt.Fprint(b, "============================================")
164
165 return b.String()
166}
167
Dan Willemsen1e704462016-08-21 15:17:17 -0700168func runMakeProductConfig(ctx Context, config Config) {
169 // Variables to export into the environment of Kati/Ninja
170 exportEnvVars := []string{
171 // So that we can use the correct TARGET_PRODUCT if it's been
Dan Willemsen04a16c72017-05-25 22:18:57 -0700172 // modified by PRODUCT-*/APP-* arguments
Dan Willemsen1e704462016-08-21 15:17:17 -0700173 "TARGET_PRODUCT",
Dan Willemsen02781d52017-05-12 19:28:13 -0700174 "TARGET_BUILD_VARIANT",
Dan Willemsen04a16c72017-05-25 22:18:57 -0700175 "TARGET_BUILD_APPS",
Dan Willemsen1e704462016-08-21 15:17:17 -0700176
177 // compiler wrappers set up by make
178 "CC_WRAPPER",
179 "CXX_WRAPPER",
Yoshisato Yanagisawa13fd3ff2017-04-05 11:05:31 +0900180 "JAVAC_WRAPPER",
Dan Willemsen1e704462016-08-21 15:17:17 -0700181
182 // ccache settings
183 "CCACHE_COMPILERCHECK",
184 "CCACHE_SLOPPINESS",
185 "CCACHE_BASEDIR",
186 "CCACHE_CPP2",
187 }
188
Dan Willemsen1e704462016-08-21 15:17:17 -0700189 allVars := append(append([]string{
190 // Used to execute Kati and Ninja
191 "NINJA_GOALS",
192 "KATI_GOALS",
Dan Willemsen02781d52017-05-12 19:28:13 -0700193
194 // To find target/product/<DEVICE>
195 "TARGET_DEVICE",
Dan Willemsen3d60b112018-04-04 22:25:56 -0700196
Dan Willemsen6ab79db2018-05-02 00:06:28 -0700197 // So that later Kati runs can find BoardConfig.mk faster
198 "TARGET_DEVICE_DIR",
199
Dan Willemsen3d60b112018-04-04 22:25:56 -0700200 // Whether --werror_overriding_commands will work
201 "BUILD_BROKEN_DUP_RULES",
Dan Willemsenb58f1202018-06-21 10:12:53 -0700202
Dan Willemsend8aa39d2018-08-27 15:01:03 -0700203 // Used to turn on --werror_ options in Kati
204 "BUILD_BROKEN_PHONY_TARGETS",
205
Dan Willemsenb58f1202018-06-21 10:12:53 -0700206 // Not used, but useful to be in the soong.log
207 "BUILD_BROKEN_ANDROIDMK_EXPORTS",
208 "BUILD_BROKEN_DUP_COPY_HEADERS",
Dan Willemsen051133b2017-07-14 11:29:29 -0700209 }, exportEnvVars...), BannerVars...)
Dan Willemsen1e704462016-08-21 15:17:17 -0700210
Dan Willemsenb2e6c2e2017-07-13 17:24:44 -0700211 make_vars, err := dumpMakeVars(ctx, config, config.Arguments(), allVars, true)
Dan Willemsen1e704462016-08-21 15:17:17 -0700212 if err != nil {
213 ctx.Fatalln("Error dumping make vars:", err)
214 }
215
216 // Print the banner like make does
Dan Willemsenb82471a2018-05-17 16:37:09 -0700217 ctx.Writer.Print(Banner(make_vars))
Dan Willemsen1e704462016-08-21 15:17:17 -0700218
219 // Populate the environment
220 env := config.Environment()
221 for _, name := range exportEnvVars {
222 if make_vars[name] == "" {
223 env.Unset(name)
224 } else {
225 env.Set(name, make_vars[name])
226 }
227 }
228
229 config.SetKatiArgs(strings.Fields(make_vars["KATI_GOALS"]))
230 config.SetNinjaArgs(strings.Fields(make_vars["NINJA_GOALS"]))
Dan Willemsen02781d52017-05-12 19:28:13 -0700231 config.SetTargetDevice(make_vars["TARGET_DEVICE"])
Dan Willemsen6ab79db2018-05-02 00:06:28 -0700232 config.SetTargetDeviceDir(make_vars["TARGET_DEVICE_DIR"])
Dan Willemsen3d60b112018-04-04 22:25:56 -0700233
Dan Willemsenfa42f3c2018-06-15 21:54:47 -0700234 config.SetPdkBuild(make_vars["TARGET_BUILD_PDK"] == "true")
Dan Willemsen9dc69a42018-06-22 13:18:06 -0700235 config.SetBuildBrokenDupRules(make_vars["BUILD_BROKEN_DUP_RULES"] == "true")
Dan Willemsen14569582018-09-10 13:06:43 -0700236 config.SetBuildBrokenPhonyTargets(make_vars["BUILD_BROKEN_PHONY_TARGETS"] == "true")
Dan Willemsen1e704462016-08-21 15:17:17 -0700237}