blob: 4f7ffb4ade701c1419bdb5b741677cfa9e7a2b9a [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
27var (
Colin Crossec193632015-07-06 17:49:43 -070028 Arm = newArch("arm", "lib32")
29 Arm64 = newArch("arm64", "lib64")
30 Mips = newArch("mips", "lib32")
31 Mips64 = newArch("mips64", "lib64")
32 X86 = newArch("x86", "lib32")
33 X86_64 = newArch("x86_64", "lib64")
Colin Cross2fe66872015-03-30 17:20:39 -070034
35 Common = ArchType{
36 Name: "common",
37 }
Colin Cross3f40fa42015-01-30 17:27:36 -080038)
39
Colin Cross4225f652015-09-17 14:33:42 -070040var archTypeMap = map[string]ArchType{
41 "arm": Arm,
42 "arm64": Arm64,
43 "mips": Mips,
Colin Cross3b336c22015-11-23 16:28:31 -080044 "mips64": Mips64,
Colin Cross4225f652015-09-17 14:33:42 -070045 "x86": X86,
46 "x86_64": X86_64,
47}
48
Colin Cross3f40fa42015-01-30 17:27:36 -080049/*
50Example blueprints file containing all variant property groups, with comment listing what type
51of variants get properties in that group:
52
53module {
54 arch: {
55 arm: {
56 // Host or device variants with arm architecture
57 },
58 arm64: {
59 // Host or device variants with arm64 architecture
60 },
61 mips: {
62 // Host or device variants with mips architecture
63 },
64 mips64: {
65 // Host or device variants with mips64 architecture
66 },
67 x86: {
68 // Host or device variants with x86 architecture
69 },
70 x86_64: {
71 // Host or device variants with x86_64 architecture
72 },
73 },
74 multilib: {
75 lib32: {
76 // Host or device variants for 32-bit architectures
77 },
78 lib64: {
79 // Host or device variants for 64-bit architectures
80 },
81 },
82 target: {
83 android: {
84 // Device variants
85 },
86 host: {
87 // Host variants
88 },
89 linux: {
90 // Linux host variants
91 },
92 darwin: {
93 // Darwin host variants
94 },
95 windows: {
96 // Windows host variants
97 },
98 not_windows: {
99 // Non-windows host variants
100 },
101 },
102}
103*/
Colin Cross7d5136f2015-05-11 13:39:40 -0700104
Colin Cross85a88972015-11-23 13:29:51 -0800105type Embed interface{}
106
Colin Cross3f40fa42015-01-30 17:27:36 -0800107type archProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700108 // Properties to vary by target architecture
Colin Cross3f40fa42015-01-30 17:27:36 -0800109 Arch struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700110 // Properties for module variants being built to run on arm (host or device)
Colin Cross85a88972015-11-23 13:29:51 -0800111 Arm struct {
112 Embed `blueprint:"filter(android:\"arch_variant\")"`
113
114 // Arm arch variants
115 Armv5te interface{} `blueprint:"filter(android:\"arch_variant\")"`
116 Armv7_a interface{} `blueprint:"filter(android:\"arch_variant\")"`
117 Armv7_a_neon interface{} `blueprint:"filter(android:\"arch_variant\")"`
118
119 // Arm cpu variants
120 Cortex_a7 interface{} `blueprint:"filter(android:\"arch_variant\")"`
121 Cortex_a8 interface{} `blueprint:"filter(android:\"arch_variant\")"`
122 Cortex_a9 interface{} `blueprint:"filter(android:\"arch_variant\")"`
123 Cortex_a15 interface{} `blueprint:"filter(android:\"arch_variant\")"`
124 Cortex_a53 interface{} `blueprint:"filter(android:\"arch_variant\")"`
125 Cortex_a53_a57 interface{} `blueprint:"filter(android:\"arch_variant\")"`
126 Krait interface{} `blueprint:"filter(android:\"arch_variant\")"`
127 Denver interface{} `blueprint:"filter(android:\"arch_variant\")"`
128 }
129
Colin Cross7d5136f2015-05-11 13:39:40 -0700130 // Properties for module variants being built to run on arm64 (host or device)
Colin Cross85a88972015-11-23 13:29:51 -0800131 Arm64 struct {
132 Embed `blueprint:"filter(android:\"arch_variant\")"`
133
134 // Arm64 arch variants
135 Armv8_a interface{} `blueprint:"filter(android:\"arch_variant\")"`
136
137 // Arm64 cpu variants
138 Cortex_a53 interface{} `blueprint:"filter(android:\"arch_variant\")"`
139 Denver64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
140 }
141
Colin Cross7d5136f2015-05-11 13:39:40 -0700142 // Properties for module variants being built to run on mips (host or device)
Colin Cross85a88972015-11-23 13:29:51 -0800143 Mips struct {
144 Embed `blueprint:"filter(android:\"arch_variant\")"`
145
146 // Mips arch variants
Colin Cross023f1e82015-11-23 16:15:10 -0800147 Mips32_fp interface{} `blueprint:"filter(android:\"arch_variant\")"`
148 Mips32r2_fp interface{} `blueprint:"filter(android:\"arch_variant\")"`
149 Mips32r2_fp_xburst interface{} `blueprint:"filter(android:\"arch_variant\")"`
150 Mips32r2dsp_fp interface{} `blueprint:"filter(android:\"arch_variant\")"`
151 Mips32r2dspr2_fp interface{} `blueprint:"filter(android:\"arch_variant\")"`
152 Mips32r6 interface{} `blueprint:"filter(android:\"arch_variant\")"`
153
154 // Mips arch features
Colin Cross85a88972015-11-23 13:29:51 -0800155 Rev6 interface{} `blueprint:"filter(android:\"arch_variant\")"`
156 }
157
Colin Cross7d5136f2015-05-11 13:39:40 -0700158 // Properties for module variants being built to run on mips64 (host or device)
Colin Cross85a88972015-11-23 13:29:51 -0800159 Mips64 struct {
160 Embed `blueprint:"filter(android:\"arch_variant\")"`
161
162 // Mips64 arch variants
Colin Cross3b336c22015-11-23 16:28:31 -0800163 Mips64r2 interface{} `blueprint:"filter(android:\"arch_variant\")"`
164 Mips64r6 interface{} `blueprint:"filter(android:\"arch_variant\")"`
165
166 // Mips64 arch features
Colin Cross85a88972015-11-23 13:29:51 -0800167 Rev6 interface{} `blueprint:"filter(android:\"arch_variant\")"`
168 }
169
Colin Cross7d5136f2015-05-11 13:39:40 -0700170 // Properties for module variants being built to run on x86 (host or device)
Colin Cross85a88972015-11-23 13:29:51 -0800171 X86 struct {
172 Embed `blueprint:"filter(android:\"arch_variant\")"`
173
174 // X86 arch variants
Colin Crossb0cba6a2015-11-20 15:35:26 -0800175 Atom interface{} `blueprint:"filter(android:\"arch_variant\")"`
176 Haswell interface{} `blueprint:"filter(android:\"arch_variant\")"`
177 Ivybridge interface{} `blueprint:"filter(android:\"arch_variant\")"`
178 Sandybridge interface{} `blueprint:"filter(android:\"arch_variant\")"`
179 Silvermont interface{} `blueprint:"filter(android:\"arch_variant\")"`
Dan Willemsen8a354052016-05-10 14:30:51 -0700180 // Generic variant for X86 on X86_64
Colin Cross635c3b02016-05-18 15:37:25 -0700181 X86_64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
Colin Cross85a88972015-11-23 13:29:51 -0800182
183 // X86 arch features
Colin Crossb0cba6a2015-11-20 15:35:26 -0800184 Ssse3 interface{} `blueprint:"filter(android:\"arch_variant\")"`
185 Sse4 interface{} `blueprint:"filter(android:\"arch_variant\")"`
186 Sse4_1 interface{} `blueprint:"filter(android:\"arch_variant\")"`
187 Sse4_2 interface{} `blueprint:"filter(android:\"arch_variant\")"`
188 Aes_ni interface{} `blueprint:"filter(android:\"arch_variant\")"`
189 Avx interface{} `blueprint:"filter(android:\"arch_variant\")"`
190 Popcnt interface{} `blueprint:"filter(android:\"arch_variant\")"`
191 Movbe interface{} `blueprint:"filter(android:\"arch_variant\")"`
Colin Cross85a88972015-11-23 13:29:51 -0800192 }
193
Colin Cross7d5136f2015-05-11 13:39:40 -0700194 // Properties for module variants being built to run on x86_64 (host or device)
Colin Cross85a88972015-11-23 13:29:51 -0800195 X86_64 struct {
196 Embed `blueprint:"filter(android:\"arch_variant\")"`
Colin Cross6371b382015-11-23 14:53:57 -0800197
198 // X86 arch variants
199 Haswell interface{} `blueprint:"filter(android:\"arch_variant\")"`
200 Ivybridge interface{} `blueprint:"filter(android:\"arch_variant\")"`
201 Sandybridge interface{} `blueprint:"filter(android:\"arch_variant\")"`
202 Silvermont interface{} `blueprint:"filter(android:\"arch_variant\")"`
203
204 // X86 arch features
205 Ssse3 interface{} `blueprint:"filter(android:\"arch_variant\")"`
206 Sse4 interface{} `blueprint:"filter(android:\"arch_variant\")"`
207 Sse4_1 interface{} `blueprint:"filter(android:\"arch_variant\")"`
208 Sse4_2 interface{} `blueprint:"filter(android:\"arch_variant\")"`
209 Aes_ni interface{} `blueprint:"filter(android:\"arch_variant\")"`
210 Avx interface{} `blueprint:"filter(android:\"arch_variant\")"`
211 Popcnt interface{} `blueprint:"filter(android:\"arch_variant\")"`
Colin Cross85a88972015-11-23 13:29:51 -0800212 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800213 }
Colin Crossec193632015-07-06 17:49:43 -0700214
Colin Cross7d5136f2015-05-11 13:39:40 -0700215 // Properties to vary by 32-bit or 64-bit
Colin Cross3f40fa42015-01-30 17:27:36 -0800216 Multilib struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700217 // Properties for module variants being built to run on 32-bit devices
218 Lib32 interface{} `blueprint:"filter(android:\"arch_variant\")"`
219 // Properties for module variants being built to run on 64-bit devices
220 Lib64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800221 }
Colin Cross7d5136f2015-05-11 13:39:40 -0700222 // Properties to vary by build target (host or device, os, os+archictecture)
Colin Cross3f40fa42015-01-30 17:27:36 -0800223 Target struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700224 // Properties for module variants being built to run on the host
225 Host interface{} `blueprint:"filter(android:\"arch_variant\")"`
226 // Properties for module variants being built to run on the device
227 Android interface{} `blueprint:"filter(android:\"arch_variant\")"`
228 // Properties for module variants being built to run on arm devices
229 Android_arm interface{} `blueprint:"filter(android:\"arch_variant\")"`
230 // Properties for module variants being built to run on arm64 devices
231 Android_arm64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
232 // Properties for module variants being built to run on mips devices
233 Android_mips interface{} `blueprint:"filter(android:\"arch_variant\")"`
234 // Properties for module variants being built to run on mips64 devices
235 Android_mips64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
236 // Properties for module variants being built to run on x86 devices
237 Android_x86 interface{} `blueprint:"filter(android:\"arch_variant\")"`
238 // Properties for module variants being built to run on x86_64 devices
239 Android_x86_64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
240 // Properties for module variants being built to run on devices that support 64-bit
241 Android64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
242 // Properties for module variants being built to run on devices that do not support 64-bit
243 Android32 interface{} `blueprint:"filter(android:\"arch_variant\")"`
244 // Properties for module variants being built to run on linux hosts
245 Linux interface{} `blueprint:"filter(android:\"arch_variant\")"`
246 // Properties for module variants being built to run on linux x86 hosts
247 Linux_x86 interface{} `blueprint:"filter(android:\"arch_variant\")"`
248 // Properties for module variants being built to run on linux x86_64 hosts
249 Linux_x86_64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
250 // Properties for module variants being built to run on darwin hosts
251 Darwin interface{} `blueprint:"filter(android:\"arch_variant\")"`
252 // Properties for module variants being built to run on darwin x86 hosts
253 Darwin_x86 interface{} `blueprint:"filter(android:\"arch_variant\")"`
254 // Properties for module variants being built to run on darwin x86_64 hosts
255 Darwin_x86_64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
256 // Properties for module variants being built to run on windows hosts
257 Windows interface{} `blueprint:"filter(android:\"arch_variant\")"`
Dan Willemsen490fd492015-11-24 17:53:15 -0800258 // Properties for module variants being built to run on windows x86 hosts
259 Windows_x86 interface{} `blueprint:"filter(android:\"arch_variant\")"`
Dan Willemsen07cd0512016-02-03 23:16:33 -0800260 // Properties for module variants being built to run on windows x86_64 hosts
261 Windows_x86_64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
Colin Cross7d5136f2015-05-11 13:39:40 -0700262 // Properties for module variants being built to run on linux or darwin hosts
263 Not_windows interface{} `blueprint:"filter(android:\"arch_variant\")"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800264 }
265}
266
Colin Crossc5c24ad2015-11-20 15:35:00 -0800267var archFeatureMap = map[ArchType]map[string][]string{}
268
269func RegisterArchFeatures(arch ArchType, variant string, features ...string) {
Colin Cross85a88972015-11-23 13:29:51 -0800270 archField := proptools.FieldNameForProperty(arch.Name)
271 variantField := proptools.FieldNameForProperty(variant)
272 archStruct := reflect.ValueOf(archProperties{}.Arch).FieldByName(archField)
Colin Crossc5c24ad2015-11-20 15:35:00 -0800273 if variant != "" {
Colin Cross85a88972015-11-23 13:29:51 -0800274 if !archStruct.FieldByName(variantField).IsValid() {
Colin Crossc5c24ad2015-11-20 15:35:00 -0800275 panic(fmt.Errorf("Invalid variant %q for arch %q", variant, arch))
276 }
277 }
278 for _, feature := range features {
279 field := proptools.FieldNameForProperty(feature)
Colin Cross85a88972015-11-23 13:29:51 -0800280 if !archStruct.FieldByName(field).IsValid() {
Colin Crossc5c24ad2015-11-20 15:35:00 -0800281 panic(fmt.Errorf("Invalid feature %q for arch %q variant %q", feature, arch, variant))
282 }
283 }
284 if archFeatureMap[arch] == nil {
285 archFeatureMap[arch] = make(map[string][]string)
286 }
287 archFeatureMap[arch][variant] = features
288}
289
Colin Cross3f40fa42015-01-30 17:27:36 -0800290// An Arch indicates a single CPU architecture.
291type Arch struct {
Colin Crossc5c24ad2015-11-20 15:35:00 -0800292 ArchType ArchType
293 ArchVariant string
294 CpuVariant string
295 Abi []string
296 ArchFeatures []string
Dan Willemsen17f05262016-05-31 16:27:00 -0700297 Native bool
Colin Cross3f40fa42015-01-30 17:27:36 -0800298}
299
300func (a Arch) String() string {
Colin Crossd3ba0392015-05-07 14:11:29 -0700301 s := a.ArchType.String()
Colin Cross3f40fa42015-01-30 17:27:36 -0800302 if a.ArchVariant != "" {
303 s += "_" + a.ArchVariant
304 }
305 if a.CpuVariant != "" {
306 s += "_" + a.CpuVariant
307 }
308 return s
309}
310
311type ArchType struct {
Colin Crossec193632015-07-06 17:49:43 -0700312 Name string
313 Multilib string
Colin Cross3f40fa42015-01-30 17:27:36 -0800314}
315
Colin Crossec193632015-07-06 17:49:43 -0700316func newArch(name, multilib string) ArchType {
Colin Cross3f40fa42015-01-30 17:27:36 -0800317 return ArchType{
Colin Crossec193632015-07-06 17:49:43 -0700318 Name: name,
319 Multilib: multilib,
Colin Cross3f40fa42015-01-30 17:27:36 -0800320 }
321}
322
323func (a ArchType) String() string {
324 return a.Name
325}
326
Colin Crossa1ad8d12016-06-01 17:09:44 -0700327var BuildOs = func() OsType {
Dan Willemsen490fd492015-11-24 17:53:15 -0800328 switch runtime.GOOS {
329 case "linux":
330 return Linux
331 case "darwin":
332 return Darwin
333 default:
334 panic(fmt.Sprintf("unsupported OS: %s", runtime.GOOS))
335 }
Colin Crossa1ad8d12016-06-01 17:09:44 -0700336}()
337
338var (
339 osTypeList []OsType
340
341 NoOsType OsType
342 Linux = NewOsType("linux", Host)
343 Darwin = NewOsType("darwin", Host)
344 Windows = NewOsType("windows", HostCross)
345 Android = NewOsType("android", Device)
346)
347
348type OsType struct {
349 Name, Field string
350 Class OsClass
Dan Willemsen490fd492015-11-24 17:53:15 -0800351}
352
Colin Crossa1ad8d12016-06-01 17:09:44 -0700353type OsClass int
354
355const (
356 Device OsClass = iota
357 Host
358 HostCross
359)
360
361func (os OsType) String() string {
362 return os.Name
Colin Cross54c71122016-06-01 17:09:44 -0700363}
364
Colin Crossa1ad8d12016-06-01 17:09:44 -0700365func NewOsType(name string, class OsClass) OsType {
366 os := OsType{
367 Name: name,
368 Field: strings.Title(name),
369 Class: class,
Colin Cross54c71122016-06-01 17:09:44 -0700370 }
Colin Crossa1ad8d12016-06-01 17:09:44 -0700371 osTypeList = append(osTypeList, os)
372 return os
373}
374
375func osByName(name string) OsType {
376 for _, os := range osTypeList {
377 if os.Name == name {
378 return os
379 }
380 }
381
382 return NoOsType
Dan Willemsen490fd492015-11-24 17:53:15 -0800383}
384
Colin Cross3f40fa42015-01-30 17:27:36 -0800385var (
Colin Crossa1ad8d12016-06-01 17:09:44 -0700386 commonTarget = Target{
387 Os: Android,
388 Arch: Arch{
389 ArchType: Common,
390 },
Colin Cross2fe66872015-03-30 17:20:39 -0700391 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800392)
393
Colin Crossa1ad8d12016-06-01 17:09:44 -0700394type Target struct {
395 Os OsType
396 Arch Arch
Colin Crossd3ba0392015-05-07 14:11:29 -0700397}
398
Colin Crossa1ad8d12016-06-01 17:09:44 -0700399func (target Target) String() string {
400 return target.Os.String() + "_" + target.Arch.String()
Dan Willemsen490fd492015-11-24 17:53:15 -0800401}
402
Colin Cross635c3b02016-05-18 15:37:25 -0700403func ArchMutator(mctx BottomUpMutatorContext) {
404 var module Module
Colin Cross3f40fa42015-01-30 17:27:36 -0800405 var ok bool
Colin Cross635c3b02016-05-18 15:37:25 -0700406 if module, ok = mctx.Module().(Module); !ok {
Colin Cross3f40fa42015-01-30 17:27:36 -0800407 return
408 }
409
Colin Crossa1ad8d12016-06-01 17:09:44 -0700410 osClasses := module.base().OsClassSupported()
Colin Cross3f40fa42015-01-30 17:27:36 -0800411
Colin Crossa1ad8d12016-06-01 17:09:44 -0700412 if len(osClasses) == 0 {
Colin Crossb9db4802016-06-03 01:50:47 +0000413 return
414 }
415
Colin Crossa1ad8d12016-06-01 17:09:44 -0700416 var moduleTargets []Target
417
418 for _, class := range osClasses {
419 targets := mctx.AConfig().Targets[class]
420 if len(targets) == 0 {
421 continue
422 }
Colin Cross69617d32016-09-06 10:39:07 -0700423 var multilib string
424 switch class {
425 case Device:
426 multilib = module.base().commonProperties.Target.Android.Compile_multilib
427 case Host, HostCross:
428 multilib = module.base().commonProperties.Target.Host.Compile_multilib
429 }
430 if multilib == "" {
431 multilib = module.base().commonProperties.Compile_multilib
432 }
433 if multilib == "" {
434 multilib = module.base().commonProperties.Default_multilib
435 }
Colin Crossa1ad8d12016-06-01 17:09:44 -0700436 targets, err := decodeMultilib(multilib, targets)
437 if err != nil {
438 mctx.ModuleErrorf("%s", err.Error())
439 }
440 moduleTargets = append(moduleTargets, targets...)
Colin Crossb9db4802016-06-03 01:50:47 +0000441 }
442
Dan Willemsen3f32f032016-07-11 14:36:48 -0700443 if len(moduleTargets) == 0 {
444 module.base().commonProperties.Enabled = boolPtr(false)
445 return
446 }
447
Colin Crossa1ad8d12016-06-01 17:09:44 -0700448 targetNames := make([]string, len(moduleTargets))
Colin Crossb9db4802016-06-03 01:50:47 +0000449
Colin Crossa1ad8d12016-06-01 17:09:44 -0700450 for i, target := range moduleTargets {
451 targetNames[i] = target.String()
452 }
453
454 modules := mctx.CreateVariations(targetNames...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800455 for i, m := range modules {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700456 m.(Module).base().SetTarget(moduleTargets[i])
Colin Cross635c3b02016-05-18 15:37:25 -0700457 m.(Module).base().setArchProperties(mctx)
Colin Cross3f40fa42015-01-30 17:27:36 -0800458 }
459}
460
Colin Cross635c3b02016-05-18 15:37:25 -0700461func InitArchModule(m Module,
Colin Cross3f40fa42015-01-30 17:27:36 -0800462 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
463
464 base := m.base()
465
Colin Cross3f40fa42015-01-30 17:27:36 -0800466 base.generalProperties = append(base.generalProperties,
Colin Cross3f40fa42015-01-30 17:27:36 -0800467 propertyStructs...)
468
469 for _, properties := range base.generalProperties {
470 propertiesValue := reflect.ValueOf(properties)
Colin Cross62496a02016-08-08 15:49:17 -0700471 t := propertiesValue.Type()
Colin Cross3f40fa42015-01-30 17:27:36 -0800472 if propertiesValue.Kind() != reflect.Ptr {
Colin Crossca860ac2016-01-04 14:34:37 -0800473 panic(fmt.Errorf("properties must be a pointer to a struct, got %T",
474 propertiesValue.Interface()))
Colin Cross3f40fa42015-01-30 17:27:36 -0800475 }
476
477 propertiesValue = propertiesValue.Elem()
478 if propertiesValue.Kind() != reflect.Struct {
Colin Crossca860ac2016-01-04 14:34:37 -0800479 panic(fmt.Errorf("properties must be a pointer to a struct, got %T",
480 propertiesValue.Interface()))
Colin Cross3f40fa42015-01-30 17:27:36 -0800481 }
482
483 archProperties := &archProperties{}
484 forEachInterface(reflect.ValueOf(archProperties), func(v reflect.Value) {
Colin Cross62496a02016-08-08 15:49:17 -0700485 newValue := reflect.Zero(t)
Colin Cross3f40fa42015-01-30 17:27:36 -0800486 v.Set(newValue)
487 })
488
489 base.archProperties = append(base.archProperties, archProperties)
490 }
491
492 var allProperties []interface{}
493 allProperties = append(allProperties, base.generalProperties...)
494 for _, asp := range base.archProperties {
495 allProperties = append(allProperties, asp)
496 }
497
Colin Crossa120ec12016-08-19 16:07:38 -0700498 base.customizableProperties = allProperties
499
Colin Cross3f40fa42015-01-30 17:27:36 -0800500 return m, allProperties
501}
502
Colin Crossa716add2015-12-16 11:07:39 -0800503var variantReplacer = strings.NewReplacer("-", "_", ".", "_")
Colin Crossec193632015-07-06 17:49:43 -0700504
Colin Cross635c3b02016-05-18 15:37:25 -0700505func (a *ModuleBase) appendProperties(ctx BottomUpMutatorContext,
Colin Cross85a88972015-11-23 13:29:51 -0800506 dst, src interface{}, field, srcPrefix string) interface{} {
Colin Cross06a931b2015-10-28 17:23:31 -0700507
Colin Crosseeabb892015-11-20 13:07:51 -0800508 srcField := reflect.ValueOf(src).FieldByName(field)
509 if !srcField.IsValid() {
510 ctx.ModuleErrorf("field %q does not exist", srcPrefix)
Colin Cross85a88972015-11-23 13:29:51 -0800511 return nil
512 }
513
514 ret := srcField
515
516 if srcField.Kind() == reflect.Struct {
517 srcField = srcField.FieldByName("Embed")
Colin Crosseeabb892015-11-20 13:07:51 -0800518 }
519
520 src = srcField.Elem().Interface()
Colin Cross06a931b2015-10-28 17:23:31 -0700521
522 filter := func(property string,
523 dstField, srcField reflect.StructField,
524 dstValue, srcValue interface{}) (bool, error) {
525
526 srcProperty := srcPrefix + "." + property
527
528 if !proptools.HasTag(dstField, "android", "arch_variant") {
529 if ctx.ContainsProperty(srcProperty) {
530 return false, fmt.Errorf("can't be specific to a build variant")
531 } else {
532 return false, nil
533 }
534 }
535
536 return true, nil
537 }
538
Colin Cross6ee75b62016-05-05 15:57:15 -0700539 order := func(property string,
540 dstField, srcField reflect.StructField,
541 dstValue, srcValue interface{}) (proptools.Order, error) {
542 if proptools.HasTag(dstField, "android", "variant_prepend") {
543 return proptools.Prepend, nil
544 } else {
545 return proptools.Append, nil
546 }
547 }
548
549 err := proptools.ExtendProperties(dst, src, filter, order)
Colin Cross06a931b2015-10-28 17:23:31 -0700550 if err != nil {
551 if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok {
552 ctx.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error())
553 } else {
554 panic(err)
555 }
556 }
Colin Cross85a88972015-11-23 13:29:51 -0800557
558 return ret.Interface()
Colin Cross06a931b2015-10-28 17:23:31 -0700559}
560
Colin Cross3f40fa42015-01-30 17:27:36 -0800561// Rewrite the module's properties structs to contain arch-specific values.
Colin Cross635c3b02016-05-18 15:37:25 -0700562func (a *ModuleBase) setArchProperties(ctx BottomUpMutatorContext) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700563 arch := a.Arch()
564 os := a.Os()
Colin Crossd3ba0392015-05-07 14:11:29 -0700565
Colin Cross2fe66872015-03-30 17:20:39 -0700566 if arch.ArchType == Common {
567 return
568 }
569
Colin Cross3f40fa42015-01-30 17:27:36 -0800570 for i := range a.generalProperties {
Colin Cross06a931b2015-10-28 17:23:31 -0700571 genProps := a.generalProperties[i]
572 archProps := a.archProperties[i]
Colin Cross3f40fa42015-01-30 17:27:36 -0800573 // Handle arch-specific properties in the form:
Colin Crossb05bff22015-04-30 15:08:04 -0700574 // arch: {
575 // arm64: {
Colin Cross3f40fa42015-01-30 17:27:36 -0800576 // key: value,
577 // },
578 // },
579 t := arch.ArchType
Colin Cross06a931b2015-10-28 17:23:31 -0700580
Colin Crossec193632015-07-06 17:49:43 -0700581 field := proptools.FieldNameForProperty(t.Name)
Colin Cross06a931b2015-10-28 17:23:31 -0700582 prefix := "arch." + t.Name
Colin Cross85a88972015-11-23 13:29:51 -0800583 archStruct := a.appendProperties(ctx, genProps, archProps.Arch, field, prefix)
Colin Crossec193632015-07-06 17:49:43 -0700584
585 // Handle arch-variant-specific properties in the form:
586 // arch: {
587 // variant: {
588 // key: value,
589 // },
590 // },
Colin Crossa716add2015-12-16 11:07:39 -0800591 v := variantReplacer.Replace(arch.ArchVariant)
Colin Crossec193632015-07-06 17:49:43 -0700592 if v != "" {
593 field := proptools.FieldNameForProperty(v)
Colin Cross85a88972015-11-23 13:29:51 -0800594 prefix := "arch." + t.Name + "." + v
595 a.appendProperties(ctx, genProps, archStruct, field, prefix)
Colin Crossec193632015-07-06 17:49:43 -0700596 }
597
598 // Handle cpu-variant-specific properties in the form:
599 // arch: {
600 // variant: {
601 // key: value,
602 // },
603 // },
Colin Crossa716add2015-12-16 11:07:39 -0800604 c := variantReplacer.Replace(arch.CpuVariant)
Colin Crossec193632015-07-06 17:49:43 -0700605 if c != "" {
606 field := proptools.FieldNameForProperty(c)
Colin Cross85a88972015-11-23 13:29:51 -0800607 prefix := "arch." + t.Name + "." + c
608 a.appendProperties(ctx, genProps, archStruct, field, prefix)
Colin Crossec193632015-07-06 17:49:43 -0700609 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800610
Colin Crossc5c24ad2015-11-20 15:35:00 -0800611 // Handle arch-feature-specific properties in the form:
612 // arch: {
613 // feature: {
614 // key: value,
615 // },
616 // },
617 for _, feature := range arch.ArchFeatures {
618 field := proptools.FieldNameForProperty(feature)
Colin Cross85a88972015-11-23 13:29:51 -0800619 prefix := "arch." + t.Name + "." + feature
620 a.appendProperties(ctx, genProps, archStruct, field, prefix)
Colin Crossc5c24ad2015-11-20 15:35:00 -0800621 }
622
Colin Cross3f40fa42015-01-30 17:27:36 -0800623 // Handle multilib-specific properties in the form:
Colin Crossb05bff22015-04-30 15:08:04 -0700624 // multilib: {
625 // lib32: {
Colin Cross3f40fa42015-01-30 17:27:36 -0800626 // key: value,
627 // },
628 // },
Colin Cross06a931b2015-10-28 17:23:31 -0700629 field = proptools.FieldNameForProperty(t.Multilib)
630 prefix = "multilib." + t.Multilib
631 a.appendProperties(ctx, genProps, archProps.Multilib, field, prefix)
Colin Cross3f40fa42015-01-30 17:27:36 -0800632
Colin Crossa1ad8d12016-06-01 17:09:44 -0700633 // Handle host-specific properties in the form:
Colin Crossb05bff22015-04-30 15:08:04 -0700634 // target: {
635 // host: {
Colin Cross3f40fa42015-01-30 17:27:36 -0800636 // key: value,
637 // },
638 // },
Colin Crossa1ad8d12016-06-01 17:09:44 -0700639 if os.Class == Host || os.Class == HostCross {
640 field = "Host"
641 prefix = "target.host"
642 a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
643 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800644
Colin Crossa1ad8d12016-06-01 17:09:44 -0700645 // Handle target OS properties in the form:
Colin Crossb05bff22015-04-30 15:08:04 -0700646 // target: {
647 // linux: {
Colin Cross3f40fa42015-01-30 17:27:36 -0800648 // key: value,
649 // },
Colin Crossb05bff22015-04-30 15:08:04 -0700650 // not_windows: {
651 // key: value,
652 // },
653 // linux_x86: {
654 // key: value,
655 // },
656 // linux_arm: {
Colin Cross3f40fa42015-01-30 17:27:36 -0800657 // key: value,
658 // },
Colin Crossa1ad8d12016-06-01 17:09:44 -0700659 // android {
660 // key: value,
661 // },
662 // android_arm {
663 // key: value,
664 // },
665 // android_x86 {
666 // key: value,
667 // },
Colin Cross3f40fa42015-01-30 17:27:36 -0800668 // },
Colin Crossa1ad8d12016-06-01 17:09:44 -0700669 // },
670 field = os.Field
671 prefix = "target." + os.Name
672 a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
Colin Crossb9db4802016-06-03 01:50:47 +0000673
Colin Crossa1ad8d12016-06-01 17:09:44 -0700674 field = os.Field + "_" + t.Name
675 prefix = "target." + os.Name + "_" + t.Name
676 a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
Colin Crossb9db4802016-06-03 01:50:47 +0000677
Colin Crossa1ad8d12016-06-01 17:09:44 -0700678 if (os.Class == Host || os.Class == HostCross) && os != Windows {
679 field := "Not_windows"
680 prefix := "target.not_windows"
681 a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
Colin Cross3f40fa42015-01-30 17:27:36 -0800682 }
683
Colin Crossf8209412015-03-26 14:44:26 -0700684 // Handle 64-bit device properties in the form:
685 // target {
686 // android64 {
687 // key: value,
688 // },
689 // android32 {
690 // key: value,
691 // },
692 // },
693 // WARNING: this is probably not what you want to use in your blueprints file, it selects
694 // options for all targets on a device that supports 64-bit binaries, not just the targets
695 // that are being compiled for 64-bit. Its expected use case is binaries like linker and
696 // 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 -0700697 if os.Class == Device {
698 if ctx.AConfig().Android64() {
Colin Cross06a931b2015-10-28 17:23:31 -0700699 field := "Android64"
700 prefix := "target.android64"
701 a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
Colin Crossf8209412015-03-26 14:44:26 -0700702 } else {
Colin Cross06a931b2015-10-28 17:23:31 -0700703 field := "Android32"
704 prefix := "target.android32"
705 a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
Colin Crossf8209412015-03-26 14:44:26 -0700706 }
707 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800708 }
709}
710
711func forEachInterface(v reflect.Value, f func(reflect.Value)) {
712 switch v.Kind() {
713 case reflect.Interface:
714 f(v)
715 case reflect.Struct:
716 for i := 0; i < v.NumField(); i++ {
717 forEachInterface(v.Field(i), f)
718 }
719 case reflect.Ptr:
720 forEachInterface(v.Elem(), f)
721 default:
722 panic(fmt.Errorf("Unsupported kind %s", v.Kind()))
723 }
724}
Colin Cross4225f652015-09-17 14:33:42 -0700725
Colin Crossa1ad8d12016-06-01 17:09:44 -0700726// Convert the arch product variables into a list of targets for each os class structs
Colin Cross9272ade2016-08-17 15:24:12 -0700727func decodeTargetProductVariables(config *config) (map[OsClass][]Target, error) {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700728 variables := config.ProductVariables
Dan Willemsen490fd492015-11-24 17:53:15 -0800729
Colin Crossa1ad8d12016-06-01 17:09:44 -0700730 targets := make(map[OsClass][]Target)
731 var targetErr error
732
733 addTarget := func(os OsType, archName string, archVariant, cpuVariant *string, abi *[]string) {
734 if targetErr != nil {
735 return
Dan Willemsen490fd492015-11-24 17:53:15 -0800736 }
Colin Crossa1ad8d12016-06-01 17:09:44 -0700737
738 arch, err := decodeArch(archName, archVariant, cpuVariant, abi)
739 if err != nil {
740 targetErr = err
741 return
742 }
743
744 targets[os.Class] = append(targets[os.Class],
745 Target{
746 Os: os,
747 Arch: arch,
748 })
Dan Willemsen490fd492015-11-24 17:53:15 -0800749 }
750
Colin Cross4225f652015-09-17 14:33:42 -0700751 if variables.HostArch == nil {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700752 return nil, fmt.Errorf("No host primary architecture set")
Colin Cross4225f652015-09-17 14:33:42 -0700753 }
754
Colin Crossa1ad8d12016-06-01 17:09:44 -0700755 addTarget(BuildOs, *variables.HostArch, nil, nil, nil)
Colin Cross4225f652015-09-17 14:33:42 -0700756
Colin Crosseeabb892015-11-20 13:07:51 -0800757 if variables.HostSecondaryArch != nil && *variables.HostSecondaryArch != "" {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700758 addTarget(BuildOs, *variables.HostSecondaryArch, nil, nil, nil)
Dan Willemsen490fd492015-11-24 17:53:15 -0800759 }
760
761 if variables.CrossHost != nil && *variables.CrossHost != "" {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700762 crossHostOs := osByName(*variables.CrossHost)
763 if crossHostOs == NoOsType {
764 return nil, fmt.Errorf("Unknown cross host OS %q", *variables.CrossHost)
765 }
766
Dan Willemsen490fd492015-11-24 17:53:15 -0800767 if variables.CrossHostArch == nil || *variables.CrossHostArch == "" {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700768 return nil, fmt.Errorf("No cross-host primary architecture set")
Dan Willemsen490fd492015-11-24 17:53:15 -0800769 }
770
Colin Crossa1ad8d12016-06-01 17:09:44 -0700771 addTarget(crossHostOs, *variables.CrossHostArch, nil, nil, nil)
Dan Willemsen490fd492015-11-24 17:53:15 -0800772
773 if variables.CrossHostSecondaryArch != nil && *variables.CrossHostSecondaryArch != "" {
Colin Crossa1ad8d12016-06-01 17:09:44 -0700774 addTarget(crossHostOs, *variables.CrossHostSecondaryArch, nil, nil, nil)
Dan Willemsen490fd492015-11-24 17:53:15 -0800775 }
776 }
777
Dan Willemsen3f32f032016-07-11 14:36:48 -0700778 if variables.DeviceArch != nil && *variables.DeviceArch != "" {
779 addTarget(Android, *variables.DeviceArch, variables.DeviceArchVariant,
780 variables.DeviceCpuVariant, variables.DeviceAbi)
Colin Cross4225f652015-09-17 14:33:42 -0700781
Dan Willemsen3f32f032016-07-11 14:36:48 -0700782 if variables.DeviceSecondaryArch != nil && *variables.DeviceSecondaryArch != "" {
783 addTarget(Android, *variables.DeviceSecondaryArch,
784 variables.DeviceSecondaryArchVariant, variables.DeviceSecondaryCpuVariant,
785 variables.DeviceSecondaryAbi)
Colin Cross4225f652015-09-17 14:33:42 -0700786
Dan Willemsen3f32f032016-07-11 14:36:48 -0700787 deviceArches := targets[Device]
788 if deviceArches[0].Arch.ArchType.Multilib == deviceArches[1].Arch.ArchType.Multilib {
789 deviceArches[1].Arch.Native = false
790 }
Colin Cross4225f652015-09-17 14:33:42 -0700791 }
Colin Cross4225f652015-09-17 14:33:42 -0700792 }
793
Colin Crossa1ad8d12016-06-01 17:09:44 -0700794 if targetErr != nil {
795 return nil, targetErr
796 }
797
798 return targets, nil
Colin Cross4225f652015-09-17 14:33:42 -0700799}
800
Colin Crossa1ad8d12016-06-01 17:09:44 -0700801func decodeMegaDevice() ([]Target, error) {
Dan Willemsen322acaf2016-01-12 23:07:05 -0800802 archSettings := []struct {
803 arch string
804 archVariant string
805 cpuVariant string
806 abi []string
807 }{
Dan Willemsen110a89d2016-01-14 15:17:19 -0800808 // armv5 is only used for unbundled apps
809 //{"arm", "armv5te", "", []string{"armeabi"}},
810 {"arm", "armv7-a", "generic", []string{"armeabi-v7a"}},
811 {"arm", "armv7-a-neon", "generic", []string{"armeabi-v7a"}},
Dan Willemsen322acaf2016-01-12 23:07:05 -0800812 {"arm", "armv7-a-neon", "cortex-a7", []string{"armeabi-v7a"}},
813 {"arm", "armv7-a-neon", "cortex-a8", []string{"armeabi-v7a"}},
Dan Willemsen110a89d2016-01-14 15:17:19 -0800814 {"arm", "armv7-a-neon", "cortex-a9", []string{"armeabi-v7a"}},
Dan Willemsen322acaf2016-01-12 23:07:05 -0800815 {"arm", "armv7-a-neon", "cortex-a15", []string{"armeabi-v7a"}},
816 {"arm", "armv7-a-neon", "cortex-a53", []string{"armeabi-v7a"}},
817 {"arm", "armv7-a-neon", "cortex-a53.a57", []string{"armeabi-v7a"}},
818 {"arm", "armv7-a-neon", "denver", []string{"armeabi-v7a"}},
819 {"arm", "armv7-a-neon", "krait", []string{"armeabi-v7a"}},
Dan Willemsen110a89d2016-01-14 15:17:19 -0800820 {"arm64", "armv8-a", "cortex-a53", []string{"arm64-v8a"}},
821 {"arm64", "armv8-a", "denver64", []string{"arm64-v8a"}},
Dan Willemsen468cc312016-01-13 23:25:19 -0800822 {"mips", "mips32-fp", "", []string{"mips"}},
823 {"mips", "mips32r2-fp", "", []string{"mips"}},
824 {"mips", "mips32r2-fp-xburst", "", []string{"mips"}},
Dan Willemsen65fb9812016-07-19 21:37:28 -0700825 //{"mips", "mips32r6", "", []string{"mips"}},
Dan Willemsen468cc312016-01-13 23:25:19 -0800826 // mips32r2dsp[r2]-fp fails in the assembler for divdf3.c in compiler-rt:
827 // (same errors in make and soong)
828 // Error: invalid operands `mtlo $ac0,$11'
829 // Error: invalid operands `mthi $ac0,$12'
Dan Willemsen322acaf2016-01-12 23:07:05 -0800830 //{"mips", "mips32r2dsp-fp", "", []string{"mips"}},
831 //{"mips", "mips32r2dspr2-fp", "", []string{"mips"}},
832 // mips64r2 is mismatching 64r2 and 64r6 libraries during linking to libgcc
833 //{"mips64", "mips64r2", "", []string{"mips64"}},
834 {"mips64", "mips64r6", "", []string{"mips64"}},
835 {"x86", "", "", []string{"x86"}},
836 {"x86", "atom", "", []string{"x86"}},
837 {"x86", "haswell", "", []string{"x86"}},
838 {"x86", "ivybridge", "", []string{"x86"}},
839 {"x86", "sandybridge", "", []string{"x86"}},
840 {"x86", "silvermont", "", []string{"x86"}},
Dan Willemsen8a354052016-05-10 14:30:51 -0700841 {"x86", "x86_64", "", []string{"x86"}},
Dan Willemsen322acaf2016-01-12 23:07:05 -0800842 {"x86_64", "", "", []string{"x86_64"}},
843 {"x86_64", "haswell", "", []string{"x86_64"}},
844 {"x86_64", "ivybridge", "", []string{"x86_64"}},
845 {"x86_64", "sandybridge", "", []string{"x86_64"}},
846 {"x86_64", "silvermont", "", []string{"x86_64"}},
847 }
848
Colin Crossa1ad8d12016-06-01 17:09:44 -0700849 var ret []Target
Dan Willemsen322acaf2016-01-12 23:07:05 -0800850
851 for _, config := range archSettings {
852 arch, err := decodeArch(config.arch, &config.archVariant,
853 &config.cpuVariant, &config.abi)
854 if err != nil {
855 return nil, err
856 }
Dan Willemsen17f05262016-05-31 16:27:00 -0700857 arch.Native = false
Colin Crossa1ad8d12016-06-01 17:09:44 -0700858 ret = append(ret, Target{
859 Os: Android,
860 Arch: arch,
861 })
Dan Willemsen322acaf2016-01-12 23:07:05 -0800862 }
863
864 return ret, nil
865}
866
Colin Cross4225f652015-09-17 14:33:42 -0700867// Convert a set of strings from product variables into a single Arch struct
868func decodeArch(arch string, archVariant, cpuVariant *string, abi *[]string) (Arch, error) {
869 stringPtr := func(p *string) string {
870 if p != nil {
871 return *p
872 }
873 return ""
874 }
875
876 slicePtr := func(p *[]string) []string {
877 if p != nil {
878 return *p
879 }
880 return nil
881 }
882
Colin Crosseeabb892015-11-20 13:07:51 -0800883 archType, ok := archTypeMap[arch]
884 if !ok {
885 return Arch{}, fmt.Errorf("unknown arch %q", arch)
886 }
Colin Cross4225f652015-09-17 14:33:42 -0700887
Colin Crosseeabb892015-11-20 13:07:51 -0800888 a := Arch{
Colin Cross4225f652015-09-17 14:33:42 -0700889 ArchType: archType,
890 ArchVariant: stringPtr(archVariant),
891 CpuVariant: stringPtr(cpuVariant),
892 Abi: slicePtr(abi),
Dan Willemsen17f05262016-05-31 16:27:00 -0700893 Native: true,
Colin Crosseeabb892015-11-20 13:07:51 -0800894 }
895
896 if a.ArchVariant == a.ArchType.Name || a.ArchVariant == "generic" {
897 a.ArchVariant = ""
898 }
899
900 if a.CpuVariant == a.ArchType.Name || a.CpuVariant == "generic" {
901 a.CpuVariant = ""
902 }
903
904 for i := 0; i < len(a.Abi); i++ {
905 if a.Abi[i] == "" {
906 a.Abi = append(a.Abi[:i], a.Abi[i+1:]...)
907 i--
908 }
909 }
910
Colin Crossc5c24ad2015-11-20 15:35:00 -0800911 if featureMap, ok := archFeatureMap[archType]; ok {
Dan Willemsenb4850992016-05-06 17:21:20 -0700912 a.ArchFeatures = featureMap[a.ArchVariant]
Colin Crossc5c24ad2015-11-20 15:35:00 -0800913 }
914
Colin Crosseeabb892015-11-20 13:07:51 -0800915 return a, nil
Colin Cross4225f652015-09-17 14:33:42 -0700916}
917
Colin Cross69617d32016-09-06 10:39:07 -0700918func filterMultilibTargets(targets []Target, multilib string) []Target {
919 var ret []Target
920 for _, t := range targets {
921 if t.Arch.ArchType.Multilib == multilib {
922 ret = append(ret, t)
923 }
924 }
925 return ret
926}
927
Colin Crossa1ad8d12016-06-01 17:09:44 -0700928// Use the module multilib setting to select one or more targets from a target list
929func decodeMultilib(multilib string, targets []Target) ([]Target, error) {
930 buildTargets := []Target{}
Colin Cross4225f652015-09-17 14:33:42 -0700931 switch multilib {
932 case "common":
Colin Crossa1ad8d12016-06-01 17:09:44 -0700933 buildTargets = append(buildTargets, commonTarget)
Colin Cross4225f652015-09-17 14:33:42 -0700934 case "both":
Colin Crossa1ad8d12016-06-01 17:09:44 -0700935 buildTargets = append(buildTargets, targets...)
Colin Cross4225f652015-09-17 14:33:42 -0700936 case "first":
Colin Crossa1ad8d12016-06-01 17:09:44 -0700937 buildTargets = append(buildTargets, targets[0])
Colin Cross4225f652015-09-17 14:33:42 -0700938 case "32":
Colin Cross69617d32016-09-06 10:39:07 -0700939 buildTargets = filterMultilibTargets(targets, "lib32")
Colin Cross4225f652015-09-17 14:33:42 -0700940 case "64":
Colin Cross69617d32016-09-06 10:39:07 -0700941 buildTargets = filterMultilibTargets(targets, "lib64")
942 case "prefer32":
943 buildTargets = filterMultilibTargets(targets, "lib32")
944 if len(buildTargets) == 0 {
945 buildTargets = filterMultilibTargets(targets, "lib64")
Colin Cross4225f652015-09-17 14:33:42 -0700946 }
947 default:
Colin Cross69617d32016-09-06 10:39:07 -0700948 return nil, fmt.Errorf(`compile_multilib must be "both", "first", "32", "64", or "prefer32" found %q`,
Colin Cross4225f652015-09-17 14:33:42 -0700949 multilib)
Colin Cross4225f652015-09-17 14:33:42 -0700950 }
951
Colin Crossa1ad8d12016-06-01 17:09:44 -0700952 return buildTargets, nil
Colin Cross4225f652015-09-17 14:33:42 -0700953}