arch.go 68 KB

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