blob: 22393cc86657df52e2c69d0f33e190f762db3f79 [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
15package common
16
17import (
Colin Cross3f40fa42015-01-30 17:27:36 -080018 "fmt"
19 "reflect"
20 "runtime"
21 "strings"
Colin Crossf6566ed2015-03-24 11:13:38 -070022
Colin Cross463a90e2015-06-17 14:20:06 -070023 "android/soong"
24
Colin Crossf6566ed2015-03-24 11:13:38 -070025 "github.com/google/blueprint"
26 "github.com/google/blueprint/proptools"
Colin Cross3f40fa42015-01-30 17:27:36 -080027)
28
Colin Cross463a90e2015-06-17 14:20:06 -070029func init() {
30 soong.RegisterEarlyMutator("host_or_device", HostOrDeviceMutator)
31 soong.RegisterEarlyMutator("arch", ArchMutator)
32}
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
47/*
48Example blueprints file containing all variant property groups, with comment listing what type
49of variants get properties in that group:
50
51module {
52 arch: {
53 arm: {
54 // Host or device variants with arm architecture
55 },
56 arm64: {
57 // Host or device variants with arm64 architecture
58 },
59 mips: {
60 // Host or device variants with mips architecture
61 },
62 mips64: {
63 // Host or device variants with mips64 architecture
64 },
65 x86: {
66 // Host or device variants with x86 architecture
67 },
68 x86_64: {
69 // Host or device variants with x86_64 architecture
70 },
71 },
72 multilib: {
73 lib32: {
74 // Host or device variants for 32-bit architectures
75 },
76 lib64: {
77 // Host or device variants for 64-bit architectures
78 },
79 },
80 target: {
81 android: {
82 // Device variants
83 },
84 host: {
85 // Host variants
86 },
87 linux: {
88 // Linux host variants
89 },
90 darwin: {
91 // Darwin host variants
92 },
93 windows: {
94 // Windows host variants
95 },
96 not_windows: {
97 // Non-windows host variants
98 },
99 },
100}
101*/
Colin Cross7d5136f2015-05-11 13:39:40 -0700102
Colin Cross3f40fa42015-01-30 17:27:36 -0800103type archProperties struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700104 // Properties to vary by target architecture
Colin Cross3f40fa42015-01-30 17:27:36 -0800105 Arch struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700106 // Properties for module variants being built to run on arm (host or device)
107 Arm interface{} `blueprint:"filter(android:\"arch_variant\")"`
108 // Properties for module variants being built to run on arm64 (host or device)
109 Arm64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
110 // Properties for module variants being built to run on mips (host or device)
111 Mips interface{} `blueprint:"filter(android:\"arch_variant\")"`
112 // Properties for module variants being built to run on mips64 (host or device)
113 Mips64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
114 // Properties for module variants being built to run on x86 (host or device)
115 X86 interface{} `blueprint:"filter(android:\"arch_variant\")"`
116 // Properties for module variants being built to run on x86_64 (host or device)
117 X86_64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
Colin Crossec193632015-07-06 17:49:43 -0700118
119 // Arm arch variants
120 Armv5te interface{} `blueprint:"filter(android:\"arch_variant\")"`
121 Armv7_a interface{} `blueprint:"filter(android:\"arch_variant\")"`
122 Armv7_a_neon interface{} `blueprint:"filter(android:\"arch_variant\")"`
123
124 // Arm cpu variants
125 Cortex_a7 interface{} `blueprint:"filter(android:\"arch_variant\")"`
126 Cortex_a8 interface{} `blueprint:"filter(android:\"arch_variant\")"`
127 Cortex_a9 interface{} `blueprint:"filter(android:\"arch_variant\")"`
128 Cortex_a15 interface{} `blueprint:"filter(android:\"arch_variant\")"`
129 Krait interface{} `blueprint:"filter(android:\"arch_variant\")"`
130 Denver interface{} `blueprint:"filter(android:\"arch_variant\")"`
131
132 // Arm64 cpu variants
Dan Willemsen00faa6d2015-09-11 17:38:13 -0700133 Cortex_a53 interface{} `blueprint:"filter(android:\"arch_variant\")"`
134 Denver64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
Colin Crossec193632015-07-06 17:49:43 -0700135
136 // Mips arch variants
137 Mips_rev6 interface{} `blueprint:"filter(android:\"arch_variant\")"`
138
Colin Cross01432f62015-07-09 17:56:26 -0700139 // X86 arch variants
140 X86_sse3 interface{} `blueprint:"filter(android:\"arch_variant\")"`
141 X86_sse4 interface{} `blueprint:"filter(android:\"arch_variant\")"`
142
Colin Crossec193632015-07-06 17:49:43 -0700143 // X86 cpu variants
144 Atom interface{} `blueprint:"filter(android:\"arch_variant\")"`
145 Silvermont interface{} `blueprint:"filter(android:\"arch_variant\")"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800146 }
Colin Crossec193632015-07-06 17:49:43 -0700147
Colin Cross7d5136f2015-05-11 13:39:40 -0700148 // Properties to vary by 32-bit or 64-bit
Colin Cross3f40fa42015-01-30 17:27:36 -0800149 Multilib struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700150 // Properties for module variants being built to run on 32-bit devices
151 Lib32 interface{} `blueprint:"filter(android:\"arch_variant\")"`
152 // Properties for module variants being built to run on 64-bit devices
153 Lib64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800154 }
Colin Cross7d5136f2015-05-11 13:39:40 -0700155 // Properties to vary by build target (host or device, os, os+archictecture)
Colin Cross3f40fa42015-01-30 17:27:36 -0800156 Target struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700157 // Properties for module variants being built to run on the host
158 Host interface{} `blueprint:"filter(android:\"arch_variant\")"`
159 // Properties for module variants being built to run on the device
160 Android interface{} `blueprint:"filter(android:\"arch_variant\")"`
161 // Properties for module variants being built to run on arm devices
162 Android_arm interface{} `blueprint:"filter(android:\"arch_variant\")"`
163 // Properties for module variants being built to run on arm64 devices
164 Android_arm64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
165 // Properties for module variants being built to run on mips devices
166 Android_mips interface{} `blueprint:"filter(android:\"arch_variant\")"`
167 // Properties for module variants being built to run on mips64 devices
168 Android_mips64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
169 // Properties for module variants being built to run on x86 devices
170 Android_x86 interface{} `blueprint:"filter(android:\"arch_variant\")"`
171 // Properties for module variants being built to run on x86_64 devices
172 Android_x86_64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
173 // Properties for module variants being built to run on devices that support 64-bit
174 Android64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
175 // Properties for module variants being built to run on devices that do not support 64-bit
176 Android32 interface{} `blueprint:"filter(android:\"arch_variant\")"`
177 // Properties for module variants being built to run on linux hosts
178 Linux interface{} `blueprint:"filter(android:\"arch_variant\")"`
179 // Properties for module variants being built to run on linux x86 hosts
180 Linux_x86 interface{} `blueprint:"filter(android:\"arch_variant\")"`
181 // Properties for module variants being built to run on linux x86_64 hosts
182 Linux_x86_64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
183 // Properties for module variants being built to run on darwin hosts
184 Darwin interface{} `blueprint:"filter(android:\"arch_variant\")"`
185 // Properties for module variants being built to run on darwin x86 hosts
186 Darwin_x86 interface{} `blueprint:"filter(android:\"arch_variant\")"`
187 // Properties for module variants being built to run on darwin x86_64 hosts
188 Darwin_x86_64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
189 // Properties for module variants being built to run on windows hosts
190 Windows interface{} `blueprint:"filter(android:\"arch_variant\")"`
191 // Properties for module variants being built to run on linux or darwin hosts
192 Not_windows interface{} `blueprint:"filter(android:\"arch_variant\")"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800193 }
194}
195
196// An Arch indicates a single CPU architecture.
197type Arch struct {
Colin Crossd3ba0392015-05-07 14:11:29 -0700198 ArchType ArchType
199 ArchVariant string
200 CpuVariant string
201 Abi string
Colin Cross3f40fa42015-01-30 17:27:36 -0800202}
203
204func (a Arch) String() string {
Colin Crossd3ba0392015-05-07 14:11:29 -0700205 s := a.ArchType.String()
Colin Cross3f40fa42015-01-30 17:27:36 -0800206 if a.ArchVariant != "" {
207 s += "_" + a.ArchVariant
208 }
209 if a.CpuVariant != "" {
210 s += "_" + a.CpuVariant
211 }
212 return s
213}
214
215type ArchType struct {
Colin Crossec193632015-07-06 17:49:43 -0700216 Name string
217 Multilib string
Colin Cross3f40fa42015-01-30 17:27:36 -0800218}
219
Colin Crossec193632015-07-06 17:49:43 -0700220func newArch(name, multilib string) ArchType {
Colin Cross3f40fa42015-01-30 17:27:36 -0800221 return ArchType{
Colin Crossec193632015-07-06 17:49:43 -0700222 Name: name,
223 Multilib: multilib,
Colin Cross3f40fa42015-01-30 17:27:36 -0800224 }
225}
226
227func (a ArchType) String() string {
228 return a.Name
229}
230
231type HostOrDeviceSupported int
232
233const (
234 _ HostOrDeviceSupported = iota
235 HostSupported
236 DeviceSupported
237 HostAndDeviceSupported
238)
239
240type HostOrDevice int
241
242const (
243 _ HostOrDevice = iota
244 Host
245 Device
246)
247
248func (hod HostOrDevice) String() string {
249 switch hod {
250 case Device:
251 return "device"
252 case Host:
253 return "host"
254 default:
255 panic(fmt.Sprintf("unexpected HostOrDevice value %d", hod))
256 }
257}
258
Colin Crossec193632015-07-06 17:49:43 -0700259func (hod HostOrDevice) Property() string {
Colin Cross3f40fa42015-01-30 17:27:36 -0800260 switch hod {
261 case Device:
262 return "android"
263 case Host:
264 return "host"
265 default:
266 panic(fmt.Sprintf("unexpected HostOrDevice value %d", hod))
267 }
268}
269
Colin Cross3f40fa42015-01-30 17:27:36 -0800270func (hod HostOrDevice) Host() bool {
271 if hod == 0 {
272 panic("HostOrDevice unset")
273 }
274 return hod == Host
275}
276
277func (hod HostOrDevice) Device() bool {
278 if hod == 0 {
279 panic("HostOrDevice unset")
280 }
281 return hod == Device
282}
283
284var hostOrDeviceName = map[HostOrDevice]string{
285 Device: "device",
286 Host: "host",
287}
288
289var (
290 armArch = Arch{
Colin Crossd3ba0392015-05-07 14:11:29 -0700291 ArchType: Arm,
292 ArchVariant: "armv7-a-neon",
293 CpuVariant: "cortex-a15",
294 Abi: "armeabi-v7a",
Colin Cross3f40fa42015-01-30 17:27:36 -0800295 }
296 arm64Arch = Arch{
Colin Crossec193632015-07-06 17:49:43 -0700297 ArchType: Arm64,
298 CpuVariant: "denver64",
299 Abi: "arm64-v8a",
Colin Cross3f40fa42015-01-30 17:27:36 -0800300 }
Colin Crossd3ba0392015-05-07 14:11:29 -0700301 x86Arch = Arch{
302 ArchType: X86,
Colin Cross3f40fa42015-01-30 17:27:36 -0800303 }
Colin Crossd3ba0392015-05-07 14:11:29 -0700304 x8664Arch = Arch{
305 ArchType: X86_64,
Colin Cross3f40fa42015-01-30 17:27:36 -0800306 }
Colin Crossd3ba0392015-05-07 14:11:29 -0700307 commonArch = Arch{
308 ArchType: Common,
Colin Cross2fe66872015-03-30 17:20:39 -0700309 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800310)
311
Colin Crossd3ba0392015-05-07 14:11:29 -0700312func HostOrDeviceMutator(mctx blueprint.EarlyMutatorContext) {
313 var module AndroidModule
314 var ok bool
315 if module, ok = mctx.Module().(AndroidModule); !ok {
316 return
317 }
318
319 hods := []HostOrDevice{}
320
321 if module.base().HostSupported() {
322 hods = append(hods, Host)
323 }
324
325 if module.base().DeviceSupported() {
326 hods = append(hods, Device)
327 }
328
329 if len(hods) == 0 {
330 return
331 }
332
333 hodNames := []string{}
334 for _, hod := range hods {
335 hodNames = append(hodNames, hod.String())
336 }
337
338 modules := mctx.CreateVariations(hodNames...)
339 for i, m := range modules {
340 m.(AndroidModule).base().SetHostOrDevice(hods[i])
341 }
342}
343
Colin Cross3f40fa42015-01-30 17:27:36 -0800344func ArchMutator(mctx blueprint.EarlyMutatorContext) {
345 var module AndroidModule
346 var ok bool
347 if module, ok = mctx.Module().(AndroidModule); !ok {
348 return
349 }
350
351 // TODO: this is all hardcoded for arm64 primary, arm secondary for now
352 // Replace with a configuration file written by lunch or bootstrap
353
354 arches := []Arch{}
355
Colin Crossd3ba0392015-05-07 14:11:29 -0700356 if module.base().HostSupported() && module.base().HostOrDevice().Host() {
Colin Cross2fe66872015-03-30 17:20:39 -0700357 switch module.base().commonProperties.Compile_multilib {
358 case "common":
Colin Crossd3ba0392015-05-07 14:11:29 -0700359 arches = append(arches, commonArch)
Dan Willemsenffce3fc2015-07-08 13:02:19 -0700360 case "both":
361 arches = append(arches, x8664Arch, x86Arch)
362 case "first", "64":
363 arches = append(arches, x8664Arch)
364 case "32":
365 arches = append(arches, x86Arch)
Colin Cross2fe66872015-03-30 17:20:39 -0700366 default:
Colin Crossd3ba0392015-05-07 14:11:29 -0700367 arches = append(arches, x8664Arch)
Colin Cross2fe66872015-03-30 17:20:39 -0700368 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800369 }
370
Colin Crossd3ba0392015-05-07 14:11:29 -0700371 if module.base().DeviceSupported() && module.base().HostOrDevice().Device() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800372 switch module.base().commonProperties.Compile_multilib {
Colin Cross2fe66872015-03-30 17:20:39 -0700373 case "common":
Colin Crossd3ba0392015-05-07 14:11:29 -0700374 arches = append(arches, commonArch)
Colin Cross3f40fa42015-01-30 17:27:36 -0800375 case "both":
376 arches = append(arches, arm64Arch, armArch)
377 case "first", "64":
378 arches = append(arches, arm64Arch)
379 case "32":
380 arches = append(arches, armArch)
381 default:
382 mctx.ModuleErrorf(`compile_multilib must be "both", "first", "32", or "64", found %q`,
383 module.base().commonProperties.Compile_multilib)
384 }
385 }
386
Colin Cross5049f022015-03-18 13:28:46 -0700387 if len(arches) == 0 {
388 return
389 }
390
Colin Cross3f40fa42015-01-30 17:27:36 -0800391 archNames := []string{}
392 for _, arch := range arches {
393 archNames = append(archNames, arch.String())
394 }
395
396 modules := mctx.CreateVariations(archNames...)
397
398 for i, m := range modules {
399 m.(AndroidModule).base().SetArch(arches[i])
Colin Crossd3ba0392015-05-07 14:11:29 -0700400 m.(AndroidModule).base().setArchProperties(mctx)
Colin Cross3f40fa42015-01-30 17:27:36 -0800401 }
402}
403
Colin Crossc472d572015-03-17 15:06:21 -0700404func InitArchModule(m AndroidModule, defaultMultilib Multilib,
Colin Cross3f40fa42015-01-30 17:27:36 -0800405 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
406
407 base := m.base()
408
Colin Crossc472d572015-03-17 15:06:21 -0700409 base.commonProperties.Compile_multilib = string(defaultMultilib)
Colin Cross3f40fa42015-01-30 17:27:36 -0800410
411 base.generalProperties = append(base.generalProperties,
Colin Cross3f40fa42015-01-30 17:27:36 -0800412 propertyStructs...)
413
414 for _, properties := range base.generalProperties {
415 propertiesValue := reflect.ValueOf(properties)
416 if propertiesValue.Kind() != reflect.Ptr {
417 panic("properties must be a pointer to a struct")
418 }
419
420 propertiesValue = propertiesValue.Elem()
421 if propertiesValue.Kind() != reflect.Struct {
422 panic("properties must be a pointer to a struct")
423 }
424
425 archProperties := &archProperties{}
426 forEachInterface(reflect.ValueOf(archProperties), func(v reflect.Value) {
Colin Cross3ab7d882015-05-19 13:03:01 -0700427 newValue := proptools.CloneEmptyProperties(propertiesValue)
Colin Cross3f40fa42015-01-30 17:27:36 -0800428 v.Set(newValue)
429 })
430
431 base.archProperties = append(base.archProperties, archProperties)
432 }
433
434 var allProperties []interface{}
435 allProperties = append(allProperties, base.generalProperties...)
436 for _, asp := range base.archProperties {
437 allProperties = append(allProperties, asp)
438 }
439
440 return m, allProperties
441}
442
Colin Crossec193632015-07-06 17:49:43 -0700443var dashToUnderscoreReplacer = strings.NewReplacer("-", "_")
444
Colin Cross3f40fa42015-01-30 17:27:36 -0800445// Rewrite the module's properties structs to contain arch-specific values.
Colin Crossd3ba0392015-05-07 14:11:29 -0700446func (a *AndroidModuleBase) setArchProperties(ctx blueprint.EarlyMutatorContext) {
447 arch := a.commonProperties.CompileArch
448 hod := a.commonProperties.CompileHostOrDevice
449
Colin Cross2fe66872015-03-30 17:20:39 -0700450 if arch.ArchType == Common {
451 return
452 }
453
Colin Cross7f64b6d2015-07-09 13:57:48 -0700454 callback := func(srcPropertyName, dstPropertyName string) {
455 a.extendedProperties[dstPropertyName] = struct{}{}
456 }
457
Colin Cross3f40fa42015-01-30 17:27:36 -0800458 for i := range a.generalProperties {
Colin Cross7f64b6d2015-07-09 13:57:48 -0700459 generalPropsValue := []reflect.Value{reflect.ValueOf(a.generalProperties[i]).Elem()}
Colin Cross3f40fa42015-01-30 17:27:36 -0800460
461 // Handle arch-specific properties in the form:
Colin Crossb05bff22015-04-30 15:08:04 -0700462 // arch: {
463 // arm64: {
Colin Cross3f40fa42015-01-30 17:27:36 -0800464 // key: value,
465 // },
466 // },
467 t := arch.ArchType
Colin Crossec193632015-07-06 17:49:43 -0700468 field := proptools.FieldNameForProperty(t.Name)
Colin Cross7f64b6d2015-07-09 13:57:48 -0700469 extendProperties(ctx, "arch_variant", "arch."+t.Name, generalPropsValue,
470 reflect.ValueOf(a.archProperties[i].Arch).FieldByName(field).Elem().Elem(), callback)
Colin Crossec193632015-07-06 17:49:43 -0700471
472 // Handle arch-variant-specific properties in the form:
473 // arch: {
474 // variant: {
475 // key: value,
476 // },
477 // },
478 v := dashToUnderscoreReplacer.Replace(arch.ArchVariant)
479 if v != "" {
480 field := proptools.FieldNameForProperty(v)
Colin Cross7f64b6d2015-07-09 13:57:48 -0700481 extendProperties(ctx, "arch_variant", "arch."+v, generalPropsValue,
482 reflect.ValueOf(a.archProperties[i].Arch).FieldByName(field).Elem().Elem(), callback)
Colin Crossec193632015-07-06 17:49:43 -0700483 }
484
485 // Handle cpu-variant-specific properties in the form:
486 // arch: {
487 // variant: {
488 // key: value,
489 // },
490 // },
491 c := dashToUnderscoreReplacer.Replace(arch.CpuVariant)
492 if c != "" {
493 field := proptools.FieldNameForProperty(c)
Colin Cross7f64b6d2015-07-09 13:57:48 -0700494 extendProperties(ctx, "arch_variant", "arch."+c, generalPropsValue,
495 reflect.ValueOf(a.archProperties[i].Arch).FieldByName(field).Elem().Elem(), callback)
Colin Crossec193632015-07-06 17:49:43 -0700496 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800497
498 // Handle multilib-specific properties in the form:
Colin Crossb05bff22015-04-30 15:08:04 -0700499 // multilib: {
500 // lib32: {
Colin Cross3f40fa42015-01-30 17:27:36 -0800501 // key: value,
502 // },
503 // },
Colin Crossec193632015-07-06 17:49:43 -0700504 multilibField := proptools.FieldNameForProperty(t.Multilib)
Colin Cross7f64b6d2015-07-09 13:57:48 -0700505 extendProperties(ctx, "arch_variant", "multilib."+t.Multilib, generalPropsValue,
506 reflect.ValueOf(a.archProperties[i].Multilib).FieldByName(multilibField).Elem().Elem(), callback)
Colin Cross3f40fa42015-01-30 17:27:36 -0800507
508 // Handle host-or-device-specific properties in the form:
Colin Crossb05bff22015-04-30 15:08:04 -0700509 // target: {
510 // host: {
Colin Cross3f40fa42015-01-30 17:27:36 -0800511 // key: value,
512 // },
513 // },
Colin Crossec193632015-07-06 17:49:43 -0700514 hodProperty := hod.Property()
515 hodField := proptools.FieldNameForProperty(hodProperty)
Colin Cross7f64b6d2015-07-09 13:57:48 -0700516 extendProperties(ctx, "arch_variant", "target."+hodProperty, generalPropsValue,
517 reflect.ValueOf(a.archProperties[i].Target).FieldByName(hodField).Elem().Elem(), callback)
Colin Cross3f40fa42015-01-30 17:27:36 -0800518
519 // Handle host target properties in the form:
Colin Crossb05bff22015-04-30 15:08:04 -0700520 // target: {
521 // linux: {
Colin Cross3f40fa42015-01-30 17:27:36 -0800522 // key: value,
523 // },
Colin Crossb05bff22015-04-30 15:08:04 -0700524 // not_windows: {
525 // key: value,
526 // },
527 // linux_x86: {
528 // key: value,
529 // },
530 // linux_arm: {
Colin Cross3f40fa42015-01-30 17:27:36 -0800531 // key: value,
532 // },
533 // },
534 var osList = []struct {
535 goos string
536 field string
537 }{
538 {"darwin", "Darwin"},
539 {"linux", "Linux"},
540 {"windows", "Windows"},
541 }
542
543 if hod.Host() {
544 for _, v := range osList {
545 if v.goos == runtime.GOOS {
Colin Cross7f64b6d2015-07-09 13:57:48 -0700546 extendProperties(ctx, "arch_variant", "target."+v.goos, generalPropsValue,
547 reflect.ValueOf(a.archProperties[i].Target).FieldByName(v.field).Elem().Elem(), callback)
Colin Crossb05bff22015-04-30 15:08:04 -0700548 t := arch.ArchType
Colin Cross7f64b6d2015-07-09 13:57:48 -0700549 extendProperties(ctx, "arch_variant", "target."+v.goos+"_"+t.Name, generalPropsValue,
550 reflect.ValueOf(a.archProperties[i].Target).FieldByName(v.field+"_"+t.Name).Elem().Elem(), callback)
Colin Cross3f40fa42015-01-30 17:27:36 -0800551 }
552 }
Colin Cross7f64b6d2015-07-09 13:57:48 -0700553 extendProperties(ctx, "arch_variant", "target.not_windows", generalPropsValue,
554 reflect.ValueOf(a.archProperties[i].Target).FieldByName("Not_windows").Elem().Elem(), callback)
Colin Cross3f40fa42015-01-30 17:27:36 -0800555 }
556
Colin Crossf8209412015-03-26 14:44:26 -0700557 // Handle 64-bit device properties in the form:
558 // target {
559 // android64 {
560 // key: value,
561 // },
562 // android32 {
563 // key: value,
564 // },
565 // },
566 // WARNING: this is probably not what you want to use in your blueprints file, it selects
567 // options for all targets on a device that supports 64-bit binaries, not just the targets
568 // that are being compiled for 64-bit. Its expected use case is binaries like linker and
569 // debuggerd that need to know when they are a 32-bit process running on a 64-bit device
570 if hod.Device() {
571 if true /* && target_is_64_bit */ {
Colin Cross7f64b6d2015-07-09 13:57:48 -0700572 extendProperties(ctx, "arch_variant", "target.android64", generalPropsValue,
573 reflect.ValueOf(a.archProperties[i].Target).FieldByName("Android64").Elem().Elem(), callback)
Colin Crossf8209412015-03-26 14:44:26 -0700574 } else {
Colin Cross7f64b6d2015-07-09 13:57:48 -0700575 extendProperties(ctx, "arch_variant", "target.android32", generalPropsValue,
576 reflect.ValueOf(a.archProperties[i].Target).FieldByName("Android32").Elem().Elem(), callback)
Colin Crossf8209412015-03-26 14:44:26 -0700577 }
578 }
Colin Crossb05bff22015-04-30 15:08:04 -0700579
580 // Handle device architecture properties in the form:
581 // target {
582 // android_arm {
583 // key: value,
584 // },
585 // android_x86 {
586 // key: value,
587 // },
588 // },
589 if hod.Device() {
590 t := arch.ArchType
Colin Cross7f64b6d2015-07-09 13:57:48 -0700591 extendProperties(ctx, "arch_variant", "target.android_"+t.Name, generalPropsValue,
592 reflect.ValueOf(a.archProperties[i].Target).FieldByName("Android_"+t.Name).Elem().Elem(), callback)
Colin Crossb05bff22015-04-30 15:08:04 -0700593 }
594
Colin Cross3f40fa42015-01-30 17:27:36 -0800595 if ctx.Failed() {
596 return
597 }
598 }
599}
600
601func forEachInterface(v reflect.Value, f func(reflect.Value)) {
602 switch v.Kind() {
603 case reflect.Interface:
604 f(v)
605 case reflect.Struct:
606 for i := 0; i < v.NumField(); i++ {
607 forEachInterface(v.Field(i), f)
608 }
609 case reflect.Ptr:
610 forEachInterface(v.Elem(), f)
611 default:
612 panic(fmt.Errorf("Unsupported kind %s", v.Kind()))
613 }
614}