arch.go 79 KB

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