| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 1 | // 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 |  | 
|  | 15 | package common | 
|  | 16 |  | 
|  | 17 | import ( | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 18 | "fmt" | 
|  | 19 | "reflect" | 
|  | 20 | "runtime" | 
|  | 21 | "strings" | 
| Colin Cross | f6566ed | 2015-03-24 11:13:38 -0700 | [diff] [blame] | 22 |  | 
|  | 23 | "github.com/google/blueprint" | 
|  | 24 | "github.com/google/blueprint/proptools" | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 25 | ) | 
|  | 26 |  | 
| Colin Cross | 463a90e | 2015-06-17 14:20:06 -0700 | [diff] [blame] | 27 | func init() { | 
| Colin Cross | cfad119 | 2015-11-02 16:43:11 -0800 | [diff] [blame] | 28 | RegisterBottomUpMutator("defaults_deps", defaultsDepsMutator) | 
|  | 29 | RegisterTopDownMutator("defaults", defaultsMutator) | 
|  | 30 |  | 
| Colin Cross | 6362e27 | 2015-10-29 15:25:03 -0700 | [diff] [blame] | 31 | RegisterBottomUpMutator("host_or_device", HostOrDeviceMutator) | 
|  | 32 | RegisterBottomUpMutator("arch", ArchMutator) | 
| Colin Cross | 463a90e | 2015-06-17 14:20:06 -0700 | [diff] [blame] | 33 | } | 
|  | 34 |  | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 35 | var ( | 
| Colin Cross | ec19363 | 2015-07-06 17:49:43 -0700 | [diff] [blame] | 36 | Arm    = newArch("arm", "lib32") | 
|  | 37 | Arm64  = newArch("arm64", "lib64") | 
|  | 38 | Mips   = newArch("mips", "lib32") | 
|  | 39 | Mips64 = newArch("mips64", "lib64") | 
|  | 40 | X86    = newArch("x86", "lib32") | 
|  | 41 | X86_64 = newArch("x86_64", "lib64") | 
| Colin Cross | 2fe6687 | 2015-03-30 17:20:39 -0700 | [diff] [blame] | 42 |  | 
|  | 43 | Common = ArchType{ | 
|  | 44 | Name: "common", | 
|  | 45 | } | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 46 | ) | 
|  | 47 |  | 
| Colin Cross | 4225f65 | 2015-09-17 14:33:42 -0700 | [diff] [blame] | 48 | var archTypeMap = map[string]ArchType{ | 
|  | 49 | "arm":    Arm, | 
|  | 50 | "arm64":  Arm64, | 
|  | 51 | "mips":   Mips, | 
|  | 52 | "misp64": Mips64, | 
|  | 53 | "x86":    X86, | 
|  | 54 | "x86_64": X86_64, | 
|  | 55 | } | 
|  | 56 |  | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 57 | /* | 
|  | 58 | Example blueprints file containing all variant property groups, with comment listing what type | 
|  | 59 | of variants get properties in that group: | 
|  | 60 |  | 
|  | 61 | module { | 
|  | 62 | arch: { | 
|  | 63 | arm: { | 
|  | 64 | // Host or device variants with arm architecture | 
|  | 65 | }, | 
|  | 66 | arm64: { | 
|  | 67 | // Host or device variants with arm64 architecture | 
|  | 68 | }, | 
|  | 69 | mips: { | 
|  | 70 | // Host or device variants with mips architecture | 
|  | 71 | }, | 
|  | 72 | mips64: { | 
|  | 73 | // Host or device variants with mips64 architecture | 
|  | 74 | }, | 
|  | 75 | x86: { | 
|  | 76 | // Host or device variants with x86 architecture | 
|  | 77 | }, | 
|  | 78 | x86_64: { | 
|  | 79 | // Host or device variants with x86_64 architecture | 
|  | 80 | }, | 
|  | 81 | }, | 
|  | 82 | multilib: { | 
|  | 83 | lib32: { | 
|  | 84 | // Host or device variants for 32-bit architectures | 
|  | 85 | }, | 
|  | 86 | lib64: { | 
|  | 87 | // Host or device variants for 64-bit architectures | 
|  | 88 | }, | 
|  | 89 | }, | 
|  | 90 | target: { | 
|  | 91 | android: { | 
|  | 92 | // Device variants | 
|  | 93 | }, | 
|  | 94 | host: { | 
|  | 95 | // Host variants | 
|  | 96 | }, | 
|  | 97 | linux: { | 
|  | 98 | // Linux host variants | 
|  | 99 | }, | 
|  | 100 | darwin: { | 
|  | 101 | // Darwin host variants | 
|  | 102 | }, | 
|  | 103 | windows: { | 
|  | 104 | // Windows host variants | 
|  | 105 | }, | 
|  | 106 | not_windows: { | 
|  | 107 | // Non-windows host variants | 
|  | 108 | }, | 
|  | 109 | }, | 
|  | 110 | } | 
|  | 111 | */ | 
| Colin Cross | 7d5136f | 2015-05-11 13:39:40 -0700 | [diff] [blame] | 112 |  | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 113 | type archProperties struct { | 
| Colin Cross | 7d5136f | 2015-05-11 13:39:40 -0700 | [diff] [blame] | 114 | // Properties to vary by target architecture | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 115 | Arch struct { | 
| Colin Cross | 7d5136f | 2015-05-11 13:39:40 -0700 | [diff] [blame] | 116 | // Properties for module variants being built to run on arm (host or device) | 
|  | 117 | Arm interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 118 | // Properties for module variants being built to run on arm64 (host or device) | 
|  | 119 | Arm64 interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 120 | // Properties for module variants being built to run on mips (host or device) | 
|  | 121 | Mips interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 122 | // Properties for module variants being built to run on mips64 (host or device) | 
|  | 123 | Mips64 interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 124 | // Properties for module variants being built to run on x86 (host or device) | 
|  | 125 | X86 interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 126 | // Properties for module variants being built to run on x86_64 (host or device) | 
|  | 127 | X86_64 interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
| Colin Cross | ec19363 | 2015-07-06 17:49:43 -0700 | [diff] [blame] | 128 |  | 
|  | 129 | // Arm arch variants | 
|  | 130 | Armv5te      interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 131 | Armv7_a      interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 132 | Armv7_a_neon interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 133 |  | 
|  | 134 | // Arm cpu variants | 
| Dan Willemsen | 60c3dfb | 2015-10-16 17:29:12 -0700 | [diff] [blame] | 135 | Cortex_a7      interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 136 | Cortex_a8      interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 137 | Cortex_a9      interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 138 | Cortex_a15     interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 139 | Cortex_a53     interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 140 | Cortex_a53_a57 interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 141 | Krait          interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 142 | Denver         interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
| Colin Cross | ec19363 | 2015-07-06 17:49:43 -0700 | [diff] [blame] | 143 |  | 
| Colin Cross | 5602b58 | 2015-11-10 16:18:47 -0800 | [diff] [blame] | 144 | // Arm64 arch variants | 
|  | 145 | Armv8_a interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 146 |  | 
| Colin Cross | ec19363 | 2015-07-06 17:49:43 -0700 | [diff] [blame] | 147 | // Arm64 cpu variants | 
| Dan Willemsen | 60c3dfb | 2015-10-16 17:29:12 -0700 | [diff] [blame] | 148 | Cortex_a53_64 interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 149 | Denver64      interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
| Colin Cross | ec19363 | 2015-07-06 17:49:43 -0700 | [diff] [blame] | 150 |  | 
|  | 151 | // Mips arch variants | 
|  | 152 | Mips_rev6 interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 153 |  | 
| Colin Cross | 01432f6 | 2015-07-09 17:56:26 -0700 | [diff] [blame] | 154 | // X86 arch variants | 
| Dan Willemsen | 96dc9f3 | 2015-10-16 16:31:15 -0700 | [diff] [blame] | 155 | X86_ssse3 interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
| Colin Cross | 6d27f34 | 2015-10-28 17:23:16 -0700 | [diff] [blame] | 156 | X86_sse4  interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
| Colin Cross | 01432f6 | 2015-07-09 17:56:26 -0700 | [diff] [blame] | 157 |  | 
| Colin Cross | ec19363 | 2015-07-06 17:49:43 -0700 | [diff] [blame] | 158 | // X86 cpu variants | 
|  | 159 | Atom       interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 160 | Silvermont interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 161 | } | 
| Colin Cross | ec19363 | 2015-07-06 17:49:43 -0700 | [diff] [blame] | 162 |  | 
| Colin Cross | 7d5136f | 2015-05-11 13:39:40 -0700 | [diff] [blame] | 163 | // Properties to vary by 32-bit or 64-bit | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 164 | Multilib struct { | 
| Colin Cross | 7d5136f | 2015-05-11 13:39:40 -0700 | [diff] [blame] | 165 | // Properties for module variants being built to run on 32-bit devices | 
|  | 166 | Lib32 interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 167 | // Properties for module variants being built to run on 64-bit devices | 
|  | 168 | Lib64 interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 169 | } | 
| Colin Cross | 7d5136f | 2015-05-11 13:39:40 -0700 | [diff] [blame] | 170 | // Properties to vary by build target (host or device, os, os+archictecture) | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 171 | Target struct { | 
| Colin Cross | 7d5136f | 2015-05-11 13:39:40 -0700 | [diff] [blame] | 172 | // Properties for module variants being built to run on the host | 
|  | 173 | Host interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 174 | // Properties for module variants being built to run on the device | 
|  | 175 | Android interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 176 | // Properties for module variants being built to run on arm devices | 
|  | 177 | Android_arm interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 178 | // Properties for module variants being built to run on arm64 devices | 
|  | 179 | Android_arm64 interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 180 | // Properties for module variants being built to run on mips devices | 
|  | 181 | Android_mips interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 182 | // Properties for module variants being built to run on mips64 devices | 
|  | 183 | Android_mips64 interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 184 | // Properties for module variants being built to run on x86 devices | 
|  | 185 | Android_x86 interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 186 | // Properties for module variants being built to run on x86_64 devices | 
|  | 187 | Android_x86_64 interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 188 | // Properties for module variants being built to run on devices that support 64-bit | 
|  | 189 | Android64 interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 190 | // Properties for module variants being built to run on devices that do not support 64-bit | 
|  | 191 | Android32 interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 192 | // Properties for module variants being built to run on linux hosts | 
|  | 193 | Linux interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 194 | // Properties for module variants being built to run on linux x86 hosts | 
|  | 195 | Linux_x86 interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 196 | // Properties for module variants being built to run on linux x86_64 hosts | 
|  | 197 | Linux_x86_64 interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 198 | // Properties for module variants being built to run on darwin hosts | 
|  | 199 | Darwin interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 200 | // Properties for module variants being built to run on darwin x86 hosts | 
|  | 201 | Darwin_x86 interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 202 | // Properties for module variants being built to run on darwin x86_64 hosts | 
|  | 203 | Darwin_x86_64 interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 204 | // Properties for module variants being built to run on windows hosts | 
|  | 205 | Windows interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
|  | 206 | // Properties for module variants being built to run on linux or darwin hosts | 
|  | 207 | Not_windows interface{} `blueprint:"filter(android:\"arch_variant\")"` | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 208 | } | 
|  | 209 | } | 
|  | 210 |  | 
|  | 211 | // An Arch indicates a single CPU architecture. | 
|  | 212 | type Arch struct { | 
| Colin Cross | d3ba039 | 2015-05-07 14:11:29 -0700 | [diff] [blame] | 213 | ArchType    ArchType | 
|  | 214 | ArchVariant string | 
|  | 215 | CpuVariant  string | 
| Colin Cross | 4225f65 | 2015-09-17 14:33:42 -0700 | [diff] [blame] | 216 | Abi         []string | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 217 | } | 
|  | 218 |  | 
|  | 219 | func (a Arch) String() string { | 
| Colin Cross | d3ba039 | 2015-05-07 14:11:29 -0700 | [diff] [blame] | 220 | s := a.ArchType.String() | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 221 | if a.ArchVariant != "" { | 
|  | 222 | s += "_" + a.ArchVariant | 
|  | 223 | } | 
|  | 224 | if a.CpuVariant != "" { | 
|  | 225 | s += "_" + a.CpuVariant | 
|  | 226 | } | 
|  | 227 | return s | 
|  | 228 | } | 
|  | 229 |  | 
|  | 230 | type ArchType struct { | 
| Colin Cross | ec19363 | 2015-07-06 17:49:43 -0700 | [diff] [blame] | 231 | Name     string | 
|  | 232 | Multilib string | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 233 | } | 
|  | 234 |  | 
| Colin Cross | ec19363 | 2015-07-06 17:49:43 -0700 | [diff] [blame] | 235 | func newArch(name, multilib string) ArchType { | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 236 | return ArchType{ | 
| Colin Cross | ec19363 | 2015-07-06 17:49:43 -0700 | [diff] [blame] | 237 | Name:     name, | 
|  | 238 | Multilib: multilib, | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 239 | } | 
|  | 240 | } | 
|  | 241 |  | 
|  | 242 | func (a ArchType) String() string { | 
|  | 243 | return a.Name | 
|  | 244 | } | 
|  | 245 |  | 
|  | 246 | type HostOrDeviceSupported int | 
|  | 247 |  | 
|  | 248 | const ( | 
|  | 249 | _ HostOrDeviceSupported = iota | 
|  | 250 | HostSupported | 
|  | 251 | DeviceSupported | 
|  | 252 | HostAndDeviceSupported | 
|  | 253 | ) | 
|  | 254 |  | 
|  | 255 | type HostOrDevice int | 
|  | 256 |  | 
|  | 257 | const ( | 
|  | 258 | _ HostOrDevice = iota | 
|  | 259 | Host | 
|  | 260 | Device | 
|  | 261 | ) | 
|  | 262 |  | 
|  | 263 | func (hod HostOrDevice) String() string { | 
|  | 264 | switch hod { | 
|  | 265 | case Device: | 
|  | 266 | return "device" | 
|  | 267 | case Host: | 
|  | 268 | return "host" | 
|  | 269 | default: | 
|  | 270 | panic(fmt.Sprintf("unexpected HostOrDevice value %d", hod)) | 
|  | 271 | } | 
|  | 272 | } | 
|  | 273 |  | 
| Colin Cross | ec19363 | 2015-07-06 17:49:43 -0700 | [diff] [blame] | 274 | func (hod HostOrDevice) Property() string { | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 275 | switch hod { | 
|  | 276 | case Device: | 
|  | 277 | return "android" | 
|  | 278 | case Host: | 
|  | 279 | return "host" | 
|  | 280 | default: | 
|  | 281 | panic(fmt.Sprintf("unexpected HostOrDevice value %d", hod)) | 
|  | 282 | } | 
|  | 283 | } | 
|  | 284 |  | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 285 | func (hod HostOrDevice) Host() bool { | 
|  | 286 | if hod == 0 { | 
|  | 287 | panic("HostOrDevice unset") | 
|  | 288 | } | 
|  | 289 | return hod == Host | 
|  | 290 | } | 
|  | 291 |  | 
|  | 292 | func (hod HostOrDevice) Device() bool { | 
|  | 293 | if hod == 0 { | 
|  | 294 | panic("HostOrDevice unset") | 
|  | 295 | } | 
|  | 296 | return hod == Device | 
|  | 297 | } | 
|  | 298 |  | 
|  | 299 | var hostOrDeviceName = map[HostOrDevice]string{ | 
|  | 300 | Device: "device", | 
|  | 301 | Host:   "host", | 
|  | 302 | } | 
|  | 303 |  | 
|  | 304 | var ( | 
| Colin Cross | d3ba039 | 2015-05-07 14:11:29 -0700 | [diff] [blame] | 305 | commonArch = Arch{ | 
|  | 306 | ArchType: Common, | 
| Colin Cross | 2fe6687 | 2015-03-30 17:20:39 -0700 | [diff] [blame] | 307 | } | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 308 | ) | 
|  | 309 |  | 
| Colin Cross | 6362e27 | 2015-10-29 15:25:03 -0700 | [diff] [blame] | 310 | func HostOrDeviceMutator(mctx AndroidBottomUpMutatorContext) { | 
| Colin Cross | d3ba039 | 2015-05-07 14:11:29 -0700 | [diff] [blame] | 311 | var module AndroidModule | 
|  | 312 | var ok bool | 
|  | 313 | if module, ok = mctx.Module().(AndroidModule); !ok { | 
|  | 314 | return | 
|  | 315 | } | 
|  | 316 |  | 
|  | 317 | hods := []HostOrDevice{} | 
|  | 318 |  | 
|  | 319 | if module.base().HostSupported() { | 
|  | 320 | hods = append(hods, Host) | 
|  | 321 | } | 
|  | 322 |  | 
|  | 323 | if module.base().DeviceSupported() { | 
|  | 324 | hods = append(hods, Device) | 
|  | 325 | } | 
|  | 326 |  | 
|  | 327 | if len(hods) == 0 { | 
|  | 328 | return | 
|  | 329 | } | 
|  | 330 |  | 
|  | 331 | hodNames := []string{} | 
|  | 332 | for _, hod := range hods { | 
|  | 333 | hodNames = append(hodNames, hod.String()) | 
|  | 334 | } | 
|  | 335 |  | 
|  | 336 | modules := mctx.CreateVariations(hodNames...) | 
|  | 337 | for i, m := range modules { | 
|  | 338 | m.(AndroidModule).base().SetHostOrDevice(hods[i]) | 
|  | 339 | } | 
|  | 340 | } | 
|  | 341 |  | 
| Colin Cross | 6362e27 | 2015-10-29 15:25:03 -0700 | [diff] [blame] | 342 | func ArchMutator(mctx AndroidBottomUpMutatorContext) { | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 343 | var module AndroidModule | 
|  | 344 | var ok bool | 
|  | 345 | if module, ok = mctx.Module().(AndroidModule); !ok { | 
|  | 346 | return | 
|  | 347 | } | 
|  | 348 |  | 
| Colin Cross | 4225f65 | 2015-09-17 14:33:42 -0700 | [diff] [blame] | 349 | hostArches, deviceArches, err := decodeArchProductVariables(mctx.Config().(Config).ProductVariables) | 
|  | 350 | if err != nil { | 
|  | 351 | mctx.ModuleErrorf("%s", err.Error()) | 
|  | 352 | } | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 353 |  | 
| Colin Cross | 4225f65 | 2015-09-17 14:33:42 -0700 | [diff] [blame] | 354 | moduleArches := []Arch{} | 
|  | 355 | multilib := module.base().commonProperties.Compile_multilib | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 356 |  | 
| Colin Cross | d3ba039 | 2015-05-07 14:11:29 -0700 | [diff] [blame] | 357 | if module.base().HostSupported() && module.base().HostOrDevice().Host() { | 
| Colin Cross | 4225f65 | 2015-09-17 14:33:42 -0700 | [diff] [blame] | 358 | hostModuleArches, err := decodeMultilib(multilib, hostArches) | 
|  | 359 | if err != nil { | 
|  | 360 | mctx.ModuleErrorf("%s", err.Error()) | 
| Colin Cross | 2fe6687 | 2015-03-30 17:20:39 -0700 | [diff] [blame] | 361 | } | 
| Colin Cross | 4225f65 | 2015-09-17 14:33:42 -0700 | [diff] [blame] | 362 |  | 
|  | 363 | moduleArches = append(moduleArches, hostModuleArches...) | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 364 | } | 
|  | 365 |  | 
| Colin Cross | d3ba039 | 2015-05-07 14:11:29 -0700 | [diff] [blame] | 366 | if module.base().DeviceSupported() && module.base().HostOrDevice().Device() { | 
| Colin Cross | 4225f65 | 2015-09-17 14:33:42 -0700 | [diff] [blame] | 367 | deviceModuleArches, err := decodeMultilib(multilib, deviceArches) | 
|  | 368 | if err != nil { | 
|  | 369 | mctx.ModuleErrorf("%s", err.Error()) | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 370 | } | 
| Colin Cross | 4225f65 | 2015-09-17 14:33:42 -0700 | [diff] [blame] | 371 |  | 
|  | 372 | moduleArches = append(moduleArches, deviceModuleArches...) | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 373 | } | 
|  | 374 |  | 
| Colin Cross | 4225f65 | 2015-09-17 14:33:42 -0700 | [diff] [blame] | 375 | if len(moduleArches) == 0 { | 
| Colin Cross | 5049f02 | 2015-03-18 13:28:46 -0700 | [diff] [blame] | 376 | return | 
|  | 377 | } | 
|  | 378 |  | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 379 | archNames := []string{} | 
| Colin Cross | 4225f65 | 2015-09-17 14:33:42 -0700 | [diff] [blame] | 380 | for _, arch := range moduleArches { | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 381 | archNames = append(archNames, arch.String()) | 
|  | 382 | } | 
|  | 383 |  | 
|  | 384 | modules := mctx.CreateVariations(archNames...) | 
|  | 385 |  | 
|  | 386 | for i, m := range modules { | 
| Colin Cross | 4225f65 | 2015-09-17 14:33:42 -0700 | [diff] [blame] | 387 | m.(AndroidModule).base().SetArch(moduleArches[i]) | 
| Colin Cross | d3ba039 | 2015-05-07 14:11:29 -0700 | [diff] [blame] | 388 | m.(AndroidModule).base().setArchProperties(mctx) | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 389 | } | 
|  | 390 | } | 
|  | 391 |  | 
| Colin Cross | cfad119 | 2015-11-02 16:43:11 -0800 | [diff] [blame] | 392 | func InitArchModule(m AndroidModule, | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 393 | propertyStructs ...interface{}) (blueprint.Module, []interface{}) { | 
|  | 394 |  | 
|  | 395 | base := m.base() | 
|  | 396 |  | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 397 | base.generalProperties = append(base.generalProperties, | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 398 | propertyStructs...) | 
|  | 399 |  | 
|  | 400 | for _, properties := range base.generalProperties { | 
|  | 401 | propertiesValue := reflect.ValueOf(properties) | 
|  | 402 | if propertiesValue.Kind() != reflect.Ptr { | 
|  | 403 | panic("properties must be a pointer to a struct") | 
|  | 404 | } | 
|  | 405 |  | 
|  | 406 | propertiesValue = propertiesValue.Elem() | 
|  | 407 | if propertiesValue.Kind() != reflect.Struct { | 
|  | 408 | panic("properties must be a pointer to a struct") | 
|  | 409 | } | 
|  | 410 |  | 
|  | 411 | archProperties := &archProperties{} | 
|  | 412 | forEachInterface(reflect.ValueOf(archProperties), func(v reflect.Value) { | 
| Colin Cross | 3ab7d88 | 2015-05-19 13:03:01 -0700 | [diff] [blame] | 413 | newValue := proptools.CloneEmptyProperties(propertiesValue) | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 414 | v.Set(newValue) | 
|  | 415 | }) | 
|  | 416 |  | 
|  | 417 | base.archProperties = append(base.archProperties, archProperties) | 
|  | 418 | } | 
|  | 419 |  | 
|  | 420 | var allProperties []interface{} | 
|  | 421 | allProperties = append(allProperties, base.generalProperties...) | 
|  | 422 | for _, asp := range base.archProperties { | 
|  | 423 | allProperties = append(allProperties, asp) | 
|  | 424 | } | 
|  | 425 |  | 
|  | 426 | return m, allProperties | 
|  | 427 | } | 
|  | 428 |  | 
| Colin Cross | ec19363 | 2015-07-06 17:49:43 -0700 | [diff] [blame] | 429 | var dashToUnderscoreReplacer = strings.NewReplacer("-", "_") | 
|  | 430 |  | 
| Colin Cross | 6362e27 | 2015-10-29 15:25:03 -0700 | [diff] [blame] | 431 | func (a *AndroidModuleBase) appendProperties(ctx AndroidBottomUpMutatorContext, | 
| Colin Cross | 06a931b | 2015-10-28 17:23:31 -0700 | [diff] [blame] | 432 | dst, src interface{}, field, srcPrefix string) { | 
|  | 433 |  | 
| Colin Cross | eeabb89 | 2015-11-20 13:07:51 -0800 | [diff] [blame^] | 434 | srcField := reflect.ValueOf(src).FieldByName(field) | 
|  | 435 | if !srcField.IsValid() { | 
|  | 436 | ctx.ModuleErrorf("field %q does not exist", srcPrefix) | 
|  | 437 | return | 
|  | 438 | } | 
|  | 439 |  | 
|  | 440 | src = srcField.Elem().Interface() | 
| Colin Cross | 06a931b | 2015-10-28 17:23:31 -0700 | [diff] [blame] | 441 |  | 
|  | 442 | filter := func(property string, | 
|  | 443 | dstField, srcField reflect.StructField, | 
|  | 444 | dstValue, srcValue interface{}) (bool, error) { | 
|  | 445 |  | 
|  | 446 | srcProperty := srcPrefix + "." + property | 
|  | 447 |  | 
|  | 448 | if !proptools.HasTag(dstField, "android", "arch_variant") { | 
|  | 449 | if ctx.ContainsProperty(srcProperty) { | 
|  | 450 | return false, fmt.Errorf("can't be specific to a build variant") | 
|  | 451 | } else { | 
|  | 452 | return false, nil | 
|  | 453 | } | 
|  | 454 | } | 
|  | 455 |  | 
|  | 456 | return true, nil | 
|  | 457 | } | 
|  | 458 |  | 
|  | 459 | err := proptools.AppendProperties(dst, src, filter) | 
|  | 460 | if err != nil { | 
|  | 461 | if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok { | 
|  | 462 | ctx.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error()) | 
|  | 463 | } else { | 
|  | 464 | panic(err) | 
|  | 465 | } | 
|  | 466 | } | 
|  | 467 | } | 
|  | 468 |  | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 469 | // Rewrite the module's properties structs to contain arch-specific values. | 
| Colin Cross | 6362e27 | 2015-10-29 15:25:03 -0700 | [diff] [blame] | 470 | func (a *AndroidModuleBase) setArchProperties(ctx AndroidBottomUpMutatorContext) { | 
| Colin Cross | d3ba039 | 2015-05-07 14:11:29 -0700 | [diff] [blame] | 471 | arch := a.commonProperties.CompileArch | 
|  | 472 | hod := a.commonProperties.CompileHostOrDevice | 
|  | 473 |  | 
| Colin Cross | 2fe6687 | 2015-03-30 17:20:39 -0700 | [diff] [blame] | 474 | if arch.ArchType == Common { | 
|  | 475 | return | 
|  | 476 | } | 
|  | 477 |  | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 478 | for i := range a.generalProperties { | 
| Colin Cross | 06a931b | 2015-10-28 17:23:31 -0700 | [diff] [blame] | 479 | genProps := a.generalProperties[i] | 
|  | 480 | archProps := a.archProperties[i] | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 481 | // Handle arch-specific properties in the form: | 
| Colin Cross | b05bff2 | 2015-04-30 15:08:04 -0700 | [diff] [blame] | 482 | // arch: { | 
|  | 483 | //     arm64: { | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 484 | //         key: value, | 
|  | 485 | //     }, | 
|  | 486 | // }, | 
|  | 487 | t := arch.ArchType | 
| Colin Cross | 06a931b | 2015-10-28 17:23:31 -0700 | [diff] [blame] | 488 |  | 
| Colin Cross | ec19363 | 2015-07-06 17:49:43 -0700 | [diff] [blame] | 489 | field := proptools.FieldNameForProperty(t.Name) | 
| Colin Cross | 06a931b | 2015-10-28 17:23:31 -0700 | [diff] [blame] | 490 | prefix := "arch." + t.Name | 
|  | 491 | a.appendProperties(ctx, genProps, archProps.Arch, field, prefix) | 
| Colin Cross | ec19363 | 2015-07-06 17:49:43 -0700 | [diff] [blame] | 492 |  | 
|  | 493 | // Handle arch-variant-specific properties in the form: | 
|  | 494 | // arch: { | 
|  | 495 | //     variant: { | 
|  | 496 | //         key: value, | 
|  | 497 | //     }, | 
|  | 498 | // }, | 
|  | 499 | v := dashToUnderscoreReplacer.Replace(arch.ArchVariant) | 
|  | 500 | if v != "" { | 
|  | 501 | field := proptools.FieldNameForProperty(v) | 
| Colin Cross | 06a931b | 2015-10-28 17:23:31 -0700 | [diff] [blame] | 502 | prefix := "arch." + v | 
|  | 503 | a.appendProperties(ctx, genProps, archProps.Arch, field, prefix) | 
| Colin Cross | ec19363 | 2015-07-06 17:49:43 -0700 | [diff] [blame] | 504 | } | 
|  | 505 |  | 
|  | 506 | // Handle cpu-variant-specific properties in the form: | 
|  | 507 | // arch: { | 
|  | 508 | //     variant: { | 
|  | 509 | //         key: value, | 
|  | 510 | //     }, | 
|  | 511 | // }, | 
|  | 512 | c := dashToUnderscoreReplacer.Replace(arch.CpuVariant) | 
|  | 513 | if c != "" { | 
|  | 514 | field := proptools.FieldNameForProperty(c) | 
| Colin Cross | 06a931b | 2015-10-28 17:23:31 -0700 | [diff] [blame] | 515 | prefix := "arch." + c | 
|  | 516 | a.appendProperties(ctx, genProps, archProps.Arch, field, prefix) | 
| Colin Cross | ec19363 | 2015-07-06 17:49:43 -0700 | [diff] [blame] | 517 | } | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 518 |  | 
|  | 519 | // Handle multilib-specific properties in the form: | 
| Colin Cross | b05bff2 | 2015-04-30 15:08:04 -0700 | [diff] [blame] | 520 | // multilib: { | 
|  | 521 | //     lib32: { | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 522 | //         key: value, | 
|  | 523 | //     }, | 
|  | 524 | // }, | 
| Colin Cross | 06a931b | 2015-10-28 17:23:31 -0700 | [diff] [blame] | 525 | field = proptools.FieldNameForProperty(t.Multilib) | 
|  | 526 | prefix = "multilib." + t.Multilib | 
|  | 527 | a.appendProperties(ctx, genProps, archProps.Multilib, field, prefix) | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 528 |  | 
|  | 529 | // Handle host-or-device-specific properties in the form: | 
| Colin Cross | b05bff2 | 2015-04-30 15:08:04 -0700 | [diff] [blame] | 530 | // target: { | 
|  | 531 | //     host: { | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 532 | //         key: value, | 
|  | 533 | //     }, | 
|  | 534 | // }, | 
| Colin Cross | ec19363 | 2015-07-06 17:49:43 -0700 | [diff] [blame] | 535 | hodProperty := hod.Property() | 
| Colin Cross | 06a931b | 2015-10-28 17:23:31 -0700 | [diff] [blame] | 536 | field = proptools.FieldNameForProperty(hodProperty) | 
|  | 537 | prefix = "target." + hodProperty | 
|  | 538 | a.appendProperties(ctx, genProps, archProps.Target, field, prefix) | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 539 |  | 
|  | 540 | // Handle host target properties in the form: | 
| Colin Cross | b05bff2 | 2015-04-30 15:08:04 -0700 | [diff] [blame] | 541 | // target: { | 
|  | 542 | //     linux: { | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 543 | //         key: value, | 
|  | 544 | //     }, | 
| Colin Cross | b05bff2 | 2015-04-30 15:08:04 -0700 | [diff] [blame] | 545 | //     not_windows: { | 
|  | 546 | //         key: value, | 
|  | 547 | //     }, | 
|  | 548 | //     linux_x86: { | 
|  | 549 | //         key: value, | 
|  | 550 | //     }, | 
|  | 551 | //     linux_arm: { | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 552 | //         key: value, | 
|  | 553 | //     }, | 
|  | 554 | // }, | 
|  | 555 | var osList = []struct { | 
|  | 556 | goos  string | 
|  | 557 | field string | 
|  | 558 | }{ | 
|  | 559 | {"darwin", "Darwin"}, | 
|  | 560 | {"linux", "Linux"}, | 
|  | 561 | {"windows", "Windows"}, | 
|  | 562 | } | 
|  | 563 |  | 
|  | 564 | if hod.Host() { | 
|  | 565 | for _, v := range osList { | 
|  | 566 | if v.goos == runtime.GOOS { | 
| Colin Cross | 06a931b | 2015-10-28 17:23:31 -0700 | [diff] [blame] | 567 | field := v.field | 
|  | 568 | prefix := "target." + v.goos | 
|  | 569 | a.appendProperties(ctx, genProps, archProps.Target, field, prefix) | 
| Colin Cross | b05bff2 | 2015-04-30 15:08:04 -0700 | [diff] [blame] | 570 | t := arch.ArchType | 
| Colin Cross | 06a931b | 2015-10-28 17:23:31 -0700 | [diff] [blame] | 571 | field = v.field + "_" + t.Name | 
|  | 572 | prefix = "target." + v.goos + "_" + t.Name | 
|  | 573 | a.appendProperties(ctx, genProps, archProps.Target, field, prefix) | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 574 | } | 
|  | 575 | } | 
| Colin Cross | 06a931b | 2015-10-28 17:23:31 -0700 | [diff] [blame] | 576 | field := "Not_windows" | 
|  | 577 | prefix := "target.not_windows" | 
|  | 578 | a.appendProperties(ctx, genProps, archProps.Target, field, prefix) | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 579 | } | 
|  | 580 |  | 
| Colin Cross | f820941 | 2015-03-26 14:44:26 -0700 | [diff] [blame] | 581 | // Handle 64-bit device properties in the form: | 
|  | 582 | // target { | 
|  | 583 | //     android64 { | 
|  | 584 | //         key: value, | 
|  | 585 | //     }, | 
|  | 586 | //     android32 { | 
|  | 587 | //         key: value, | 
|  | 588 | //     }, | 
|  | 589 | // }, | 
|  | 590 | // WARNING: this is probably not what you want to use in your blueprints file, it selects | 
|  | 591 | // options for all targets on a device that supports 64-bit binaries, not just the targets | 
|  | 592 | // that are being compiled for 64-bit.  Its expected use case is binaries like linker and | 
|  | 593 | // debuggerd that need to know when they are a 32-bit process running on a 64-bit device | 
|  | 594 | if hod.Device() { | 
|  | 595 | if true /* && target_is_64_bit */ { | 
| Colin Cross | 06a931b | 2015-10-28 17:23:31 -0700 | [diff] [blame] | 596 | field := "Android64" | 
|  | 597 | prefix := "target.android64" | 
|  | 598 | a.appendProperties(ctx, genProps, archProps.Target, field, prefix) | 
| Colin Cross | f820941 | 2015-03-26 14:44:26 -0700 | [diff] [blame] | 599 | } else { | 
| Colin Cross | 06a931b | 2015-10-28 17:23:31 -0700 | [diff] [blame] | 600 | field := "Android32" | 
|  | 601 | prefix := "target.android32" | 
|  | 602 | a.appendProperties(ctx, genProps, archProps.Target, field, prefix) | 
| Colin Cross | f820941 | 2015-03-26 14:44:26 -0700 | [diff] [blame] | 603 | } | 
|  | 604 | } | 
| Colin Cross | b05bff2 | 2015-04-30 15:08:04 -0700 | [diff] [blame] | 605 |  | 
|  | 606 | // Handle device architecture properties in the form: | 
|  | 607 | // target { | 
|  | 608 | //     android_arm { | 
|  | 609 | //         key: value, | 
|  | 610 | //     }, | 
|  | 611 | //     android_x86 { | 
|  | 612 | //         key: value, | 
|  | 613 | //     }, | 
|  | 614 | // }, | 
|  | 615 | if hod.Device() { | 
|  | 616 | t := arch.ArchType | 
| Colin Cross | 06a931b | 2015-10-28 17:23:31 -0700 | [diff] [blame] | 617 | field := "Android_" + t.Name | 
|  | 618 | prefix := "target.android_" + t.Name | 
|  | 619 | a.appendProperties(ctx, genProps, archProps.Target, field, prefix) | 
| Colin Cross | b05bff2 | 2015-04-30 15:08:04 -0700 | [diff] [blame] | 620 | } | 
|  | 621 |  | 
| Colin Cross | 3f40fa4 | 2015-01-30 17:27:36 -0800 | [diff] [blame] | 622 | if ctx.Failed() { | 
|  | 623 | return | 
|  | 624 | } | 
|  | 625 | } | 
|  | 626 | } | 
|  | 627 |  | 
|  | 628 | func forEachInterface(v reflect.Value, f func(reflect.Value)) { | 
|  | 629 | switch v.Kind() { | 
|  | 630 | case reflect.Interface: | 
|  | 631 | f(v) | 
|  | 632 | case reflect.Struct: | 
|  | 633 | for i := 0; i < v.NumField(); i++ { | 
|  | 634 | forEachInterface(v.Field(i), f) | 
|  | 635 | } | 
|  | 636 | case reflect.Ptr: | 
|  | 637 | forEachInterface(v.Elem(), f) | 
|  | 638 | default: | 
|  | 639 | panic(fmt.Errorf("Unsupported kind %s", v.Kind())) | 
|  | 640 | } | 
|  | 641 | } | 
| Colin Cross | 4225f65 | 2015-09-17 14:33:42 -0700 | [diff] [blame] | 642 |  | 
|  | 643 | // Convert the arch product variables into a list of host and device Arch structs | 
|  | 644 | func decodeArchProductVariables(variables productVariables) ([]Arch, []Arch, error) { | 
|  | 645 | if variables.HostArch == nil { | 
|  | 646 | return nil, nil, fmt.Errorf("No host primary architecture set") | 
|  | 647 | } | 
|  | 648 |  | 
|  | 649 | hostArch, err := decodeArch(*variables.HostArch, nil, nil, nil) | 
|  | 650 | if err != nil { | 
|  | 651 | return nil, nil, err | 
|  | 652 | } | 
|  | 653 |  | 
|  | 654 | hostArches := []Arch{hostArch} | 
|  | 655 |  | 
| Colin Cross | eeabb89 | 2015-11-20 13:07:51 -0800 | [diff] [blame^] | 656 | if variables.HostSecondaryArch != nil && *variables.HostSecondaryArch != "" { | 
| Colin Cross | 4225f65 | 2015-09-17 14:33:42 -0700 | [diff] [blame] | 657 | hostSecondaryArch, err := decodeArch(*variables.HostSecondaryArch, nil, nil, nil) | 
|  | 658 | if err != nil { | 
|  | 659 | return nil, nil, err | 
|  | 660 | } | 
|  | 661 | hostArches = append(hostArches, hostSecondaryArch) | 
|  | 662 | } | 
|  | 663 |  | 
|  | 664 | if variables.DeviceArch == nil { | 
|  | 665 | return nil, nil, fmt.Errorf("No device primary architecture set") | 
|  | 666 | } | 
|  | 667 |  | 
|  | 668 | deviceArch, err := decodeArch(*variables.DeviceArch, variables.DeviceArchVariant, | 
|  | 669 | variables.DeviceCpuVariant, variables.DeviceAbi) | 
|  | 670 | if err != nil { | 
|  | 671 | return nil, nil, err | 
|  | 672 | } | 
|  | 673 |  | 
|  | 674 | deviceArches := []Arch{deviceArch} | 
|  | 675 |  | 
| Colin Cross | eeabb89 | 2015-11-20 13:07:51 -0800 | [diff] [blame^] | 676 | if variables.DeviceSecondaryArch != nil && *variables.DeviceSecondaryArch != "" { | 
| Colin Cross | 4225f65 | 2015-09-17 14:33:42 -0700 | [diff] [blame] | 677 | deviceSecondaryArch, err := decodeArch(*variables.DeviceSecondaryArch, | 
|  | 678 | variables.DeviceSecondaryArchVariant, variables.DeviceSecondaryCpuVariant, | 
|  | 679 | variables.DeviceSecondaryAbi) | 
|  | 680 | if err != nil { | 
|  | 681 | return nil, nil, err | 
|  | 682 | } | 
|  | 683 | deviceArches = append(deviceArches, deviceSecondaryArch) | 
|  | 684 | } | 
|  | 685 |  | 
|  | 686 | return hostArches, deviceArches, nil | 
|  | 687 | } | 
|  | 688 |  | 
|  | 689 | // Convert a set of strings from product variables into a single Arch struct | 
|  | 690 | func decodeArch(arch string, archVariant, cpuVariant *string, abi *[]string) (Arch, error) { | 
|  | 691 | stringPtr := func(p *string) string { | 
|  | 692 | if p != nil { | 
|  | 693 | return *p | 
|  | 694 | } | 
|  | 695 | return "" | 
|  | 696 | } | 
|  | 697 |  | 
|  | 698 | slicePtr := func(p *[]string) []string { | 
|  | 699 | if p != nil { | 
|  | 700 | return *p | 
|  | 701 | } | 
|  | 702 | return nil | 
|  | 703 | } | 
|  | 704 |  | 
| Colin Cross | eeabb89 | 2015-11-20 13:07:51 -0800 | [diff] [blame^] | 705 | archType, ok := archTypeMap[arch] | 
|  | 706 | if !ok { | 
|  | 707 | return Arch{}, fmt.Errorf("unknown arch %q", arch) | 
|  | 708 | } | 
| Colin Cross | 4225f65 | 2015-09-17 14:33:42 -0700 | [diff] [blame] | 709 |  | 
| Colin Cross | eeabb89 | 2015-11-20 13:07:51 -0800 | [diff] [blame^] | 710 | a := Arch{ | 
| Colin Cross | 4225f65 | 2015-09-17 14:33:42 -0700 | [diff] [blame] | 711 | ArchType:    archType, | 
|  | 712 | ArchVariant: stringPtr(archVariant), | 
|  | 713 | CpuVariant:  stringPtr(cpuVariant), | 
|  | 714 | Abi:         slicePtr(abi), | 
| Colin Cross | eeabb89 | 2015-11-20 13:07:51 -0800 | [diff] [blame^] | 715 | } | 
|  | 716 |  | 
|  | 717 | if a.ArchVariant == a.ArchType.Name || a.ArchVariant == "generic" { | 
|  | 718 | a.ArchVariant = "" | 
|  | 719 | } | 
|  | 720 |  | 
|  | 721 | if a.CpuVariant == a.ArchType.Name || a.CpuVariant == "generic" { | 
|  | 722 | a.CpuVariant = "" | 
|  | 723 | } | 
|  | 724 |  | 
|  | 725 | for i := 0; i < len(a.Abi); i++ { | 
|  | 726 | if a.Abi[i] == "" { | 
|  | 727 | a.Abi = append(a.Abi[:i], a.Abi[i+1:]...) | 
|  | 728 | i-- | 
|  | 729 | } | 
|  | 730 | } | 
|  | 731 |  | 
|  | 732 | return a, nil | 
| Colin Cross | 4225f65 | 2015-09-17 14:33:42 -0700 | [diff] [blame] | 733 | } | 
|  | 734 |  | 
|  | 735 | // Use the module multilib setting to select one or more arches from an arch list | 
|  | 736 | func decodeMultilib(multilib string, arches []Arch) ([]Arch, error) { | 
|  | 737 | buildArches := []Arch{} | 
|  | 738 | switch multilib { | 
|  | 739 | case "common": | 
|  | 740 | buildArches = append(buildArches, commonArch) | 
|  | 741 | case "both": | 
|  | 742 | buildArches = append(buildArches, arches...) | 
|  | 743 | case "first": | 
|  | 744 | buildArches = append(buildArches, arches[0]) | 
|  | 745 | case "32": | 
|  | 746 | for _, a := range arches { | 
|  | 747 | if a.ArchType.Multilib == "lib32" { | 
|  | 748 | buildArches = append(buildArches, a) | 
|  | 749 | } | 
|  | 750 | } | 
|  | 751 | case "64": | 
|  | 752 | for _, a := range arches { | 
|  | 753 | if a.ArchType.Multilib == "lib64" { | 
|  | 754 | buildArches = append(buildArches, a) | 
|  | 755 | } | 
|  | 756 | } | 
|  | 757 | default: | 
|  | 758 | return nil, fmt.Errorf(`compile_multilib must be "both", "first", "32", or "64", found %q`, | 
|  | 759 | multilib) | 
|  | 760 | //buildArches = append(buildArches, arches[0]) | 
|  | 761 | } | 
|  | 762 |  | 
|  | 763 | return buildArches, nil | 
|  | 764 | } |