blob: 2d38dafc12188693974905053622a1b39bb929fd [file] [log] [blame]
Colin Cross3f40fa42015-01-30 17:27:36 -08001// Copyright 2015 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
Colin Cross635c3b02016-05-18 15:37:25 -070015package android
Colin Cross3f40fa42015-01-30 17:27:36 -080016
17import (
Colin Cross3f40fa42015-01-30 17:27:36 -080018 "fmt"
19 "reflect"
20 "runtime"
21 "strings"
Colin Crossf6566ed2015-03-24 11:13:38 -070022
23 "github.com/google/blueprint"
24 "github.com/google/blueprint/proptools"
Colin Cross3f40fa42015-01-30 17:27:36 -080025)
26
Colin Cross463a90e2015-06-17 14:20:06 -070027func init() {
Colin Crosse8a67a72016-08-07 21:17:54 -070028 RegisterBottomUpMutator("defaults_deps", defaultsDepsMutator).Parallel()
Colin Cross76f2f972016-08-11 14:10:54 -070029 RegisterTopDownMutator("defaults", defaultsMutator).Parallel()
Colin Crosscfad1192015-11-02 16:43:11 -080030
Colin Crosse8a67a72016-08-07 21:17:54 -070031 RegisterBottomUpMutator("arch", ArchMutator).Parallel()
Colin Cross463a90e2015-06-17 14:20:06 -070032}
33
Colin Cross3f40fa42015-01-30 17:27:36 -080034var (
Colin Crossec193632015-07-06 17:49:43 -070035 Arm = newArch("arm", "lib32")
36 Arm64 = newArch("arm64", "lib64")
37 Mips = newArch("mips", "lib32")
38 Mips64 = newArch("mips64", "lib64")
39 X86 = newArch("x86", "lib32")
40 X86_64 = newArch("x86_64", "lib64")
Colin Cross2fe66872015-03-30 17:20:39 -070041
42 Common = ArchType{
43 Name: "common",
44 }
Colin Cross3f40fa42015-01-30 17:27:36 -080045)
46
Colin Cross4225f652015-09-17 14:33:42 -070047var archTypeMap = map[string]ArchType{
48 "arm": Arm,
49 "arm64": Arm64,
50 "mips": Mips,
Colin Cross3b336c22015-11-23 16:28:31 -080051 "mips64": Mips64,
Colin Cross4225f652015-09-17 14:33:42 -070052 "x86": X86,
53 "x86_64": X86_64,
54}
55
Colin Cross3f40fa42015-01-30 17:27:36 -080056/*
57Example blueprints file containing all variant property groups, with comment listing what type
58of variants get properties in that group:
59
60module {
61 arch: {
62 arm: {
63 // Host or device variants with arm architecture
64 },
65 arm64: {
66 // Host or device variants with arm64 architecture
67 },
68 mips: {
69 // Host or device variants with mips architecture
70 },
71 mips64: {
72 // Host or device variants with mips64 architecture
73 },
74 x86: {
75 // Host or device variants with x86 architecture
76 },
77 x86_64: {
78 // Host or device variants with x86_64 architecture
79 },
80 },
81 multilib: {
82 lib32: {
83 // Host or device variants for 32-bit architectures
84 },
85 lib64: {
86 // Host or device variants for 64-bit architectures
87 },
88 },
89 target: {
90 android: {
91 // Device variants
92 },
93 host: {
94 // Host variants
95 },
96 linux: {
97 // Linux host variants
98 },
99 darwin: {
100 // Darwin host variants
101 },
102 windows: {
103 // Windows host variants
104 },
105 not_windows: {
106 // Non-windows host variants
107 },
108 },
109}
110*/
Colin Cross7d5136f2015-05-11 13:39:40 -0700111
Colin Cross85a88972015-11-23 13:29:51 -0800112type Embed interface{}
113
Colin Cross3f40fa42015-01-30 17:27:36 -0800114type archProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700115 // Properties to vary by target architecture
Colin Cross3f40fa42015-01-30 17:27:36 -0800116 Arch struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700117 // Properties for module variants being built to run on arm (host or device)
Colin Cross85a88972015-11-23 13:29:51 -0800118 Arm struct {
119 Embed `blueprint:"filter(android:\"arch_variant\")"`
120
121 // Arm arch variants
122 Armv5te interface{} `blueprint:"filter(android:\"arch_variant\")"`
123 Armv7_a interface{} `blueprint:"filter(android:\"arch_variant\")"`
124 Armv7_a_neon interface{} `blueprint:"filter(android:\"arch_variant\")"`
125
126 // Arm cpu variants
127 Cortex_a7 interface{} `blueprint:"filter(android:\"arch_variant\")"`
128 Cortex_a8 interface{} `blueprint:"filter(android:\"arch_variant\")"`
129 Cortex_a9 interface{} `blueprint:"filter(android:\"arch_variant\")"`
130 Cortex_a15 interface{} `blueprint:"filter(android:\"arch_variant\")"`
131 Cortex_a53 interface{} `blueprint:"filter(android:\"arch_variant\")"`
132 Cortex_a53_a57 interface{} `blueprint:"filter(android:\"arch_variant\")"`
133 Krait interface{} `blueprint:"filter(android:\"arch_variant\")"`
134 Denver interface{} `blueprint:"filter(android:\"arch_variant\")"`
135 }
136
Colin Cross7d5136f2015-05-11 13:39:40 -0700137 // Properties for module variants being built to run on arm64 (host or device)
Colin Cross85a88972015-11-23 13:29:51 -0800138 Arm64 struct {
139 Embed `blueprint:"filter(android:\"arch_variant\")"`
140
141 // Arm64 arch variants
142 Armv8_a interface{} `blueprint:"filter(android:\"arch_variant\")"`
143
144 // Arm64 cpu variants
145 Cortex_a53 interface{} `blueprint:"filter(android:\"arch_variant\")"`
146 Denver64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
147 }
148
Colin Cross7d5136f2015-05-11 13:39:40 -0700149 // Properties for module variants being built to run on mips (host or device)
Colin Cross85a88972015-11-23 13:29:51 -0800150 Mips struct {
151 Embed `blueprint:"filter(android:\"arch_variant\")"`
152
153 // Mips arch variants
Colin Cross023f1e82015-11-23 16:15:10 -0800154 Mips32_fp interface{} `blueprint:"filter(android:\"arch_variant\")"`
155 Mips32r2_fp interface{} `blueprint:"filter(android:\"arch_variant\")"`
156 Mips32r2_fp_xburst interface{} `blueprint:"filter(android:\"arch_variant\")"`
157 Mips32r2dsp_fp interface{} `blueprint:"filter(android:\"arch_variant\")"`
158 Mips32r2dspr2_fp interface{} `blueprint:"filter(android:\"arch_variant\")"`
159 Mips32r6 interface{} `blueprint:"filter(android:\"arch_variant\")"`
160
161 // Mips arch features
Colin Cross85a88972015-11-23 13:29:51 -0800162 Rev6 interface{} `blueprint:"filter(android:\"arch_variant\")"`
163 }
164
Colin Cross7d5136f2015-05-11 13:39:40 -0700165 // Properties for module variants being built to run on mips64 (host or device)
Colin Cross85a88972015-11-23 13:29:51 -0800166 Mips64 struct {
167 Embed `blueprint:"filter(android:\"arch_variant\")"`
168
169 // Mips64 arch variants
Colin Cross3b336c22015-11-23 16:28:31 -0800170 Mips64r2 interface{} `blueprint:"filter(android:\"arch_variant\")"`
171 Mips64r6 interface{} `blueprint:"filter(android:\"arch_variant\")"`
172
173 // Mips64 arch features
Colin Cross85a88972015-11-23 13:29:51 -0800174 Rev6 interface{} `blueprint:"filter(android:\"arch_variant\")"`
175 }
176
Colin Cross7d5136f2015-05-11 13:39:40 -0700177 // Properties for module variants being built to run on x86 (host or device)
Colin Cross85a88972015-11-23 13:29:51 -0800178 X86 struct {
179 Embed `blueprint:"filter(android:\"arch_variant\")"`
180
181 // X86 arch variants
Colin Crossb0cba6a2015-11-20 15:35:26 -0800182 Atom interface{} `blueprint:"filter(android:\"arch_variant\")"`
183 Haswell interface{} `blueprint:"filter(android:\"arch_variant\")"`
184 Ivybridge interface{} `blueprint:"filter(android:\"arch_variant\")"`
185 Sandybridge interface{} `blueprint:"filter(android:\"arch_variant\")"`
186 Silvermont interface{} `blueprint:"filter(android:\"arch_variant\")"`
Dan Willemsen8a354052016-05-10 14:30:51 -0700187 // Generic variant for X86 on X86_64
Colin Cross635c3b02016-05-18 15:37:25 -0700188 X86_64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
Colin Cross85a88972015-11-23 13:29:51 -0800189
190 // X86 arch features
Colin Crossb0cba6a2015-11-20 15:35:26 -0800191 Ssse3 interface{} `blueprint:"filter(android:\"arch_variant\")"`
192 Sse4 interface{} `blueprint:"filter(android:\"arch_variant\")"`
193 Sse4_1 interface{} `blueprint:"filter(android:\"arch_variant\")"`
194 Sse4_2 interface{} `blueprint:"filter(android:\"arch_variant\")"`
195 Aes_ni interface{} `blueprint:"filter(android:\"arch_variant\")"`
196 Avx interface{} `blueprint:"filter(android:\"arch_variant\")"`
197 Popcnt interface{} `blueprint:"filter(android:\"arch_variant\")"`
198 Movbe interface{} `blueprint:"filter(android:\"arch_variant\")"`
Colin Cross85a88972015-11-23 13:29:51 -0800199 }
200
Colin Cross7d5136f2015-05-11 13:39:40 -0700201 // Properties for module variants being built to run on x86_64 (host or device)
Colin Cross85a88972015-11-23 13:29:51 -0800202 X86_64 struct {
203 Embed `blueprint:"filter(android:\"arch_variant\")"`
Colin Cross6371b382015-11-23 14:53:57 -0800204
205 // X86 arch variants
206 Haswell interface{} `blueprint:"filter(android:\"arch_variant\")"`
207 Ivybridge interface{} `blueprint:"filter(android:\"arch_variant\")"`
208 Sandybridge interface{} `blueprint:"filter(android:\"arch_variant\")"`
209 Silvermont interface{} `blueprint:"filter(android:\"arch_variant\")"`
210
211 // X86 arch features
212 Ssse3 interface{} `blueprint:"filter(android:\"arch_variant\")"`
213 Sse4 interface{} `blueprint:"filter(android:\"arch_variant\")"`
214 Sse4_1 interface{} `blueprint:"filter(android:\"arch_variant\")"`
215 Sse4_2 interface{} `blueprint:"filter(android:\"arch_variant\")"`
216 Aes_ni interface{} `blueprint:"filter(android:\"arch_variant\")"`
217 Avx interface{} `blueprint:"filter(android:\"arch_variant\")"`
218 Popcnt interface{} `blueprint:"filter(android:\"arch_variant\")"`
Colin Cross85a88972015-11-23 13:29:51 -0800219 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800220 }
Colin Crossec193632015-07-06 17:49:43 -0700221
Colin Cross7d5136f2015-05-11 13:39:40 -0700222 // Properties to vary by 32-bit or 64-bit
Colin Cross3f40fa42015-01-30 17:27:36 -0800223 Multilib struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700224 // Properties for module variants being built to run on 32-bit devices
225 Lib32 interface{} `blueprint:"filter(android:\"arch_variant\")"`
226 // Properties for module variants being built to run on 64-bit devices
227 Lib64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800228 }
Colin Cross7d5136f2015-05-11 13:39:40 -0700229 // Properties to vary by build target (host or device, os, os+archictecture)
Colin Cross3f40fa42015-01-30 17:27:36 -0800230 Target struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700231 // Properties for module variants being built to run on the host
232 Host interface{} `blueprint:"filter(android:\"arch_variant\")"`
233 // Properties for module variants being built to run on the device
234 Android interface{} `blueprint:"filter(android:\"arch_variant\")"`
235 // Properties for module variants being built to run on arm devices
236 Android_arm interface{} `blueprint:"filter(android:\"arch_variant\")"`
237 // Properties for module variants being built to run on arm64 devices
238 Android_arm64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
239 // Properties for module variants being built to run on mips devices
240 Android_mips interface{} `blueprint:"filter(android:\"arch_variant\")"`
241 // Properties for module variants being built to run on mips64 devices
242 Android_mips64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
243 // Properties for module variants being built to run on x86 devices
244 Android_x86 interface{} `blueprint:"filter(android:\"arch_variant\")"`
245 // Properties for module variants being built to run on x86_64 devices
246 Android_x86_64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
247 // Properties for module variants being built to run on devices that support 64-bit
248 Android64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
249 // Properties for module variants being built to run on devices that do not support 64-bit
250 Android32 interface{} `blueprint:"filter(android:\"arch_variant\")"`
251 // Properties for module variants being built to run on linux hosts
252 Linux interface{} `blueprint:"filter(android:\"arch_variant\")"`
253 // Properties for module variants being built to run on linux x86 hosts
254 Linux_x86 interface{} `blueprint:"filter(android:\"arch_variant\")"`
255 // Properties for module variants being built to run on linux x86_64 hosts
256 Linux_x86_64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
257 // Properties for module variants being built to run on darwin hosts
258 Darwin interface{} `blueprint:"filter(android:\"arch_variant\")"`
259 // Properties for module variants being built to run on darwin x86 hosts
260 Darwin_x86 interface{} `blueprint:"filter(android:\"arch_variant\")"`
261 // Properties for module variants being built to run on darwin x86_64 hosts
262 Darwin_x86_64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
263 // Properties for module variants being built to run on windows hosts
264 Windows interface{} `blueprint:"filter(android:\"arch_variant\")"`
Dan Willemsen490fd492015-11-24 17:53:15 -0800265 // Properties for module variants being built to run on windows x86 hosts
266 Windows_x86 interface{} `blueprint:"filter(android:\"arch_variant\")"`
Dan Willemsen07cd0512016-02-03 23:16:33 -0800267 // Properties for module variants being built to run on windows x86_64 hosts
268 Windows_x86_64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700269 // Properties for module variants being built to run on linux or darwin hosts
270 Not_windows interface{} `blueprint:"filter(android:\"arch_variant\")"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800271 }
272}
273
Colin Crossc5c24ad2015-11-20 15:35:00 -0800274var archFeatureMap = map[ArchType]map[string][]string{}
275
276func RegisterArchFeatures(arch ArchType, variant string, features ...string) {
Colin Cross85a88972015-11-23 13:29:51 -0800277 archField := proptools.FieldNameForProperty(arch.Name)
278 variantField := proptools.FieldNameForProperty(variant)
279 archStruct := reflect.ValueOf(archProperties{}.Arch).FieldByName(archField)
Colin Crossc5c24ad2015-11-20 15:35:00 -0800280 if variant != "" {
Colin Cross85a88972015-11-23 13:29:51 -0800281 if !archStruct.FieldByName(variantField).IsValid() {
Colin Crossc5c24ad2015-11-20 15:35:00 -0800282 panic(fmt.Errorf("Invalid variant %q for arch %q", variant, arch))
283 }
284 }
285 for _, feature := range features {
286 field := proptools.FieldNameForProperty(feature)
Colin Cross85a88972015-11-23 13:29:51 -0800287 if !archStruct.FieldByName(field).IsValid() {
Colin Crossc5c24ad2015-11-20 15:35:00 -0800288 panic(fmt.Errorf("Invalid feature %q for arch %q variant %q", feature, arch, variant))
289 }
290 }
291 if archFeatureMap[arch] == nil {
292 archFeatureMap[arch] = make(map[string][]string)
293 }
294 archFeatureMap[arch][variant] = features
295}
296
Colin Cross3f40fa42015-01-30 17:27:36 -0800297// An Arch indicates a single CPU architecture.
298type Arch struct {
Colin Crossc5c24ad2015-11-20 15:35:00 -0800299 ArchType ArchType
300 ArchVariant string
301 CpuVariant string
302 Abi []string
303 ArchFeatures []string
Dan Willemsen17f05262016-05-31 16:27:00 -0700304 Native bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800305}
306
307func (a Arch) String() string {
Colin Crossd3ba0392015-05-07 14:11:29 -0700308 s := a.ArchType.String()
Colin Cross3f40fa42015-01-30 17:27:36 -0800309 if a.ArchVariant != "" {
310 s += "_" + a.ArchVariant
311 }
312 if a.CpuVariant != "" {
313 s += "_" + a.CpuVariant
314 }
315 return s
316}
317
318type ArchType struct {
Colin Crossec193632015-07-06 17:49:43 -0700319 Name string
320 Multilib string
Colin Cross3f40fa42015-01-30 17:27:36 -0800321}
322
Colin Crossec193632015-07-06 17:49:43 -0700323func newArch(name, multilib string) ArchType {
Colin Cross3f40fa42015-01-30 17:27:36 -0800324 return ArchType{
Colin Crossec193632015-07-06 17:49:43 -0700325 Name: name,
326 Multilib: multilib,
Colin Cross3f40fa42015-01-30 17:27:36 -0800327 }
328}
329
330func (a ArchType) String() string {
331 return a.Name
332}
333
Colin Crossa1ad8d12016-06-01 17:09:44 -0700334var BuildOs = func() OsType {
Dan Willemsen490fd492015-11-24 17:53:15 -0800335 switch runtime.GOOS {
336 case "linux":
337 return Linux
338 case "darwin":
339 return Darwin
340 default:
341 panic(fmt.Sprintf("unsupported OS: %s", runtime.GOOS))
342 }
Colin Crossa1ad8d12016-06-01 17:09:44 -0700343}()
344
345var (
346 osTypeList []OsType
347
348 NoOsType OsType
349 Linux = NewOsType("linux", Host)
350 Darwin = NewOsType("darwin", Host)
351 Windows = NewOsType("windows", HostCross)
352 Android = NewOsType("android", Device)
353)
354
355type OsType struct {
356 Name, Field string
357 Class OsClass
Dan Willemsen490fd492015-11-24 17:53:15 -0800358}
359
Colin Crossa1ad8d12016-06-01 17:09:44 -0700360type OsClass int
361
362const (
363 Device OsClass = iota
364 Host
365 HostCross
366)
367
368func (os OsType) String() string {
369 return os.Name
Colin Cross54c71122016-06-01 17:09:44 -0700370}
371
Colin Crossa1ad8d12016-06-01 17:09:44 -0700372func NewOsType(name string, class OsClass) OsType {
373 os := OsType{
374 Name: name,
375 Field: strings.Title(name),
376 Class: class,
Colin Cross54c71122016-06-01 17:09:44 -0700377 }
Colin Crossa1ad8d12016-06-01 17:09:44 -0700378 osTypeList = append(osTypeList, os)
379 return os
380}
381
382func osByName(name string) OsType {
383 for _, os := range osTypeList {
384 if os.Name == name {
385 return os
386 }
387 }
388
389 return NoOsType
Dan Willemsen490fd492015-11-24 17:53:15 -0800390}
391
Colin Cross3f40fa42015-01-30 17:27:36 -0800392var (
Colin Crossa1ad8d12016-06-01 17:09:44 -0700393 commonTarget = Target{
394 Os: Android,
395 Arch: Arch{
396 ArchType: Common,
397 },
Colin Cross2fe66872015-03-30 17:20:39 -0700398 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800399)
400
Colin Crossa1ad8d12016-06-01 17:09:44 -0700401type Target struct {
402 Os OsType
403 Arch Arch
Colin Crossd3ba0392015-05-07 14:11:29 -0700404}
405
Colin Crossa1ad8d12016-06-01 17:09:44 -0700406func (target Target) String() string {
407 return target.Os.String() + "_" + target.Arch.String()
Dan Willemsen490fd492015-11-24 17:53:15 -0800408}
409
Colin Cross635c3b02016-05-18 15:37:25 -0700410func ArchMutator(mctx BottomUpMutatorContext) {
411 var module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800412 var ok bool
Colin Cross635c3b02016-05-18 15:37:25 -0700413 if module, ok = mctx.Module().(Module); !ok {
Colin Cross3f40fa42015-01-30 17:27:36 -0800414 return
415 }
416
Colin Crossa1ad8d12016-06-01 17:09:44 -0700417 osClasses := module.base().OsClassSupported()
Colin Cross3f40fa42015-01-30 17:27:36 -0800418
Colin Crossa1ad8d12016-06-01 17:09:44 -0700419 if len(osClasses) == 0 {
Colin Crossb9db4802016-06-03 01:50:47 +0000420 return
421 }
422
Colin Crossa1ad8d12016-06-01 17:09:44 -0700423 var moduleTargets []Target
424
425 for _, class := range osClasses {
426 targets := mctx.AConfig().Targets[class]
427 if len(targets) == 0 {
428 continue
429 }
430 multilib := module.base().commonProperties.Compile_multilib
431 targets, err := decodeMultilib(multilib, targets)
432 if err != nil {
433 mctx.ModuleErrorf("%s", err.Error())
434 }
435 moduleTargets = append(moduleTargets, targets...)
Colin Crossb9db4802016-06-03 01:50:47 +0000436 }
437
Dan Willemsen3f32f032016-07-11 14:36:48 -0700438 if len(moduleTargets) == 0 {
439 module.base().commonProperties.Enabled = boolPtr(false)
440 return
441 }
442
Colin Crossa1ad8d12016-06-01 17:09:44 -0700443 targetNames := make([]string, len(moduleTargets))
Colin Crossb9db4802016-06-03 01:50:47 +0000444
Colin Crossa1ad8d12016-06-01 17:09:44 -0700445 for i, target := range moduleTargets {
446 targetNames[i] = target.String()
447 }
448
449 modules := mctx.CreateVariations(targetNames...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800450 for i, m := range modules {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700451 m.(Module).base().SetTarget(moduleTargets[i])
Colin Cross635c3b02016-05-18 15:37:25 -0700452 m.(Module).base().setArchProperties(mctx)
Colin Cross3f40fa42015-01-30 17:27:36 -0800453 }
454}
455
Colin Cross635c3b02016-05-18 15:37:25 -0700456func InitArchModule(m Module,
Colin Cross3f40fa42015-01-30 17:27:36 -0800457 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
458
459 base := m.base()
460
Colin Cross3f40fa42015-01-30 17:27:36 -0800461 base.generalProperties = append(base.generalProperties,
Colin Cross3f40fa42015-01-30 17:27:36 -0800462 propertyStructs...)
463
464 for _, properties := range base.generalProperties {
465 propertiesValue := reflect.ValueOf(properties)
Colin Cross62496a02016-08-08 15:49:17 -0700466 t := propertiesValue.Type()
Colin Cross3f40fa42015-01-30 17:27:36 -0800467 if propertiesValue.Kind() != reflect.Ptr {
Colin Crossca860ac2016-01-04 14:34:37 -0800468 panic(fmt.Errorf("properties must be a pointer to a struct, got %T",
469 propertiesValue.Interface()))
Colin Cross3f40fa42015-01-30 17:27:36 -0800470 }
471
472 propertiesValue = propertiesValue.Elem()
473 if propertiesValue.Kind() != reflect.Struct {
Colin Crossca860ac2016-01-04 14:34:37 -0800474 panic(fmt.Errorf("properties must be a pointer to a struct, got %T",
475 propertiesValue.Interface()))
Colin Cross3f40fa42015-01-30 17:27:36 -0800476 }
477
478 archProperties := &archProperties{}
479 forEachInterface(reflect.ValueOf(archProperties), func(v reflect.Value) {
Colin Cross62496a02016-08-08 15:49:17 -0700480 newValue := reflect.Zero(t)
Colin Cross3f40fa42015-01-30 17:27:36 -0800481 v.Set(newValue)
482 })
483
484 base.archProperties = append(base.archProperties, archProperties)
485 }
486
487 var allProperties []interface{}
488 allProperties = append(allProperties, base.generalProperties...)
489 for _, asp := range base.archProperties {
490 allProperties = append(allProperties, asp)
491 }
492
493 return m, allProperties
494}
495
Colin Crossa716add2015-12-16 11:07:39 -0800496var variantReplacer = strings.NewReplacer("-", "_", ".", "_")
Colin Crossec193632015-07-06 17:49:43 -0700497
Colin Cross635c3b02016-05-18 15:37:25 -0700498func (a *ModuleBase) appendProperties(ctx BottomUpMutatorContext,
Colin Cross85a88972015-11-23 13:29:51 -0800499 dst, src interface{}, field, srcPrefix string) interface{} {
Colin Cross06a931b2015-10-28 17:23:31 -0700500
Colin Crosseeabb892015-11-20 13:07:51 -0800501 srcField := reflect.ValueOf(src).FieldByName(field)
502 if !srcField.IsValid() {
503 ctx.ModuleErrorf("field %q does not exist", srcPrefix)
Colin Cross85a88972015-11-23 13:29:51 -0800504 return nil
505 }
506
507 ret := srcField
508
509 if srcField.Kind() == reflect.Struct {
510 srcField = srcField.FieldByName("Embed")
Colin Crosseeabb892015-11-20 13:07:51 -0800511 }
512
513 src = srcField.Elem().Interface()
Colin Cross06a931b2015-10-28 17:23:31 -0700514
515 filter := func(property string,
516 dstField, srcField reflect.StructField,
517 dstValue, srcValue interface{}) (bool, error) {
518
519 srcProperty := srcPrefix + "." + property
520
521 if !proptools.HasTag(dstField, "android", "arch_variant") {
522 if ctx.ContainsProperty(srcProperty) {
523 return false, fmt.Errorf("can't be specific to a build variant")
524 } else {
525 return false, nil
526 }
527 }
528
529 return true, nil
530 }
531
Colin Cross6ee75b62016-05-05 15:57:15 -0700532 order := func(property string,
533 dstField, srcField reflect.StructField,
534 dstValue, srcValue interface{}) (proptools.Order, error) {
535 if proptools.HasTag(dstField, "android", "variant_prepend") {
536 return proptools.Prepend, nil
537 } else {
538 return proptools.Append, nil
539 }
540 }
541
542 err := proptools.ExtendProperties(dst, src, filter, order)
Colin Cross06a931b2015-10-28 17:23:31 -0700543 if err != nil {
544 if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok {
545 ctx.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error())
546 } else {
547 panic(err)
548 }
549 }
Colin Cross85a88972015-11-23 13:29:51 -0800550
551 return ret.Interface()
Colin Cross06a931b2015-10-28 17:23:31 -0700552}
553
Colin Cross3f40fa42015-01-30 17:27:36 -0800554// Rewrite the module's properties structs to contain arch-specific values.
Colin Cross635c3b02016-05-18 15:37:25 -0700555func (a *ModuleBase) setArchProperties(ctx BottomUpMutatorContext) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700556 arch := a.Arch()
557 os := a.Os()
Colin Crossd3ba0392015-05-07 14:11:29 -0700558
Colin Cross2fe66872015-03-30 17:20:39 -0700559 if arch.ArchType == Common {
560 return
561 }
562
Colin Cross3f40fa42015-01-30 17:27:36 -0800563 for i := range a.generalProperties {
Colin Cross06a931b2015-10-28 17:23:31 -0700564 genProps := a.generalProperties[i]
565 archProps := a.archProperties[i]
Colin Cross3f40fa42015-01-30 17:27:36 -0800566 // Handle arch-specific properties in the form:
Colin Crossb05bff22015-04-30 15:08:04 -0700567 // arch: {
568 // arm64: {
Colin Cross3f40fa42015-01-30 17:27:36 -0800569 // key: value,
570 // },
571 // },
572 t := arch.ArchType
Colin Cross06a931b2015-10-28 17:23:31 -0700573
Colin Crossec193632015-07-06 17:49:43 -0700574 field := proptools.FieldNameForProperty(t.Name)
Colin Cross06a931b2015-10-28 17:23:31 -0700575 prefix := "arch." + t.Name
Colin Cross85a88972015-11-23 13:29:51 -0800576 archStruct := a.appendProperties(ctx, genProps, archProps.Arch, field, prefix)
Colin Crossec193632015-07-06 17:49:43 -0700577
578 // Handle arch-variant-specific properties in the form:
579 // arch: {
580 // variant: {
581 // key: value,
582 // },
583 // },
Colin Crossa716add2015-12-16 11:07:39 -0800584 v := variantReplacer.Replace(arch.ArchVariant)
Colin Crossec193632015-07-06 17:49:43 -0700585 if v != "" {
586 field := proptools.FieldNameForProperty(v)
Colin Cross85a88972015-11-23 13:29:51 -0800587 prefix := "arch." + t.Name + "." + v
588 a.appendProperties(ctx, genProps, archStruct, field, prefix)
Colin Crossec193632015-07-06 17:49:43 -0700589 }
590
591 // Handle cpu-variant-specific properties in the form:
592 // arch: {
593 // variant: {
594 // key: value,
595 // },
596 // },
Colin Crossa716add2015-12-16 11:07:39 -0800597 c := variantReplacer.Replace(arch.CpuVariant)
Colin Crossec193632015-07-06 17:49:43 -0700598 if c != "" {
599 field := proptools.FieldNameForProperty(c)
Colin Cross85a88972015-11-23 13:29:51 -0800600 prefix := "arch." + t.Name + "." + c
601 a.appendProperties(ctx, genProps, archStruct, field, prefix)
Colin Crossec193632015-07-06 17:49:43 -0700602 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800603
Colin Crossc5c24ad2015-11-20 15:35:00 -0800604 // Handle arch-feature-specific properties in the form:
605 // arch: {
606 // feature: {
607 // key: value,
608 // },
609 // },
610 for _, feature := range arch.ArchFeatures {
611 field := proptools.FieldNameForProperty(feature)
Colin Cross85a88972015-11-23 13:29:51 -0800612 prefix := "arch." + t.Name + "." + feature
613 a.appendProperties(ctx, genProps, archStruct, field, prefix)
Colin Crossc5c24ad2015-11-20 15:35:00 -0800614 }
615
Colin Cross3f40fa42015-01-30 17:27:36 -0800616 // Handle multilib-specific properties in the form:
Colin Crossb05bff22015-04-30 15:08:04 -0700617 // multilib: {
618 // lib32: {
Colin Cross3f40fa42015-01-30 17:27:36 -0800619 // key: value,
620 // },
621 // },
Colin Cross06a931b2015-10-28 17:23:31 -0700622 field = proptools.FieldNameForProperty(t.Multilib)
623 prefix = "multilib." + t.Multilib
624 a.appendProperties(ctx, genProps, archProps.Multilib, field, prefix)
Colin Cross3f40fa42015-01-30 17:27:36 -0800625
Colin Crossa1ad8d12016-06-01 17:09:44 -0700626 // Handle host-specific properties in the form:
Colin Crossb05bff22015-04-30 15:08:04 -0700627 // target: {
628 // host: {
Colin Cross3f40fa42015-01-30 17:27:36 -0800629 // key: value,
630 // },
631 // },
Colin Crossa1ad8d12016-06-01 17:09:44 -0700632 if os.Class == Host || os.Class == HostCross {
633 field = "Host"
634 prefix = "target.host"
635 a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
636 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800637
Colin Crossa1ad8d12016-06-01 17:09:44 -0700638 // Handle target OS properties in the form:
Colin Crossb05bff22015-04-30 15:08:04 -0700639 // target: {
640 // linux: {
Colin Cross3f40fa42015-01-30 17:27:36 -0800641 // key: value,
642 // },
Colin Crossb05bff22015-04-30 15:08:04 -0700643 // not_windows: {
644 // key: value,
645 // },
646 // linux_x86: {
647 // key: value,
648 // },
649 // linux_arm: {
Colin Cross3f40fa42015-01-30 17:27:36 -0800650 // key: value,
651 // },
Colin Crossa1ad8d12016-06-01 17:09:44 -0700652 // android {
653 // key: value,
654 // },
655 // android_arm {
656 // key: value,
657 // },
658 // android_x86 {
659 // key: value,
660 // },
Colin Cross3f40fa42015-01-30 17:27:36 -0800661 // },
Colin Crossa1ad8d12016-06-01 17:09:44 -0700662 // },
663 field = os.Field
664 prefix = "target." + os.Name
665 a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
Colin Crossb9db4802016-06-03 01:50:47 +0000666
Colin Crossa1ad8d12016-06-01 17:09:44 -0700667 field = os.Field + "_" + t.Name
668 prefix = "target." + os.Name + "_" + t.Name
669 a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
Colin Crossb9db4802016-06-03 01:50:47 +0000670
Colin Crossa1ad8d12016-06-01 17:09:44 -0700671 if (os.Class == Host || os.Class == HostCross) && os != Windows {
672 field := "Not_windows"
673 prefix := "target.not_windows"
674 a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
Colin Cross3f40fa42015-01-30 17:27:36 -0800675 }
676
Colin Crossf8209412015-03-26 14:44:26 -0700677 // Handle 64-bit device properties in the form:
678 // target {
679 // android64 {
680 // key: value,
681 // },
682 // android32 {
683 // key: value,
684 // },
685 // },
686 // WARNING: this is probably not what you want to use in your blueprints file, it selects
687 // options for all targets on a device that supports 64-bit binaries, not just the targets
688 // that are being compiled for 64-bit. Its expected use case is binaries like linker and
689 // debuggerd that need to know when they are a 32-bit process running on a 64-bit device
Colin Crossa1ad8d12016-06-01 17:09:44 -0700690 if os.Class == Device {
691 if ctx.AConfig().Android64() {
Colin Cross06a931b2015-10-28 17:23:31 -0700692 field := "Android64"
693 prefix := "target.android64"
694 a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
Colin Crossf8209412015-03-26 14:44:26 -0700695 } else {
Colin Cross06a931b2015-10-28 17:23:31 -0700696 field := "Android32"
697 prefix := "target.android32"
698 a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
Colin Crossf8209412015-03-26 14:44:26 -0700699 }
700 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800701 }
702}
703
704func forEachInterface(v reflect.Value, f func(reflect.Value)) {
705 switch v.Kind() {
706 case reflect.Interface:
707 f(v)
708 case reflect.Struct:
709 for i := 0; i < v.NumField(); i++ {
710 forEachInterface(v.Field(i), f)
711 }
712 case reflect.Ptr:
713 forEachInterface(v.Elem(), f)
714 default:
715 panic(fmt.Errorf("Unsupported kind %s", v.Kind()))
716 }
717}
Colin Cross4225f652015-09-17 14:33:42 -0700718
Colin Crossa1ad8d12016-06-01 17:09:44 -0700719// Convert the arch product variables into a list of targets for each os class structs
Colin Cross9272ade2016-08-17 15:24:12 -0700720func decodeTargetProductVariables(config *config) (map[OsClass][]Target, error) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700721 variables := config.ProductVariables
Dan Willemsen490fd492015-11-24 17:53:15 -0800722
Colin Crossa1ad8d12016-06-01 17:09:44 -0700723 targets := make(map[OsClass][]Target)
724 var targetErr error
725
726 addTarget := func(os OsType, archName string, archVariant, cpuVariant *string, abi *[]string) {
727 if targetErr != nil {
728 return
Dan Willemsen490fd492015-11-24 17:53:15 -0800729 }
Colin Crossa1ad8d12016-06-01 17:09:44 -0700730
731 arch, err := decodeArch(archName, archVariant, cpuVariant, abi)
732 if err != nil {
733 targetErr = err
734 return
735 }
736
737 targets[os.Class] = append(targets[os.Class],
738 Target{
739 Os: os,
740 Arch: arch,
741 })
Dan Willemsen490fd492015-11-24 17:53:15 -0800742 }
743
Colin Cross4225f652015-09-17 14:33:42 -0700744 if variables.HostArch == nil {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700745 return nil, fmt.Errorf("No host primary architecture set")
Colin Cross4225f652015-09-17 14:33:42 -0700746 }
747
Colin Crossa1ad8d12016-06-01 17:09:44 -0700748 addTarget(BuildOs, *variables.HostArch, nil, nil, nil)
Colin Cross4225f652015-09-17 14:33:42 -0700749
Colin Crosseeabb892015-11-20 13:07:51 -0800750 if variables.HostSecondaryArch != nil && *variables.HostSecondaryArch != "" {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700751 addTarget(BuildOs, *variables.HostSecondaryArch, nil, nil, nil)
Dan Willemsen490fd492015-11-24 17:53:15 -0800752 }
753
754 if variables.CrossHost != nil && *variables.CrossHost != "" {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700755 crossHostOs := osByName(*variables.CrossHost)
756 if crossHostOs == NoOsType {
757 return nil, fmt.Errorf("Unknown cross host OS %q", *variables.CrossHost)
758 }
759
Dan Willemsen490fd492015-11-24 17:53:15 -0800760 if variables.CrossHostArch == nil || *variables.CrossHostArch == "" {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700761 return nil, fmt.Errorf("No cross-host primary architecture set")
Dan Willemsen490fd492015-11-24 17:53:15 -0800762 }
763
Colin Crossa1ad8d12016-06-01 17:09:44 -0700764 addTarget(crossHostOs, *variables.CrossHostArch, nil, nil, nil)
Dan Willemsen490fd492015-11-24 17:53:15 -0800765
766 if variables.CrossHostSecondaryArch != nil && *variables.CrossHostSecondaryArch != "" {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700767 addTarget(crossHostOs, *variables.CrossHostSecondaryArch, nil, nil, nil)
Dan Willemsen490fd492015-11-24 17:53:15 -0800768 }
769 }
770
Dan Willemsen3f32f032016-07-11 14:36:48 -0700771 if variables.DeviceArch != nil && *variables.DeviceArch != "" {
772 addTarget(Android, *variables.DeviceArch, variables.DeviceArchVariant,
773 variables.DeviceCpuVariant, variables.DeviceAbi)
Colin Cross4225f652015-09-17 14:33:42 -0700774
Dan Willemsen3f32f032016-07-11 14:36:48 -0700775 if variables.DeviceSecondaryArch != nil && *variables.DeviceSecondaryArch != "" {
776 addTarget(Android, *variables.DeviceSecondaryArch,
777 variables.DeviceSecondaryArchVariant, variables.DeviceSecondaryCpuVariant,
778 variables.DeviceSecondaryAbi)
Colin Cross4225f652015-09-17 14:33:42 -0700779
Dan Willemsen3f32f032016-07-11 14:36:48 -0700780 deviceArches := targets[Device]
781 if deviceArches[0].Arch.ArchType.Multilib == deviceArches[1].Arch.ArchType.Multilib {
782 deviceArches[1].Arch.Native = false
783 }
Colin Cross4225f652015-09-17 14:33:42 -0700784 }
Colin Cross4225f652015-09-17 14:33:42 -0700785 }
786
Colin Crossa1ad8d12016-06-01 17:09:44 -0700787 if targetErr != nil {
788 return nil, targetErr
789 }
790
791 return targets, nil
Colin Cross4225f652015-09-17 14:33:42 -0700792}
793
Colin Crossa1ad8d12016-06-01 17:09:44 -0700794func decodeMegaDevice() ([]Target, error) {
Dan Willemsen322acaf2016-01-12 23:07:05 -0800795 archSettings := []struct {
796 arch string
797 archVariant string
798 cpuVariant string
799 abi []string
800 }{
Dan Willemsen110a89d2016-01-14 15:17:19 -0800801 // armv5 is only used for unbundled apps
802 //{"arm", "armv5te", "", []string{"armeabi"}},
803 {"arm", "armv7-a", "generic", []string{"armeabi-v7a"}},
804 {"arm", "armv7-a-neon", "generic", []string{"armeabi-v7a"}},
Dan Willemsen322acaf2016-01-12 23:07:05 -0800805 {"arm", "armv7-a-neon", "cortex-a7", []string{"armeabi-v7a"}},
806 {"arm", "armv7-a-neon", "cortex-a8", []string{"armeabi-v7a"}},
Dan Willemsen110a89d2016-01-14 15:17:19 -0800807 {"arm", "armv7-a-neon", "cortex-a9", []string{"armeabi-v7a"}},
Dan Willemsen322acaf2016-01-12 23:07:05 -0800808 {"arm", "armv7-a-neon", "cortex-a15", []string{"armeabi-v7a"}},
809 {"arm", "armv7-a-neon", "cortex-a53", []string{"armeabi-v7a"}},
810 {"arm", "armv7-a-neon", "cortex-a53.a57", []string{"armeabi-v7a"}},
811 {"arm", "armv7-a-neon", "denver", []string{"armeabi-v7a"}},
812 {"arm", "armv7-a-neon", "krait", []string{"armeabi-v7a"}},
Dan Willemsen110a89d2016-01-14 15:17:19 -0800813 {"arm64", "armv8-a", "cortex-a53", []string{"arm64-v8a"}},
814 {"arm64", "armv8-a", "denver64", []string{"arm64-v8a"}},
Dan Willemsen468cc312016-01-13 23:25:19 -0800815 {"mips", "mips32-fp", "", []string{"mips"}},
816 {"mips", "mips32r2-fp", "", []string{"mips"}},
817 {"mips", "mips32r2-fp-xburst", "", []string{"mips"}},
Dan Willemsen65fb9812016-07-19 21:37:28 -0700818 //{"mips", "mips32r6", "", []string{"mips"}},
Dan Willemsen468cc312016-01-13 23:25:19 -0800819 // mips32r2dsp[r2]-fp fails in the assembler for divdf3.c in compiler-rt:
820 // (same errors in make and soong)
821 // Error: invalid operands `mtlo $ac0,$11'
822 // Error: invalid operands `mthi $ac0,$12'
Dan Willemsen322acaf2016-01-12 23:07:05 -0800823 //{"mips", "mips32r2dsp-fp", "", []string{"mips"}},
824 //{"mips", "mips32r2dspr2-fp", "", []string{"mips"}},
825 // mips64r2 is mismatching 64r2 and 64r6 libraries during linking to libgcc
826 //{"mips64", "mips64r2", "", []string{"mips64"}},
827 {"mips64", "mips64r6", "", []string{"mips64"}},
828 {"x86", "", "", []string{"x86"}},
829 {"x86", "atom", "", []string{"x86"}},
830 {"x86", "haswell", "", []string{"x86"}},
831 {"x86", "ivybridge", "", []string{"x86"}},
832 {"x86", "sandybridge", "", []string{"x86"}},
833 {"x86", "silvermont", "", []string{"x86"}},
Dan Willemsen8a354052016-05-10 14:30:51 -0700834 {"x86", "x86_64", "", []string{"x86"}},
Dan Willemsen322acaf2016-01-12 23:07:05 -0800835 {"x86_64", "", "", []string{"x86_64"}},
836 {"x86_64", "haswell", "", []string{"x86_64"}},
837 {"x86_64", "ivybridge", "", []string{"x86_64"}},
838 {"x86_64", "sandybridge", "", []string{"x86_64"}},
839 {"x86_64", "silvermont", "", []string{"x86_64"}},
840 }
841
Colin Crossa1ad8d12016-06-01 17:09:44 -0700842 var ret []Target
Dan Willemsen322acaf2016-01-12 23:07:05 -0800843
844 for _, config := range archSettings {
845 arch, err := decodeArch(config.arch, &config.archVariant,
846 &config.cpuVariant, &config.abi)
847 if err != nil {
848 return nil, err
849 }
Dan Willemsen17f05262016-05-31 16:27:00 -0700850 arch.Native = false
Colin Crossa1ad8d12016-06-01 17:09:44 -0700851 ret = append(ret, Target{
852 Os: Android,
853 Arch: arch,
854 })
Dan Willemsen322acaf2016-01-12 23:07:05 -0800855 }
856
857 return ret, nil
858}
859
Colin Cross4225f652015-09-17 14:33:42 -0700860// Convert a set of strings from product variables into a single Arch struct
861func decodeArch(arch string, archVariant, cpuVariant *string, abi *[]string) (Arch, error) {
862 stringPtr := func(p *string) string {
863 if p != nil {
864 return *p
865 }
866 return ""
867 }
868
869 slicePtr := func(p *[]string) []string {
870 if p != nil {
871 return *p
872 }
873 return nil
874 }
875
Colin Crosseeabb892015-11-20 13:07:51 -0800876 archType, ok := archTypeMap[arch]
877 if !ok {
878 return Arch{}, fmt.Errorf("unknown arch %q", arch)
879 }
Colin Cross4225f652015-09-17 14:33:42 -0700880
Colin Crosseeabb892015-11-20 13:07:51 -0800881 a := Arch{
Colin Cross4225f652015-09-17 14:33:42 -0700882 ArchType: archType,
883 ArchVariant: stringPtr(archVariant),
884 CpuVariant: stringPtr(cpuVariant),
885 Abi: slicePtr(abi),
Dan Willemsen17f05262016-05-31 16:27:00 -0700886 Native: true,
Colin Crosseeabb892015-11-20 13:07:51 -0800887 }
888
889 if a.ArchVariant == a.ArchType.Name || a.ArchVariant == "generic" {
890 a.ArchVariant = ""
891 }
892
893 if a.CpuVariant == a.ArchType.Name || a.CpuVariant == "generic" {
894 a.CpuVariant = ""
895 }
896
897 for i := 0; i < len(a.Abi); i++ {
898 if a.Abi[i] == "" {
899 a.Abi = append(a.Abi[:i], a.Abi[i+1:]...)
900 i--
901 }
902 }
903
Colin Crossc5c24ad2015-11-20 15:35:00 -0800904 if featureMap, ok := archFeatureMap[archType]; ok {
Dan Willemsenb4850992016-05-06 17:21:20 -0700905 a.ArchFeatures = featureMap[a.ArchVariant]
Colin Crossc5c24ad2015-11-20 15:35:00 -0800906 }
907
Colin Crosseeabb892015-11-20 13:07:51 -0800908 return a, nil
Colin Cross4225f652015-09-17 14:33:42 -0700909}
910
Colin Crossa1ad8d12016-06-01 17:09:44 -0700911// Use the module multilib setting to select one or more targets from a target list
912func decodeMultilib(multilib string, targets []Target) ([]Target, error) {
913 buildTargets := []Target{}
Colin Cross4225f652015-09-17 14:33:42 -0700914 switch multilib {
915 case "common":
Colin Crossa1ad8d12016-06-01 17:09:44 -0700916 buildTargets = append(buildTargets, commonTarget)
Colin Cross4225f652015-09-17 14:33:42 -0700917 case "both":
Colin Crossa1ad8d12016-06-01 17:09:44 -0700918 buildTargets = append(buildTargets, targets...)
Colin Cross4225f652015-09-17 14:33:42 -0700919 case "first":
Colin Crossa1ad8d12016-06-01 17:09:44 -0700920 buildTargets = append(buildTargets, targets[0])
Colin Cross4225f652015-09-17 14:33:42 -0700921 case "32":
Colin Crossa1ad8d12016-06-01 17:09:44 -0700922 for _, t := range targets {
923 if t.Arch.ArchType.Multilib == "lib32" {
924 buildTargets = append(buildTargets, t)
Colin Cross4225f652015-09-17 14:33:42 -0700925 }
926 }
927 case "64":
Colin Crossa1ad8d12016-06-01 17:09:44 -0700928 for _, t := range targets {
929 if t.Arch.ArchType.Multilib == "lib64" {
930 buildTargets = append(buildTargets, t)
Colin Cross4225f652015-09-17 14:33:42 -0700931 }
932 }
933 default:
934 return nil, fmt.Errorf(`compile_multilib must be "both", "first", "32", or "64", found %q`,
935 multilib)
Colin Cross4225f652015-09-17 14:33:42 -0700936 }
937
Colin Crossa1ad8d12016-06-01 17:09:44 -0700938 return buildTargets, nil
Colin Cross4225f652015-09-17 14:33:42 -0700939}