blob: 2b3992633b2399ccfe10cfacf4150c476de4428a [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 "fmt"
Dan Willemsen1e704462016-08-21 15:17:17 -070019 "path/filepath"
20 "strings"
21)
22
23// DumpMakeVars can be used to extract the values of Make variables after the
24// product configurations are loaded. This is roughly equivalent to the
25// `get_build_var` bash function.
26//
27// goals can be used to set MAKECMDGOALS, which emulates passing arguments to
28// Make without actually building them. So all the variables based on
29// MAKECMDGOALS can be read.
30//
31// extra_targets adds real arguments to the make command, in case other targets
32// actually need to be run (like the Soong config generator).
33//
34// vars is the list of variables to read. The values will be put in the
35// returned map.
36func DumpMakeVars(ctx Context, config Config, goals, extra_targets, vars []string) (map[string]string, error) {
Dan Willemsend9f6fa22016-08-21 15:17:17 -070037 ctx.BeginTrace("dumpvars")
38 defer ctx.EndTrace()
39
Dan Willemsen269a8c72017-05-03 17:15:47 -070040 cmd := Command(ctx, config, "make",
Dan Willemsen1e704462016-08-21 15:17:17 -070041 "make",
42 "--no-print-directory",
43 "-f", "build/core/config.mk",
44 "dump-many-vars",
45 "CALLED_FROM_SETUP=true",
46 "BUILD_SYSTEM=build/core",
47 "MAKECMDGOALS="+strings.Join(goals, " "),
48 "DUMP_MANY_VARS="+strings.Join(vars, " "),
49 "OUT_DIR="+config.OutDir())
Dan Willemsen1e704462016-08-21 15:17:17 -070050 cmd.Args = append(cmd.Args, extra_targets...)
Dan Willemsen269a8c72017-05-03 17:15:47 -070051 cmd.Sandbox = makeSandbox
Dan Willemsen1e704462016-08-21 15:17:17 -070052 // TODO: error out when Stderr contains any content
53 cmd.Stderr = ctx.Stderr()
Dan Willemsen1e704462016-08-21 15:17:17 -070054 output, err := cmd.Output()
55 if err != nil {
56 return nil, err
57 }
58
59 ret := make(map[string]string, len(vars))
60 for _, line := range strings.Split(string(output), "\n") {
61 if len(line) == 0 {
62 continue
63 }
64
65 if key, value, ok := decodeKeyValue(line); ok {
66 if value, ok = singleUnquote(value); ok {
67 ret[key] = value
68 ctx.Verboseln(key, value)
69 } else {
70 return nil, fmt.Errorf("Failed to parse make line: %q", line)
71 }
72 } else {
73 return nil, fmt.Errorf("Failed to parse make line: %q", line)
74 }
75 }
76
77 return ret, nil
78}
79
80func runMakeProductConfig(ctx Context, config Config) {
81 // Variables to export into the environment of Kati/Ninja
82 exportEnvVars := []string{
83 // So that we can use the correct TARGET_PRODUCT if it's been
84 // modified by PRODUCT-* arguments
85 "TARGET_PRODUCT",
Dan Willemsen02781d52017-05-12 19:28:13 -070086 "TARGET_BUILD_VARIANT",
Dan Willemsen1e704462016-08-21 15:17:17 -070087
88 // compiler wrappers set up by make
89 "CC_WRAPPER",
90 "CXX_WRAPPER",
Yoshisato Yanagisawa13fd3ff2017-04-05 11:05:31 +090091 "JAVAC_WRAPPER",
Dan Willemsen1e704462016-08-21 15:17:17 -070092
93 // ccache settings
94 "CCACHE_COMPILERCHECK",
95 "CCACHE_SLOPPINESS",
96 "CCACHE_BASEDIR",
97 "CCACHE_CPP2",
98 }
99
100 // Variables to print out in the top banner
101 bannerVars := []string{
102 "PLATFORM_VERSION_CODENAME",
103 "PLATFORM_VERSION",
104 "TARGET_PRODUCT",
105 "TARGET_BUILD_VARIANT",
106 "TARGET_BUILD_TYPE",
107 "TARGET_BUILD_APPS",
108 "TARGET_ARCH",
109 "TARGET_ARCH_VARIANT",
110 "TARGET_CPU_VARIANT",
111 "TARGET_2ND_ARCH",
112 "TARGET_2ND_ARCH_VARIANT",
113 "TARGET_2ND_CPU_VARIANT",
114 "HOST_ARCH",
115 "HOST_2ND_ARCH",
116 "HOST_OS",
117 "HOST_OS_EXTRA",
118 "HOST_CROSS_OS",
119 "HOST_CROSS_ARCH",
120 "HOST_CROSS_2ND_ARCH",
121 "HOST_BUILD_TYPE",
122 "BUILD_ID",
123 "OUT_DIR",
124 "AUX_OS_VARIANT_LIST",
125 "TARGET_BUILD_PDK",
126 "PDK_FUSION_PLATFORM_ZIP",
127 }
128
129 allVars := append(append([]string{
130 // Used to execute Kati and Ninja
131 "NINJA_GOALS",
132 "KATI_GOALS",
Dan Willemsen02781d52017-05-12 19:28:13 -0700133
134 // To find target/product/<DEVICE>
135 "TARGET_DEVICE",
Dan Willemsen1e704462016-08-21 15:17:17 -0700136 }, exportEnvVars...), bannerVars...)
137
138 make_vars, err := DumpMakeVars(ctx, config, config.Arguments(), []string{
139 filepath.Join(config.SoongOutDir(), "soong.variables"),
140 }, allVars)
141 if err != nil {
142 ctx.Fatalln("Error dumping make vars:", err)
143 }
144
145 // Print the banner like make does
146 fmt.Fprintln(ctx.Stdout(), "============================================")
147 for _, name := range bannerVars {
148 if make_vars[name] != "" {
149 fmt.Fprintf(ctx.Stdout(), "%s=%s\n", name, make_vars[name])
150 }
151 }
152 fmt.Fprintln(ctx.Stdout(), "============================================")
153
154 // Populate the environment
155 env := config.Environment()
156 for _, name := range exportEnvVars {
157 if make_vars[name] == "" {
158 env.Unset(name)
159 } else {
160 env.Set(name, make_vars[name])
161 }
162 }
163
164 config.SetKatiArgs(strings.Fields(make_vars["KATI_GOALS"]))
165 config.SetNinjaArgs(strings.Fields(make_vars["NINJA_GOALS"]))
Dan Willemsen02781d52017-05-12 19:28:13 -0700166 config.SetTargetDevice(make_vars["TARGET_DEVICE"])
Dan Willemsen1e704462016-08-21 15:17:17 -0700167}