arch.go 76 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254
  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. package android
  15. import (
  16. "encoding"
  17. "fmt"
  18. "reflect"
  19. "runtime"
  20. "strings"
  21. "android/soong/bazel"
  22. "android/soong/starlark_fmt"
  23. "github.com/google/blueprint"
  24. "github.com/google/blueprint/bootstrap"
  25. "github.com/google/blueprint/proptools"
  26. )
  27. /*
  28. Example blueprints file containing all variant property groups, with comment listing what type
  29. of variants get properties in that group:
  30. module {
  31. arch: {
  32. arm: {
  33. // Host or device variants with arm architecture
  34. },
  35. arm64: {
  36. // Host or device variants with arm64 architecture
  37. },
  38. x86: {
  39. // Host or device variants with x86 architecture
  40. },
  41. x86_64: {
  42. // Host or device variants with x86_64 architecture
  43. },
  44. },
  45. multilib: {
  46. lib32: {
  47. // Host or device variants for 32-bit architectures
  48. },
  49. lib64: {
  50. // Host or device variants for 64-bit architectures
  51. },
  52. },
  53. target: {
  54. android: {
  55. // Device variants (implies Bionic)
  56. },
  57. host: {
  58. // Host variants
  59. },
  60. bionic: {
  61. // Bionic (device and host) variants
  62. },
  63. linux_bionic: {
  64. // Bionic host variants
  65. },
  66. linux: {
  67. // Bionic (device and host) and Linux glibc variants
  68. },
  69. linux_glibc: {
  70. // Linux host variants (using non-Bionic libc)
  71. },
  72. darwin: {
  73. // Darwin host variants
  74. },
  75. windows: {
  76. // Windows host variants
  77. },
  78. not_windows: {
  79. // Non-windows host variants
  80. },
  81. android_arm: {
  82. // Any <os>_<arch> combination restricts to that os and arch
  83. },
  84. },
  85. }
  86. */
  87. // An Arch indicates a single CPU architecture.
  88. type Arch struct {
  89. // The type of the architecture (arm, arm64, x86, or x86_64).
  90. ArchType ArchType
  91. // The variant of the architecture, for example "armv7-a" or "armv7-a-neon" for arm.
  92. ArchVariant string
  93. // The variant of the CPU, for example "cortex-a53" for arm64.
  94. CpuVariant string
  95. // The list of Android app ABIs supported by the CPU architecture, for example "arm64-v8a".
  96. Abi []string
  97. // The list of arch-specific features supported by the CPU architecture, for example "neon".
  98. ArchFeatures []string
  99. }
  100. // String returns the Arch as a string. The value is used as the name of the variant created
  101. // by archMutator.
  102. func (a Arch) String() string {
  103. s := a.ArchType.String()
  104. if a.ArchVariant != "" {
  105. s += "_" + a.ArchVariant
  106. }
  107. if a.CpuVariant != "" {
  108. s += "_" + a.CpuVariant
  109. }
  110. return s
  111. }
  112. // ArchType is used to define the 4 supported architecture types (arm, arm64, x86, x86_64), as
  113. // well as the "common" architecture used for modules that support multiple architectures, for
  114. // example Java modules.
  115. type ArchType struct {
  116. // Name is the name of the architecture type, "arm", "arm64", "x86", or "x86_64".
  117. Name string
  118. // Field is the name of the field used in properties that refer to the architecture, e.g. "Arm64".
  119. Field string
  120. // Multilib is either "lib32" or "lib64" for 32-bit or 64-bit architectures.
  121. Multilib string
  122. }
  123. // String returns the name of the ArchType.
  124. func (a ArchType) String() string {
  125. return a.Name
  126. }
  127. const COMMON_VARIANT = "common"
  128. var (
  129. archTypeList []ArchType
  130. Arm = newArch("arm", "lib32")
  131. Arm64 = newArch("arm64", "lib64")
  132. X86 = newArch("x86", "lib32")
  133. X86_64 = newArch("x86_64", "lib64")
  134. Common = ArchType{
  135. Name: COMMON_VARIANT,
  136. }
  137. )
  138. var archTypeMap = map[string]ArchType{}
  139. func newArch(name, multilib string) ArchType {
  140. archType := ArchType{
  141. Name: name,
  142. Field: proptools.FieldNameForProperty(name),
  143. Multilib: multilib,
  144. }
  145. archTypeList = append(archTypeList, archType)
  146. archTypeMap[name] = archType
  147. return archType
  148. }
  149. // ArchTypeList returns a slice copy of the 4 supported ArchTypes for arm,
  150. // arm64, x86 and x86_64.
  151. func ArchTypeList() []ArchType {
  152. return append([]ArchType(nil), archTypeList...)
  153. }
  154. // MarshalText allows an ArchType to be serialized through any encoder that supports
  155. // encoding.TextMarshaler.
  156. func (a ArchType) MarshalText() ([]byte, error) {
  157. return []byte(a.String()), nil
  158. }
  159. var _ encoding.TextMarshaler = ArchType{}
  160. // UnmarshalText allows an ArchType to be deserialized through any decoder that supports
  161. // encoding.TextUnmarshaler.
  162. func (a *ArchType) UnmarshalText(text []byte) error {
  163. if u, ok := archTypeMap[string(text)]; ok {
  164. *a = u
  165. return nil
  166. }
  167. return fmt.Errorf("unknown ArchType %q", text)
  168. }
  169. var _ encoding.TextUnmarshaler = &ArchType{}
  170. // OsClass is an enum that describes whether a variant of a module runs on the host, on the device,
  171. // or is generic.
  172. type OsClass int
  173. const (
  174. // Generic is used for variants of modules that are not OS-specific.
  175. Generic OsClass = iota
  176. // Device is used for variants of modules that run on the device.
  177. Device
  178. // Host is used for variants of modules that run on the host.
  179. Host
  180. )
  181. // String returns the OsClass as a string.
  182. func (class OsClass) String() string {
  183. switch class {
  184. case Generic:
  185. return "generic"
  186. case Device:
  187. return "device"
  188. case Host:
  189. return "host"
  190. default:
  191. panic(fmt.Errorf("unknown class %d", class))
  192. }
  193. }
  194. // OsType describes an OS variant of a module.
  195. type OsType struct {
  196. // Name is the name of the OS. It is also used as the name of the property in Android.bp
  197. // files.
  198. Name string
  199. // Field is the name of the OS converted to an exported field name, i.e. with the first
  200. // character capitalized.
  201. Field string
  202. // Class is the OsClass of the OS.
  203. Class OsClass
  204. // DefaultDisabled is set when the module variants for the OS should not be created unless
  205. // the module explicitly requests them. This is used to limit Windows cross compilation to
  206. // only modules that need it.
  207. DefaultDisabled bool
  208. }
  209. // String returns the name of the OsType.
  210. func (os OsType) String() string {
  211. return os.Name
  212. }
  213. // Bionic returns true if the OS uses the Bionic libc runtime, i.e. if the OS is Android or
  214. // is Linux with Bionic.
  215. func (os OsType) Bionic() bool {
  216. return os == Android || os == LinuxBionic
  217. }
  218. // Linux returns true if the OS uses the Linux kernel, i.e. if the OS is Android or is Linux
  219. // with or without the Bionic libc runtime.
  220. func (os OsType) Linux() bool {
  221. return os == Android || os == Linux || os == LinuxBionic || os == LinuxMusl
  222. }
  223. // newOsType constructs an OsType and adds it to the global lists.
  224. func newOsType(name string, class OsClass, defDisabled bool, archTypes ...ArchType) OsType {
  225. checkCalledFromInit()
  226. os := OsType{
  227. Name: name,
  228. Field: proptools.FieldNameForProperty(name),
  229. Class: class,
  230. DefaultDisabled: defDisabled,
  231. }
  232. osTypeList = append(osTypeList, os)
  233. if _, found := commonTargetMap[name]; found {
  234. panic(fmt.Errorf("Found Os type duplicate during OsType registration: %q", name))
  235. } else {
  236. commonTargetMap[name] = Target{Os: os, Arch: CommonArch}
  237. }
  238. osArchTypeMap[os] = archTypes
  239. return os
  240. }
  241. // osByName returns the OsType that has the given name, or NoOsType if none match.
  242. func osByName(name string) OsType {
  243. for _, os := range osTypeList {
  244. if os.Name == name {
  245. return os
  246. }
  247. }
  248. return NoOsType
  249. }
  250. var (
  251. // osTypeList contains a list of all the supported OsTypes, including ones not supported
  252. // by the current build host or the target device.
  253. osTypeList []OsType
  254. // commonTargetMap maps names of OsTypes to the corresponding common Target, i.e. the
  255. // Target with the same OsType and the common ArchType.
  256. commonTargetMap = make(map[string]Target)
  257. // osArchTypeMap maps OsTypes to the list of supported ArchTypes for that OS.
  258. osArchTypeMap = map[OsType][]ArchType{}
  259. // NoOsType is a placeholder for when no OS is needed.
  260. NoOsType OsType
  261. // Linux is the OS for the Linux kernel plus the glibc runtime.
  262. Linux = newOsType("linux_glibc", Host, false, X86, X86_64)
  263. // LinuxMusl is the OS for the Linux kernel plus the musl runtime.
  264. LinuxMusl = newOsType("linux_musl", Host, false, X86, X86_64, Arm64, Arm)
  265. // Darwin is the OS for MacOS/Darwin host machines.
  266. Darwin = newOsType("darwin", Host, false, Arm64, X86_64)
  267. // LinuxBionic is the OS for the Linux kernel plus the Bionic libc runtime, but without the
  268. // rest of Android.
  269. LinuxBionic = newOsType("linux_bionic", Host, false, Arm64, X86_64)
  270. // Windows the OS for Windows host machines.
  271. Windows = newOsType("windows", Host, true, X86, X86_64)
  272. // Android is the OS for target devices that run all of Android, including the Linux kernel
  273. // and the Bionic libc runtime.
  274. Android = newOsType("android", Device, false, Arm, Arm64, X86, X86_64)
  275. // CommonOS is a pseudo OSType for a common OS variant, which is OsType agnostic and which
  276. // has dependencies on all the OS variants.
  277. CommonOS = newOsType("common_os", Generic, false)
  278. // CommonArch is the Arch for all modules that are os-specific but not arch specific,
  279. // for example most Java modules.
  280. CommonArch = Arch{ArchType: Common}
  281. )
  282. // OsTypeList returns a slice copy of the supported OsTypes.
  283. func OsTypeList() []OsType {
  284. return append([]OsType(nil), osTypeList...)
  285. }
  286. // Target specifies the OS and architecture that a module is being compiled for.
  287. type Target struct {
  288. // Os the OS that the module is being compiled for (e.g. "linux_glibc", "android").
  289. Os OsType
  290. // Arch is the architecture that the module is being compiled for.
  291. Arch Arch
  292. // NativeBridge is NativeBridgeEnabled if the architecture is supported using NativeBridge
  293. // (i.e. arm on x86) for this device.
  294. NativeBridge NativeBridgeSupport
  295. // NativeBridgeHostArchName is the name of the real architecture that is used to implement
  296. // the NativeBridge architecture. For example, for arm on x86 this would be "x86".
  297. NativeBridgeHostArchName string
  298. // NativeBridgeRelativePath is the name of the subdirectory that will contain NativeBridge
  299. // libraries and binaries.
  300. NativeBridgeRelativePath string
  301. // HostCross is true when the target cannot run natively on the current build host.
  302. // For example, linux_glibc_x86 returns true on a regular x86/i686/Linux machines, but returns false
  303. // on Mac (different OS), or on 64-bit only i686/Linux machines (unsupported arch).
  304. HostCross bool
  305. }
  306. // NativeBridgeSupport is an enum that specifies if a Target supports NativeBridge.
  307. type NativeBridgeSupport bool
  308. const (
  309. NativeBridgeDisabled NativeBridgeSupport = false
  310. NativeBridgeEnabled NativeBridgeSupport = true
  311. )
  312. // String returns the OS and arch variations used for the Target.
  313. func (target Target) String() string {
  314. return target.OsVariation() + "_" + target.ArchVariation()
  315. }
  316. // OsVariation returns the name of the variation used by the osMutator for the Target.
  317. func (target Target) OsVariation() string {
  318. return target.Os.String()
  319. }
  320. // ArchVariation returns the name of the variation used by the archMutator for the Target.
  321. func (target Target) ArchVariation() string {
  322. var variation string
  323. if target.NativeBridge {
  324. variation = "native_bridge_"
  325. }
  326. variation += target.Arch.String()
  327. return variation
  328. }
  329. // Variations returns a list of blueprint.Variations for the osMutator and archMutator for the
  330. // Target.
  331. func (target Target) Variations() []blueprint.Variation {
  332. return []blueprint.Variation{
  333. {Mutator: "os", Variation: target.OsVariation()},
  334. {Mutator: "arch", Variation: target.ArchVariation()},
  335. }
  336. }
  337. // osMutator splits an arch-specific module into a variant for each OS that is enabled for the
  338. // module. It uses the HostOrDevice value passed to InitAndroidArchModule and the
  339. // device_supported and host_supported properties to determine which OsTypes are enabled for this
  340. // module, then searches through the Targets to determine which have enabled Targets for this
  341. // module.
  342. func osMutator(bpctx blueprint.BottomUpMutatorContext) {
  343. var module Module
  344. var ok bool
  345. if module, ok = bpctx.Module().(Module); !ok {
  346. // The module is not a Soong module, it is a Blueprint module.
  347. if bootstrap.IsBootstrapModule(bpctx.Module()) {
  348. // Bootstrap Go modules are always the build OS or linux bionic.
  349. config := bpctx.Config().(Config)
  350. osNames := []string{config.BuildOSTarget.OsVariation()}
  351. for _, hostCrossTarget := range config.Targets[LinuxBionic] {
  352. if hostCrossTarget.Arch.ArchType == config.BuildOSTarget.Arch.ArchType {
  353. osNames = append(osNames, hostCrossTarget.OsVariation())
  354. }
  355. }
  356. osNames = FirstUniqueStrings(osNames)
  357. bpctx.CreateVariations(osNames...)
  358. }
  359. return
  360. }
  361. // Bootstrap Go module support above requires this mutator to be a
  362. // blueprint.BottomUpMutatorContext because android.BottomUpMutatorContext
  363. // filters out non-Soong modules. Now that we've handled them, create a
  364. // normal android.BottomUpMutatorContext.
  365. mctx := bottomUpMutatorContextFactory(bpctx, module, false, false)
  366. base := module.base()
  367. // Nothing to do for modules that are not architecture specific (e.g. a genrule).
  368. if !base.ArchSpecific() {
  369. return
  370. }
  371. // Collect a list of OSTypes supported by this module based on the HostOrDevice value
  372. // passed to InitAndroidArchModule and the device_supported and host_supported properties.
  373. var moduleOSList []OsType
  374. for _, os := range osTypeList {
  375. for _, t := range mctx.Config().Targets[os] {
  376. if base.supportsTarget(t) {
  377. moduleOSList = append(moduleOSList, os)
  378. break
  379. }
  380. }
  381. }
  382. // If there are no supported OSes then disable the module.
  383. if len(moduleOSList) == 0 {
  384. base.Disable()
  385. return
  386. }
  387. // Convert the list of supported OsTypes to the variation names.
  388. osNames := make([]string, len(moduleOSList))
  389. for i, os := range moduleOSList {
  390. osNames[i] = os.String()
  391. }
  392. createCommonOSVariant := base.commonProperties.CreateCommonOSVariant
  393. if createCommonOSVariant {
  394. // A CommonOS variant was requested so add it to the list of OS variants to
  395. // create. It needs to be added to the end because it needs to depend on the
  396. // the other variants in the list returned by CreateVariations(...) and inter
  397. // variant dependencies can only be created from a later variant in that list to
  398. // an earlier one. That is because variants are always processed in the order in
  399. // which they are returned from CreateVariations(...).
  400. osNames = append(osNames, CommonOS.Name)
  401. moduleOSList = append(moduleOSList, CommonOS)
  402. }
  403. // Create the variations, annotate each one with which OS it was created for, and
  404. // squash the appropriate OS-specific properties into the top level properties.
  405. modules := mctx.CreateVariations(osNames...)
  406. for i, m := range modules {
  407. m.base().commonProperties.CompileOS = moduleOSList[i]
  408. m.base().setOSProperties(mctx)
  409. }
  410. if createCommonOSVariant {
  411. // A CommonOS variant was requested so add dependencies from it (the last one in
  412. // the list) to the OS type specific variants.
  413. last := len(modules) - 1
  414. commonOSVariant := modules[last]
  415. commonOSVariant.base().commonProperties.CommonOSVariant = true
  416. for _, module := range modules[0:last] {
  417. // Ignore modules that are enabled. Note, this will only avoid adding
  418. // dependencies on OsType variants that are explicitly disabled in their
  419. // properties. The CommonOS variant will still depend on disabled variants
  420. // if they are disabled afterwards, e.g. in archMutator if
  421. if module.Enabled() {
  422. mctx.AddInterVariantDependency(commonOsToOsSpecificVariantTag, commonOSVariant, module)
  423. }
  424. }
  425. }
  426. }
  427. type archDepTag struct {
  428. blueprint.BaseDependencyTag
  429. name string
  430. }
  431. // Identifies the dependency from CommonOS variant to the os specific variants.
  432. var commonOsToOsSpecificVariantTag = archDepTag{name: "common os to os specific"}
  433. // Get the OsType specific variants for the current CommonOS variant.
  434. //
  435. // The returned list will only contain enabled OsType specific variants of the
  436. // module referenced in the supplied context. An empty list is returned if there
  437. // are no enabled variants or the supplied context is not for an CommonOS
  438. // variant.
  439. func GetOsSpecificVariantsOfCommonOSVariant(mctx BaseModuleContext) []Module {
  440. var variants []Module
  441. mctx.VisitDirectDeps(func(m Module) {
  442. if mctx.OtherModuleDependencyTag(m) == commonOsToOsSpecificVariantTag {
  443. if m.Enabled() {
  444. variants = append(variants, m)
  445. }
  446. }
  447. })
  448. return variants
  449. }
  450. var DarwinUniversalVariantTag = archDepTag{name: "darwin universal binary"}
  451. // archMutator splits a module into a variant for each Target requested by the module. Target selection
  452. // for a module is in three levels, OsClass, multilib, and then Target.
  453. // OsClass selection is determined by:
  454. // - The HostOrDeviceSupported value passed in to InitAndroidArchModule by the module type factory, which selects
  455. // whether the module type can compile for host, device or both.
  456. // - The host_supported and device_supported properties on the module.
  457. //
  458. // If host is supported for the module, the Host and HostCross OsClasses are selected. If device is supported
  459. // for the module, the Device OsClass is selected.
  460. // Within each selected OsClass, the multilib selection is determined by:
  461. // - The compile_multilib property if it set (which may be overridden by target.android.compile_multilib or
  462. // target.host.compile_multilib).
  463. // - The default multilib passed to InitAndroidArchModule if compile_multilib was not set.
  464. //
  465. // Valid multilib values include:
  466. //
  467. // "both": compile for all Targets supported by the OsClass (generally x86_64 and x86, or arm64 and arm).
  468. // "first": compile for only a single preferred Target supported by the OsClass. This is generally x86_64 or arm64,
  469. // but may be arm for a 32-bit only build.
  470. // "32": compile for only a single 32-bit Target supported by the OsClass.
  471. // "64": compile for only a single 64-bit Target supported by the OsClass.
  472. // "common": compile a for a single Target that will work on all Targets supported by the OsClass (for example Java).
  473. // "common_first": compile a for a Target that will work on all Targets supported by the OsClass
  474. // (same as "common"), plus a second Target for the preferred Target supported by the OsClass
  475. // (same as "first"). This is used for java_binary that produces a common .jar and a wrapper
  476. // executable script.
  477. //
  478. // Once the list of Targets is determined, the module is split into a variant for each Target.
  479. //
  480. // Modules can be initialized with InitAndroidMultiTargetsArchModule, in which case they will be split by OsClass,
  481. // but will have a common Target that is expected to handle all other selected Targets via ctx.MultiTargets().
  482. func archMutator(bpctx blueprint.BottomUpMutatorContext) {
  483. var module Module
  484. var ok bool
  485. if module, ok = bpctx.Module().(Module); !ok {
  486. if bootstrap.IsBootstrapModule(bpctx.Module()) {
  487. // Bootstrap Go modules are always the build architecture.
  488. bpctx.CreateVariations(bpctx.Config().(Config).BuildOSTarget.ArchVariation())
  489. }
  490. return
  491. }
  492. // Bootstrap Go module support above requires this mutator to be a
  493. // blueprint.BottomUpMutatorContext because android.BottomUpMutatorContext
  494. // filters out non-Soong modules. Now that we've handled them, create a
  495. // normal android.BottomUpMutatorContext.
  496. mctx := bottomUpMutatorContextFactory(bpctx, module, false, false)
  497. base := module.base()
  498. if !base.ArchSpecific() {
  499. return
  500. }
  501. os := base.commonProperties.CompileOS
  502. if os == CommonOS {
  503. // Make sure that the target related properties are initialized for the
  504. // CommonOS variant.
  505. addTargetProperties(module, commonTargetMap[os.Name], nil, true)
  506. // Do not create arch specific variants for the CommonOS variant.
  507. return
  508. }
  509. osTargets := mctx.Config().Targets[os]
  510. image := base.commonProperties.ImageVariation
  511. // Filter NativeBridge targets unless they are explicitly supported.
  512. // Skip creating native bridge variants for non-core modules.
  513. if os == Android && !(base.IsNativeBridgeSupported() && image == CoreVariation) {
  514. var targets []Target
  515. for _, t := range osTargets {
  516. if !t.NativeBridge {
  517. targets = append(targets, t)
  518. }
  519. }
  520. osTargets = targets
  521. }
  522. // only the primary arch in the ramdisk / vendor_ramdisk / recovery partition
  523. if os == Android && (module.InstallInRecovery() || module.InstallInRamdisk() || module.InstallInVendorRamdisk() || module.InstallInDebugRamdisk()) {
  524. osTargets = []Target{osTargets[0]}
  525. }
  526. // Windows builds always prefer 32-bit
  527. prefer32 := os == Windows
  528. // Determine the multilib selection for this module.
  529. ignorePrefer32OnDevice := mctx.Config().IgnorePrefer32OnDevice()
  530. multilib, extraMultilib := decodeMultilib(base, os, ignorePrefer32OnDevice)
  531. // Convert the multilib selection into a list of Targets.
  532. targets, err := decodeMultilibTargets(multilib, osTargets, prefer32)
  533. if err != nil {
  534. mctx.ModuleErrorf("%s", err.Error())
  535. }
  536. // If the module is using extraMultilib, decode the extraMultilib selection into
  537. // a separate list of Targets.
  538. var multiTargets []Target
  539. if extraMultilib != "" {
  540. multiTargets, err = decodeMultilibTargets(extraMultilib, osTargets, prefer32)
  541. if err != nil {
  542. mctx.ModuleErrorf("%s", err.Error())
  543. }
  544. }
  545. // Recovery is always the primary architecture, filter out any other architectures.
  546. // Common arch is also allowed
  547. if image == RecoveryVariation {
  548. primaryArch := mctx.Config().DevicePrimaryArchType()
  549. targets = filterToArch(targets, primaryArch, Common)
  550. multiTargets = filterToArch(multiTargets, primaryArch, Common)
  551. }
  552. // If there are no supported targets disable the module.
  553. if len(targets) == 0 {
  554. base.Disable()
  555. return
  556. }
  557. // Convert the targets into a list of arch variation names.
  558. targetNames := make([]string, len(targets))
  559. for i, target := range targets {
  560. targetNames[i] = target.ArchVariation()
  561. }
  562. // Create the variations, annotate each one with which Target it was created for, and
  563. // squash the appropriate arch-specific properties into the top level properties.
  564. modules := mctx.CreateVariations(targetNames...)
  565. for i, m := range modules {
  566. addTargetProperties(m, targets[i], multiTargets, i == 0)
  567. m.base().setArchProperties(mctx)
  568. // Install support doesn't understand Darwin+Arm64
  569. if os == Darwin && targets[i].HostCross {
  570. m.base().commonProperties.SkipInstall = true
  571. }
  572. }
  573. // Create a dependency for Darwin Universal binaries from the primary to secondary
  574. // architecture. The module itself will be responsible for calling lipo to merge the outputs.
  575. if os == Darwin {
  576. if multilib == "darwin_universal" && len(modules) == 2 {
  577. mctx.AddInterVariantDependency(DarwinUniversalVariantTag, modules[1], modules[0])
  578. } else if multilib == "darwin_universal_common_first" && len(modules) == 3 {
  579. mctx.AddInterVariantDependency(DarwinUniversalVariantTag, modules[2], modules[1])
  580. }
  581. }
  582. }
  583. // addTargetProperties annotates a variant with the Target is is being compiled for, the list
  584. // of additional Targets it is supporting (if any), and whether it is the primary Target for
  585. // the module.
  586. func addTargetProperties(m Module, target Target, multiTargets []Target, primaryTarget bool) {
  587. m.base().commonProperties.CompileTarget = target
  588. m.base().commonProperties.CompileMultiTargets = multiTargets
  589. m.base().commonProperties.CompilePrimary = primaryTarget
  590. }
  591. // decodeMultilib returns the appropriate compile_multilib property for the module, or the default
  592. // multilib from the factory's call to InitAndroidArchModule if none was set. For modules that
  593. // called InitAndroidMultiTargetsArchModule it always returns "common" for multilib, and returns
  594. // the actual multilib in extraMultilib.
  595. func decodeMultilib(base *ModuleBase, os OsType, ignorePrefer32OnDevice bool) (multilib, extraMultilib string) {
  596. // First check the "android.compile_multilib" or "host.compile_multilib" properties.
  597. switch os.Class {
  598. case Device:
  599. multilib = String(base.commonProperties.Target.Android.Compile_multilib)
  600. case Host:
  601. multilib = String(base.commonProperties.Target.Host.Compile_multilib)
  602. }
  603. // If those aren't set, try the "compile_multilib" property.
  604. if multilib == "" {
  605. multilib = String(base.commonProperties.Compile_multilib)
  606. }
  607. // If that wasn't set, use the default multilib set by the factory.
  608. if multilib == "" {
  609. multilib = base.commonProperties.Default_multilib
  610. }
  611. // If a device is configured with multiple targets, this option
  612. // force all device targets that prefer32 to be compiled only as
  613. // the first target.
  614. if ignorePrefer32OnDevice && os.Class == Device && (multilib == "prefer32" || multilib == "first_prefer32") {
  615. multilib = "first"
  616. }
  617. if base.commonProperties.UseTargetVariants {
  618. // Darwin has the concept of "universal binaries" which is implemented in Soong by
  619. // building both x86_64 and arm64 variants, and having select module types know how to
  620. // merge the outputs of their corresponding variants together into a final binary. Most
  621. // module types don't need to understand this logic, as we only build a small portion
  622. // of the tree for Darwin, and only module types writing macho files need to do the
  623. // merging.
  624. //
  625. // This logic is not enabled for:
  626. // "common", as it's not an arch-specific variant
  627. // "32", as Darwin never has a 32-bit variant
  628. // !UseTargetVariants, as the module has opted into handling the arch-specific logic on
  629. // its own.
  630. if os == Darwin && multilib != "common" && multilib != "32" {
  631. if multilib == "common_first" {
  632. multilib = "darwin_universal_common_first"
  633. } else {
  634. multilib = "darwin_universal"
  635. }
  636. }
  637. return multilib, ""
  638. } else {
  639. // For app modules a single arch variant will be created per OS class which is expected to handle all the
  640. // selected arches. Return the common-type as multilib and any Android.bp provided multilib as extraMultilib
  641. if multilib == base.commonProperties.Default_multilib {
  642. multilib = "first"
  643. }
  644. return base.commonProperties.Default_multilib, multilib
  645. }
  646. }
  647. // filterToArch takes a list of Targets and an ArchType, and returns a modified list that contains
  648. // only Targets that have the specified ArchTypes.
  649. func filterToArch(targets []Target, archs ...ArchType) []Target {
  650. for i := 0; i < len(targets); i++ {
  651. found := false
  652. for _, arch := range archs {
  653. if targets[i].Arch.ArchType == arch {
  654. found = true
  655. break
  656. }
  657. }
  658. if !found {
  659. targets = append(targets[:i], targets[i+1:]...)
  660. i--
  661. }
  662. }
  663. return targets
  664. }
  665. // archPropRoot is a struct type used as the top level of the arch-specific properties. It
  666. // contains the "arch", "multilib", and "target" property structs. It is used to split up the
  667. // property structs to limit how much is allocated when a single arch-specific property group is
  668. // used. The types are interface{} because they will hold instances of runtime-created types.
  669. type archPropRoot struct {
  670. Arch, Multilib, Target interface{}
  671. }
  672. // archPropTypeDesc holds the runtime-created types for the property structs to instantiate to
  673. // create an archPropRoot property struct.
  674. type archPropTypeDesc struct {
  675. arch, multilib, target reflect.Type
  676. }
  677. // createArchPropTypeDesc takes a reflect.Type that is either a struct or a pointer to a struct, and
  678. // returns lists of reflect.Types that contains the arch-variant properties inside structs for each
  679. // arch, multilib and target property.
  680. //
  681. // This is a relatively expensive operation, so the results are cached in the global
  682. // archPropTypeMap. It is constructed entirely based on compile-time data, so there is no need
  683. // to isolate the results between multiple tests running in parallel.
  684. func createArchPropTypeDesc(props reflect.Type) []archPropTypeDesc {
  685. // Each property struct shard will be nested many times under the runtime generated arch struct,
  686. // which can hit the limit of 64kB for the name of runtime generated structs. They are nested
  687. // 97 times now, which may grow in the future, plus there is some overhead for the containing
  688. // type. This number may need to be reduced if too many are added, but reducing it too far
  689. // could cause problems if a single deeply nested property no longer fits in the name.
  690. const maxArchTypeNameSize = 500
  691. // Convert the type to a new set of types that contains only the arch-specific properties
  692. // (those that are tagged with `android:"arch_variant"`), and sharded into multiple types
  693. // to keep the runtime-generated names under the limit.
  694. propShards, _ := proptools.FilterPropertyStructSharded(props, maxArchTypeNameSize, filterArchStruct)
  695. // If the type has no arch-specific properties there is nothing to do.
  696. if len(propShards) == 0 {
  697. return nil
  698. }
  699. var ret []archPropTypeDesc
  700. for _, props := range propShards {
  701. // variantFields takes a list of variant property field names and returns a list the
  702. // StructFields with the names and the type of the current shard.
  703. variantFields := func(names []string) []reflect.StructField {
  704. ret := make([]reflect.StructField, len(names))
  705. for i, name := range names {
  706. ret[i].Name = name
  707. ret[i].Type = props
  708. }
  709. return ret
  710. }
  711. // Create a type that contains the properties in this shard repeated for each
  712. // architecture, architecture variant, and architecture feature.
  713. archFields := make([]reflect.StructField, len(archTypeList))
  714. for i, arch := range archTypeList {
  715. var variants []string
  716. for _, archVariant := range archVariants[arch] {
  717. archVariant := variantReplacer.Replace(archVariant)
  718. variants = append(variants, proptools.FieldNameForProperty(archVariant))
  719. }
  720. for _, cpuVariant := range cpuVariants[arch] {
  721. cpuVariant := variantReplacer.Replace(cpuVariant)
  722. variants = append(variants, proptools.FieldNameForProperty(cpuVariant))
  723. }
  724. for _, feature := range archFeatures[arch] {
  725. feature := variantReplacer.Replace(feature)
  726. variants = append(variants, proptools.FieldNameForProperty(feature))
  727. }
  728. // Create the StructFields for each architecture variant architecture feature
  729. // (e.g. "arch.arm.cortex-a53" or "arch.arm.neon").
  730. fields := variantFields(variants)
  731. // Create the StructField for the architecture itself (e.g. "arch.arm"). The special
  732. // "BlueprintEmbed" name is used by Blueprint to put the properties in the
  733. // parent struct.
  734. fields = append([]reflect.StructField{{
  735. Name: "BlueprintEmbed",
  736. Type: props,
  737. Anonymous: true,
  738. }}, fields...)
  739. archFields[i] = reflect.StructField{
  740. Name: arch.Field,
  741. Type: reflect.StructOf(fields),
  742. }
  743. }
  744. // Create the type of the "arch" property struct for this shard.
  745. archType := reflect.StructOf(archFields)
  746. // Create the type for the "multilib" property struct for this shard, containing the
  747. // "multilib.lib32" and "multilib.lib64" property structs.
  748. multilibType := reflect.StructOf(variantFields([]string{"Lib32", "Lib64"}))
  749. // Start with a list of the special targets
  750. targets := []string{
  751. "Host",
  752. "Android64",
  753. "Android32",
  754. "Bionic",
  755. "Glibc",
  756. "Musl",
  757. "Linux",
  758. "Host_linux",
  759. "Not_windows",
  760. "Arm_on_x86",
  761. "Arm_on_x86_64",
  762. "Native_bridge",
  763. }
  764. for _, os := range osTypeList {
  765. // Add all the OSes.
  766. targets = append(targets, os.Field)
  767. // Add the OS/Arch combinations, e.g. "android_arm64".
  768. for _, archType := range osArchTypeMap[os] {
  769. targets = append(targets, GetCompoundTargetField(os, archType))
  770. // Also add the special "linux_<arch>", "bionic_<arch>" , "glibc_<arch>", and
  771. // "musl_<arch>" property structs.
  772. if os.Linux() {
  773. target := "Linux_" + archType.Name
  774. if !InList(target, targets) {
  775. targets = append(targets, target)
  776. }
  777. }
  778. if os.Linux() && os.Class == Host {
  779. target := "Host_linux_" + archType.Name
  780. if !InList(target, targets) {
  781. targets = append(targets, target)
  782. }
  783. }
  784. if os.Bionic() {
  785. target := "Bionic_" + archType.Name
  786. if !InList(target, targets) {
  787. targets = append(targets, target)
  788. }
  789. }
  790. if os == Linux {
  791. target := "Glibc_" + archType.Name
  792. if !InList(target, targets) {
  793. targets = append(targets, target)
  794. }
  795. }
  796. if os == LinuxMusl {
  797. target := "Musl_" + archType.Name
  798. if !InList(target, targets) {
  799. targets = append(targets, target)
  800. }
  801. }
  802. }
  803. }
  804. // Create the type for the "target" property struct for this shard.
  805. targetType := reflect.StructOf(variantFields(targets))
  806. // Return a descriptor of the 3 runtime-created types.
  807. ret = append(ret, archPropTypeDesc{
  808. arch: reflect.PtrTo(archType),
  809. multilib: reflect.PtrTo(multilibType),
  810. target: reflect.PtrTo(targetType),
  811. })
  812. }
  813. return ret
  814. }
  815. // variantReplacer converts architecture variant or architecture feature names into names that
  816. // are valid for an Android.bp file.
  817. var variantReplacer = strings.NewReplacer("-", "_", ".", "_")
  818. // filterArchStruct returns true if the given field is an architecture specific property.
  819. func filterArchStruct(field reflect.StructField, prefix string) (bool, reflect.StructField) {
  820. if proptools.HasTag(field, "android", "arch_variant") {
  821. // The arch_variant field isn't necessary past this point
  822. // Instead of wasting space, just remove it. Go also has a
  823. // 16-bit limit on structure name length. The name is constructed
  824. // based on the Go source representation of the structure, so
  825. // the tag names count towards that length.
  826. androidTag := field.Tag.Get("android")
  827. values := strings.Split(androidTag, ",")
  828. if string(field.Tag) != `android:"`+strings.Join(values, ",")+`"` {
  829. panic(fmt.Errorf("unexpected tag format %q", field.Tag))
  830. }
  831. // these tags don't need to be present in the runtime generated struct type.
  832. values = RemoveListFromList(values, []string{"arch_variant", "variant_prepend", "path"})
  833. if len(values) > 0 {
  834. panic(fmt.Errorf("unknown tags %q in field %q", values, prefix+field.Name))
  835. }
  836. field.Tag = ``
  837. return true, field
  838. }
  839. return false, field
  840. }
  841. // archPropTypeMap contains a cache of the results of createArchPropTypeDesc for each type. It is
  842. // shared across all Contexts, but is constructed based only on compile-time information so there
  843. // is no risk of contaminating one Context with data from another.
  844. var archPropTypeMap OncePer
  845. // initArchModule adds the architecture-specific property structs to a Module.
  846. func initArchModule(m Module) {
  847. base := m.base()
  848. if len(base.archProperties) != 0 {
  849. panic(fmt.Errorf("module %s already has archProperties", m.Name()))
  850. }
  851. getStructType := func(properties interface{}) reflect.Type {
  852. propertiesValue := reflect.ValueOf(properties)
  853. t := propertiesValue.Type()
  854. if propertiesValue.Kind() != reflect.Ptr {
  855. panic(fmt.Errorf("properties must be a pointer to a struct, got %T",
  856. propertiesValue.Interface()))
  857. }
  858. propertiesValue = propertiesValue.Elem()
  859. if propertiesValue.Kind() != reflect.Struct {
  860. panic(fmt.Errorf("properties must be a pointer to a struct, got a pointer to %T",
  861. propertiesValue.Interface()))
  862. }
  863. return t
  864. }
  865. for _, properties := range m.GetProperties() {
  866. t := getStructType(properties)
  867. // Get or create the arch-specific property struct types for this property struct type.
  868. archPropTypes := archPropTypeMap.Once(NewCustomOnceKey(t), func() interface{} {
  869. return createArchPropTypeDesc(t)
  870. }).([]archPropTypeDesc)
  871. // Instantiate one of each arch-specific property struct type and add it to the
  872. // properties for the Module.
  873. var archProperties []interface{}
  874. for _, t := range archPropTypes {
  875. archProperties = append(archProperties, &archPropRoot{
  876. Arch: reflect.Zero(t.arch).Interface(),
  877. Multilib: reflect.Zero(t.multilib).Interface(),
  878. Target: reflect.Zero(t.target).Interface(),
  879. })
  880. }
  881. base.archProperties = append(base.archProperties, archProperties)
  882. m.AddProperties(archProperties...)
  883. }
  884. }
  885. func maybeBlueprintEmbed(src reflect.Value) reflect.Value {
  886. // If the value of the field is a struct (as opposed to a pointer to a struct) then step
  887. // into the BlueprintEmbed field.
  888. if src.Kind() == reflect.Struct {
  889. return src.FieldByName("BlueprintEmbed")
  890. } else {
  891. return src
  892. }
  893. }
  894. // Merges the property struct in srcValue into dst.
  895. func mergePropertyStruct(ctx ArchVariantContext, dst interface{}, srcValue reflect.Value) {
  896. src := maybeBlueprintEmbed(srcValue).Interface()
  897. // order checks the `android:"variant_prepend"` tag to handle properties where the
  898. // arch-specific value needs to come before the generic value, for example for lists of
  899. // include directories.
  900. order := func(property string,
  901. dstField, srcField reflect.StructField,
  902. dstValue, srcValue interface{}) (proptools.Order, error) {
  903. if proptools.HasTag(dstField, "android", "variant_prepend") {
  904. return proptools.Prepend, nil
  905. } else {
  906. return proptools.Append, nil
  907. }
  908. }
  909. // Squash the located property struct into the destination property struct.
  910. err := proptools.ExtendMatchingProperties([]interface{}{dst}, src, nil, order)
  911. if err != nil {
  912. if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok {
  913. ctx.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error())
  914. } else {
  915. panic(err)
  916. }
  917. }
  918. }
  919. // Returns the immediate child of the input property struct that corresponds to
  920. // the sub-property "field".
  921. func getChildPropertyStruct(ctx ArchVariantContext,
  922. src reflect.Value, field, userFriendlyField string) (reflect.Value, bool) {
  923. // Step into non-nil pointers to structs in the src value.
  924. if src.Kind() == reflect.Ptr {
  925. if src.IsNil() {
  926. return reflect.Value{}, false
  927. }
  928. src = src.Elem()
  929. }
  930. // Find the requested field in the src struct.
  931. child := src.FieldByName(proptools.FieldNameForProperty(field))
  932. if !child.IsValid() {
  933. ctx.ModuleErrorf("field %q does not exist", userFriendlyField)
  934. return reflect.Value{}, false
  935. }
  936. if child.IsZero() {
  937. return reflect.Value{}, false
  938. }
  939. return child, true
  940. }
  941. // Squash the appropriate OS-specific property structs into the matching top level property structs
  942. // based on the CompileOS value that was annotated on the variant.
  943. func (m *ModuleBase) setOSProperties(ctx BottomUpMutatorContext) {
  944. os := m.commonProperties.CompileOS
  945. for i := range m.archProperties {
  946. genProps := m.GetProperties()[i]
  947. if m.archProperties[i] == nil {
  948. continue
  949. }
  950. for _, archProperties := range m.archProperties[i] {
  951. archPropValues := reflect.ValueOf(archProperties).Elem()
  952. targetProp := archPropValues.FieldByName("Target").Elem()
  953. // Handle host-specific properties in the form:
  954. // target: {
  955. // host: {
  956. // key: value,
  957. // },
  958. // },
  959. if os.Class == Host {
  960. field := "Host"
  961. prefix := "target.host"
  962. if hostProperties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok {
  963. mergePropertyStruct(ctx, genProps, hostProperties)
  964. }
  965. }
  966. // Handle target OS generalities of the form:
  967. // target: {
  968. // bionic: {
  969. // key: value,
  970. // },
  971. // }
  972. if os.Linux() {
  973. field := "Linux"
  974. prefix := "target.linux"
  975. if linuxProperties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok {
  976. mergePropertyStruct(ctx, genProps, linuxProperties)
  977. }
  978. }
  979. if os.Linux() && os.Class == Host {
  980. field := "Host_linux"
  981. prefix := "target.host_linux"
  982. if linuxProperties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok {
  983. mergePropertyStruct(ctx, genProps, linuxProperties)
  984. }
  985. }
  986. if os.Bionic() {
  987. field := "Bionic"
  988. prefix := "target.bionic"
  989. if bionicProperties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok {
  990. mergePropertyStruct(ctx, genProps, bionicProperties)
  991. }
  992. }
  993. if os == Linux {
  994. field := "Glibc"
  995. prefix := "target.glibc"
  996. if bionicProperties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok {
  997. mergePropertyStruct(ctx, genProps, bionicProperties)
  998. }
  999. }
  1000. if os == LinuxMusl {
  1001. field := "Musl"
  1002. prefix := "target.musl"
  1003. if bionicProperties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok {
  1004. mergePropertyStruct(ctx, genProps, bionicProperties)
  1005. }
  1006. }
  1007. // Handle target OS properties in the form:
  1008. // target: {
  1009. // linux_glibc: {
  1010. // key: value,
  1011. // },
  1012. // not_windows: {
  1013. // key: value,
  1014. // },
  1015. // android {
  1016. // key: value,
  1017. // },
  1018. // },
  1019. field := os.Field
  1020. prefix := "target." + os.Name
  1021. if osProperties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok {
  1022. mergePropertyStruct(ctx, genProps, osProperties)
  1023. }
  1024. if os.Class == Host && os != Windows {
  1025. field := "Not_windows"
  1026. prefix := "target.not_windows"
  1027. if notWindowsProperties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok {
  1028. mergePropertyStruct(ctx, genProps, notWindowsProperties)
  1029. }
  1030. }
  1031. // Handle 64-bit device properties in the form:
  1032. // target {
  1033. // android64 {
  1034. // key: value,
  1035. // },
  1036. // android32 {
  1037. // key: value,
  1038. // },
  1039. // },
  1040. // WARNING: this is probably not what you want to use in your blueprints file, it selects
  1041. // options for all targets on a device that supports 64-bit binaries, not just the targets
  1042. // that are being compiled for 64-bit. Its expected use case is binaries like linker and
  1043. // debuggerd that need to know when they are a 32-bit process running on a 64-bit device
  1044. if os.Class == Device {
  1045. if ctx.Config().Android64() {
  1046. field := "Android64"
  1047. prefix := "target.android64"
  1048. if android64Properties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok {
  1049. mergePropertyStruct(ctx, genProps, android64Properties)
  1050. }
  1051. } else {
  1052. field := "Android32"
  1053. prefix := "target.android32"
  1054. if android32Properties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok {
  1055. mergePropertyStruct(ctx, genProps, android32Properties)
  1056. }
  1057. }
  1058. }
  1059. }
  1060. }
  1061. }
  1062. // Returns the struct containing the properties specific to the given
  1063. // architecture type. These look like this in Blueprint files:
  1064. //
  1065. // arch: {
  1066. // arm64: {
  1067. // key: value,
  1068. // },
  1069. // },
  1070. //
  1071. // This struct will also contain sub-structs containing to the architecture/CPU
  1072. // variants and features that themselves contain properties specific to those.
  1073. func getArchTypeStruct(ctx ArchVariantContext, archProperties interface{}, archType ArchType) (reflect.Value, bool) {
  1074. archPropValues := reflect.ValueOf(archProperties).Elem()
  1075. archProp := archPropValues.FieldByName("Arch").Elem()
  1076. prefix := "arch." + archType.Name
  1077. return getChildPropertyStruct(ctx, archProp, archType.Name, prefix)
  1078. }
  1079. // Returns the struct containing the properties specific to a given multilib
  1080. // value. These look like this in the Blueprint file:
  1081. //
  1082. // multilib: {
  1083. // lib32: {
  1084. // key: value,
  1085. // },
  1086. // },
  1087. func getMultilibStruct(ctx ArchVariantContext, archProperties interface{}, archType ArchType) (reflect.Value, bool) {
  1088. archPropValues := reflect.ValueOf(archProperties).Elem()
  1089. multilibProp := archPropValues.FieldByName("Multilib").Elem()
  1090. return getChildPropertyStruct(ctx, multilibProp, archType.Multilib, "multilib."+archType.Multilib)
  1091. }
  1092. func GetCompoundTargetField(os OsType, arch ArchType) string {
  1093. return os.Field + "_" + arch.Name
  1094. }
  1095. // Returns the structs corresponding to the properties specific to the given
  1096. // architecture and OS in archProperties.
  1097. func getArchProperties(ctx BaseMutatorContext, archProperties interface{}, arch Arch, os OsType, nativeBridgeEnabled bool) []reflect.Value {
  1098. result := make([]reflect.Value, 0)
  1099. archPropValues := reflect.ValueOf(archProperties).Elem()
  1100. targetProp := archPropValues.FieldByName("Target").Elem()
  1101. archType := arch.ArchType
  1102. if arch.ArchType != Common {
  1103. archStruct, ok := getArchTypeStruct(ctx, archProperties, arch.ArchType)
  1104. if ok {
  1105. result = append(result, archStruct)
  1106. // Handle arch-variant-specific properties in the form:
  1107. // arch: {
  1108. // arm: {
  1109. // variant: {
  1110. // key: value,
  1111. // },
  1112. // },
  1113. // },
  1114. v := variantReplacer.Replace(arch.ArchVariant)
  1115. if v != "" {
  1116. prefix := "arch." + archType.Name + "." + v
  1117. if variantProperties, ok := getChildPropertyStruct(ctx, archStruct, v, prefix); ok {
  1118. result = append(result, variantProperties)
  1119. }
  1120. }
  1121. // Handle cpu-variant-specific properties in the form:
  1122. // arch: {
  1123. // arm: {
  1124. // variant: {
  1125. // key: value,
  1126. // },
  1127. // },
  1128. // },
  1129. if arch.CpuVariant != arch.ArchVariant {
  1130. c := variantReplacer.Replace(arch.CpuVariant)
  1131. if c != "" {
  1132. prefix := "arch." + archType.Name + "." + c
  1133. if cpuVariantProperties, ok := getChildPropertyStruct(ctx, archStruct, c, prefix); ok {
  1134. result = append(result, cpuVariantProperties)
  1135. }
  1136. }
  1137. }
  1138. // Handle arch-feature-specific properties in the form:
  1139. // arch: {
  1140. // arm: {
  1141. // feature: {
  1142. // key: value,
  1143. // },
  1144. // },
  1145. // },
  1146. for _, feature := range arch.ArchFeatures {
  1147. prefix := "arch." + archType.Name + "." + feature
  1148. if featureProperties, ok := getChildPropertyStruct(ctx, archStruct, feature, prefix); ok {
  1149. result = append(result, featureProperties)
  1150. }
  1151. }
  1152. }
  1153. if multilibProperties, ok := getMultilibStruct(ctx, archProperties, archType); ok {
  1154. result = append(result, multilibProperties)
  1155. }
  1156. // Handle combined OS-feature and arch specific properties in the form:
  1157. // target: {
  1158. // bionic_x86: {
  1159. // key: value,
  1160. // },
  1161. // }
  1162. if os.Linux() {
  1163. field := "Linux_" + arch.ArchType.Name
  1164. userFriendlyField := "target.linux_" + arch.ArchType.Name
  1165. if linuxProperties, ok := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField); ok {
  1166. result = append(result, linuxProperties)
  1167. }
  1168. }
  1169. if os.Bionic() {
  1170. field := "Bionic_" + archType.Name
  1171. userFriendlyField := "target.bionic_" + archType.Name
  1172. if bionicProperties, ok := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField); ok {
  1173. result = append(result, bionicProperties)
  1174. }
  1175. }
  1176. // Handle combined OS and arch specific properties in the form:
  1177. // target: {
  1178. // linux_glibc_x86: {
  1179. // key: value,
  1180. // },
  1181. // linux_glibc_arm: {
  1182. // key: value,
  1183. // },
  1184. // android_arm {
  1185. // key: value,
  1186. // },
  1187. // android_x86 {
  1188. // key: value,
  1189. // },
  1190. // },
  1191. field := GetCompoundTargetField(os, archType)
  1192. userFriendlyField := "target." + os.Name + "_" + archType.Name
  1193. if osArchProperties, ok := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField); ok {
  1194. result = append(result, osArchProperties)
  1195. }
  1196. if os == Linux {
  1197. field := "Glibc_" + archType.Name
  1198. userFriendlyField := "target.glibc_" + "_" + archType.Name
  1199. if osArchProperties, ok := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField); ok {
  1200. result = append(result, osArchProperties)
  1201. }
  1202. }
  1203. if os == LinuxMusl {
  1204. field := "Musl_" + archType.Name
  1205. userFriendlyField := "target.musl_" + "_" + archType.Name
  1206. if osArchProperties, ok := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField); ok {
  1207. result = append(result, osArchProperties)
  1208. }
  1209. }
  1210. }
  1211. // Handle arm on x86 properties in the form:
  1212. // target {
  1213. // arm_on_x86 {
  1214. // key: value,
  1215. // },
  1216. // arm_on_x86_64 {
  1217. // key: value,
  1218. // },
  1219. // },
  1220. if os.Class == Device {
  1221. if arch.ArchType == X86 && (hasArmAbi(arch) ||
  1222. hasArmAndroidArch(ctx.Config().Targets[Android])) {
  1223. field := "Arm_on_x86"
  1224. userFriendlyField := "target.arm_on_x86"
  1225. if armOnX86Properties, ok := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField); ok {
  1226. result = append(result, armOnX86Properties)
  1227. }
  1228. }
  1229. if arch.ArchType == X86_64 && (hasArmAbi(arch) ||
  1230. hasArmAndroidArch(ctx.Config().Targets[Android])) {
  1231. field := "Arm_on_x86_64"
  1232. userFriendlyField := "target.arm_on_x86_64"
  1233. if armOnX8664Properties, ok := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField); ok {
  1234. result = append(result, armOnX8664Properties)
  1235. }
  1236. }
  1237. if os == Android && nativeBridgeEnabled {
  1238. userFriendlyField := "Native_bridge"
  1239. prefix := "target.native_bridge"
  1240. if nativeBridgeProperties, ok := getChildPropertyStruct(ctx, targetProp, userFriendlyField, prefix); ok {
  1241. result = append(result, nativeBridgeProperties)
  1242. }
  1243. }
  1244. }
  1245. return result
  1246. }
  1247. // Squash the appropriate arch-specific property structs into the matching top level property
  1248. // structs based on the CompileTarget value that was annotated on the variant.
  1249. func (m *ModuleBase) setArchProperties(ctx BottomUpMutatorContext) {
  1250. arch := m.Arch()
  1251. os := m.Os()
  1252. for i := range m.archProperties {
  1253. genProps := m.GetProperties()[i]
  1254. if m.archProperties[i] == nil {
  1255. continue
  1256. }
  1257. propStructs := make([]reflect.Value, 0)
  1258. for _, archProperty := range m.archProperties[i] {
  1259. propStructShard := getArchProperties(ctx, archProperty, arch, os, m.Target().NativeBridge == NativeBridgeEnabled)
  1260. propStructs = append(propStructs, propStructShard...)
  1261. }
  1262. for _, propStruct := range propStructs {
  1263. mergePropertyStruct(ctx, genProps, propStruct)
  1264. }
  1265. }
  1266. }
  1267. // determineBuildOS stores the OS and architecture used for host targets used during the build into
  1268. // config based on the runtime OS and architecture determined by Go and the product configuration.
  1269. func determineBuildOS(config *config) {
  1270. config.BuildOS = func() OsType {
  1271. switch runtime.GOOS {
  1272. case "linux":
  1273. if Bool(config.productVariables.HostMusl) {
  1274. return LinuxMusl
  1275. }
  1276. return Linux
  1277. case "darwin":
  1278. return Darwin
  1279. default:
  1280. panic(fmt.Sprintf("unsupported OS: %s", runtime.GOOS))
  1281. }
  1282. }()
  1283. config.BuildArch = func() ArchType {
  1284. switch runtime.GOARCH {
  1285. case "amd64":
  1286. return X86_64
  1287. default:
  1288. panic(fmt.Sprintf("unsupported Arch: %s", runtime.GOARCH))
  1289. }
  1290. }()
  1291. }
  1292. // Convert the arch product variables into a list of targets for each OsType.
  1293. func decodeTargetProductVariables(config *config) (map[OsType][]Target, error) {
  1294. variables := config.productVariables
  1295. targets := make(map[OsType][]Target)
  1296. var targetErr error
  1297. type targetConfig struct {
  1298. os OsType
  1299. archName string
  1300. archVariant *string
  1301. cpuVariant *string
  1302. abi []string
  1303. nativeBridgeEnabled NativeBridgeSupport
  1304. nativeBridgeHostArchName *string
  1305. nativeBridgeRelativePath *string
  1306. }
  1307. addTarget := func(target targetConfig) {
  1308. if targetErr != nil {
  1309. return
  1310. }
  1311. arch, err := decodeArch(target.os, target.archName, target.archVariant, target.cpuVariant, target.abi)
  1312. if err != nil {
  1313. targetErr = err
  1314. return
  1315. }
  1316. nativeBridgeRelativePathStr := String(target.nativeBridgeRelativePath)
  1317. nativeBridgeHostArchNameStr := String(target.nativeBridgeHostArchName)
  1318. // Use guest arch as relative install path by default
  1319. if target.nativeBridgeEnabled && nativeBridgeRelativePathStr == "" {
  1320. nativeBridgeRelativePathStr = arch.ArchType.String()
  1321. }
  1322. // A target is considered as HostCross if it's a host target which can't run natively on
  1323. // the currently configured build machine (either because the OS is different or because of
  1324. // the unsupported arch)
  1325. hostCross := false
  1326. if target.os.Class == Host {
  1327. var osSupported bool
  1328. if target.os == config.BuildOS {
  1329. osSupported = true
  1330. } else if config.BuildOS.Linux() && target.os.Linux() {
  1331. // LinuxBionic and Linux are compatible
  1332. osSupported = true
  1333. } else {
  1334. osSupported = false
  1335. }
  1336. var archSupported bool
  1337. if arch.ArchType == Common {
  1338. archSupported = true
  1339. } else if arch.ArchType.Name == *variables.HostArch {
  1340. archSupported = true
  1341. } else if variables.HostSecondaryArch != nil && arch.ArchType.Name == *variables.HostSecondaryArch {
  1342. archSupported = true
  1343. } else {
  1344. archSupported = false
  1345. }
  1346. if !osSupported || !archSupported {
  1347. hostCross = true
  1348. }
  1349. }
  1350. targets[target.os] = append(targets[target.os],
  1351. Target{
  1352. Os: target.os,
  1353. Arch: arch,
  1354. NativeBridge: target.nativeBridgeEnabled,
  1355. NativeBridgeHostArchName: nativeBridgeHostArchNameStr,
  1356. NativeBridgeRelativePath: nativeBridgeRelativePathStr,
  1357. HostCross: hostCross,
  1358. })
  1359. }
  1360. if variables.HostArch == nil {
  1361. return nil, fmt.Errorf("No host primary architecture set")
  1362. }
  1363. // The primary host target, which must always exist.
  1364. addTarget(targetConfig{os: config.BuildOS, archName: *variables.HostArch, nativeBridgeEnabled: NativeBridgeDisabled})
  1365. // An optional secondary host target.
  1366. if variables.HostSecondaryArch != nil && *variables.HostSecondaryArch != "" {
  1367. addTarget(targetConfig{os: config.BuildOS, archName: *variables.HostSecondaryArch, nativeBridgeEnabled: NativeBridgeDisabled})
  1368. }
  1369. // Optional cross-compiled host targets, generally Windows.
  1370. if String(variables.CrossHost) != "" {
  1371. crossHostOs := osByName(*variables.CrossHost)
  1372. if crossHostOs == NoOsType {
  1373. return nil, fmt.Errorf("Unknown cross host OS %q", *variables.CrossHost)
  1374. }
  1375. if String(variables.CrossHostArch) == "" {
  1376. return nil, fmt.Errorf("No cross-host primary architecture set")
  1377. }
  1378. // The primary cross-compiled host target.
  1379. addTarget(targetConfig{os: crossHostOs, archName: *variables.CrossHostArch, nativeBridgeEnabled: NativeBridgeDisabled})
  1380. // An optional secondary cross-compiled host target.
  1381. if variables.CrossHostSecondaryArch != nil && *variables.CrossHostSecondaryArch != "" {
  1382. addTarget(targetConfig{os: crossHostOs, archName: *variables.CrossHostSecondaryArch, nativeBridgeEnabled: NativeBridgeDisabled})
  1383. }
  1384. }
  1385. // Optional device targets
  1386. if variables.DeviceArch != nil && *variables.DeviceArch != "" {
  1387. // The primary device target.
  1388. addTarget(targetConfig{
  1389. os: Android,
  1390. archName: *variables.DeviceArch,
  1391. archVariant: variables.DeviceArchVariant,
  1392. cpuVariant: variables.DeviceCpuVariant,
  1393. abi: variables.DeviceAbi,
  1394. nativeBridgeEnabled: NativeBridgeDisabled,
  1395. })
  1396. // An optional secondary device target.
  1397. if variables.DeviceSecondaryArch != nil && *variables.DeviceSecondaryArch != "" {
  1398. addTarget(targetConfig{
  1399. os: Android,
  1400. archName: *variables.DeviceSecondaryArch,
  1401. archVariant: variables.DeviceSecondaryArchVariant,
  1402. cpuVariant: variables.DeviceSecondaryCpuVariant,
  1403. abi: variables.DeviceSecondaryAbi,
  1404. nativeBridgeEnabled: NativeBridgeDisabled,
  1405. })
  1406. }
  1407. // An optional NativeBridge device target.
  1408. if variables.NativeBridgeArch != nil && *variables.NativeBridgeArch != "" {
  1409. addTarget(targetConfig{
  1410. os: Android,
  1411. archName: *variables.NativeBridgeArch,
  1412. archVariant: variables.NativeBridgeArchVariant,
  1413. cpuVariant: variables.NativeBridgeCpuVariant,
  1414. abi: variables.NativeBridgeAbi,
  1415. nativeBridgeEnabled: NativeBridgeEnabled,
  1416. nativeBridgeHostArchName: variables.DeviceArch,
  1417. nativeBridgeRelativePath: variables.NativeBridgeRelativePath,
  1418. })
  1419. }
  1420. // An optional secondary NativeBridge device target.
  1421. if variables.DeviceSecondaryArch != nil && *variables.DeviceSecondaryArch != "" &&
  1422. variables.NativeBridgeSecondaryArch != nil && *variables.NativeBridgeSecondaryArch != "" {
  1423. addTarget(targetConfig{
  1424. os: Android,
  1425. archName: *variables.NativeBridgeSecondaryArch,
  1426. archVariant: variables.NativeBridgeSecondaryArchVariant,
  1427. cpuVariant: variables.NativeBridgeSecondaryCpuVariant,
  1428. abi: variables.NativeBridgeSecondaryAbi,
  1429. nativeBridgeEnabled: NativeBridgeEnabled,
  1430. nativeBridgeHostArchName: variables.DeviceSecondaryArch,
  1431. nativeBridgeRelativePath: variables.NativeBridgeSecondaryRelativePath,
  1432. })
  1433. }
  1434. }
  1435. if targetErr != nil {
  1436. return nil, targetErr
  1437. }
  1438. return targets, nil
  1439. }
  1440. // hasArmAbi returns true if arch has at least one arm ABI
  1441. func hasArmAbi(arch Arch) bool {
  1442. return PrefixInList(arch.Abi, "arm")
  1443. }
  1444. // hasArmAndroidArch returns true if targets has at least
  1445. // one arm Android arch (possibly native bridged)
  1446. func hasArmAndroidArch(targets []Target) bool {
  1447. for _, target := range targets {
  1448. if target.Os == Android &&
  1449. (target.Arch.ArchType == Arm || target.Arch.ArchType == Arm64) {
  1450. return true
  1451. }
  1452. }
  1453. return false
  1454. }
  1455. // archConfig describes a built-in configuration.
  1456. type archConfig struct {
  1457. arch string
  1458. archVariant string
  1459. cpuVariant string
  1460. abi []string
  1461. }
  1462. // getNdkAbisConfig returns the list of archConfigs that are used for bulding
  1463. // the API stubs and static libraries that are included in the NDK. These are
  1464. // built *without Neon*, because non-Neon is still supported and building these
  1465. // with Neon will break those users.
  1466. func getNdkAbisConfig() []archConfig {
  1467. return []archConfig{
  1468. {"arm64", "armv8-a-branchprot", "", []string{"arm64-v8a"}},
  1469. {"arm", "armv7-a", "", []string{"armeabi-v7a"}},
  1470. {"x86_64", "", "", []string{"x86_64"}},
  1471. {"x86", "", "", []string{"x86"}},
  1472. }
  1473. }
  1474. // getAmlAbisConfig returns a list of archConfigs for the ABIs supported by mainline modules.
  1475. func getAmlAbisConfig() []archConfig {
  1476. return []archConfig{
  1477. {"arm64", "armv8-a", "", []string{"arm64-v8a"}},
  1478. {"arm", "armv7-a-neon", "", []string{"armeabi-v7a"}},
  1479. {"x86_64", "", "", []string{"x86_64"}},
  1480. {"x86", "", "", []string{"x86"}},
  1481. }
  1482. }
  1483. // decodeArchSettings converts a list of archConfigs into a list of Targets for the given OsType.
  1484. func decodeAndroidArchSettings(archConfigs []archConfig) ([]Target, error) {
  1485. var ret []Target
  1486. for _, config := range archConfigs {
  1487. arch, err := decodeArch(Android, config.arch, &config.archVariant,
  1488. &config.cpuVariant, config.abi)
  1489. if err != nil {
  1490. return nil, err
  1491. }
  1492. ret = append(ret, Target{
  1493. Os: Android,
  1494. Arch: arch,
  1495. })
  1496. }
  1497. return ret, nil
  1498. }
  1499. // decodeArch converts a set of strings from product variables into an Arch struct.
  1500. func decodeArch(os OsType, arch string, archVariant, cpuVariant *string, abi []string) (Arch, error) {
  1501. // Verify the arch is valid
  1502. archType, ok := archTypeMap[arch]
  1503. if !ok {
  1504. return Arch{}, fmt.Errorf("unknown arch %q", arch)
  1505. }
  1506. a := Arch{
  1507. ArchType: archType,
  1508. ArchVariant: String(archVariant),
  1509. CpuVariant: String(cpuVariant),
  1510. Abi: abi,
  1511. }
  1512. // Convert generic arch variants into the empty string.
  1513. if a.ArchVariant == a.ArchType.Name || a.ArchVariant == "generic" {
  1514. a.ArchVariant = ""
  1515. }
  1516. // Convert generic CPU variants into the empty string.
  1517. if a.CpuVariant == a.ArchType.Name || a.CpuVariant == "generic" {
  1518. a.CpuVariant = ""
  1519. }
  1520. if a.ArchVariant != "" {
  1521. if validArchVariants := archVariants[archType]; !InList(a.ArchVariant, validArchVariants) {
  1522. return Arch{}, fmt.Errorf("[%q] unknown arch variant %q, support variants: %q", archType, a.ArchVariant, validArchVariants)
  1523. }
  1524. }
  1525. if a.CpuVariant != "" {
  1526. if validCpuVariants := cpuVariants[archType]; !InList(a.CpuVariant, validCpuVariants) {
  1527. return Arch{}, fmt.Errorf("[%q] unknown cpu variant %q, support variants: %q", archType, a.CpuVariant, validCpuVariants)
  1528. }
  1529. }
  1530. // Filter empty ABIs out of the list.
  1531. for i := 0; i < len(a.Abi); i++ {
  1532. if a.Abi[i] == "" {
  1533. a.Abi = append(a.Abi[:i], a.Abi[i+1:]...)
  1534. i--
  1535. }
  1536. }
  1537. // Set ArchFeatures from the arch type. for Android OS, other os-es do not specify features
  1538. if os == Android {
  1539. if featureMap, ok := androidArchFeatureMap[archType]; ok {
  1540. a.ArchFeatures = featureMap[a.ArchVariant]
  1541. }
  1542. }
  1543. return a, nil
  1544. }
  1545. // filterMultilibTargets takes a list of Targets and a multilib value and returns a new list of
  1546. // Targets containing only those that have the given multilib value.
  1547. func filterMultilibTargets(targets []Target, multilib string) []Target {
  1548. var ret []Target
  1549. for _, t := range targets {
  1550. if t.Arch.ArchType.Multilib == multilib {
  1551. ret = append(ret, t)
  1552. }
  1553. }
  1554. return ret
  1555. }
  1556. // getCommonTargets returns the set of Os specific common architecture targets for each Os in a list
  1557. // of targets.
  1558. func getCommonTargets(targets []Target) []Target {
  1559. var ret []Target
  1560. set := make(map[string]bool)
  1561. for _, t := range targets {
  1562. if _, found := set[t.Os.String()]; !found {
  1563. set[t.Os.String()] = true
  1564. common := commonTargetMap[t.Os.String()]
  1565. common.HostCross = t.HostCross
  1566. ret = append(ret, common)
  1567. }
  1568. }
  1569. return ret
  1570. }
  1571. // FirstTarget takes a list of Targets and a list of multilib values and returns a list of Targets
  1572. // that contains zero or one Target for each OsType, selecting the one that matches the earliest
  1573. // filter.
  1574. func FirstTarget(targets []Target, filters ...string) []Target {
  1575. // find the first target from each OS
  1576. var ret []Target
  1577. hasHost := false
  1578. set := make(map[OsType]bool)
  1579. for _, filter := range filters {
  1580. buildTargets := filterMultilibTargets(targets, filter)
  1581. for _, t := range buildTargets {
  1582. if _, found := set[t.Os]; !found {
  1583. hasHost = hasHost || (t.Os.Class == Host)
  1584. set[t.Os] = true
  1585. ret = append(ret, t)
  1586. }
  1587. }
  1588. }
  1589. return ret
  1590. }
  1591. // decodeMultilibTargets uses the module's multilib setting to select one or more targets from a
  1592. // list of Targets.
  1593. func decodeMultilibTargets(multilib string, targets []Target, prefer32 bool) ([]Target, error) {
  1594. var buildTargets []Target
  1595. switch multilib {
  1596. case "common":
  1597. buildTargets = getCommonTargets(targets)
  1598. case "common_first":
  1599. buildTargets = getCommonTargets(targets)
  1600. if prefer32 {
  1601. buildTargets = append(buildTargets, FirstTarget(targets, "lib32", "lib64")...)
  1602. } else {
  1603. buildTargets = append(buildTargets, FirstTarget(targets, "lib64", "lib32")...)
  1604. }
  1605. case "both":
  1606. if prefer32 {
  1607. buildTargets = append(buildTargets, filterMultilibTargets(targets, "lib32")...)
  1608. buildTargets = append(buildTargets, filterMultilibTargets(targets, "lib64")...)
  1609. } else {
  1610. buildTargets = append(buildTargets, filterMultilibTargets(targets, "lib64")...)
  1611. buildTargets = append(buildTargets, filterMultilibTargets(targets, "lib32")...)
  1612. }
  1613. case "32":
  1614. buildTargets = filterMultilibTargets(targets, "lib32")
  1615. case "64":
  1616. buildTargets = filterMultilibTargets(targets, "lib64")
  1617. case "first":
  1618. if prefer32 {
  1619. buildTargets = FirstTarget(targets, "lib32", "lib64")
  1620. } else {
  1621. buildTargets = FirstTarget(targets, "lib64", "lib32")
  1622. }
  1623. case "first_prefer32":
  1624. buildTargets = FirstTarget(targets, "lib32", "lib64")
  1625. case "prefer32":
  1626. buildTargets = filterMultilibTargets(targets, "lib32")
  1627. if len(buildTargets) == 0 {
  1628. buildTargets = filterMultilibTargets(targets, "lib64")
  1629. }
  1630. case "darwin_universal":
  1631. buildTargets = filterMultilibTargets(targets, "lib64")
  1632. // Reverse the targets so that the first architecture can depend on the second
  1633. // architecture module in order to merge the outputs.
  1634. reverseSliceInPlace(buildTargets)
  1635. case "darwin_universal_common_first":
  1636. archTargets := filterMultilibTargets(targets, "lib64")
  1637. reverseSliceInPlace(archTargets)
  1638. buildTargets = append(getCommonTargets(targets), archTargets...)
  1639. default:
  1640. return nil, fmt.Errorf(`compile_multilib must be "both", "first", "32", "64", "prefer32" or "first_prefer32" found %q`,
  1641. multilib)
  1642. }
  1643. return buildTargets, nil
  1644. }
  1645. func (m *ModuleBase) getArchPropertySet(propertySet interface{}, archType ArchType) interface{} {
  1646. archString := archType.Field
  1647. for i := range m.archProperties {
  1648. if m.archProperties[i] == nil {
  1649. // Skip over nil properties
  1650. continue
  1651. }
  1652. // Not archProperties are usable; this function looks for properties of a very specific
  1653. // form, and ignores the rest.
  1654. for _, archProperty := range m.archProperties[i] {
  1655. // archPropValue is a property struct, we are looking for the form:
  1656. // `arch: { arm: { key: value, ... }}`
  1657. archPropValue := reflect.ValueOf(archProperty).Elem()
  1658. // Unwrap src so that it should looks like a pointer to `arm: { key: value, ... }`
  1659. src := archPropValue.FieldByName("Arch").Elem()
  1660. // Step into non-nil pointers to structs in the src value.
  1661. if src.Kind() == reflect.Ptr {
  1662. if src.IsNil() {
  1663. continue
  1664. }
  1665. src = src.Elem()
  1666. }
  1667. // Find the requested field (e.g. arm, x86) in the src struct.
  1668. src = src.FieldByName(archString)
  1669. // We only care about structs.
  1670. if !src.IsValid() || src.Kind() != reflect.Struct {
  1671. continue
  1672. }
  1673. // If the value of the field is a struct then step into the
  1674. // BlueprintEmbed field. The special "BlueprintEmbed" name is
  1675. // used by createArchPropTypeDesc to embed the arch properties
  1676. // in the parent struct, so the src arch prop should be in this
  1677. // field.
  1678. //
  1679. // See createArchPropTypeDesc for more details on how Arch-specific
  1680. // module properties are processed from the nested props and written
  1681. // into the module's archProperties.
  1682. src = src.FieldByName("BlueprintEmbed")
  1683. // Clone the destination prop, since we want a unique prop struct per arch.
  1684. propertySetClone := reflect.New(reflect.ValueOf(propertySet).Elem().Type()).Interface()
  1685. // Copy the located property struct into the cloned destination property struct.
  1686. err := proptools.ExtendMatchingProperties([]interface{}{propertySetClone}, src.Interface(), nil, proptools.OrderReplace)
  1687. if err != nil {
  1688. // This is fine, it just means the src struct doesn't match the type of propertySet.
  1689. continue
  1690. }
  1691. return propertySetClone
  1692. }
  1693. }
  1694. // No property set was found specific to the given arch, so return an empty
  1695. // property set.
  1696. return reflect.New(reflect.ValueOf(propertySet).Elem().Type()).Interface()
  1697. }
  1698. // getMultilibPropertySet returns a property set struct matching the type of
  1699. // `propertySet`, containing multilib-specific module properties for the given architecture.
  1700. // If no multilib-specific properties exist for the given architecture, returns an empty property
  1701. // set matching `propertySet`'s type.
  1702. func (m *ModuleBase) getMultilibPropertySet(propertySet interface{}, archType ArchType) interface{} {
  1703. // archType.Multilib is lowercase (for example, lib32) but property struct field is
  1704. // capitalized, such as Lib32, so use strings.Title to capitalize it.
  1705. multiLibString := strings.Title(archType.Multilib)
  1706. for i := range m.archProperties {
  1707. if m.archProperties[i] == nil {
  1708. // Skip over nil properties
  1709. continue
  1710. }
  1711. // Not archProperties are usable; this function looks for properties of a very specific
  1712. // form, and ignores the rest.
  1713. for _, archProperties := range m.archProperties[i] {
  1714. // archPropValue is a property struct, we are looking for the form:
  1715. // `multilib: { lib32: { key: value, ... }}`
  1716. archPropValue := reflect.ValueOf(archProperties).Elem()
  1717. // Unwrap src so that it should looks like a pointer to `lib32: { key: value, ... }`
  1718. src := archPropValue.FieldByName("Multilib").Elem()
  1719. // Step into non-nil pointers to structs in the src value.
  1720. if src.Kind() == reflect.Ptr {
  1721. if src.IsNil() {
  1722. // Ignore nil pointers.
  1723. continue
  1724. }
  1725. src = src.Elem()
  1726. }
  1727. // Find the requested field (e.g. lib32) in the src struct.
  1728. src = src.FieldByName(multiLibString)
  1729. // We only care about valid struct pointers.
  1730. if !src.IsValid() || src.Kind() != reflect.Ptr || src.Elem().Kind() != reflect.Struct {
  1731. continue
  1732. }
  1733. // Get the zero value for the requested property set.
  1734. propertySetClone := reflect.New(reflect.ValueOf(propertySet).Elem().Type()).Interface()
  1735. // Copy the located property struct into the "zero" property set struct.
  1736. err := proptools.ExtendMatchingProperties([]interface{}{propertySetClone}, src.Interface(), nil, proptools.OrderReplace)
  1737. if err != nil {
  1738. // This is fine, it just means the src struct doesn't match.
  1739. continue
  1740. }
  1741. return propertySetClone
  1742. }
  1743. }
  1744. // There were no multilib properties specifically matching the given archtype.
  1745. // Return zeroed value.
  1746. return reflect.New(reflect.ValueOf(propertySet).Elem().Type()).Interface()
  1747. }
  1748. // ArchVariantContext defines the limited context necessary to retrieve arch_variant properties.
  1749. type ArchVariantContext interface {
  1750. ModuleErrorf(fmt string, args ...interface{})
  1751. PropertyErrorf(property, fmt string, args ...interface{})
  1752. }
  1753. // ArchVariantProperties represents a map of arch-variant config strings to a property interface{}.
  1754. type ArchVariantProperties map[string]interface{}
  1755. // ConfigurationAxisToArchVariantProperties represents a map of bazel.ConfigurationAxis to
  1756. // ArchVariantProperties, such that each independent arch-variant axis maps to the
  1757. // configs/properties for that axis.
  1758. type ConfigurationAxisToArchVariantProperties map[bazel.ConfigurationAxis]ArchVariantProperties
  1759. // GetArchVariantProperties returns a ConfigurationAxisToArchVariantProperties where the
  1760. // arch-variant properties correspond to the values of the properties of the 'propertySet' struct
  1761. // that are specific to that axis/configuration. Each axis is independent, containing
  1762. // non-overlapping configs that correspond to the various "arch-variant" support, at this time:
  1763. //
  1764. // arches (including multilib)
  1765. // oses
  1766. // arch+os combinations
  1767. //
  1768. // For example, passing a struct { Foo bool, Bar string } will return an interface{} that can be
  1769. // type asserted back into the same struct, containing the config-specific property value specified
  1770. // by the module if defined.
  1771. //
  1772. // Arch-specific properties may come from an arch stanza or a multilib stanza; properties
  1773. // in these stanzas are combined.
  1774. // For example: `arch: { x86: { Foo: ["bar"] } }, multilib: { lib32: {` Foo: ["baz"] } }`
  1775. // will result in `Foo: ["bar", "baz"]` being returned for architecture x86, if the given
  1776. // propertyset contains `Foo []string`.
  1777. func (m *ModuleBase) GetArchVariantProperties(ctx ArchVariantContext, propertySet interface{}) ConfigurationAxisToArchVariantProperties {
  1778. // Return value of the arch types to the prop values for that arch.
  1779. axisToProps := ConfigurationAxisToArchVariantProperties{}
  1780. // Nothing to do for non-arch-specific modules.
  1781. if !m.ArchSpecific() {
  1782. return axisToProps
  1783. }
  1784. dstType := reflect.ValueOf(propertySet).Type()
  1785. var archProperties []interface{}
  1786. // First find the property set in the module that corresponds to the requested
  1787. // one. m.archProperties[i] corresponds to m.GetProperties()[i].
  1788. for i, generalProp := range m.GetProperties() {
  1789. srcType := reflect.ValueOf(generalProp).Type()
  1790. if srcType == dstType {
  1791. archProperties = m.archProperties[i]
  1792. axisToProps[bazel.NoConfigAxis] = ArchVariantProperties{"": generalProp}
  1793. break
  1794. }
  1795. }
  1796. if archProperties == nil {
  1797. // This module does not have the property set requested
  1798. return axisToProps
  1799. }
  1800. archToProp := ArchVariantProperties{}
  1801. // For each arch type (x86, arm64, etc.)
  1802. for _, arch := range ArchTypeList() {
  1803. // Arch properties are sometimes sharded (see createArchPropTypeDesc() ).
  1804. // Iterate over ever shard and extract a struct with the same type as the
  1805. // input one that contains the data specific to that arch.
  1806. propertyStructs := make([]reflect.Value, 0)
  1807. for _, archProperty := range archProperties {
  1808. archTypeStruct, ok := getArchTypeStruct(ctx, archProperty, arch)
  1809. if ok {
  1810. propertyStructs = append(propertyStructs, archTypeStruct)
  1811. }
  1812. multilibStruct, ok := getMultilibStruct(ctx, archProperty, arch)
  1813. if ok {
  1814. propertyStructs = append(propertyStructs, multilibStruct)
  1815. }
  1816. }
  1817. // Create a new instance of the requested property set
  1818. value := reflect.New(reflect.ValueOf(propertySet).Elem().Type()).Interface()
  1819. archToProp[arch.Name] = mergeStructs(ctx, propertyStructs, value)
  1820. }
  1821. axisToProps[bazel.ArchConfigurationAxis] = archToProp
  1822. osToProp := ArchVariantProperties{}
  1823. archOsToProp := ArchVariantProperties{}
  1824. linuxStructs := getTargetStructs(ctx, archProperties, "Linux")
  1825. bionicStructs := getTargetStructs(ctx, archProperties, "Bionic")
  1826. hostStructs := getTargetStructs(ctx, archProperties, "Host")
  1827. hostLinuxStructs := getTargetStructs(ctx, archProperties, "Host_linux")
  1828. hostNotWindowsStructs := getTargetStructs(ctx, archProperties, "Not_windows")
  1829. // For android, linux, ...
  1830. for _, os := range osTypeList {
  1831. if os == CommonOS {
  1832. // It looks like this OS value is not used in Blueprint files
  1833. continue
  1834. }
  1835. osStructs := make([]reflect.Value, 0)
  1836. osSpecificStructs := getTargetStructs(ctx, archProperties, os.Field)
  1837. if os.Class == Host {
  1838. osStructs = append(osStructs, hostStructs...)
  1839. }
  1840. if os.Linux() {
  1841. osStructs = append(osStructs, linuxStructs...)
  1842. }
  1843. if os.Bionic() {
  1844. osStructs = append(osStructs, bionicStructs...)
  1845. }
  1846. if os.Linux() && os.Class == Host {
  1847. osStructs = append(osStructs, hostLinuxStructs...)
  1848. }
  1849. if os == LinuxMusl {
  1850. osStructs = append(osStructs, getTargetStructs(ctx, archProperties, "Musl")...)
  1851. }
  1852. if os == Linux {
  1853. osStructs = append(osStructs, getTargetStructs(ctx, archProperties, "Glibc")...)
  1854. }
  1855. osStructs = append(osStructs, osSpecificStructs...)
  1856. if os.Class == Host && os != Windows {
  1857. osStructs = append(osStructs, hostNotWindowsStructs...)
  1858. }
  1859. osToProp[os.Name] = mergeStructs(ctx, osStructs, propertySet)
  1860. // For arm, x86, ...
  1861. for _, arch := range osArchTypeMap[os] {
  1862. osArchStructs := make([]reflect.Value, 0)
  1863. // Auto-combine with Linux_ and Bionic_ targets. This potentially results in
  1864. // repetition and select() bloat, but use of Linux_* and Bionic_* targets is rare.
  1865. // TODO(b/201423152): Look into cleanup.
  1866. if os.Linux() {
  1867. targetField := "Linux_" + arch.Name
  1868. targetStructs := getTargetStructs(ctx, archProperties, targetField)
  1869. osArchStructs = append(osArchStructs, targetStructs...)
  1870. }
  1871. if os.Bionic() {
  1872. targetField := "Bionic_" + arch.Name
  1873. targetStructs := getTargetStructs(ctx, archProperties, targetField)
  1874. osArchStructs = append(osArchStructs, targetStructs...)
  1875. }
  1876. if os == LinuxMusl {
  1877. targetField := "Musl_" + arch.Name
  1878. targetStructs := getTargetStructs(ctx, archProperties, targetField)
  1879. osArchStructs = append(osArchStructs, targetStructs...)
  1880. }
  1881. if os == Linux {
  1882. targetField := "Glibc_" + arch.Name
  1883. targetStructs := getTargetStructs(ctx, archProperties, targetField)
  1884. osArchStructs = append(osArchStructs, targetStructs...)
  1885. }
  1886. targetField := GetCompoundTargetField(os, arch)
  1887. targetName := fmt.Sprintf("%s_%s", os.Name, arch.Name)
  1888. targetStructs := getTargetStructs(ctx, archProperties, targetField)
  1889. osArchStructs = append(osArchStructs, targetStructs...)
  1890. archOsToProp[targetName] = mergeStructs(ctx, osArchStructs, propertySet)
  1891. }
  1892. }
  1893. axisToProps[bazel.OsConfigurationAxis] = osToProp
  1894. axisToProps[bazel.OsArchConfigurationAxis] = archOsToProp
  1895. return axisToProps
  1896. }
  1897. // Returns a struct matching the propertySet interface, containing properties specific to the targetName
  1898. // For example, given these arguments:
  1899. //
  1900. // propertySet = BaseCompilerProperties
  1901. // targetName = "android_arm"
  1902. //
  1903. // And given this Android.bp fragment:
  1904. //
  1905. // target:
  1906. // android_arm: {
  1907. // srcs: ["foo.c"],
  1908. // }
  1909. // android_arm64: {
  1910. // srcs: ["bar.c"],
  1911. // }
  1912. // }
  1913. //
  1914. // This would return a BaseCompilerProperties with BaseCompilerProperties.Srcs = ["foo.c"]
  1915. func getTargetStructs(ctx ArchVariantContext, archProperties []interface{}, targetName string) []reflect.Value {
  1916. var propertyStructs []reflect.Value
  1917. for _, archProperty := range archProperties {
  1918. archPropValues := reflect.ValueOf(archProperty).Elem()
  1919. targetProp := archPropValues.FieldByName("Target").Elem()
  1920. targetStruct, ok := getChildPropertyStruct(ctx, targetProp, targetName, targetName)
  1921. if ok {
  1922. propertyStructs = append(propertyStructs, targetStruct)
  1923. } else {
  1924. return []reflect.Value{}
  1925. }
  1926. }
  1927. return propertyStructs
  1928. }
  1929. func mergeStructs(ctx ArchVariantContext, propertyStructs []reflect.Value, propertySet interface{}) interface{} {
  1930. // Create a new instance of the requested property set
  1931. value := reflect.New(reflect.ValueOf(propertySet).Elem().Type()).Interface()
  1932. // Merge all the structs together
  1933. for _, propertyStruct := range propertyStructs {
  1934. mergePropertyStruct(ctx, value, propertyStruct)
  1935. }
  1936. return value
  1937. }
  1938. func printArchTypeStarlarkDict(dict map[ArchType][]string) string {
  1939. valDict := make(map[string]string, len(dict))
  1940. for k, v := range dict {
  1941. valDict[k.String()] = starlark_fmt.PrintStringList(v, 1)
  1942. }
  1943. return starlark_fmt.PrintDict(valDict, 0)
  1944. }
  1945. func printArchTypeNestedStarlarkDict(dict map[ArchType]map[string][]string) string {
  1946. valDict := make(map[string]string, len(dict))
  1947. for k, v := range dict {
  1948. valDict[k.String()] = starlark_fmt.PrintStringListDict(v, 1)
  1949. }
  1950. return starlark_fmt.PrintDict(valDict, 0)
  1951. }
  1952. func StarlarkArchConfigurations() string {
  1953. return fmt.Sprintf(`
  1954. _arch_to_variants = %s
  1955. _arch_to_cpu_variants = %s
  1956. _arch_to_features = %s
  1957. _android_arch_feature_for_arch_variant = %s
  1958. arch_to_variants = _arch_to_variants
  1959. arch_to_cpu_variants = _arch_to_cpu_variants
  1960. arch_to_features = _arch_to_features
  1961. android_arch_feature_for_arch_variants = _android_arch_feature_for_arch_variant
  1962. `, printArchTypeStarlarkDict(archVariants),
  1963. printArchTypeStarlarkDict(cpuVariants),
  1964. printArchTypeStarlarkDict(archFeatures),
  1965. printArchTypeNestedStarlarkDict(androidArchFeatureMap),
  1966. )
  1967. }