blob: b9e3a5c3489d36c427f8a3112dd1aca8d0e566bd [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
133 Denver64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
134
135 // Mips arch variants
136 Mips_rev6 interface{} `blueprint:"filter(android:\"arch_variant\")"`
137
Colin Cross01432f62015-07-09 17:56:26 -0700138 // X86 arch variants
139 X86_sse3 interface{} `blueprint:"filter(android:\"arch_variant\")"`
140 X86_sse4 interface{} `blueprint:"filter(android:\"arch_variant\")"`
141
Colin Crossec193632015-07-06 17:49:43 -0700142 // X86 cpu variants
143 Atom interface{} `blueprint:"filter(android:\"arch_variant\")"`
144 Silvermont interface{} `blueprint:"filter(android:\"arch_variant\")"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800145 }
Colin Crossec193632015-07-06 17:49:43 -0700146
Colin Cross7d5136f2015-05-11 13:39:40 -0700147 // Properties to vary by 32-bit or 64-bit
Colin Cross3f40fa42015-01-30 17:27:36 -0800148 Multilib struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700149 // Properties for module variants being built to run on 32-bit devices
150 Lib32 interface{} `blueprint:"filter(android:\"arch_variant\")"`
151 // Properties for module variants being built to run on 64-bit devices
152 Lib64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800153 }
Colin Cross7d5136f2015-05-11 13:39:40 -0700154 // Properties to vary by build target (host or device, os, os+archictecture)
Colin Cross3f40fa42015-01-30 17:27:36 -0800155 Target struct {
Colin Cross7d5136f2015-05-11 13:39:40 -0700156 // Properties for module variants being built to run on the host
157 Host interface{} `blueprint:"filter(android:\"arch_variant\")"`
158 // Properties for module variants being built to run on the device
159 Android interface{} `blueprint:"filter(android:\"arch_variant\")"`
160 // Properties for module variants being built to run on arm devices
161 Android_arm interface{} `blueprint:"filter(android:\"arch_variant\")"`
162 // Properties for module variants being built to run on arm64 devices
163 Android_arm64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
164 // Properties for module variants being built to run on mips devices
165 Android_mips interface{} `blueprint:"filter(android:\"arch_variant\")"`
166 // Properties for module variants being built to run on mips64 devices
167 Android_mips64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
168 // Properties for module variants being built to run on x86 devices
169 Android_x86 interface{} `blueprint:"filter(android:\"arch_variant\")"`
170 // Properties for module variants being built to run on x86_64 devices
171 Android_x86_64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
172 // Properties for module variants being built to run on devices that support 64-bit
173 Android64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
174 // Properties for module variants being built to run on devices that do not support 64-bit
175 Android32 interface{} `blueprint:"filter(android:\"arch_variant\")"`
176 // Properties for module variants being built to run on linux hosts
177 Linux interface{} `blueprint:"filter(android:\"arch_variant\")"`
178 // Properties for module variants being built to run on linux x86 hosts
179 Linux_x86 interface{} `blueprint:"filter(android:\"arch_variant\")"`
180 // Properties for module variants being built to run on linux x86_64 hosts
181 Linux_x86_64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
182 // Properties for module variants being built to run on darwin hosts
183 Darwin interface{} `blueprint:"filter(android:\"arch_variant\")"`
184 // Properties for module variants being built to run on darwin x86 hosts
185 Darwin_x86 interface{} `blueprint:"filter(android:\"arch_variant\")"`
186 // Properties for module variants being built to run on darwin x86_64 hosts
187 Darwin_x86_64 interface{} `blueprint:"filter(android:\"arch_variant\")"`
188 // Properties for module variants being built to run on windows hosts
189 Windows interface{} `blueprint:"filter(android:\"arch_variant\")"`
190 // Properties for module variants being built to run on linux or darwin hosts
191 Not_windows interface{} `blueprint:"filter(android:\"arch_variant\")"`
Colin Cross3f40fa42015-01-30 17:27:36 -0800192 }
193}
194
195// An Arch indicates a single CPU architecture.
196type Arch struct {
Colin Crossd3ba0392015-05-07 14:11:29 -0700197 ArchType ArchType
198 ArchVariant string
199 CpuVariant string
200 Abi string
Colin Cross3f40fa42015-01-30 17:27:36 -0800201}
202
203func (a Arch) String() string {
Colin Crossd3ba0392015-05-07 14:11:29 -0700204 s := a.ArchType.String()
Colin Cross3f40fa42015-01-30 17:27:36 -0800205 if a.ArchVariant != "" {
206 s += "_" + a.ArchVariant
207 }
208 if a.CpuVariant != "" {
209 s += "_" + a.CpuVariant
210 }
211 return s
212}
213
214type ArchType struct {
Colin Crossec193632015-07-06 17:49:43 -0700215 Name string
216 Multilib string
Colin Cross3f40fa42015-01-30 17:27:36 -0800217}
218
Colin Crossec193632015-07-06 17:49:43 -0700219func newArch(name, multilib string) ArchType {
Colin Cross3f40fa42015-01-30 17:27:36 -0800220 return ArchType{
Colin Crossec193632015-07-06 17:49:43 -0700221 Name: name,
222 Multilib: multilib,
Colin Cross3f40fa42015-01-30 17:27:36 -0800223 }
224}
225
226func (a ArchType) String() string {
227 return a.Name
228}
229
230type HostOrDeviceSupported int
231
232const (
233 _ HostOrDeviceSupported = iota
234 HostSupported
235 DeviceSupported
236 HostAndDeviceSupported
237)
238
239type HostOrDevice int
240
241const (
242 _ HostOrDevice = iota
243 Host
244 Device
245)
246
247func (hod HostOrDevice) String() string {
248 switch hod {
249 case Device:
250 return "device"
251 case Host:
252 return "host"
253 default:
254 panic(fmt.Sprintf("unexpected HostOrDevice value %d", hod))
255 }
256}
257
Colin Crossec193632015-07-06 17:49:43 -0700258func (hod HostOrDevice) Property() string {
Colin Cross3f40fa42015-01-30 17:27:36 -0800259 switch hod {
260 case Device:
261 return "android"
262 case Host:
263 return "host"
264 default:
265 panic(fmt.Sprintf("unexpected HostOrDevice value %d", hod))
266 }
267}
268
Colin Cross3f40fa42015-01-30 17:27:36 -0800269func (hod HostOrDevice) Host() bool {
270 if hod == 0 {
271 panic("HostOrDevice unset")
272 }
273 return hod == Host
274}
275
276func (hod HostOrDevice) Device() bool {
277 if hod == 0 {
278 panic("HostOrDevice unset")
279 }
280 return hod == Device
281}
282
283var hostOrDeviceName = map[HostOrDevice]string{
284 Device: "device",
285 Host: "host",
286}
287
288var (
289 armArch = Arch{
Colin Crossd3ba0392015-05-07 14:11:29 -0700290 ArchType: Arm,
291 ArchVariant: "armv7-a-neon",
292 CpuVariant: "cortex-a15",
293 Abi: "armeabi-v7a",
Colin Cross3f40fa42015-01-30 17:27:36 -0800294 }
295 arm64Arch = Arch{
Colin Crossec193632015-07-06 17:49:43 -0700296 ArchType: Arm64,
297 CpuVariant: "denver64",
298 Abi: "arm64-v8a",
Colin Cross3f40fa42015-01-30 17:27:36 -0800299 }
Colin Crossd3ba0392015-05-07 14:11:29 -0700300 x86Arch = Arch{
301 ArchType: X86,
Colin Cross3f40fa42015-01-30 17:27:36 -0800302 }
Colin Crossd3ba0392015-05-07 14:11:29 -0700303 x8664Arch = Arch{
304 ArchType: X86_64,
Colin Cross3f40fa42015-01-30 17:27:36 -0800305 }
Colin Crossd3ba0392015-05-07 14:11:29 -0700306 commonArch = Arch{
307 ArchType: Common,
Colin Cross2fe66872015-03-30 17:20:39 -0700308 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800309)
310
Colin Crossd3ba0392015-05-07 14:11:29 -0700311func HostOrDeviceMutator(mctx blueprint.EarlyMutatorContext) {
312 var module AndroidModule
313 var ok bool
314 if module, ok = mctx.Module().(AndroidModule); !ok {
315 return
316 }
317
318 hods := []HostOrDevice{}
319
320 if module.base().HostSupported() {
321 hods = append(hods, Host)
322 }
323
324 if module.base().DeviceSupported() {
325 hods = append(hods, Device)
326 }
327
328 if len(hods) == 0 {
329 return
330 }
331
332 hodNames := []string{}
333 for _, hod := range hods {
334 hodNames = append(hodNames, hod.String())
335 }
336
337 modules := mctx.CreateVariations(hodNames...)
338 for i, m := range modules {
339 m.(AndroidModule).base().SetHostOrDevice(hods[i])
340 }
341}
342
Colin Cross3f40fa42015-01-30 17:27:36 -0800343func ArchMutator(mctx blueprint.EarlyMutatorContext) {
344 var module AndroidModule
345 var ok bool
346 if module, ok = mctx.Module().(AndroidModule); !ok {
347 return
348 }
349
350 // TODO: this is all hardcoded for arm64 primary, arm secondary for now
351 // Replace with a configuration file written by lunch or bootstrap
352
353 arches := []Arch{}
354
Colin Crossd3ba0392015-05-07 14:11:29 -0700355 if module.base().HostSupported() && module.base().HostOrDevice().Host() {
Colin Cross2fe66872015-03-30 17:20:39 -0700356 switch module.base().commonProperties.Compile_multilib {
357 case "common":
Colin Crossd3ba0392015-05-07 14:11:29 -0700358 arches = append(arches, commonArch)
Dan Willemsenffce3fc2015-07-08 13:02:19 -0700359 case "both":
360 arches = append(arches, x8664Arch, x86Arch)
361 case "first", "64":
362 arches = append(arches, x8664Arch)
363 case "32":
364 arches = append(arches, x86Arch)
Colin Cross2fe66872015-03-30 17:20:39 -0700365 default:
Colin Crossd3ba0392015-05-07 14:11:29 -0700366 arches = append(arches, x8664Arch)
Colin Cross2fe66872015-03-30 17:20:39 -0700367 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800368 }
369
Colin Crossd3ba0392015-05-07 14:11:29 -0700370 if module.base().DeviceSupported() && module.base().HostOrDevice().Device() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800371 switch module.base().commonProperties.Compile_multilib {
Colin Cross2fe66872015-03-30 17:20:39 -0700372 case "common":
Colin Crossd3ba0392015-05-07 14:11:29 -0700373 arches = append(arches, commonArch)
Colin Cross3f40fa42015-01-30 17:27:36 -0800374 case "both":
375 arches = append(arches, arm64Arch, armArch)
376 case "first", "64":
377 arches = append(arches, arm64Arch)
378 case "32":
379 arches = append(arches, armArch)
380 default:
381 mctx.ModuleErrorf(`compile_multilib must be "both", "first", "32", or "64", found %q`,
382 module.base().commonProperties.Compile_multilib)
383 }
384 }
385
Colin Cross5049f022015-03-18 13:28:46 -0700386 if len(arches) == 0 {
387 return
388 }
389
Colin Cross3f40fa42015-01-30 17:27:36 -0800390 archNames := []string{}
391 for _, arch := range arches {
392 archNames = append(archNames, arch.String())
393 }
394
395 modules := mctx.CreateVariations(archNames...)
396
397 for i, m := range modules {
398 m.(AndroidModule).base().SetArch(arches[i])
Colin Crossd3ba0392015-05-07 14:11:29 -0700399 m.(AndroidModule).base().setArchProperties(mctx)
Colin Cross3f40fa42015-01-30 17:27:36 -0800400 }
401}
402
Colin Crossc472d572015-03-17 15:06:21 -0700403func InitArchModule(m AndroidModule, defaultMultilib Multilib,
Colin Cross3f40fa42015-01-30 17:27:36 -0800404 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
405
406 base := m.base()
407
Colin Crossc472d572015-03-17 15:06:21 -0700408 base.commonProperties.Compile_multilib = string(defaultMultilib)
Colin Cross3f40fa42015-01-30 17:27:36 -0800409
410 base.generalProperties = append(base.generalProperties,
Colin Cross3f40fa42015-01-30 17:27:36 -0800411 propertyStructs...)
412
413 for _, properties := range base.generalProperties {
414 propertiesValue := reflect.ValueOf(properties)
415 if propertiesValue.Kind() != reflect.Ptr {
416 panic("properties must be a pointer to a struct")
417 }
418
419 propertiesValue = propertiesValue.Elem()
420 if propertiesValue.Kind() != reflect.Struct {
421 panic("properties must be a pointer to a struct")
422 }
423
424 archProperties := &archProperties{}
425 forEachInterface(reflect.ValueOf(archProperties), func(v reflect.Value) {
Colin Cross3ab7d882015-05-19 13:03:01 -0700426 newValue := proptools.CloneEmptyProperties(propertiesValue)
Colin Cross3f40fa42015-01-30 17:27:36 -0800427 v.Set(newValue)
428 })
429
430 base.archProperties = append(base.archProperties, archProperties)
431 }
432
433 var allProperties []interface{}
434 allProperties = append(allProperties, base.generalProperties...)
435 for _, asp := range base.archProperties {
436 allProperties = append(allProperties, asp)
437 }
438
439 return m, allProperties
440}
441
Colin Crossec193632015-07-06 17:49:43 -0700442var dashToUnderscoreReplacer = strings.NewReplacer("-", "_")
443
Colin Cross3f40fa42015-01-30 17:27:36 -0800444// Rewrite the module's properties structs to contain arch-specific values.
Colin Crossd3ba0392015-05-07 14:11:29 -0700445func (a *AndroidModuleBase) setArchProperties(ctx blueprint.EarlyMutatorContext) {
446 arch := a.commonProperties.CompileArch
447 hod := a.commonProperties.CompileHostOrDevice
448
Colin Cross2fe66872015-03-30 17:20:39 -0700449 if arch.ArchType == Common {
450 return
451 }
452
Colin Cross7f64b6d2015-07-09 13:57:48 -0700453 callback := func(srcPropertyName, dstPropertyName string) {
454 a.extendedProperties[dstPropertyName] = struct{}{}
455 }
456
Colin Cross3f40fa42015-01-30 17:27:36 -0800457 for i := range a.generalProperties {
Colin Cross7f64b6d2015-07-09 13:57:48 -0700458 generalPropsValue := []reflect.Value{reflect.ValueOf(a.generalProperties[i]).Elem()}
Colin Cross3f40fa42015-01-30 17:27:36 -0800459
460 // Handle arch-specific properties in the form:
Colin Crossb05bff22015-04-30 15:08:04 -0700461 // arch: {
462 // arm64: {
Colin Cross3f40fa42015-01-30 17:27:36 -0800463 // key: value,
464 // },
465 // },
466 t := arch.ArchType
Colin Crossec193632015-07-06 17:49:43 -0700467 field := proptools.FieldNameForProperty(t.Name)
Colin Cross7f64b6d2015-07-09 13:57:48 -0700468 extendProperties(ctx, "arch_variant", "arch."+t.Name, generalPropsValue,
469 reflect.ValueOf(a.archProperties[i].Arch).FieldByName(field).Elem().Elem(), callback)
Colin Crossec193632015-07-06 17:49:43 -0700470
471 // Handle arch-variant-specific properties in the form:
472 // arch: {
473 // variant: {
474 // key: value,
475 // },
476 // },
477 v := dashToUnderscoreReplacer.Replace(arch.ArchVariant)
478 if v != "" {
479 field := proptools.FieldNameForProperty(v)
Colin Cross7f64b6d2015-07-09 13:57:48 -0700480 extendProperties(ctx, "arch_variant", "arch."+v, generalPropsValue,
481 reflect.ValueOf(a.archProperties[i].Arch).FieldByName(field).Elem().Elem(), callback)
Colin Crossec193632015-07-06 17:49:43 -0700482 }
483
484 // Handle cpu-variant-specific properties in the form:
485 // arch: {
486 // variant: {
487 // key: value,
488 // },
489 // },
490 c := dashToUnderscoreReplacer.Replace(arch.CpuVariant)
491 if c != "" {
492 field := proptools.FieldNameForProperty(c)
Colin Cross7f64b6d2015-07-09 13:57:48 -0700493 extendProperties(ctx, "arch_variant", "arch."+c, generalPropsValue,
494 reflect.ValueOf(a.archProperties[i].Arch).FieldByName(field).Elem().Elem(), callback)
Colin Crossec193632015-07-06 17:49:43 -0700495 }
Colin Cross3f40fa42015-01-30 17:27:36 -0800496
497 // Handle multilib-specific properties in the form:
Colin Crossb05bff22015-04-30 15:08:04 -0700498 // multilib: {
499 // lib32: {
Colin Cross3f40fa42015-01-30 17:27:36 -0800500 // key: value,
501 // },
502 // },
Colin Crossec193632015-07-06 17:49:43 -0700503 multilibField := proptools.FieldNameForProperty(t.Multilib)
Colin Cross7f64b6d2015-07-09 13:57:48 -0700504 extendProperties(ctx, "arch_variant", "multilib."+t.Multilib, generalPropsValue,
505 reflect.ValueOf(a.archProperties[i].Multilib).FieldByName(multilibField).Elem().Elem(), callback)
Colin Cross3f40fa42015-01-30 17:27:36 -0800506
507 // Handle host-or-device-specific properties in the form:
Colin Crossb05bff22015-04-30 15:08:04 -0700508 // target: {
509 // host: {
Colin Cross3f40fa42015-01-30 17:27:36 -0800510 // key: value,
511 // },
512 // },
Colin Crossec193632015-07-06 17:49:43 -0700513 hodProperty := hod.Property()
514 hodField := proptools.FieldNameForProperty(hodProperty)
Colin Cross7f64b6d2015-07-09 13:57:48 -0700515 extendProperties(ctx, "arch_variant", "target."+hodProperty, generalPropsValue,
516 reflect.ValueOf(a.archProperties[i].Target).FieldByName(hodField).Elem().Elem(), callback)
Colin Cross3f40fa42015-01-30 17:27:36 -0800517
518 // Handle host target properties in the form:
Colin Crossb05bff22015-04-30 15:08:04 -0700519 // target: {
520 // linux: {
Colin Cross3f40fa42015-01-30 17:27:36 -0800521 // key: value,
522 // },
Colin Crossb05bff22015-04-30 15:08:04 -0700523 // not_windows: {
524 // key: value,
525 // },
526 // linux_x86: {
527 // key: value,
528 // },
529 // linux_arm: {
Colin Cross3f40fa42015-01-30 17:27:36 -0800530 // key: value,
531 // },
532 // },
533 var osList = []struct {
534 goos string
535 field string
536 }{
537 {"darwin", "Darwin"},
538 {"linux", "Linux"},
539 {"windows", "Windows"},
540 }
541
542 if hod.Host() {
543 for _, v := range osList {
544 if v.goos == runtime.GOOS {
Colin Cross7f64b6d2015-07-09 13:57:48 -0700545 extendProperties(ctx, "arch_variant", "target."+v.goos, generalPropsValue,
546 reflect.ValueOf(a.archProperties[i].Target).FieldByName(v.field).Elem().Elem(), callback)
Colin Crossb05bff22015-04-30 15:08:04 -0700547 t := arch.ArchType
Colin Cross7f64b6d2015-07-09 13:57:48 -0700548 extendProperties(ctx, "arch_variant", "target."+v.goos+"_"+t.Name, generalPropsValue,
549 reflect.ValueOf(a.archProperties[i].Target).FieldByName(v.field+"_"+t.Name).Elem().Elem(), callback)
Colin Cross3f40fa42015-01-30 17:27:36 -0800550 }
551 }
Colin Cross7f64b6d2015-07-09 13:57:48 -0700552 extendProperties(ctx, "arch_variant", "target.not_windows", generalPropsValue,
553 reflect.ValueOf(a.archProperties[i].Target).FieldByName("Not_windows").Elem().Elem(), callback)
Colin Cross3f40fa42015-01-30 17:27:36 -0800554 }
555
Colin Crossf8209412015-03-26 14:44:26 -0700556 // Handle 64-bit device properties in the form:
557 // target {
558 // android64 {
559 // key: value,
560 // },
561 // android32 {
562 // key: value,
563 // },
564 // },
565 // WARNING: this is probably not what you want to use in your blueprints file, it selects
566 // options for all targets on a device that supports 64-bit binaries, not just the targets
567 // that are being compiled for 64-bit. Its expected use case is binaries like linker and
568 // debuggerd that need to know when they are a 32-bit process running on a 64-bit device
569 if hod.Device() {
570 if true /* && target_is_64_bit */ {
Colin Cross7f64b6d2015-07-09 13:57:48 -0700571 extendProperties(ctx, "arch_variant", "target.android64", generalPropsValue,
572 reflect.ValueOf(a.archProperties[i].Target).FieldByName("Android64").Elem().Elem(), callback)
Colin Crossf8209412015-03-26 14:44:26 -0700573 } else {
Colin Cross7f64b6d2015-07-09 13:57:48 -0700574 extendProperties(ctx, "arch_variant", "target.android32", generalPropsValue,
575 reflect.ValueOf(a.archProperties[i].Target).FieldByName("Android32").Elem().Elem(), callback)
Colin Crossf8209412015-03-26 14:44:26 -0700576 }
577 }
Colin Crossb05bff22015-04-30 15:08:04 -0700578
579 // Handle device architecture properties in the form:
580 // target {
581 // android_arm {
582 // key: value,
583 // },
584 // android_x86 {
585 // key: value,
586 // },
587 // },
588 if hod.Device() {
589 t := arch.ArchType
Colin Cross7f64b6d2015-07-09 13:57:48 -0700590 extendProperties(ctx, "arch_variant", "target.android_"+t.Name, generalPropsValue,
591 reflect.ValueOf(a.archProperties[i].Target).FieldByName("Android_"+t.Name).Elem().Elem(), callback)
Colin Crossb05bff22015-04-30 15:08:04 -0700592 }
593
Colin Cross3f40fa42015-01-30 17:27:36 -0800594 if ctx.Failed() {
595 return
596 }
597 }
598}
599
600func forEachInterface(v reflect.Value, f func(reflect.Value)) {
601 switch v.Kind() {
602 case reflect.Interface:
603 f(v)
604 case reflect.Struct:
605 for i := 0; i < v.NumField(); i++ {
606 forEachInterface(v.Field(i), f)
607 }
608 case reflect.Ptr:
609 forEachInterface(v.Elem(), f)
610 default:
611 panic(fmt.Errorf("Unsupported kind %s", v.Kind()))
612 }
613}