bp2build.go 76 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917
  1. // Copyright 2021 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 cc
  15. import (
  16. "fmt"
  17. "path/filepath"
  18. "strings"
  19. "sync"
  20. "android/soong/android"
  21. "android/soong/bazel"
  22. "android/soong/cc/config"
  23. "github.com/google/blueprint"
  24. "github.com/google/blueprint/proptools"
  25. )
  26. const (
  27. cSrcPartition = "c"
  28. asSrcPartition = "as"
  29. asmSrcPartition = "asm"
  30. lSrcPartition = "l"
  31. llSrcPartition = "ll"
  32. cppSrcPartition = "cpp"
  33. protoSrcPartition = "proto"
  34. aidlSrcPartition = "aidl"
  35. syspropSrcPartition = "sysprop"
  36. yaccSrcPartition = "yacc"
  37. rScriptSrcPartition = "renderScript"
  38. stubsSuffix = "_stub_libs_current"
  39. )
  40. // staticOrSharedAttributes are the Bazel-ified versions of StaticOrSharedProperties --
  41. // properties which apply to either the shared or static version of a cc_library module.
  42. type staticOrSharedAttributes struct {
  43. Srcs bazel.LabelListAttribute
  44. Srcs_c bazel.LabelListAttribute
  45. Srcs_as bazel.LabelListAttribute
  46. Srcs_aidl bazel.LabelListAttribute
  47. Hdrs bazel.LabelListAttribute
  48. Copts bazel.StringListAttribute
  49. Deps bazel.LabelListAttribute
  50. Implementation_deps bazel.LabelListAttribute
  51. Dynamic_deps bazel.LabelListAttribute
  52. Implementation_dynamic_deps bazel.LabelListAttribute
  53. Whole_archive_deps bazel.LabelListAttribute
  54. Implementation_whole_archive_deps bazel.LabelListAttribute
  55. Runtime_deps bazel.LabelListAttribute
  56. System_dynamic_deps bazel.LabelListAttribute
  57. Enabled bazel.BoolAttribute
  58. Native_coverage *bool
  59. Apex_available []string
  60. Features bazel.StringListAttribute
  61. sdkAttributes
  62. tidyAttributes
  63. }
  64. type tidyAttributes struct {
  65. Tidy *string
  66. Tidy_flags []string
  67. Tidy_checks []string
  68. Tidy_checks_as_errors []string
  69. Tidy_disabled_srcs bazel.LabelListAttribute
  70. Tidy_timeout_srcs bazel.LabelListAttribute
  71. }
  72. func (m *Module) convertTidyAttributes(ctx android.BaseMutatorContext, moduleAttrs *tidyAttributes) {
  73. for _, f := range m.features {
  74. if tidy, ok := f.(*tidyFeature); ok {
  75. var tidyAttr *string
  76. if tidy.Properties.Tidy != nil {
  77. if *tidy.Properties.Tidy {
  78. tidyAttr = proptools.StringPtr("local")
  79. } else {
  80. tidyAttr = proptools.StringPtr("never")
  81. }
  82. }
  83. moduleAttrs.Tidy = tidyAttr
  84. moduleAttrs.Tidy_flags = tidy.Properties.Tidy_flags
  85. moduleAttrs.Tidy_checks = tidy.Properties.Tidy_checks
  86. moduleAttrs.Tidy_checks_as_errors = tidy.Properties.Tidy_checks_as_errors
  87. }
  88. }
  89. archVariantProps := m.GetArchVariantProperties(ctx, &BaseCompilerProperties{})
  90. for axis, configToProps := range archVariantProps {
  91. for cfg, _props := range configToProps {
  92. if archProps, ok := _props.(*BaseCompilerProperties); ok {
  93. archDisabledSrcs := android.BazelLabelForModuleSrc(ctx, archProps.Tidy_disabled_srcs)
  94. moduleAttrs.Tidy_disabled_srcs.SetSelectValue(axis, cfg, archDisabledSrcs)
  95. archTimeoutSrcs := android.BazelLabelForModuleSrc(ctx, archProps.Tidy_timeout_srcs)
  96. moduleAttrs.Tidy_timeout_srcs.SetSelectValue(axis, cfg, archTimeoutSrcs)
  97. }
  98. }
  99. }
  100. }
  101. // groupSrcsByExtension partitions `srcs` into groups based on file extension.
  102. func groupSrcsByExtension(ctx android.BazelConversionPathContext, srcs bazel.LabelListAttribute) bazel.PartitionToLabelListAttribute {
  103. // Convert filegroup dependencies into extension-specific filegroups filtered in the filegroup.bzl
  104. // macro.
  105. addSuffixForFilegroup := func(suffix string) bazel.LabelMapper {
  106. return func(otherModuleCtx bazel.OtherModuleContext, label bazel.Label) (string, bool) {
  107. m, exists := otherModuleCtx.ModuleFromName(label.OriginalModuleName)
  108. labelStr := label.Label
  109. if !exists || !android.IsFilegroup(otherModuleCtx, m) {
  110. return labelStr, false
  111. }
  112. // If the filegroup is already converted to aidl_library or proto_library,
  113. // skip creating _c_srcs, _as_srcs, _cpp_srcs filegroups
  114. fg, _ := m.(android.FileGroupAsLibrary)
  115. if fg.ShouldConvertToAidlLibrary(ctx) || fg.ShouldConvertToProtoLibrary(ctx) {
  116. return labelStr, false
  117. }
  118. return labelStr + suffix, true
  119. }
  120. }
  121. // TODO(b/190006308): Handle language detection of sources in a Bazel rule.
  122. labels := bazel.LabelPartitions{
  123. protoSrcPartition: android.ProtoSrcLabelPartition,
  124. cSrcPartition: bazel.LabelPartition{Extensions: []string{".c"}, LabelMapper: addSuffixForFilegroup("_c_srcs")},
  125. asSrcPartition: bazel.LabelPartition{Extensions: []string{".s", ".S"}, LabelMapper: addSuffixForFilegroup("_as_srcs")},
  126. asmSrcPartition: bazel.LabelPartition{Extensions: []string{".asm"}},
  127. aidlSrcPartition: android.AidlSrcLabelPartition,
  128. // TODO(http://b/231968910): If there is ever a filegroup target that
  129. // contains .l or .ll files we will need to find a way to add a
  130. // LabelMapper for these that identifies these filegroups and
  131. // converts them appropriately
  132. lSrcPartition: bazel.LabelPartition{Extensions: []string{".l"}},
  133. llSrcPartition: bazel.LabelPartition{Extensions: []string{".ll"}},
  134. rScriptSrcPartition: bazel.LabelPartition{Extensions: []string{".fs", ".rscript"}},
  135. // C++ is the "catch-all" group, and comprises generated sources because we don't
  136. // know the language of these sources until the genrule is executed.
  137. cppSrcPartition: bazel.LabelPartition{Extensions: []string{".cpp", ".cc", ".cxx", ".mm"}, LabelMapper: addSuffixForFilegroup("_cpp_srcs"), Keep_remainder: true},
  138. syspropSrcPartition: bazel.LabelPartition{Extensions: []string{".sysprop"}},
  139. yaccSrcPartition: bazel.LabelPartition{Extensions: []string{".y", "yy"}},
  140. }
  141. return bazel.PartitionLabelListAttribute(ctx, &srcs, labels)
  142. }
  143. // bp2BuildParseLibProps returns the attributes for a variant of a cc_library.
  144. func bp2BuildParseLibProps(ctx android.BazelConversionPathContext, module *Module, isStatic bool) staticOrSharedAttributes {
  145. lib, ok := module.compiler.(*libraryDecorator)
  146. if !ok {
  147. return staticOrSharedAttributes{}
  148. }
  149. return bp2buildParseStaticOrSharedProps(ctx, module, lib, isStatic)
  150. }
  151. // bp2buildParseSharedProps returns the attributes for the shared variant of a cc_library.
  152. func bp2BuildParseSharedProps(ctx android.BazelConversionPathContext, module *Module) staticOrSharedAttributes {
  153. return bp2BuildParseLibProps(ctx, module, false)
  154. }
  155. // bp2buildParseStaticProps returns the attributes for the static variant of a cc_library.
  156. func bp2BuildParseStaticProps(ctx android.BazelConversionPathContext, module *Module) staticOrSharedAttributes {
  157. return bp2BuildParseLibProps(ctx, module, true)
  158. }
  159. type depsPartition struct {
  160. export bazel.LabelList
  161. implementation bazel.LabelList
  162. }
  163. type bazelLabelForDepsFn func(android.BazelConversionPathContext, []string) bazel.LabelList
  164. func maybePartitionExportedAndImplementationsDeps(ctx android.BazelConversionPathContext, exportsDeps bool, allDeps, exportedDeps []string, fn bazelLabelForDepsFn) depsPartition {
  165. if !exportsDeps {
  166. return depsPartition{
  167. implementation: fn(ctx, allDeps),
  168. }
  169. }
  170. implementation, export := android.FilterList(allDeps, exportedDeps)
  171. return depsPartition{
  172. export: fn(ctx, export),
  173. implementation: fn(ctx, implementation),
  174. }
  175. }
  176. type bazelLabelForDepsExcludesFn func(android.BazelConversionPathContext, []string, []string) bazel.LabelList
  177. func maybePartitionExportedAndImplementationsDepsExcludes(ctx android.BazelConversionPathContext, exportsDeps bool, allDeps, excludes, exportedDeps []string, fn bazelLabelForDepsExcludesFn) depsPartition {
  178. if !exportsDeps {
  179. return depsPartition{
  180. implementation: fn(ctx, allDeps, excludes),
  181. }
  182. }
  183. implementation, export := android.FilterList(allDeps, exportedDeps)
  184. return depsPartition{
  185. export: fn(ctx, export, excludes),
  186. implementation: fn(ctx, implementation, excludes),
  187. }
  188. }
  189. func bp2BuildPropParseHelper(ctx android.ArchVariantContext, module *Module, propsType interface{}, parseFunc func(axis bazel.ConfigurationAxis, config string, props interface{})) {
  190. for axis, configToProps := range module.GetArchVariantProperties(ctx, propsType) {
  191. for cfg, props := range configToProps {
  192. parseFunc(axis, cfg, props)
  193. }
  194. }
  195. }
  196. // Parses properties common to static and shared libraries. Also used for prebuilt libraries.
  197. func bp2buildParseStaticOrSharedProps(ctx android.BazelConversionPathContext, module *Module, lib *libraryDecorator, isStatic bool) staticOrSharedAttributes {
  198. attrs := staticOrSharedAttributes{}
  199. setAttrs := func(axis bazel.ConfigurationAxis, config string, props StaticOrSharedProperties) {
  200. attrs.Copts.SetSelectValue(axis, config, parseCommandLineFlags(props.Cflags, filterOutStdFlag, filterOutHiddenVisibility))
  201. attrs.Srcs.SetSelectValue(axis, config, android.BazelLabelForModuleSrc(ctx, props.Srcs))
  202. attrs.System_dynamic_deps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, props.System_shared_libs))
  203. staticDeps := maybePartitionExportedAndImplementationsDeps(ctx, true, props.Static_libs, props.Export_static_lib_headers, bazelLabelForStaticDeps)
  204. attrs.Deps.SetSelectValue(axis, config, staticDeps.export)
  205. attrs.Implementation_deps.SetSelectValue(axis, config, staticDeps.implementation)
  206. sharedDeps := maybePartitionExportedAndImplementationsDeps(ctx, true, props.Shared_libs, props.Export_shared_lib_headers, bazelLabelForSharedDeps)
  207. attrs.Dynamic_deps.SetSelectValue(axis, config, sharedDeps.export)
  208. attrs.Implementation_dynamic_deps.SetSelectValue(axis, config, sharedDeps.implementation)
  209. attrs.Whole_archive_deps.SetSelectValue(axis, config, bazelLabelForWholeDeps(ctx, props.Whole_static_libs))
  210. attrs.Enabled.SetSelectValue(axis, config, props.Enabled)
  211. }
  212. // system_dynamic_deps distinguishes between nil/empty list behavior:
  213. // nil -> use default values
  214. // empty list -> no values specified
  215. attrs.System_dynamic_deps.ForceSpecifyEmptyList = true
  216. var apexAvailable []string
  217. if isStatic {
  218. apexAvailable = lib.StaticProperties.Static.Apex_available
  219. bp2BuildPropParseHelper(ctx, module, &StaticProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
  220. if staticOrSharedProps, ok := props.(*StaticProperties); ok {
  221. setAttrs(axis, config, staticOrSharedProps.Static)
  222. }
  223. })
  224. } else {
  225. apexAvailable = lib.SharedProperties.Shared.Apex_available
  226. bp2BuildPropParseHelper(ctx, module, &SharedProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
  227. if staticOrSharedProps, ok := props.(*SharedProperties); ok {
  228. setAttrs(axis, config, staticOrSharedProps.Shared)
  229. }
  230. })
  231. }
  232. partitionedSrcs := groupSrcsByExtension(ctx, attrs.Srcs)
  233. attrs.Srcs = partitionedSrcs[cppSrcPartition]
  234. attrs.Srcs_c = partitionedSrcs[cSrcPartition]
  235. attrs.Srcs_as = partitionedSrcs[asSrcPartition]
  236. attrs.Apex_available = android.ConvertApexAvailableToTagsWithoutTestApexes(ctx.(android.TopDownMutatorContext), apexAvailable)
  237. attrs.Features.Append(convertHiddenVisibilityToFeatureStaticOrShared(ctx, module, isStatic))
  238. if !partitionedSrcs[protoSrcPartition].IsEmpty() {
  239. // TODO(b/208815215): determine whether this is used and add support if necessary
  240. ctx.ModuleErrorf("Migrating static/shared only proto srcs is not currently supported")
  241. }
  242. return attrs
  243. }
  244. // Convenience struct to hold all attributes parsed from prebuilt properties.
  245. type prebuiltAttributes struct {
  246. Src bazel.LabelAttribute
  247. Enabled bazel.BoolAttribute
  248. }
  249. func parseSrc(ctx android.BazelConversionPathContext, srcLabelAttribute *bazel.LabelAttribute, axis bazel.ConfigurationAxis, config string, srcs []string) {
  250. srcFileError := func() {
  251. ctx.ModuleErrorf("parseSrc: Expected at most one source file for %s %s\n", axis, config)
  252. }
  253. if len(srcs) > 1 {
  254. srcFileError()
  255. return
  256. } else if len(srcs) == 0 {
  257. return
  258. }
  259. if srcLabelAttribute.SelectValue(axis, config) != nil {
  260. srcFileError()
  261. return
  262. }
  263. srcLabelAttribute.SetSelectValue(axis, config, android.BazelLabelForModuleSrcSingle(ctx, srcs[0]))
  264. }
  265. // NOTE: Used outside of Soong repo project, in the clangprebuilts.go bootstrap_go_package
  266. func Bp2BuildParsePrebuiltLibraryProps(ctx android.BazelConversionPathContext, module *Module, isStatic bool) prebuiltAttributes {
  267. var srcLabelAttribute bazel.LabelAttribute
  268. bp2BuildPropParseHelper(ctx, module, &prebuiltLinkerProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
  269. if prebuiltLinkerProperties, ok := props.(*prebuiltLinkerProperties); ok {
  270. parseSrc(ctx, &srcLabelAttribute, axis, config, prebuiltLinkerProperties.Srcs)
  271. }
  272. })
  273. var enabledLabelAttribute bazel.BoolAttribute
  274. parseAttrs := func(axis bazel.ConfigurationAxis, config string, props StaticOrSharedProperties) {
  275. if props.Enabled != nil {
  276. enabledLabelAttribute.SetSelectValue(axis, config, props.Enabled)
  277. }
  278. parseSrc(ctx, &srcLabelAttribute, axis, config, props.Srcs)
  279. }
  280. if isStatic {
  281. bp2BuildPropParseHelper(ctx, module, &StaticProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
  282. if staticProperties, ok := props.(*StaticProperties); ok {
  283. parseAttrs(axis, config, staticProperties.Static)
  284. }
  285. })
  286. } else {
  287. bp2BuildPropParseHelper(ctx, module, &SharedProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
  288. if sharedProperties, ok := props.(*SharedProperties); ok {
  289. parseAttrs(axis, config, sharedProperties.Shared)
  290. }
  291. })
  292. }
  293. return prebuiltAttributes{
  294. Src: srcLabelAttribute,
  295. Enabled: enabledLabelAttribute,
  296. }
  297. }
  298. func bp2BuildParsePrebuiltBinaryProps(ctx android.BazelConversionPathContext, module *Module) prebuiltAttributes {
  299. var srcLabelAttribute bazel.LabelAttribute
  300. bp2BuildPropParseHelper(ctx, module, &prebuiltLinkerProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
  301. if props, ok := props.(*prebuiltLinkerProperties); ok {
  302. parseSrc(ctx, &srcLabelAttribute, axis, config, props.Srcs)
  303. }
  304. })
  305. return prebuiltAttributes{
  306. Src: srcLabelAttribute,
  307. }
  308. }
  309. func bp2BuildParsePrebuiltObjectProps(ctx android.BazelConversionPathContext, module *Module) prebuiltAttributes {
  310. var srcLabelAttribute bazel.LabelAttribute
  311. bp2BuildPropParseHelper(ctx, module, &prebuiltObjectProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
  312. if props, ok := props.(*prebuiltObjectProperties); ok {
  313. parseSrc(ctx, &srcLabelAttribute, axis, config, props.Srcs)
  314. }
  315. })
  316. return prebuiltAttributes{
  317. Src: srcLabelAttribute,
  318. }
  319. }
  320. type baseAttributes struct {
  321. compilerAttributes
  322. linkerAttributes
  323. // A combination of compilerAttributes.features and linkerAttributes.features, as well as sanitizer features
  324. features bazel.StringListAttribute
  325. protoDependency *bazel.LabelAttribute
  326. aidlDependency *bazel.LabelAttribute
  327. Native_coverage *bool
  328. }
  329. // Convenience struct to hold all attributes parsed from compiler properties.
  330. type compilerAttributes struct {
  331. // Options for all languages
  332. copts bazel.StringListAttribute
  333. // Assembly options and sources
  334. asFlags bazel.StringListAttribute
  335. asSrcs bazel.LabelListAttribute
  336. asmSrcs bazel.LabelListAttribute
  337. // C options and sources
  338. conlyFlags bazel.StringListAttribute
  339. cSrcs bazel.LabelListAttribute
  340. // C++ options and sources
  341. cppFlags bazel.StringListAttribute
  342. srcs bazel.LabelListAttribute
  343. // xsd config sources
  344. xsdInSrcs bazel.StringListAttribute
  345. // Lex sources and options
  346. lSrcs bazel.LabelListAttribute
  347. llSrcs bazel.LabelListAttribute
  348. lexopts bazel.StringListAttribute
  349. // Sysprop sources
  350. syspropSrcs bazel.LabelListAttribute
  351. // Yacc sources
  352. yaccSrc *bazel.LabelAttribute
  353. yaccFlags bazel.StringListAttribute
  354. yaccGenLocationHeader bazel.BoolAttribute
  355. yaccGenPositionHeader bazel.BoolAttribute
  356. rsSrcs bazel.LabelListAttribute
  357. hdrs bazel.LabelListAttribute
  358. rtti bazel.BoolAttribute
  359. // Not affected by arch variants
  360. stl *string
  361. cStd *string
  362. cppStd *string
  363. localIncludes bazel.StringListAttribute
  364. absoluteIncludes bazel.StringListAttribute
  365. includes BazelIncludes
  366. protoSrcs bazel.LabelListAttribute
  367. aidlSrcs bazel.LabelListAttribute
  368. rscriptSrcs bazel.LabelListAttribute
  369. stubsSymbolFile *string
  370. stubsVersions bazel.StringListAttribute
  371. features bazel.StringListAttribute
  372. stem bazel.StringAttribute
  373. suffix bazel.StringAttribute
  374. fdoProfile bazel.LabelAttribute
  375. }
  376. type filterOutFn func(string) bool
  377. // filterOutHiddenVisibility removes the flag specifying hidden visibility as
  378. // this flag is converted to a toolchain feature
  379. func filterOutHiddenVisibility(flag string) bool {
  380. return flag == config.VisibilityHiddenFlag
  381. }
  382. func filterOutStdFlag(flag string) bool {
  383. return strings.HasPrefix(flag, "-std=")
  384. }
  385. func filterOutClangUnknownCflags(flag string) bool {
  386. for _, f := range config.ClangUnknownCflags {
  387. if f == flag {
  388. return true
  389. }
  390. }
  391. return false
  392. }
  393. func parseCommandLineFlags(soongFlags []string, filterOut ...filterOutFn) []string {
  394. var result []string
  395. for _, flag := range soongFlags {
  396. skipFlag := false
  397. for _, filter := range filterOut {
  398. if filter != nil && filter(flag) {
  399. skipFlag = true
  400. }
  401. }
  402. if skipFlag {
  403. continue
  404. }
  405. // Soong's cflags can contain spaces, like `-include header.h`. For
  406. // Bazel's copts, split them up to be compatible with the
  407. // no_copts_tokenization feature.
  408. result = append(result, strings.Split(flag, " ")...)
  409. }
  410. return result
  411. }
  412. func (ca *compilerAttributes) bp2buildForAxisAndConfig(ctx android.BazelConversionPathContext, axis bazel.ConfigurationAxis, config string, props *BaseCompilerProperties) {
  413. // If there's arch specific srcs or exclude_srcs, generate a select entry for it.
  414. // TODO(b/186153868): do this for OS specific srcs and exclude_srcs too.
  415. srcsList, xsdList, ok := parseSrcs(ctx, props)
  416. if ok {
  417. ca.srcs.SetSelectValue(axis, config, srcsList)
  418. }
  419. if len(xsdList) > 0 {
  420. ca.xsdInSrcs.SetSelectValue(axis, config, xsdList)
  421. }
  422. localIncludeDirs := props.Local_include_dirs
  423. if axis == bazel.NoConfigAxis {
  424. ca.cStd, ca.cppStd = bp2buildResolveCppStdValue(props.C_std, props.Cpp_std, props.Gnu_extensions)
  425. if includeBuildDirectory(props.Include_build_directory) {
  426. localIncludeDirs = append(localIncludeDirs, ".")
  427. }
  428. }
  429. ca.absoluteIncludes.SetSelectValue(axis, config, props.Include_dirs)
  430. ca.localIncludes.SetSelectValue(axis, config, localIncludeDirs)
  431. instructionSet := proptools.StringDefault(props.Instruction_set, "")
  432. if instructionSet == "arm" {
  433. ca.features.SetSelectValue(axis, config, []string{"arm_isa_arm"})
  434. } else if instructionSet != "" && instructionSet != "thumb" {
  435. ctx.ModuleErrorf("Unknown value for instruction_set: %s", instructionSet)
  436. }
  437. // In Soong, cflags occur on the command line before -std=<val> flag, resulting in the value being
  438. // overridden. In Bazel we always allow overriding, via flags; however, this can cause
  439. // incompatibilities, so we remove "-std=" flags from Cflag properties while leaving it in other
  440. // cases.
  441. ca.copts.SetSelectValue(axis, config, parseCommandLineFlags(props.Cflags, filterOutStdFlag, filterOutClangUnknownCflags, filterOutHiddenVisibility))
  442. ca.asFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Asflags, nil))
  443. ca.conlyFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Conlyflags, filterOutClangUnknownCflags))
  444. ca.cppFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Cppflags, filterOutClangUnknownCflags))
  445. ca.rtti.SetSelectValue(axis, config, props.Rtti)
  446. }
  447. func (ca *compilerAttributes) convertStlProps(ctx android.ArchVariantContext, module *Module) {
  448. bp2BuildPropParseHelper(ctx, module, &StlProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
  449. if stlProps, ok := props.(*StlProperties); ok {
  450. if stlProps.Stl == nil {
  451. return
  452. }
  453. if ca.stl == nil {
  454. stl := deduplicateStlInput(*stlProps.Stl)
  455. ca.stl = &stl
  456. } else if ca.stl != stlProps.Stl {
  457. ctx.ModuleErrorf("Unsupported conversion: module with different stl for different variants: %s and %s", *ca.stl, stlProps.Stl)
  458. }
  459. }
  460. })
  461. }
  462. func (ca *compilerAttributes) convertProductVariables(ctx android.BazelConversionPathContext, productVariableProps android.ProductConfigProperties) {
  463. productVarPropNameToAttribute := map[string]*bazel.StringListAttribute{
  464. "Cflags": &ca.copts,
  465. "Asflags": &ca.asFlags,
  466. "Cppflags": &ca.cppFlags,
  467. }
  468. for propName, attr := range productVarPropNameToAttribute {
  469. if productConfigProps, exists := productVariableProps[propName]; exists {
  470. for productConfigProp, prop := range productConfigProps {
  471. flags, ok := prop.([]string)
  472. if !ok {
  473. ctx.ModuleErrorf("Could not convert product variable %s property", proptools.PropertyNameForField(propName))
  474. }
  475. newFlags, _ := bazel.TryVariableSubstitutions(flags, productConfigProp.Name())
  476. attr.SetSelectValue(productConfigProp.ConfigurationAxis(), productConfigProp.SelectKey(), newFlags)
  477. }
  478. }
  479. }
  480. }
  481. func (ca *compilerAttributes) finalize(ctx android.BazelConversionPathContext, implementationHdrs bazel.LabelListAttribute) {
  482. ca.srcs.ResolveExcludes()
  483. partitionedSrcs := groupSrcsByExtension(ctx, ca.srcs)
  484. ca.protoSrcs = partitionedSrcs[protoSrcPartition]
  485. ca.aidlSrcs = partitionedSrcs[aidlSrcPartition]
  486. for p, lla := range partitionedSrcs {
  487. // if there are no sources, there is no need for headers
  488. if lla.IsEmpty() {
  489. continue
  490. }
  491. lla.Append(implementationHdrs)
  492. partitionedSrcs[p] = lla
  493. }
  494. ca.srcs = partitionedSrcs[cppSrcPartition]
  495. ca.cSrcs = partitionedSrcs[cSrcPartition]
  496. ca.asSrcs = partitionedSrcs[asSrcPartition]
  497. ca.asmSrcs = partitionedSrcs[asmSrcPartition]
  498. ca.lSrcs = partitionedSrcs[lSrcPartition]
  499. ca.llSrcs = partitionedSrcs[llSrcPartition]
  500. if yacc := partitionedSrcs[yaccSrcPartition]; !yacc.IsEmpty() {
  501. if len(yacc.Value.Includes) > 1 {
  502. ctx.PropertyErrorf("srcs", "Found multiple yacc (.y/.yy) files in library")
  503. }
  504. ca.yaccSrc = bazel.MakeLabelAttribute(yacc.Value.Includes[0].Label)
  505. }
  506. ca.syspropSrcs = partitionedSrcs[syspropSrcPartition]
  507. ca.rscriptSrcs = partitionedSrcs[rScriptSrcPartition]
  508. ca.absoluteIncludes.DeduplicateAxesFromBase()
  509. ca.localIncludes.DeduplicateAxesFromBase()
  510. }
  511. // Parse srcs from an arch or OS's props value.
  512. func parseSrcs(ctx android.BazelConversionPathContext, props *BaseCompilerProperties) (bazel.LabelList, []string, bool) {
  513. anySrcs := false
  514. // Add srcs-like dependencies such as generated files.
  515. // First create a LabelList containing these dependencies, then merge the values with srcs.
  516. genSrcs, xsd := android.PartitionXsdSrcs(ctx, props.Generated_sources)
  517. generatedSrcsLabelList := android.BazelLabelForModuleDepsExcludes(ctx, genSrcs, props.Exclude_generated_sources)
  518. if len(props.Generated_sources) > 0 || len(props.Exclude_generated_sources) > 0 {
  519. anySrcs = true
  520. }
  521. allSrcsLabelList := android.BazelLabelForModuleSrcExcludes(ctx, props.Srcs, props.Exclude_srcs)
  522. if len(props.Srcs) > 0 || len(props.Exclude_srcs) > 0 {
  523. anySrcs = true
  524. }
  525. return bazel.AppendBazelLabelLists(allSrcsLabelList, generatedSrcsLabelList), xsd, anySrcs
  526. }
  527. func bp2buildStdVal(std *string, prefix string, useGnu bool) *string {
  528. defaultVal := prefix + "_std_default"
  529. // If c{,pp}std properties are not specified, don't generate them in the BUILD file.
  530. // Defaults are handled by the toolchain definition.
  531. // However, if gnu_extensions is false, then the default gnu-to-c version must be specified.
  532. stdVal := proptools.StringDefault(std, defaultVal)
  533. if stdVal == "experimental" || stdVal == defaultVal {
  534. if stdVal == "experimental" {
  535. stdVal = prefix + "_std_experimental"
  536. }
  537. if !useGnu {
  538. stdVal += "_no_gnu"
  539. }
  540. } else if !useGnu {
  541. stdVal = gnuToCReplacer.Replace(stdVal)
  542. }
  543. if stdVal == defaultVal {
  544. return nil
  545. }
  546. return &stdVal
  547. }
  548. func bp2buildResolveCppStdValue(c_std *string, cpp_std *string, gnu_extensions *bool) (*string, *string) {
  549. useGnu := useGnuExtensions(gnu_extensions)
  550. return bp2buildStdVal(c_std, "c", useGnu), bp2buildStdVal(cpp_std, "cpp", useGnu)
  551. }
  552. // packageFromLabel extracts package from a fully-qualified or relative Label and whether the label
  553. // is fully-qualified.
  554. // e.g. fully-qualified "//a/b:foo" -> "a/b", true, relative: ":bar" -> ".", false
  555. func packageFromLabel(label string) (string, bool) {
  556. split := strings.Split(label, ":")
  557. if len(split) != 2 {
  558. return "", false
  559. }
  560. if split[0] == "" {
  561. return ".", false
  562. }
  563. // remove leading "//"
  564. return split[0][2:], true
  565. }
  566. // includesFromLabelList extracts relative/absolute includes from a bazel.LabelList>
  567. func includesFromLabelList(labelList bazel.LabelList) (relative, absolute []string) {
  568. for _, hdr := range labelList.Includes {
  569. if pkg, hasPkg := packageFromLabel(hdr.Label); hasPkg {
  570. absolute = append(absolute, pkg)
  571. } else if pkg != "" {
  572. relative = append(relative, pkg)
  573. }
  574. }
  575. return relative, absolute
  576. }
  577. type YasmAttributes struct {
  578. Srcs bazel.LabelListAttribute
  579. Flags bazel.StringListAttribute
  580. Include_dirs bazel.StringListAttribute
  581. }
  582. func bp2BuildYasm(ctx android.Bp2buildMutatorContext, m *Module, ca compilerAttributes) *bazel.LabelAttribute {
  583. if ca.asmSrcs.IsEmpty() {
  584. return nil
  585. }
  586. // Yasm needs the include directories from both local_includes and
  587. // export_include_dirs. We don't care about actually exporting them from the
  588. // yasm rule though, because they will also be present on the cc_ rule that
  589. // wraps this yasm rule.
  590. includes := ca.localIncludes.Clone()
  591. bp2BuildPropParseHelper(ctx, m, &FlagExporterProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
  592. if flagExporterProperties, ok := props.(*FlagExporterProperties); ok {
  593. if len(flagExporterProperties.Export_include_dirs) > 0 {
  594. x := bazel.StringListAttribute{}
  595. x.SetSelectValue(axis, config, flagExporterProperties.Export_include_dirs)
  596. includes.Append(x)
  597. }
  598. }
  599. })
  600. ctx.CreateBazelTargetModule(
  601. bazel.BazelTargetModuleProperties{
  602. Rule_class: "yasm",
  603. Bzl_load_location: "//build/bazel/rules/cc:yasm.bzl",
  604. },
  605. android.CommonAttributes{Name: m.Name() + "_yasm"},
  606. &YasmAttributes{
  607. Srcs: ca.asmSrcs,
  608. Flags: ca.asFlags,
  609. Include_dirs: *includes,
  610. })
  611. // We only want to add a dependency on the _yasm target if there are asm
  612. // sources in the current configuration. If there are unconfigured asm
  613. // sources, always add the dependency. Otherwise, add the dependency only
  614. // on the configuration axes and values that had asm sources.
  615. if len(ca.asmSrcs.Value.Includes) > 0 {
  616. return bazel.MakeLabelAttribute(":" + m.Name() + "_yasm")
  617. }
  618. ret := &bazel.LabelAttribute{}
  619. for _, axis := range ca.asmSrcs.SortedConfigurationAxes() {
  620. for cfg := range ca.asmSrcs.ConfigurableValues[axis] {
  621. ret.SetSelectValue(axis, cfg, bazel.Label{Label: ":" + m.Name() + "_yasm"})
  622. }
  623. }
  624. return ret
  625. }
  626. // bp2BuildParseBaseProps returns all compiler, linker, library attributes of a cc module..
  627. func bp2BuildParseBaseProps(ctx android.Bp2buildMutatorContext, module *Module) baseAttributes {
  628. archVariantCompilerProps := module.GetArchVariantProperties(ctx, &BaseCompilerProperties{})
  629. archVariantLinkerProps := module.GetArchVariantProperties(ctx, &BaseLinkerProperties{})
  630. archVariantLibraryProperties := module.GetArchVariantProperties(ctx, &LibraryProperties{})
  631. var implementationHdrs bazel.LabelListAttribute
  632. axisToConfigs := map[bazel.ConfigurationAxis]map[string]bool{}
  633. allAxesAndConfigs := func(cp android.ConfigurationAxisToArchVariantProperties) {
  634. for axis, configMap := range cp {
  635. if _, ok := axisToConfigs[axis]; !ok {
  636. axisToConfigs[axis] = map[string]bool{}
  637. }
  638. for cfg := range configMap {
  639. axisToConfigs[axis][cfg] = true
  640. }
  641. }
  642. }
  643. allAxesAndConfigs(archVariantCompilerProps)
  644. allAxesAndConfigs(archVariantLinkerProps)
  645. allAxesAndConfigs(archVariantLibraryProperties)
  646. compilerAttrs := compilerAttributes{}
  647. linkerAttrs := linkerAttributes{}
  648. var aidlLibs bazel.LabelList
  649. // Iterate through these axes in a deterministic order. This is required
  650. // because processing certain dependencies may result in concatenating
  651. // elements along other axes. (For example, processing NoConfig may result
  652. // in elements being added to InApex). This is thus the only way to ensure
  653. // that the order of entries in each list is in a predictable order.
  654. for _, axis := range bazel.SortedConfigurationAxes(axisToConfigs) {
  655. configs := axisToConfigs[axis]
  656. for cfg := range configs {
  657. var allHdrs, allHdrsXsd []string
  658. if baseCompilerProps, ok := archVariantCompilerProps[axis][cfg].(*BaseCompilerProperties); ok {
  659. allHdrs, allHdrsXsd = android.PartitionXsdSrcs(ctx, baseCompilerProps.Generated_headers)
  660. if baseCompilerProps.Lex != nil {
  661. compilerAttrs.lexopts.SetSelectValue(axis, cfg, baseCompilerProps.Lex.Flags)
  662. }
  663. if baseCompilerProps.Yacc != nil {
  664. compilerAttrs.yaccFlags.SetSelectValue(axis, cfg, baseCompilerProps.Yacc.Flags)
  665. compilerAttrs.yaccGenLocationHeader.SetSelectValue(axis, cfg, baseCompilerProps.Yacc.Gen_location_hh)
  666. compilerAttrs.yaccGenPositionHeader.SetSelectValue(axis, cfg, baseCompilerProps.Yacc.Gen_position_hh)
  667. }
  668. (&compilerAttrs).bp2buildForAxisAndConfig(ctx, axis, cfg, baseCompilerProps)
  669. aidlLibs.Append(android.BazelLabelForModuleDeps(ctx, baseCompilerProps.Aidl.Libs))
  670. }
  671. var exportHdrs, exportHdrsXsd []string
  672. if baseLinkerProps, ok := archVariantLinkerProps[axis][cfg].(*BaseLinkerProperties); ok {
  673. exportHdrs, exportHdrsXsd = android.PartitionXsdSrcs(ctx, baseLinkerProps.Export_generated_headers)
  674. (&linkerAttrs).bp2buildForAxisAndConfig(ctx, module, axis, cfg, baseLinkerProps)
  675. }
  676. // in the synthetic bp2build workspace, xsd sources are compiled to a static library
  677. xsdList := compilerAttrs.xsdInSrcs.SelectValue(axis, cfg)
  678. allHdrsXsd = android.FirstUniqueStrings(append(xsdList, allHdrsXsd...))
  679. headers := maybePartitionExportedAndImplementationsDeps(ctx, !module.Binary(), allHdrs, exportHdrs, android.BazelLabelForModuleDeps)
  680. xsdConfigLibs := maybePartitionExportedAndImplementationsDeps(ctx, !module.Binary(), allHdrsXsd, exportHdrsXsd, bazelLabelForXsdConfig)
  681. implementationHdrs.SetSelectValue(axis, cfg, headers.implementation)
  682. compilerAttrs.hdrs.SetSelectValue(axis, cfg, headers.export)
  683. exportIncludes, exportAbsoluteIncludes := includesFromLabelList(headers.export)
  684. compilerAttrs.includes.Includes.SetSelectValue(axis, cfg, exportIncludes)
  685. compilerAttrs.includes.AbsoluteIncludes.SetSelectValue(axis, cfg, exportAbsoluteIncludes)
  686. includes, absoluteIncludes := includesFromLabelList(headers.implementation)
  687. currAbsoluteIncludes := compilerAttrs.absoluteIncludes.SelectValue(axis, cfg)
  688. currAbsoluteIncludes = android.FirstUniqueStrings(append(currAbsoluteIncludes, absoluteIncludes...))
  689. compilerAttrs.absoluteIncludes.SetSelectValue(axis, cfg, currAbsoluteIncludes)
  690. currIncludes := compilerAttrs.localIncludes.SelectValue(axis, cfg)
  691. currIncludes = android.FirstUniqueStrings(append(currIncludes, includes...))
  692. compilerAttrs.localIncludes.SetSelectValue(axis, cfg, currIncludes)
  693. if libraryProps, ok := archVariantLibraryProperties[axis][cfg].(*LibraryProperties); ok {
  694. if axis == bazel.NoConfigAxis {
  695. if libraryProps.Stubs.Symbol_file != nil {
  696. compilerAttrs.stubsSymbolFile = libraryProps.Stubs.Symbol_file
  697. versions := android.CopyOf(libraryProps.Stubs.Versions)
  698. normalizeVersions(ctx, versions)
  699. versions = addCurrentVersionIfNotPresent(versions)
  700. compilerAttrs.stubsVersions.SetSelectValue(axis, cfg, versions)
  701. }
  702. }
  703. if stem := libraryProps.Stem; stem != nil {
  704. compilerAttrs.stem.SetSelectValue(axis, cfg, stem)
  705. }
  706. if suffix := libraryProps.Suffix; suffix != nil {
  707. compilerAttrs.suffix.SetSelectValue(axis, cfg, suffix)
  708. }
  709. }
  710. if len(allHdrsXsd) > 0 {
  711. wholeStaticLibs := linkerAttrs.implementationWholeArchiveDeps.SelectValue(axis, cfg)
  712. (&wholeStaticLibs).Append(xsdConfigLibs.implementation)
  713. linkerAttrs.implementationWholeArchiveDeps.SetSelectValue(axis, cfg, wholeStaticLibs)
  714. wholeStaticLibs = linkerAttrs.wholeArchiveDeps.SelectValue(axis, cfg)
  715. (&wholeStaticLibs).Append(xsdConfigLibs.export)
  716. linkerAttrs.wholeArchiveDeps.SetSelectValue(axis, cfg, wholeStaticLibs)
  717. }
  718. }
  719. }
  720. compilerAttrs.convertStlProps(ctx, module)
  721. (&linkerAttrs).convertStripProps(ctx, module)
  722. var nativeCoverage *bool
  723. if module.coverage != nil && module.coverage.Properties.Native_coverage != nil &&
  724. !Bool(module.coverage.Properties.Native_coverage) {
  725. nativeCoverage = BoolPtr(false)
  726. }
  727. productVariableProps := android.ProductVariableProperties(ctx, ctx.Module())
  728. (&compilerAttrs).convertProductVariables(ctx, productVariableProps)
  729. (&linkerAttrs).convertProductVariables(ctx, productVariableProps)
  730. (&compilerAttrs).finalize(ctx, implementationHdrs)
  731. (&linkerAttrs).finalize(ctx)
  732. (&compilerAttrs.srcs).Add(bp2BuildYasm(ctx, module, compilerAttrs))
  733. protoDep := bp2buildProto(ctx, module, compilerAttrs.protoSrcs)
  734. // bp2buildProto will only set wholeStaticLib or implementationWholeStaticLib, but we don't know
  735. // which. This will add the newly generated proto library to the appropriate attribute and nothing
  736. // to the other
  737. (&linkerAttrs).wholeArchiveDeps.Add(protoDep.wholeStaticLib)
  738. (&linkerAttrs).implementationWholeArchiveDeps.Add(protoDep.implementationWholeStaticLib)
  739. aidlDep := bp2buildCcAidlLibrary(
  740. ctx, module,
  741. compilerAttrs.aidlSrcs,
  742. bazel.LabelListAttribute{
  743. Value: aidlLibs,
  744. },
  745. linkerAttrs,
  746. compilerAttrs,
  747. )
  748. if aidlDep != nil {
  749. if lib, ok := module.linker.(*libraryDecorator); ok {
  750. if proptools.Bool(lib.Properties.Aidl.Export_aidl_headers) {
  751. (&linkerAttrs).wholeArchiveDeps.Add(aidlDep)
  752. } else {
  753. (&linkerAttrs).implementationWholeArchiveDeps.Add(aidlDep)
  754. }
  755. }
  756. }
  757. // Create a cc_yacc_static_library if srcs contains .y/.yy files
  758. // This internal target will produce an .a file that will be statically linked to the parent library
  759. if yaccDep := bp2buildCcYaccLibrary(ctx, compilerAttrs, linkerAttrs); yaccDep != nil {
  760. (&linkerAttrs).implementationWholeArchiveDeps.Add(yaccDep)
  761. }
  762. convertedLSrcs := bp2BuildLex(ctx, module.Name(), compilerAttrs)
  763. (&compilerAttrs).srcs.Add(&convertedLSrcs.srcName)
  764. (&compilerAttrs).cSrcs.Add(&convertedLSrcs.cSrcName)
  765. if module.afdo != nil && module.afdo.Properties.Afdo {
  766. fdoProfileDep := bp2buildFdoProfile(ctx, module)
  767. if fdoProfileDep != nil {
  768. (&compilerAttrs).fdoProfile.SetValue(*fdoProfileDep)
  769. }
  770. }
  771. if !compilerAttrs.syspropSrcs.IsEmpty() {
  772. (&linkerAttrs).wholeArchiveDeps.Add(bp2buildCcSysprop(ctx, module.Name(), module.Properties.Min_sdk_version, compilerAttrs.syspropSrcs))
  773. }
  774. linkerAttrs.wholeArchiveDeps.Prepend = true
  775. linkerAttrs.deps.Prepend = true
  776. compilerAttrs.localIncludes.Prepend = true
  777. compilerAttrs.absoluteIncludes.Prepend = true
  778. compilerAttrs.hdrs.Prepend = true
  779. convertedRsSrcs, rsAbsIncludes, rsLocalIncludes := bp2buildRScript(ctx, module, compilerAttrs)
  780. (&compilerAttrs).srcs.Add(&convertedRsSrcs)
  781. (&compilerAttrs).absoluteIncludes.Append(rsAbsIncludes)
  782. (&compilerAttrs).localIncludes.Append(rsLocalIncludes)
  783. (&compilerAttrs).localIncludes.Value = android.FirstUniqueStrings(compilerAttrs.localIncludes.Value)
  784. features := compilerAttrs.features.Clone().Append(linkerAttrs.features).Append(bp2buildSanitizerFeatures(ctx, module))
  785. features = features.Append(bp2buildLtoFeatures(ctx, module))
  786. features = features.Append(convertHiddenVisibilityToFeatureBase(ctx, module))
  787. features.DeduplicateAxesFromBase()
  788. addMuslSystemDynamicDeps(ctx, linkerAttrs)
  789. return baseAttributes{
  790. compilerAttrs,
  791. linkerAttrs,
  792. *features,
  793. protoDep.protoDep,
  794. aidlDep,
  795. nativeCoverage,
  796. }
  797. }
  798. type ccYaccLibraryAttributes struct {
  799. Src bazel.LabelAttribute
  800. Flags bazel.StringListAttribute
  801. Gen_location_hh bazel.BoolAttribute
  802. Gen_position_hh bazel.BoolAttribute
  803. Local_includes bazel.StringListAttribute
  804. Implementation_deps bazel.LabelListAttribute
  805. Implementation_dynamic_deps bazel.LabelListAttribute
  806. }
  807. func bp2buildCcYaccLibrary(ctx android.Bp2buildMutatorContext, ca compilerAttributes, la linkerAttributes) *bazel.LabelAttribute {
  808. if ca.yaccSrc == nil {
  809. return nil
  810. }
  811. yaccLibraryLabel := ctx.Module().Name() + "_yacc"
  812. ctx.CreateBazelTargetModule(
  813. bazel.BazelTargetModuleProperties{
  814. Rule_class: "cc_yacc_static_library",
  815. Bzl_load_location: "//build/bazel/rules/cc:cc_yacc_library.bzl",
  816. },
  817. android.CommonAttributes{
  818. Name: yaccLibraryLabel,
  819. },
  820. &ccYaccLibraryAttributes{
  821. Src: *ca.yaccSrc,
  822. Flags: ca.yaccFlags,
  823. Gen_location_hh: ca.yaccGenLocationHeader,
  824. Gen_position_hh: ca.yaccGenPositionHeader,
  825. Local_includes: ca.localIncludes,
  826. Implementation_deps: la.implementationDeps,
  827. Implementation_dynamic_deps: la.implementationDynamicDeps,
  828. },
  829. )
  830. yaccLibrary := &bazel.LabelAttribute{
  831. Value: &bazel.Label{
  832. Label: ":" + yaccLibraryLabel,
  833. },
  834. }
  835. return yaccLibrary
  836. }
  837. // As a workaround for b/261657184, we are manually adding the default value
  838. // of system_dynamic_deps for the linux_musl os.
  839. // TODO: Solve this properly
  840. func addMuslSystemDynamicDeps(ctx android.Bp2buildMutatorContext, attrs linkerAttributes) {
  841. systemDynamicDeps := attrs.systemDynamicDeps.SelectValue(bazel.OsConfigurationAxis, "linux_musl")
  842. if attrs.systemDynamicDeps.HasAxisSpecificValues(bazel.OsConfigurationAxis) && systemDynamicDeps.IsNil() {
  843. attrs.systemDynamicDeps.SetSelectValue(bazel.OsConfigurationAxis, "linux_musl", android.BazelLabelForModuleDeps(ctx, config.MuslDefaultSharedLibraries))
  844. }
  845. }
  846. type fdoProfileAttributes struct {
  847. Absolute_path_profile string
  848. }
  849. func bp2buildFdoProfile(
  850. ctx android.Bp2buildMutatorContext,
  851. m *Module,
  852. ) *bazel.Label {
  853. for _, project := range globalAfdoProfileProjects {
  854. // Ensure handcrafted BUILD file exists in the project
  855. BUILDPath := android.ExistentPathForSource(ctx, project, "BUILD")
  856. if BUILDPath.Valid() {
  857. // We handcraft a BUILD file with fdo_profile targets that use the existing profiles in the project
  858. // This implementation is assuming that every afdo profile in globalAfdoProfileProjects already has
  859. // an associated fdo_profile target declared in the same package.
  860. // TODO(b/260714900): Handle arch-specific afdo profiles (e.g. `<module-name>-arm<64>.afdo`)
  861. path := android.ExistentPathForSource(ctx, project, m.Name()+".afdo")
  862. if path.Valid() {
  863. // FIXME: Some profiles only exist internally and are not released to AOSP.
  864. // When generated BUILD files are checked in, we'll run into merge conflict.
  865. // The cc_library_shared target in AOSP won't have reference to an fdo_profile target because
  866. // the profile doesn't exist. Internally, the same cc_library_shared target will
  867. // have reference to the fdo_profile.
  868. // For more context, see b/258682955#comment2
  869. fdoProfileLabel := "//" + strings.TrimSuffix(project, "/") + ":" + m.Name()
  870. return &bazel.Label{
  871. Label: fdoProfileLabel,
  872. }
  873. }
  874. }
  875. }
  876. return nil
  877. }
  878. func bp2buildCcAidlLibrary(
  879. ctx android.Bp2buildMutatorContext,
  880. m *Module,
  881. aidlSrcs bazel.LabelListAttribute,
  882. aidlLibs bazel.LabelListAttribute,
  883. linkerAttrs linkerAttributes,
  884. compilerAttrs compilerAttributes,
  885. ) *bazel.LabelAttribute {
  886. var aidlLibsFromSrcs, aidlFiles bazel.LabelListAttribute
  887. apexAvailableTags := android.ApexAvailableTagsWithoutTestApexes(ctx.(android.TopDownMutatorContext), ctx.Module())
  888. if !aidlSrcs.IsEmpty() {
  889. aidlLibsFromSrcs, aidlFiles = aidlSrcs.Partition(func(src bazel.Label) bool {
  890. if fg, ok := android.ToFileGroupAsLibrary(ctx, src.OriginalModuleName); ok &&
  891. fg.ShouldConvertToAidlLibrary(ctx) {
  892. return true
  893. }
  894. return false
  895. })
  896. if !aidlFiles.IsEmpty() {
  897. aidlLibName := m.Name() + "_aidl_library"
  898. ctx.CreateBazelTargetModule(
  899. bazel.BazelTargetModuleProperties{
  900. Rule_class: "aidl_library",
  901. Bzl_load_location: "//build/bazel/rules/aidl:aidl_library.bzl",
  902. },
  903. android.CommonAttributes{
  904. Name: aidlLibName,
  905. Tags: apexAvailableTags,
  906. },
  907. &aidlLibraryAttributes{
  908. Srcs: aidlFiles,
  909. },
  910. )
  911. aidlLibsFromSrcs.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + aidlLibName}})
  912. }
  913. }
  914. allAidlLibs := aidlLibs.Clone()
  915. allAidlLibs.Append(aidlLibsFromSrcs)
  916. if !allAidlLibs.IsEmpty() {
  917. ccAidlLibrarylabel := m.Name() + "_cc_aidl_library"
  918. // Since parent cc_library already has these dependencies, we can add them as implementation
  919. // deps so that they don't re-export
  920. implementationDeps := linkerAttrs.deps.Clone()
  921. implementationDeps.Append(linkerAttrs.implementationDeps)
  922. implementationDynamicDeps := linkerAttrs.dynamicDeps.Clone()
  923. implementationDynamicDeps.Append(linkerAttrs.implementationDynamicDeps)
  924. sdkAttrs := bp2BuildParseSdkAttributes(m)
  925. exportedIncludes := bp2BuildParseExportedIncludes(ctx, m, &compilerAttrs.includes)
  926. includeAttrs := includesAttributes{
  927. Export_includes: exportedIncludes.Includes,
  928. Export_absolute_includes: exportedIncludes.AbsoluteIncludes,
  929. Export_system_includes: exportedIncludes.SystemIncludes,
  930. Local_includes: compilerAttrs.localIncludes,
  931. Absolute_includes: compilerAttrs.absoluteIncludes,
  932. }
  933. ctx.CreateBazelTargetModule(
  934. bazel.BazelTargetModuleProperties{
  935. Rule_class: "cc_aidl_library",
  936. Bzl_load_location: "//build/bazel/rules/cc:cc_aidl_library.bzl",
  937. },
  938. android.CommonAttributes{Name: ccAidlLibrarylabel},
  939. &ccAidlLibraryAttributes{
  940. Deps: *allAidlLibs,
  941. Implementation_deps: *implementationDeps,
  942. Implementation_dynamic_deps: *implementationDynamicDeps,
  943. Tags: apexAvailableTags,
  944. sdkAttributes: sdkAttrs,
  945. includesAttributes: includeAttrs,
  946. },
  947. )
  948. label := &bazel.LabelAttribute{
  949. Value: &bazel.Label{
  950. Label: ":" + ccAidlLibrarylabel,
  951. },
  952. }
  953. return label
  954. }
  955. return nil
  956. }
  957. func bp2BuildParseSdkAttributes(module *Module) sdkAttributes {
  958. return sdkAttributes{
  959. Sdk_version: module.Properties.Sdk_version,
  960. Min_sdk_version: module.Properties.Min_sdk_version,
  961. }
  962. }
  963. type sdkAttributes struct {
  964. Sdk_version *string
  965. Min_sdk_version *string
  966. }
  967. // Convenience struct to hold all attributes parsed from linker properties.
  968. type linkerAttributes struct {
  969. deps bazel.LabelListAttribute
  970. implementationDeps bazel.LabelListAttribute
  971. dynamicDeps bazel.LabelListAttribute
  972. implementationDynamicDeps bazel.LabelListAttribute
  973. runtimeDeps bazel.LabelListAttribute
  974. wholeArchiveDeps bazel.LabelListAttribute
  975. implementationWholeArchiveDeps bazel.LabelListAttribute
  976. systemDynamicDeps bazel.LabelListAttribute
  977. usedSystemDynamicDepAsDynamicDep map[string]bool
  978. useVersionLib bazel.BoolAttribute
  979. linkopts bazel.StringListAttribute
  980. additionalLinkerInputs bazel.LabelListAttribute
  981. stripKeepSymbols bazel.BoolAttribute
  982. stripKeepSymbolsAndDebugFrame bazel.BoolAttribute
  983. stripKeepSymbolsList bazel.StringListAttribute
  984. stripAll bazel.BoolAttribute
  985. stripNone bazel.BoolAttribute
  986. features bazel.StringListAttribute
  987. }
  988. var (
  989. soongSystemSharedLibs = []string{"libc", "libm", "libdl"}
  990. versionLib = "libbuildversion"
  991. )
  992. // resolveTargetApex re-adds the shared and static libs in target.apex.exclude_shared|static_libs props to non-apex variant
  993. // since all libs are already excluded by default
  994. func (la *linkerAttributes) resolveTargetApexProp(ctx android.BazelConversionPathContext, props *BaseLinkerProperties) {
  995. excludeSharedLibs := bazelLabelForSharedDeps(ctx, props.Target.Apex.Exclude_shared_libs)
  996. sharedExcludes := bazel.LabelList{Excludes: excludeSharedLibs.Includes}
  997. sharedExcludesLabelList := bazel.LabelListAttribute{}
  998. sharedExcludesLabelList.SetSelectValue(bazel.InApexAxis, bazel.InApex, sharedExcludes)
  999. la.dynamicDeps.Append(sharedExcludesLabelList)
  1000. la.implementationDynamicDeps.Append(sharedExcludesLabelList)
  1001. excludeStaticLibs := bazelLabelForStaticDeps(ctx, props.Target.Apex.Exclude_static_libs)
  1002. staticExcludes := bazel.LabelList{Excludes: excludeStaticLibs.Includes}
  1003. staticExcludesLabelList := bazel.LabelListAttribute{}
  1004. staticExcludesLabelList.SetSelectValue(bazel.InApexAxis, bazel.InApex, staticExcludes)
  1005. la.deps.Append(staticExcludesLabelList)
  1006. la.implementationDeps.Append(staticExcludesLabelList)
  1007. }
  1008. func (la *linkerAttributes) bp2buildForAxisAndConfig(ctx android.BazelConversionPathContext, module *Module, axis bazel.ConfigurationAxis, config string, props *BaseLinkerProperties) {
  1009. isBinary := module.Binary()
  1010. // Use a single variable to capture usage of nocrt in arch variants, so there's only 1 error message for this module
  1011. var axisFeatures []string
  1012. wholeStaticLibs := android.FirstUniqueStrings(props.Whole_static_libs)
  1013. staticLibs := android.FirstUniqueStrings(android.RemoveListFromList(props.Static_libs, wholeStaticLibs))
  1014. if axis == bazel.NoConfigAxis {
  1015. la.useVersionLib.SetSelectValue(axis, config, props.Use_version_lib)
  1016. if proptools.Bool(props.Use_version_lib) {
  1017. versionLibAlreadyInDeps := android.InList(versionLib, wholeStaticLibs)
  1018. // remove from static libs so there is no duplicate dependency
  1019. _, staticLibs = android.RemoveFromList(versionLib, staticLibs)
  1020. // only add the dep if it is not in progress
  1021. if !versionLibAlreadyInDeps {
  1022. wholeStaticLibs = append(wholeStaticLibs, versionLib)
  1023. }
  1024. }
  1025. }
  1026. // Excludes to parallel Soong:
  1027. // https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/linker.go;l=247-249;drc=088b53577dde6e40085ffd737a1ae96ad82fc4b0
  1028. la.wholeArchiveDeps.SetSelectValue(axis, config, bazelLabelForWholeDepsExcludes(ctx, wholeStaticLibs, props.Exclude_static_libs))
  1029. staticDeps := maybePartitionExportedAndImplementationsDepsExcludes(
  1030. ctx,
  1031. !isBinary,
  1032. staticLibs,
  1033. props.Exclude_static_libs,
  1034. props.Export_static_lib_headers,
  1035. bazelLabelForStaticDepsExcludes,
  1036. )
  1037. headerLibs := android.FirstUniqueStrings(props.Header_libs)
  1038. hDeps := maybePartitionExportedAndImplementationsDeps(ctx, !isBinary, headerLibs, props.Export_header_lib_headers, bazelLabelForHeaderDeps)
  1039. (&hDeps.export).Append(staticDeps.export)
  1040. la.deps.SetSelectValue(axis, config, hDeps.export)
  1041. (&hDeps.implementation).Append(staticDeps.implementation)
  1042. la.implementationDeps.SetSelectValue(axis, config, hDeps.implementation)
  1043. systemSharedLibs := props.System_shared_libs
  1044. // systemSharedLibs distinguishes between nil/empty list behavior:
  1045. // nil -> use default values
  1046. // empty list -> no values specified
  1047. if len(systemSharedLibs) > 0 {
  1048. systemSharedLibs = android.FirstUniqueStrings(systemSharedLibs)
  1049. }
  1050. la.systemDynamicDeps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, systemSharedLibs))
  1051. sharedLibs := android.FirstUniqueStrings(props.Shared_libs)
  1052. excludeSharedLibs := props.Exclude_shared_libs
  1053. usedSystem := android.FilterListPred(sharedLibs, func(s string) bool {
  1054. return android.InList(s, soongSystemSharedLibs) && !android.InList(s, excludeSharedLibs)
  1055. })
  1056. for _, el := range usedSystem {
  1057. if la.usedSystemDynamicDepAsDynamicDep == nil {
  1058. la.usedSystemDynamicDepAsDynamicDep = map[string]bool{}
  1059. }
  1060. la.usedSystemDynamicDepAsDynamicDep[el] = true
  1061. }
  1062. sharedDeps := maybePartitionExportedAndImplementationsDepsExcludes(
  1063. ctx,
  1064. !isBinary,
  1065. sharedLibs,
  1066. props.Exclude_shared_libs,
  1067. props.Export_shared_lib_headers,
  1068. bazelLabelForSharedDepsExcludes,
  1069. )
  1070. la.dynamicDeps.SetSelectValue(axis, config, sharedDeps.export)
  1071. la.implementationDynamicDeps.SetSelectValue(axis, config, sharedDeps.implementation)
  1072. la.resolveTargetApexProp(ctx, props)
  1073. if axis == bazel.NoConfigAxis || (axis == bazel.OsConfigurationAxis && config == bazel.OsAndroid) {
  1074. // If a dependency in la.implementationDynamicDeps or la.dynamicDeps has stubs, its
  1075. // stub variant should be used when the dependency is linked in a APEX. The
  1076. // dependencies in NoConfigAxis and OsConfigurationAxis/OsAndroid are grouped by
  1077. // having stubs or not, so Bazel select() statement can be used to choose
  1078. // source/stub variants of them.
  1079. apexAvailable := module.ApexAvailable()
  1080. setStubsForDynamicDeps(ctx, axis, config, apexAvailable, sharedDeps.export, &la.dynamicDeps, 0, false)
  1081. setStubsForDynamicDeps(ctx, axis, config, apexAvailable, sharedDeps.implementation, &la.implementationDynamicDeps, 1, false)
  1082. if len(systemSharedLibs) > 0 {
  1083. setStubsForDynamicDeps(ctx, axis, config, apexAvailable, bazelLabelForSharedDeps(ctx, systemSharedLibs), &la.systemDynamicDeps, 2, true)
  1084. }
  1085. }
  1086. if !BoolDefault(props.Pack_relocations, packRelocationsDefault) {
  1087. axisFeatures = append(axisFeatures, "disable_pack_relocations")
  1088. }
  1089. if Bool(props.Allow_undefined_symbols) {
  1090. axisFeatures = append(axisFeatures, "-no_undefined_symbols")
  1091. }
  1092. var linkerFlags []string
  1093. if len(props.Ldflags) > 0 {
  1094. linkerFlags = append(linkerFlags, proptools.NinjaEscapeList(props.Ldflags)...)
  1095. // binaries remove static flag if -shared is in the linker flags
  1096. if isBinary && android.InList("-shared", linkerFlags) {
  1097. axisFeatures = append(axisFeatures, "-static_flag")
  1098. }
  1099. }
  1100. if !props.libCrt() {
  1101. axisFeatures = append(axisFeatures, "-use_libcrt")
  1102. }
  1103. if !props.crt() {
  1104. axisFeatures = append(axisFeatures, "-link_crt")
  1105. }
  1106. // This must happen before the addition of flags for Version Script and
  1107. // Dynamic List, as these flags must be split on spaces and those must not
  1108. linkerFlags = parseCommandLineFlags(linkerFlags, filterOutClangUnknownCflags)
  1109. additionalLinkerInputs := bazel.LabelList{}
  1110. if props.Version_script != nil {
  1111. label := android.BazelLabelForModuleSrcSingle(ctx, *props.Version_script)
  1112. additionalLinkerInputs.Add(&label)
  1113. linkerFlags = append(linkerFlags, fmt.Sprintf("-Wl,--version-script,$(location %s)", label.Label))
  1114. axisFeatures = append(axisFeatures, "android_cfi_exports_map")
  1115. }
  1116. if props.Dynamic_list != nil {
  1117. label := android.BazelLabelForModuleSrcSingle(ctx, *props.Dynamic_list)
  1118. additionalLinkerInputs.Add(&label)
  1119. linkerFlags = append(linkerFlags, fmt.Sprintf("-Wl,--dynamic-list,$(location %s)", label.Label))
  1120. }
  1121. la.additionalLinkerInputs.SetSelectValue(axis, config, additionalLinkerInputs)
  1122. if axis == bazel.OsConfigurationAxis && (config == bazel.OsDarwin || config == bazel.OsLinux || config == bazel.OsWindows) {
  1123. linkerFlags = append(linkerFlags, props.Host_ldlibs...)
  1124. }
  1125. la.linkopts.SetSelectValue(axis, config, linkerFlags)
  1126. if axisFeatures != nil {
  1127. la.features.SetSelectValue(axis, config, axisFeatures)
  1128. }
  1129. runtimeDeps := android.BazelLabelForModuleDepsExcludes(ctx, props.Runtime_libs, props.Exclude_runtime_libs)
  1130. if !runtimeDeps.IsEmpty() {
  1131. la.runtimeDeps.SetSelectValue(axis, config, runtimeDeps)
  1132. }
  1133. }
  1134. var (
  1135. apiSurfaceModuleLibCurrentPackage = "@api_surfaces//" + android.ModuleLibApi.String() + "/current:"
  1136. )
  1137. func availableToSameApexes(a, b []string) bool {
  1138. if len(a) == 0 && len(b) == 0 {
  1139. return true
  1140. }
  1141. differ, _, _ := android.ListSetDifference(a, b)
  1142. return !differ
  1143. }
  1144. var (
  1145. apiDomainConfigSettingKey = android.NewOnceKey("apiDomainConfigSettingKey")
  1146. apiDomainConfigSettingLock sync.Mutex
  1147. )
  1148. func getApiDomainConfigSettingMap(config android.Config) *map[string]bool {
  1149. return config.Once(apiDomainConfigSettingKey, func() interface{} {
  1150. return &map[string]bool{}
  1151. }).(*map[string]bool)
  1152. }
  1153. var (
  1154. testApexNameToApiDomain = map[string]string{
  1155. "test_broken_com.android.art": "com.android.art",
  1156. }
  1157. )
  1158. // GetApiDomain returns the canonical name of the apex. This is synonymous to the apex_name definition.
  1159. // https://cs.android.com/android/_/android/platform/build/soong/+/e3f0281b8897da1fe23b2f4f3a05f1dc87bcc902:apex/prebuilt.go;l=81-83;drc=2dc7244af985a6ad701b22f1271e606cabba527f;bpv=1;bpt=0
  1160. // For test apexes, it uses a naming convention heuristic to determine the api domain.
  1161. // TODO (b/281548611): Move this build/soong/android
  1162. func GetApiDomain(apexName string) string {
  1163. if apiDomain, exists := testApexNameToApiDomain[apexName]; exists {
  1164. return apiDomain
  1165. }
  1166. // Remove `test_` prefix
  1167. return strings.TrimPrefix(apexName, "test_")
  1168. }
  1169. // Create a config setting for this apex in build/bazel/rules/apex
  1170. // The use case for this is stub/impl selection in cc libraries
  1171. // Long term, these config_setting(s) should be colocated with the respective apex definitions.
  1172. // Note that this is an anti-pattern: The config_setting should be created from the apex definition
  1173. // and not from a cc_library.
  1174. // This anti-pattern is needed today since not all apexes have been allowlisted.
  1175. func createInApexConfigSetting(ctx android.TopDownMutatorContext, apexName string) {
  1176. if apexName == android.AvailableToPlatform || apexName == android.AvailableToAnyApex {
  1177. // These correspond to android-non_apex and android-in_apex
  1178. return
  1179. }
  1180. apiDomainConfigSettingLock.Lock()
  1181. defer apiDomainConfigSettingLock.Unlock()
  1182. // Return if a config_setting has already been created
  1183. apiDomain := GetApiDomain(apexName)
  1184. acsm := getApiDomainConfigSettingMap(ctx.Config())
  1185. if _, exists := (*acsm)[apiDomain]; exists {
  1186. return
  1187. }
  1188. (*acsm)[apiDomain] = true
  1189. csa := bazel.ConfigSettingAttributes{
  1190. Flag_values: bazel.StringMapAttribute{
  1191. "//build/bazel/rules/apex:api_domain": apiDomain,
  1192. },
  1193. // Constraint this to android
  1194. Constraint_values: bazel.MakeLabelListAttribute(
  1195. bazel.MakeLabelList(
  1196. []bazel.Label{
  1197. bazel.Label{Label: "//build/bazel/platforms/os:android"},
  1198. },
  1199. ),
  1200. ),
  1201. }
  1202. ca := android.CommonAttributes{
  1203. Name: apiDomain,
  1204. }
  1205. ctx.CreateBazelConfigSetting(
  1206. csa,
  1207. ca,
  1208. "build/bazel/rules/apex",
  1209. )
  1210. }
  1211. func inApexConfigSetting(apexAvailable string) string {
  1212. if apexAvailable == android.AvailableToPlatform {
  1213. return bazel.AndroidPlatform
  1214. }
  1215. if apexAvailable == android.AvailableToAnyApex {
  1216. return bazel.AndroidAndInApex
  1217. }
  1218. apiDomain := GetApiDomain(apexAvailable)
  1219. return "//build/bazel/rules/apex:" + apiDomain
  1220. }
  1221. // Inputs to stub vs impl selection.
  1222. type stubSelectionInfo struct {
  1223. // Label of the implementation library (e.g. //bionic/libc:libc)
  1224. impl bazel.Label
  1225. // Axis containing the implementation library
  1226. axis bazel.ConfigurationAxis
  1227. // Axis key containing the implementation library
  1228. config string
  1229. // API domain of the apex
  1230. // For test apexes (test_com.android.foo), this will be the source apex (com.android.foo)
  1231. apiDomain string
  1232. // List of dep labels
  1233. dynamicDeps *bazel.LabelListAttribute
  1234. // Boolean value for determining if the dep is in the same api domain
  1235. // If false, the label will be rewritten to to the stub label
  1236. sameApiDomain bool
  1237. }
  1238. func useStubOrImplInApexWithName(ssi stubSelectionInfo) {
  1239. lib := ssi.impl
  1240. if !ssi.sameApiDomain {
  1241. lib = bazel.Label{
  1242. Label: apiSurfaceModuleLibCurrentPackage + strings.TrimPrefix(lib.OriginalModuleName, ":"),
  1243. }
  1244. }
  1245. // Create a select statement specific to this apex
  1246. inApexSelectValue := ssi.dynamicDeps.SelectValue(bazel.OsAndInApexAxis, inApexConfigSetting(ssi.apiDomain))
  1247. (&inApexSelectValue).Append(bazel.MakeLabelList([]bazel.Label{lib}))
  1248. ssi.dynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, inApexConfigSetting(ssi.apiDomain), bazel.FirstUniqueBazelLabelList(inApexSelectValue))
  1249. // Delete the library from the common config for this apex
  1250. implDynamicDeps := ssi.dynamicDeps.SelectValue(ssi.axis, ssi.config)
  1251. implDynamicDeps = bazel.SubtractBazelLabelList(implDynamicDeps, bazel.MakeLabelList([]bazel.Label{ssi.impl}))
  1252. ssi.dynamicDeps.SetSelectValue(ssi.axis, ssi.config, implDynamicDeps)
  1253. if ssi.axis == bazel.NoConfigAxis {
  1254. // Set defaults. Defaults (i.e. host) should use impl and not stubs.
  1255. defaultSelectValue := ssi.dynamicDeps.SelectValue(bazel.OsAndInApexAxis, bazel.ConditionsDefaultConfigKey)
  1256. (&defaultSelectValue).Append(bazel.MakeLabelList([]bazel.Label{ssi.impl}))
  1257. ssi.dynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, bazel.ConditionsDefaultConfigKey, bazel.FirstUniqueBazelLabelList(defaultSelectValue))
  1258. }
  1259. }
  1260. func setStubsForDynamicDeps(ctx android.BazelConversionPathContext, axis bazel.ConfigurationAxis,
  1261. config string, apexAvailable []string, dynamicLibs bazel.LabelList, dynamicDeps *bazel.LabelListAttribute, ind int, buildNonApexWithStubs bool) {
  1262. // Create a config_setting for each apex_available.
  1263. // This will be used to select impl of a dep if dep is available to the same apex.
  1264. for _, aa := range apexAvailable {
  1265. createInApexConfigSetting(ctx.(android.TopDownMutatorContext), aa)
  1266. }
  1267. apiDomainForSelects := []string{}
  1268. for _, apex := range apexAvailable {
  1269. apiDomainForSelects = append(apiDomainForSelects, GetApiDomain(apex))
  1270. }
  1271. // Always emit a select statement for the platform variant.
  1272. // This ensures that b build //foo --config=android works
  1273. // Soong always creates a platform variant even when the library might not be available to platform.
  1274. if !android.InList(android.AvailableToPlatform, apiDomainForSelects) {
  1275. apiDomainForSelects = append(apiDomainForSelects, android.AvailableToPlatform)
  1276. }
  1277. apiDomainForSelects = android.SortedUniqueStrings(apiDomainForSelects)
  1278. // Create a select for each apex this library could be included in.
  1279. for _, l := range dynamicLibs.Includes {
  1280. dep, _ := ctx.ModuleFromName(l.OriginalModuleName)
  1281. if c, ok := dep.(*Module); !ok || !c.HasStubsVariants() {
  1282. continue
  1283. }
  1284. // TODO (b/280339069): Decrease the verbosity of the generated BUILD files
  1285. for _, apiDomain := range apiDomainForSelects {
  1286. var sameApiDomain bool
  1287. if apiDomain == android.AvailableToPlatform {
  1288. // Platform variants in Soong use equality of apex_available for stub/impl selection.
  1289. // https://cs.android.com/android/_/android/platform/build/soong/+/316b0158fe57ee7764235923e7c6f3d530da39c6:cc/cc.go;l=3393-3404;drc=176271a426496fa2688efe2b40d5c74340c63375;bpv=1;bpt=0
  1290. // One of the factors behind this design choice is cc_test
  1291. // Tests only have a platform variant, and using equality of apex_available ensures
  1292. // that tests of an apex library gets its implementation and not stubs.
  1293. // TODO (b/280343104): Discuss if we can drop this special handling for platform variants.
  1294. sameApiDomain = availableToSameApexes(apexAvailable, dep.(*Module).ApexAvailable())
  1295. if linkable, ok := ctx.Module().(LinkableInterface); ok && linkable.Bootstrap() {
  1296. sameApiDomain = true
  1297. }
  1298. } else {
  1299. sameApiDomain = android.InList(apiDomain, dep.(*Module).ApexAvailable())
  1300. }
  1301. ssi := stubSelectionInfo{
  1302. impl: l,
  1303. axis: axis,
  1304. config: config,
  1305. apiDomain: apiDomain,
  1306. dynamicDeps: dynamicDeps,
  1307. sameApiDomain: sameApiDomain,
  1308. }
  1309. useStubOrImplInApexWithName(ssi)
  1310. }
  1311. }
  1312. }
  1313. func (la *linkerAttributes) convertStripProps(ctx android.BazelConversionPathContext, module *Module) {
  1314. bp2BuildPropParseHelper(ctx, module, &StripProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
  1315. if stripProperties, ok := props.(*StripProperties); ok {
  1316. la.stripKeepSymbols.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols)
  1317. la.stripKeepSymbolsList.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols_list)
  1318. la.stripKeepSymbolsAndDebugFrame.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols_and_debug_frame)
  1319. la.stripAll.SetSelectValue(axis, config, stripProperties.Strip.All)
  1320. la.stripNone.SetSelectValue(axis, config, stripProperties.Strip.None)
  1321. }
  1322. })
  1323. }
  1324. func (la *linkerAttributes) convertProductVariables(ctx android.BazelConversionPathContext, productVariableProps android.ProductConfigProperties) {
  1325. type productVarDep struct {
  1326. // the name of the corresponding excludes field, if one exists
  1327. excludesField string
  1328. // reference to the bazel attribute that should be set for the given product variable config
  1329. attribute *bazel.LabelListAttribute
  1330. depResolutionFunc func(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList
  1331. }
  1332. // an intermediate attribute that holds Header_libs info, and will be appended to
  1333. // implementationDeps at the end, to solve the confliction that both header_libs
  1334. // and static_libs use implementationDeps.
  1335. var headerDeps bazel.LabelListAttribute
  1336. productVarToDepFields := map[string]productVarDep{
  1337. // product variables do not support exclude_shared_libs
  1338. "Shared_libs": {attribute: &la.implementationDynamicDeps, depResolutionFunc: bazelLabelForSharedDepsExcludes},
  1339. "Static_libs": {"Exclude_static_libs", &la.implementationDeps, bazelLabelForStaticDepsExcludes},
  1340. "Whole_static_libs": {"Exclude_static_libs", &la.wholeArchiveDeps, bazelLabelForWholeDepsExcludes},
  1341. "Header_libs": {attribute: &headerDeps, depResolutionFunc: bazelLabelForHeaderDepsExcludes},
  1342. }
  1343. for name, dep := range productVarToDepFields {
  1344. props, exists := productVariableProps[name]
  1345. excludeProps, excludesExists := productVariableProps[dep.excludesField]
  1346. // if neither an include nor excludes property exists, then skip it
  1347. if !exists && !excludesExists {
  1348. continue
  1349. }
  1350. // Collect all the configurations that an include or exclude property exists for.
  1351. // We want to iterate all configurations rather than either the include or exclude because, for a
  1352. // particular configuration, we may have either only an include or an exclude to handle.
  1353. productConfigProps := make(map[android.ProductConfigOrSoongConfigProperty]bool, len(props)+len(excludeProps))
  1354. for p := range props {
  1355. productConfigProps[p] = true
  1356. }
  1357. for p := range excludeProps {
  1358. productConfigProps[p] = true
  1359. }
  1360. for productConfigProp := range productConfigProps {
  1361. prop, includesExists := props[productConfigProp]
  1362. excludesProp, excludesExists := excludeProps[productConfigProp]
  1363. var includes, excludes []string
  1364. var ok bool
  1365. // if there was no includes/excludes property, casting fails and that's expected
  1366. if includes, ok = prop.([]string); includesExists && !ok {
  1367. ctx.ModuleErrorf("Could not convert product variable %s property", name)
  1368. }
  1369. if excludes, ok = excludesProp.([]string); excludesExists && !ok {
  1370. ctx.ModuleErrorf("Could not convert product variable %s property", dep.excludesField)
  1371. }
  1372. dep.attribute.EmitEmptyList = productConfigProp.AlwaysEmit()
  1373. dep.attribute.SetSelectValue(
  1374. productConfigProp.ConfigurationAxis(),
  1375. productConfigProp.SelectKey(),
  1376. dep.depResolutionFunc(ctx, android.FirstUniqueStrings(includes), excludes),
  1377. )
  1378. }
  1379. }
  1380. la.implementationDeps.Append(headerDeps)
  1381. }
  1382. func (la *linkerAttributes) finalize(ctx android.BazelConversionPathContext) {
  1383. // if system dynamic deps have the default value, any use of a system dynamic library used will
  1384. // result in duplicate library errors for bionic OSes. Here, we explicitly exclude those libraries
  1385. // from bionic OSes and the no config case as these libraries only build for bionic OSes.
  1386. if la.systemDynamicDeps.IsNil() && len(la.usedSystemDynamicDepAsDynamicDep) > 0 {
  1387. toRemove := bazelLabelForSharedDeps(ctx, android.SortedKeys(la.usedSystemDynamicDepAsDynamicDep))
  1388. la.dynamicDeps.Exclude(bazel.NoConfigAxis, "", toRemove)
  1389. la.dynamicDeps.Exclude(bazel.OsConfigurationAxis, "android", toRemove)
  1390. la.dynamicDeps.Exclude(bazel.OsConfigurationAxis, "linux_bionic", toRemove)
  1391. la.implementationDynamicDeps.Exclude(bazel.NoConfigAxis, "", toRemove)
  1392. la.implementationDynamicDeps.Exclude(bazel.OsConfigurationAxis, "android", toRemove)
  1393. la.implementationDynamicDeps.Exclude(bazel.OsConfigurationAxis, "linux_bionic", toRemove)
  1394. la.implementationDynamicDeps.Exclude(bazel.OsAndInApexAxis, bazel.ConditionsDefaultConfigKey, toRemove)
  1395. stubsToRemove := make([]bazel.Label, 0, len(la.usedSystemDynamicDepAsDynamicDep))
  1396. for _, lib := range toRemove.Includes {
  1397. stubLabelInApiSurfaces := bazel.Label{
  1398. Label: apiSurfaceModuleLibCurrentPackage + lib.OriginalModuleName,
  1399. }
  1400. stubsToRemove = append(stubsToRemove, stubLabelInApiSurfaces)
  1401. }
  1402. // system libraries (e.g. libc, libm, libdl) belong the com.android.runtime api domain
  1403. // dedupe the stubs of these libraries from the other api domains (platform, other_apexes...)
  1404. for _, aa := range ctx.Module().(*Module).ApexAvailable() {
  1405. la.implementationDynamicDeps.Exclude(bazel.OsAndInApexAxis, inApexConfigSetting(aa), bazel.MakeLabelList(stubsToRemove))
  1406. }
  1407. la.implementationDynamicDeps.Exclude(bazel.OsAndInApexAxis, bazel.AndroidPlatform, bazel.MakeLabelList(stubsToRemove))
  1408. }
  1409. la.deps.ResolveExcludes()
  1410. la.implementationDeps.ResolveExcludes()
  1411. la.dynamicDeps.ResolveExcludes()
  1412. la.implementationDynamicDeps.ResolveExcludes()
  1413. la.wholeArchiveDeps.ResolveExcludes()
  1414. la.systemDynamicDeps.ForceSpecifyEmptyList = true
  1415. }
  1416. // Relativize a list of root-relative paths with respect to the module's
  1417. // directory.
  1418. //
  1419. // include_dirs Soong prop are root-relative (b/183742505), but
  1420. // local_include_dirs, export_include_dirs and export_system_include_dirs are
  1421. // module dir relative. This function makes a list of paths entirely module dir
  1422. // relative.
  1423. //
  1424. // For the `include` attribute, Bazel wants the paths to be relative to the
  1425. // module.
  1426. func bp2BuildMakePathsRelativeToModule(ctx android.BazelConversionPathContext, paths []string) []string {
  1427. var relativePaths []string
  1428. for _, path := range paths {
  1429. // Semantics of filepath.Rel: join(ModuleDir, rel(ModuleDir, path)) == path
  1430. relativePath, err := filepath.Rel(ctx.ModuleDir(), path)
  1431. if err != nil {
  1432. panic(err)
  1433. }
  1434. relativePaths = append(relativePaths, relativePath)
  1435. }
  1436. return relativePaths
  1437. }
  1438. // BazelIncludes contains information about -I and -isystem paths from a module converted to Bazel
  1439. // attributes.
  1440. type BazelIncludes struct {
  1441. AbsoluteIncludes bazel.StringListAttribute
  1442. Includes bazel.StringListAttribute
  1443. SystemIncludes bazel.StringListAttribute
  1444. }
  1445. func bp2BuildParseExportedIncludes(ctx android.BazelConversionPathContext, module *Module, includes *BazelIncludes) BazelIncludes {
  1446. var exported BazelIncludes
  1447. if includes != nil {
  1448. exported = *includes
  1449. } else {
  1450. exported = BazelIncludes{}
  1451. }
  1452. // cc library Export_include_dirs and Export_system_include_dirs are marked
  1453. // "variant_prepend" in struct tag, set their prepend property to true to make
  1454. // sure bp2build generates correct result.
  1455. exported.Includes.Prepend = true
  1456. exported.SystemIncludes.Prepend = true
  1457. bp2BuildPropParseHelper(ctx, module, &FlagExporterProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
  1458. if flagExporterProperties, ok := props.(*FlagExporterProperties); ok {
  1459. if len(flagExporterProperties.Export_include_dirs) > 0 {
  1460. exported.Includes.SetSelectValue(axis, config, android.FirstUniqueStrings(append(exported.Includes.SelectValue(axis, config), flagExporterProperties.Export_include_dirs...)))
  1461. }
  1462. if len(flagExporterProperties.Export_system_include_dirs) > 0 {
  1463. exported.SystemIncludes.SetSelectValue(axis, config, android.FirstUniqueStrings(append(exported.SystemIncludes.SelectValue(axis, config), flagExporterProperties.Export_system_include_dirs...)))
  1464. }
  1465. }
  1466. })
  1467. exported.AbsoluteIncludes.DeduplicateAxesFromBase()
  1468. exported.Includes.DeduplicateAxesFromBase()
  1469. exported.SystemIncludes.DeduplicateAxesFromBase()
  1470. return exported
  1471. }
  1472. func BazelLabelNameForStaticModule(baseLabel string) string {
  1473. return baseLabel + "_bp2build_cc_library_static"
  1474. }
  1475. func bazelLabelForStaticModule(ctx android.BazelConversionPathContext, m blueprint.Module) string {
  1476. label := android.BazelModuleLabel(ctx, m)
  1477. if ccModule, ok := m.(*Module); ok && ccModule.typ() == fullLibrary {
  1478. return BazelLabelNameForStaticModule(label)
  1479. }
  1480. return label
  1481. }
  1482. func bazelLabelForSharedModule(ctx android.BazelConversionPathContext, m blueprint.Module) string {
  1483. // cc_library, at it's root name, propagates the shared library, which depends on the static
  1484. // library.
  1485. return android.BazelModuleLabel(ctx, m)
  1486. }
  1487. func bazelLabelForStaticWholeModuleDeps(ctx android.BazelConversionPathContext, m blueprint.Module) string {
  1488. label := bazelLabelForStaticModule(ctx, m)
  1489. if aModule, ok := m.(android.Module); ok {
  1490. if android.IsModulePrebuilt(aModule) {
  1491. label += "_alwayslink"
  1492. }
  1493. }
  1494. return label
  1495. }
  1496. // Replaces //a/b/my_xsd_config with //a/b/my_xsd_config-cpp
  1497. func xsdConfigCppTarget(ctx android.BazelConversionPathContext, mod blueprint.Module) string {
  1498. callback := func(xsd android.XsdConfigBp2buildTargets) string {
  1499. return xsd.CppBp2buildTargetName()
  1500. }
  1501. return android.XsdConfigBp2buildTarget(ctx, mod, callback)
  1502. }
  1503. func bazelLabelForXsdConfig(ctx android.BazelConversionPathContext, modules []string) bazel.LabelList {
  1504. return android.BazelLabelForModuleDepsWithFn(ctx, modules, xsdConfigCppTarget)
  1505. }
  1506. func bazelLabelForWholeDeps(ctx android.BazelConversionPathContext, modules []string) bazel.LabelList {
  1507. return android.BazelLabelForModuleDepsWithFn(ctx, modules, bazelLabelForStaticWholeModuleDeps)
  1508. }
  1509. func bazelLabelForWholeDepsExcludes(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList {
  1510. return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForStaticWholeModuleDeps)
  1511. }
  1512. func bazelLabelForStaticDepsExcludes(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList {
  1513. return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForStaticModule)
  1514. }
  1515. func bazelLabelForStaticDeps(ctx android.BazelConversionPathContext, modules []string) bazel.LabelList {
  1516. return android.BazelLabelForModuleDepsWithFn(ctx, modules, bazelLabelForStaticModule)
  1517. }
  1518. func bazelLabelForSharedDeps(ctx android.BazelConversionPathContext, modules []string) bazel.LabelList {
  1519. return android.BazelLabelForModuleDepsWithFn(ctx, modules, bazelLabelForSharedModule)
  1520. }
  1521. func bazelLabelForHeaderDeps(ctx android.BazelConversionPathContext, modules []string) bazel.LabelList {
  1522. // This is not elegant, but bp2build's shared library targets only propagate
  1523. // their header information as part of the normal C++ provider.
  1524. return bazelLabelForSharedDeps(ctx, modules)
  1525. }
  1526. func bazelLabelForHeaderDepsExcludes(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList {
  1527. // This is only used when product_variable header_libs is processed, to follow
  1528. // the pattern of depResolutionFunc
  1529. return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForSharedModule)
  1530. }
  1531. func bazelLabelForSharedDepsExcludes(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList {
  1532. return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForSharedModule)
  1533. }
  1534. type binaryLinkerAttrs struct {
  1535. Linkshared *bool
  1536. Stem bazel.StringAttribute
  1537. Suffix bazel.StringAttribute
  1538. }
  1539. func bp2buildBinaryLinkerProps(ctx android.BazelConversionPathContext, m *Module) binaryLinkerAttrs {
  1540. attrs := binaryLinkerAttrs{}
  1541. bp2BuildPropParseHelper(ctx, m, &BinaryLinkerProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
  1542. linkerProps := props.(*BinaryLinkerProperties)
  1543. staticExecutable := linkerProps.Static_executable
  1544. if axis == bazel.NoConfigAxis {
  1545. if linkBinaryShared := !proptools.Bool(staticExecutable); !linkBinaryShared {
  1546. attrs.Linkshared = &linkBinaryShared
  1547. }
  1548. } else if staticExecutable != nil {
  1549. // TODO(b/202876379): Static_executable is arch-variant; however, linkshared is a
  1550. // nonconfigurable attribute. Only 4 AOSP modules use this feature, defer handling
  1551. ctx.ModuleErrorf("bp2build cannot migrate a module with arch/target-specific static_executable values")
  1552. }
  1553. if stem := linkerProps.Stem; stem != nil {
  1554. attrs.Stem.SetSelectValue(axis, config, stem)
  1555. }
  1556. if suffix := linkerProps.Suffix; suffix != nil {
  1557. attrs.Suffix.SetSelectValue(axis, config, suffix)
  1558. }
  1559. })
  1560. return attrs
  1561. }
  1562. func bp2buildSanitizerFeatures(ctx android.BazelConversionPathContext, m *Module) bazel.StringListAttribute {
  1563. sanitizerFeatures := bazel.StringListAttribute{}
  1564. bp2BuildPropParseHelper(ctx, m, &SanitizeProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
  1565. var features []string
  1566. if sanitizerProps, ok := props.(*SanitizeProperties); ok {
  1567. if sanitizerProps.Sanitize.Integer_overflow != nil && *sanitizerProps.Sanitize.Integer_overflow {
  1568. features = append(features, "ubsan_integer_overflow")
  1569. }
  1570. for _, sanitizer := range sanitizerProps.Sanitize.Misc_undefined {
  1571. features = append(features, "ubsan_"+sanitizer)
  1572. }
  1573. blocklist := sanitizerProps.Sanitize.Blocklist
  1574. if blocklist != nil {
  1575. // Format the blocklist name to be used in a feature name
  1576. blocklistFeatureSuffix := strings.Replace(strings.ToLower(*blocklist), ".", "_", -1)
  1577. features = append(features, "ubsan_blocklist_"+blocklistFeatureSuffix)
  1578. }
  1579. if sanitizerProps.Sanitize.Cfi != nil && !proptools.Bool(sanitizerProps.Sanitize.Cfi) {
  1580. features = append(features, "-android_cfi")
  1581. } else if proptools.Bool(sanitizerProps.Sanitize.Cfi) {
  1582. features = append(features, "android_cfi")
  1583. if proptools.Bool(sanitizerProps.Sanitize.Config.Cfi_assembly_support) {
  1584. features = append(features, "android_cfi_assembly_support")
  1585. }
  1586. }
  1587. sanitizerFeatures.SetSelectValue(axis, config, features)
  1588. }
  1589. })
  1590. return sanitizerFeatures
  1591. }
  1592. func bp2buildLtoFeatures(ctx android.BazelConversionPathContext, m *Module) bazel.StringListAttribute {
  1593. lto_feature_name := "android_thin_lto"
  1594. ltoBoolFeatures := bazel.BoolAttribute{}
  1595. bp2BuildPropParseHelper(ctx, m, &LTOProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
  1596. if ltoProps, ok := props.(*LTOProperties); ok {
  1597. thinProp := ltoProps.Lto.Thin != nil && *ltoProps.Lto.Thin
  1598. thinPropSetToFalse := ltoProps.Lto.Thin != nil && !*ltoProps.Lto.Thin
  1599. neverProp := ltoProps.Lto.Never != nil && *ltoProps.Lto.Never
  1600. if thinProp {
  1601. ltoBoolFeatures.SetSelectValue(axis, config, BoolPtr(true))
  1602. return
  1603. }
  1604. if neverProp || thinPropSetToFalse {
  1605. if thinProp {
  1606. ctx.ModuleErrorf("lto.thin and lto.never are mutually exclusive but were specified together")
  1607. } else {
  1608. ltoBoolFeatures.SetSelectValue(axis, config, BoolPtr(false))
  1609. }
  1610. return
  1611. }
  1612. }
  1613. ltoBoolFeatures.SetSelectValue(axis, config, nil)
  1614. })
  1615. props := m.GetArchVariantProperties(ctx, &LTOProperties{})
  1616. ltoStringFeatures, err := ltoBoolFeatures.ToStringListAttribute(func(boolPtr *bool, axis bazel.ConfigurationAxis, config string) []string {
  1617. if boolPtr == nil {
  1618. return []string{}
  1619. }
  1620. if !*boolPtr {
  1621. return []string{"-" + lto_feature_name}
  1622. }
  1623. features := []string{lto_feature_name}
  1624. if ltoProps, ok := props[axis][config].(*LTOProperties); ok {
  1625. if ltoProps.Whole_program_vtables != nil && *ltoProps.Whole_program_vtables {
  1626. features = append(features, "android_thin_lto_whole_program_vtables")
  1627. }
  1628. }
  1629. return features
  1630. })
  1631. if err != nil {
  1632. ctx.ModuleErrorf("Error processing LTO attributes: %s", err)
  1633. }
  1634. return ltoStringFeatures
  1635. }
  1636. func convertHiddenVisibilityToFeatureBase(ctx android.BazelConversionPathContext, m *Module) bazel.StringListAttribute {
  1637. visibilityHiddenFeature := bazel.StringListAttribute{}
  1638. bp2BuildPropParseHelper(ctx, m, &BaseCompilerProperties{}, func(axis bazel.ConfigurationAxis, configString string, props interface{}) {
  1639. if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
  1640. convertHiddenVisibilityToFeatureHelper(&visibilityHiddenFeature, axis, configString, baseCompilerProps.Cflags)
  1641. }
  1642. })
  1643. return visibilityHiddenFeature
  1644. }
  1645. func convertHiddenVisibilityToFeatureStaticOrShared(ctx android.BazelConversionPathContext, m *Module, isStatic bool) bazel.StringListAttribute {
  1646. visibilityHiddenFeature := bazel.StringListAttribute{}
  1647. if isStatic {
  1648. bp2BuildPropParseHelper(ctx, m, &StaticProperties{}, func(axis bazel.ConfigurationAxis, configString string, props interface{}) {
  1649. if staticProps, ok := props.(*StaticProperties); ok {
  1650. convertHiddenVisibilityToFeatureHelper(&visibilityHiddenFeature, axis, configString, staticProps.Static.Cflags)
  1651. }
  1652. })
  1653. } else {
  1654. bp2BuildPropParseHelper(ctx, m, &SharedProperties{}, func(axis bazel.ConfigurationAxis, configString string, props interface{}) {
  1655. if sharedProps, ok := props.(*SharedProperties); ok {
  1656. convertHiddenVisibilityToFeatureHelper(&visibilityHiddenFeature, axis, configString, sharedProps.Shared.Cflags)
  1657. }
  1658. })
  1659. }
  1660. return visibilityHiddenFeature
  1661. }
  1662. func convertHiddenVisibilityToFeatureHelper(feature *bazel.StringListAttribute, axis bazel.ConfigurationAxis, configString string, cflags []string) {
  1663. if inList(config.VisibilityHiddenFlag, cflags) {
  1664. feature.SetSelectValue(axis, configString, []string{"visibility_hidden"})
  1665. }
  1666. }