bp2build.go 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379
  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. "android/soong/android"
  20. "android/soong/bazel"
  21. "android/soong/cc/config"
  22. "github.com/google/blueprint"
  23. "github.com/google/blueprint/proptools"
  24. )
  25. const (
  26. cSrcPartition = "c"
  27. asSrcPartition = "as"
  28. asmSrcPartition = "asm"
  29. lSrcPartition = "l"
  30. llSrcPartition = "ll"
  31. cppSrcPartition = "cpp"
  32. protoSrcPartition = "proto"
  33. aidlSrcPartition = "aidl"
  34. syspropSrcPartition = "sysprop"
  35. stubsSuffix = "_stub_libs_current"
  36. )
  37. // staticOrSharedAttributes are the Bazel-ified versions of StaticOrSharedProperties --
  38. // properties which apply to either the shared or static version of a cc_library module.
  39. type staticOrSharedAttributes struct {
  40. Srcs bazel.LabelListAttribute
  41. Srcs_c bazel.LabelListAttribute
  42. Srcs_as bazel.LabelListAttribute
  43. Srcs_aidl bazel.LabelListAttribute
  44. Hdrs bazel.LabelListAttribute
  45. Copts bazel.StringListAttribute
  46. Deps bazel.LabelListAttribute
  47. Implementation_deps bazel.LabelListAttribute
  48. Dynamic_deps bazel.LabelListAttribute
  49. Implementation_dynamic_deps bazel.LabelListAttribute
  50. Whole_archive_deps bazel.LabelListAttribute
  51. Implementation_whole_archive_deps bazel.LabelListAttribute
  52. Runtime_deps bazel.LabelListAttribute
  53. System_dynamic_deps bazel.LabelListAttribute
  54. Enabled bazel.BoolAttribute
  55. Native_coverage bazel.BoolAttribute
  56. sdkAttributes
  57. tidyAttributes
  58. }
  59. type tidyAttributes struct {
  60. Tidy *bool
  61. Tidy_flags []string
  62. Tidy_checks []string
  63. Tidy_checks_as_errors []string
  64. Tidy_disabled_srcs bazel.LabelListAttribute
  65. Tidy_timeout_srcs bazel.LabelListAttribute
  66. }
  67. func (m *Module) convertTidyAttributes(ctx android.BaseMutatorContext, moduleAttrs *tidyAttributes) {
  68. for _, f := range m.features {
  69. if tidy, ok := f.(*tidyFeature); ok {
  70. moduleAttrs.Tidy = tidy.Properties.Tidy
  71. moduleAttrs.Tidy_flags = tidy.Properties.Tidy_flags
  72. moduleAttrs.Tidy_checks = tidy.Properties.Tidy_checks
  73. moduleAttrs.Tidy_checks_as_errors = tidy.Properties.Tidy_checks_as_errors
  74. }
  75. }
  76. archVariantProps := m.GetArchVariantProperties(ctx, &BaseCompilerProperties{})
  77. for axis, configToProps := range archVariantProps {
  78. for config, _props := range configToProps {
  79. if archProps, ok := _props.(*BaseCompilerProperties); ok {
  80. archDisabledSrcs := android.BazelLabelForModuleSrc(ctx, archProps.Tidy_disabled_srcs)
  81. moduleAttrs.Tidy_disabled_srcs.SetSelectValue(axis, config, archDisabledSrcs)
  82. archTimeoutSrcs := android.BazelLabelForModuleSrc(ctx, archProps.Tidy_timeout_srcs)
  83. moduleAttrs.Tidy_timeout_srcs.SetSelectValue(axis, config, archTimeoutSrcs)
  84. }
  85. }
  86. }
  87. }
  88. // groupSrcsByExtension partitions `srcs` into groups based on file extension.
  89. func groupSrcsByExtension(ctx android.BazelConversionPathContext, srcs bazel.LabelListAttribute) bazel.PartitionToLabelListAttribute {
  90. // Convert filegroup dependencies into extension-specific filegroups filtered in the filegroup.bzl
  91. // macro.
  92. addSuffixForFilegroup := func(suffix string) bazel.LabelMapper {
  93. return func(otherModuleCtx bazel.OtherModuleContext, label bazel.Label) (string, bool) {
  94. m, exists := otherModuleCtx.ModuleFromName(label.OriginalModuleName)
  95. labelStr := label.Label
  96. if !exists || !android.IsFilegroup(otherModuleCtx, m) {
  97. return labelStr, false
  98. }
  99. // If the filegroup is already converted to aidl_library or proto_library,
  100. // skip creating _c_srcs, _as_srcs, _cpp_srcs filegroups
  101. fg, _ := m.(android.FileGroupAsLibrary)
  102. if fg.ShouldConvertToAidlLibrary(ctx) || fg.ShouldConvertToProtoLibrary(ctx) {
  103. return labelStr, false
  104. }
  105. return labelStr + suffix, true
  106. }
  107. }
  108. // TODO(b/190006308): Handle language detection of sources in a Bazel rule.
  109. labels := bazel.LabelPartitions{
  110. protoSrcPartition: android.ProtoSrcLabelPartition,
  111. cSrcPartition: bazel.LabelPartition{Extensions: []string{".c"}, LabelMapper: addSuffixForFilegroup("_c_srcs")},
  112. asSrcPartition: bazel.LabelPartition{Extensions: []string{".s", ".S"}, LabelMapper: addSuffixForFilegroup("_as_srcs")},
  113. asmSrcPartition: bazel.LabelPartition{Extensions: []string{".asm"}},
  114. aidlSrcPartition: android.AidlSrcLabelPartition,
  115. // TODO(http://b/231968910): If there is ever a filegroup target that
  116. // contains .l or .ll files we will need to find a way to add a
  117. // LabelMapper for these that identifies these filegroups and
  118. // converts them appropriately
  119. lSrcPartition: bazel.LabelPartition{Extensions: []string{".l"}},
  120. llSrcPartition: bazel.LabelPartition{Extensions: []string{".ll"}},
  121. // C++ is the "catch-all" group, and comprises generated sources because we don't
  122. // know the language of these sources until the genrule is executed.
  123. cppSrcPartition: bazel.LabelPartition{Extensions: []string{".cpp", ".cc", ".cxx", ".mm"}, LabelMapper: addSuffixForFilegroup("_cpp_srcs"), Keep_remainder: true},
  124. syspropSrcPartition: bazel.LabelPartition{Extensions: []string{".sysprop"}},
  125. }
  126. return bazel.PartitionLabelListAttribute(ctx, &srcs, labels)
  127. }
  128. // bp2BuildParseLibProps returns the attributes for a variant of a cc_library.
  129. func bp2BuildParseLibProps(ctx android.BazelConversionPathContext, module *Module, isStatic bool) staticOrSharedAttributes {
  130. lib, ok := module.compiler.(*libraryDecorator)
  131. if !ok {
  132. return staticOrSharedAttributes{}
  133. }
  134. return bp2buildParseStaticOrSharedProps(ctx, module, lib, isStatic)
  135. }
  136. // bp2buildParseSharedProps returns the attributes for the shared variant of a cc_library.
  137. func bp2BuildParseSharedProps(ctx android.BazelConversionPathContext, module *Module) staticOrSharedAttributes {
  138. return bp2BuildParseLibProps(ctx, module, false)
  139. }
  140. // bp2buildParseStaticProps returns the attributes for the static variant of a cc_library.
  141. func bp2BuildParseStaticProps(ctx android.BazelConversionPathContext, module *Module) staticOrSharedAttributes {
  142. return bp2BuildParseLibProps(ctx, module, true)
  143. }
  144. type depsPartition struct {
  145. export bazel.LabelList
  146. implementation bazel.LabelList
  147. }
  148. type bazelLabelForDepsFn func(android.BazelConversionPathContext, []string) bazel.LabelList
  149. func maybePartitionExportedAndImplementationsDeps(ctx android.BazelConversionPathContext, exportsDeps bool, allDeps, exportedDeps []string, fn bazelLabelForDepsFn) depsPartition {
  150. if !exportsDeps {
  151. return depsPartition{
  152. implementation: fn(ctx, allDeps),
  153. }
  154. }
  155. implementation, export := android.FilterList(allDeps, exportedDeps)
  156. return depsPartition{
  157. export: fn(ctx, export),
  158. implementation: fn(ctx, implementation),
  159. }
  160. }
  161. type bazelLabelForDepsExcludesFn func(android.BazelConversionPathContext, []string, []string) bazel.LabelList
  162. func maybePartitionExportedAndImplementationsDepsExcludes(ctx android.BazelConversionPathContext, exportsDeps bool, allDeps, excludes, exportedDeps []string, fn bazelLabelForDepsExcludesFn) depsPartition {
  163. if !exportsDeps {
  164. return depsPartition{
  165. implementation: fn(ctx, allDeps, excludes),
  166. }
  167. }
  168. implementation, export := android.FilterList(allDeps, exportedDeps)
  169. return depsPartition{
  170. export: fn(ctx, export, excludes),
  171. implementation: fn(ctx, implementation, excludes),
  172. }
  173. }
  174. func bp2BuildPropParseHelper(ctx android.ArchVariantContext, module *Module, propsType interface{}, parseFunc func(axis bazel.ConfigurationAxis, config string, props interface{})) {
  175. for axis, configToProps := range module.GetArchVariantProperties(ctx, propsType) {
  176. for config, props := range configToProps {
  177. parseFunc(axis, config, props)
  178. }
  179. }
  180. }
  181. // Parses properties common to static and shared libraries. Also used for prebuilt libraries.
  182. func bp2buildParseStaticOrSharedProps(ctx android.BazelConversionPathContext, module *Module, lib *libraryDecorator, isStatic bool) staticOrSharedAttributes {
  183. attrs := staticOrSharedAttributes{}
  184. setAttrs := func(axis bazel.ConfigurationAxis, config string, props StaticOrSharedProperties) {
  185. attrs.Copts.SetSelectValue(axis, config, parseCommandLineFlags(props.Cflags, filterOutStdFlag))
  186. attrs.Srcs.SetSelectValue(axis, config, android.BazelLabelForModuleSrc(ctx, props.Srcs))
  187. attrs.System_dynamic_deps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, props.System_shared_libs))
  188. staticDeps := maybePartitionExportedAndImplementationsDeps(ctx, true, props.Static_libs, props.Export_static_lib_headers, bazelLabelForStaticDeps)
  189. attrs.Deps.SetSelectValue(axis, config, staticDeps.export)
  190. attrs.Implementation_deps.SetSelectValue(axis, config, staticDeps.implementation)
  191. sharedDeps := maybePartitionExportedAndImplementationsDeps(ctx, true, props.Shared_libs, props.Export_shared_lib_headers, bazelLabelForSharedDeps)
  192. attrs.Dynamic_deps.SetSelectValue(axis, config, sharedDeps.export)
  193. attrs.Implementation_dynamic_deps.SetSelectValue(axis, config, sharedDeps.implementation)
  194. attrs.Whole_archive_deps.SetSelectValue(axis, config, bazelLabelForWholeDeps(ctx, props.Whole_static_libs))
  195. attrs.Enabled.SetSelectValue(axis, config, props.Enabled)
  196. }
  197. // system_dynamic_deps distinguishes between nil/empty list behavior:
  198. // nil -> use default values
  199. // empty list -> no values specified
  200. attrs.System_dynamic_deps.ForceSpecifyEmptyList = true
  201. if isStatic {
  202. bp2BuildPropParseHelper(ctx, module, &StaticProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
  203. if staticOrSharedProps, ok := props.(*StaticProperties); ok {
  204. setAttrs(axis, config, staticOrSharedProps.Static)
  205. }
  206. })
  207. } else {
  208. bp2BuildPropParseHelper(ctx, module, &SharedProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
  209. if staticOrSharedProps, ok := props.(*SharedProperties); ok {
  210. setAttrs(axis, config, staticOrSharedProps.Shared)
  211. }
  212. })
  213. }
  214. partitionedSrcs := groupSrcsByExtension(ctx, attrs.Srcs)
  215. attrs.Srcs = partitionedSrcs[cppSrcPartition]
  216. attrs.Srcs_c = partitionedSrcs[cSrcPartition]
  217. attrs.Srcs_as = partitionedSrcs[asSrcPartition]
  218. if !partitionedSrcs[protoSrcPartition].IsEmpty() {
  219. // TODO(b/208815215): determine whether this is used and add support if necessary
  220. ctx.ModuleErrorf("Migrating static/shared only proto srcs is not currently supported")
  221. }
  222. return attrs
  223. }
  224. // Convenience struct to hold all attributes parsed from prebuilt properties.
  225. type prebuiltAttributes struct {
  226. Src bazel.LabelAttribute
  227. Enabled bazel.BoolAttribute
  228. }
  229. func parseSrc(ctx android.BazelConversionPathContext, srcLabelAttribute *bazel.LabelAttribute, axis bazel.ConfigurationAxis, config string, srcs []string) {
  230. srcFileError := func() {
  231. ctx.ModuleErrorf("parseSrc: Expected at most one source file for %s %s\n", axis, config)
  232. }
  233. if len(srcs) > 1 {
  234. srcFileError()
  235. return
  236. } else if len(srcs) == 0 {
  237. return
  238. }
  239. if srcLabelAttribute.SelectValue(axis, config) != nil {
  240. srcFileError()
  241. return
  242. }
  243. srcLabelAttribute.SetSelectValue(axis, config, android.BazelLabelForModuleSrcSingle(ctx, srcs[0]))
  244. }
  245. // NOTE: Used outside of Soong repo project, in the clangprebuilts.go bootstrap_go_package
  246. func Bp2BuildParsePrebuiltLibraryProps(ctx android.BazelConversionPathContext, module *Module, isStatic bool) prebuiltAttributes {
  247. var srcLabelAttribute bazel.LabelAttribute
  248. bp2BuildPropParseHelper(ctx, module, &prebuiltLinkerProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
  249. if prebuiltLinkerProperties, ok := props.(*prebuiltLinkerProperties); ok {
  250. parseSrc(ctx, &srcLabelAttribute, axis, config, prebuiltLinkerProperties.Srcs)
  251. }
  252. })
  253. var enabledLabelAttribute bazel.BoolAttribute
  254. parseAttrs := func(axis bazel.ConfigurationAxis, config string, props StaticOrSharedProperties) {
  255. if props.Enabled != nil {
  256. enabledLabelAttribute.SetSelectValue(axis, config, props.Enabled)
  257. }
  258. parseSrc(ctx, &srcLabelAttribute, axis, config, props.Srcs)
  259. }
  260. if isStatic {
  261. bp2BuildPropParseHelper(ctx, module, &StaticProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
  262. if staticProperties, ok := props.(*StaticProperties); ok {
  263. parseAttrs(axis, config, staticProperties.Static)
  264. }
  265. })
  266. } else {
  267. bp2BuildPropParseHelper(ctx, module, &SharedProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
  268. if sharedProperties, ok := props.(*SharedProperties); ok {
  269. parseAttrs(axis, config, sharedProperties.Shared)
  270. }
  271. })
  272. }
  273. return prebuiltAttributes{
  274. Src: srcLabelAttribute,
  275. Enabled: enabledLabelAttribute,
  276. }
  277. }
  278. func bp2BuildParsePrebuiltBinaryProps(ctx android.BazelConversionPathContext, module *Module) prebuiltAttributes {
  279. var srcLabelAttribute bazel.LabelAttribute
  280. bp2BuildPropParseHelper(ctx, module, &prebuiltLinkerProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
  281. if props, ok := props.(*prebuiltLinkerProperties); ok {
  282. parseSrc(ctx, &srcLabelAttribute, axis, config, props.Srcs)
  283. }
  284. })
  285. return prebuiltAttributes{
  286. Src: srcLabelAttribute,
  287. }
  288. }
  289. func bp2BuildParsePrebuiltObjectProps(ctx android.BazelConversionPathContext, module *Module) prebuiltAttributes {
  290. var srcLabelAttribute bazel.LabelAttribute
  291. bp2BuildPropParseHelper(ctx, module, &prebuiltObjectProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
  292. if props, ok := props.(*prebuiltObjectProperties); ok {
  293. parseSrc(ctx, &srcLabelAttribute, axis, config, props.Srcs)
  294. }
  295. })
  296. return prebuiltAttributes{
  297. Src: srcLabelAttribute,
  298. }
  299. }
  300. type baseAttributes struct {
  301. compilerAttributes
  302. linkerAttributes
  303. // A combination of compilerAttributes.features and linkerAttributes.features
  304. features bazel.StringListAttribute
  305. protoDependency *bazel.LabelAttribute
  306. aidlDependency *bazel.LabelAttribute
  307. }
  308. // Convenience struct to hold all attributes parsed from compiler properties.
  309. type compilerAttributes struct {
  310. // Options for all languages
  311. copts bazel.StringListAttribute
  312. // Assembly options and sources
  313. asFlags bazel.StringListAttribute
  314. asSrcs bazel.LabelListAttribute
  315. asmSrcs bazel.LabelListAttribute
  316. // C options and sources
  317. conlyFlags bazel.StringListAttribute
  318. cSrcs bazel.LabelListAttribute
  319. // C++ options and sources
  320. cppFlags bazel.StringListAttribute
  321. srcs bazel.LabelListAttribute
  322. // Lex sources and options
  323. lSrcs bazel.LabelListAttribute
  324. llSrcs bazel.LabelListAttribute
  325. lexopts bazel.StringListAttribute
  326. // Sysprop sources
  327. syspropSrcs bazel.LabelListAttribute
  328. hdrs bazel.LabelListAttribute
  329. rtti bazel.BoolAttribute
  330. // Not affected by arch variants
  331. stl *string
  332. cStd *string
  333. cppStd *string
  334. localIncludes bazel.StringListAttribute
  335. absoluteIncludes bazel.StringListAttribute
  336. includes BazelIncludes
  337. protoSrcs bazel.LabelListAttribute
  338. aidlSrcs bazel.LabelListAttribute
  339. stubsSymbolFile *string
  340. stubsVersions bazel.StringListAttribute
  341. features bazel.StringListAttribute
  342. suffix bazel.StringAttribute
  343. }
  344. type filterOutFn func(string) bool
  345. func filterOutStdFlag(flag string) bool {
  346. return strings.HasPrefix(flag, "-std=")
  347. }
  348. func filterOutClangUnknownCflags(flag string) bool {
  349. for _, f := range config.ClangUnknownCflags {
  350. if f == flag {
  351. return true
  352. }
  353. }
  354. return false
  355. }
  356. func parseCommandLineFlags(soongFlags []string, filterOut ...filterOutFn) []string {
  357. var result []string
  358. for _, flag := range soongFlags {
  359. skipFlag := false
  360. for _, filter := range filterOut {
  361. if filter != nil && filter(flag) {
  362. skipFlag = true
  363. }
  364. }
  365. if skipFlag {
  366. continue
  367. }
  368. // Soong's cflags can contain spaces, like `-include header.h`. For
  369. // Bazel's copts, split them up to be compatible with the
  370. // no_copts_tokenization feature.
  371. result = append(result, strings.Split(flag, " ")...)
  372. }
  373. return result
  374. }
  375. func (ca *compilerAttributes) bp2buildForAxisAndConfig(ctx android.BazelConversionPathContext, axis bazel.ConfigurationAxis, config string, props *BaseCompilerProperties) {
  376. // If there's arch specific srcs or exclude_srcs, generate a select entry for it.
  377. // TODO(b/186153868): do this for OS specific srcs and exclude_srcs too.
  378. if srcsList, ok := parseSrcs(ctx, props); ok {
  379. ca.srcs.SetSelectValue(axis, config, srcsList)
  380. }
  381. localIncludeDirs := props.Local_include_dirs
  382. if axis == bazel.NoConfigAxis {
  383. ca.cStd, ca.cppStd = bp2buildResolveCppStdValue(props.C_std, props.Cpp_std, props.Gnu_extensions)
  384. if includeBuildDirectory(props.Include_build_directory) {
  385. localIncludeDirs = append(localIncludeDirs, ".")
  386. }
  387. }
  388. ca.absoluteIncludes.SetSelectValue(axis, config, props.Include_dirs)
  389. ca.localIncludes.SetSelectValue(axis, config, localIncludeDirs)
  390. instructionSet := proptools.StringDefault(props.Instruction_set, "")
  391. if instructionSet == "arm" {
  392. ca.features.SetSelectValue(axis, config, []string{"arm_isa_arm", "-arm_isa_thumb"})
  393. } else if instructionSet != "" && instructionSet != "thumb" {
  394. ctx.ModuleErrorf("Unknown value for instruction_set: %s", instructionSet)
  395. }
  396. // In Soong, cflags occur on the command line before -std=<val> flag, resulting in the value being
  397. // overridden. In Bazel we always allow overriding, via flags; however, this can cause
  398. // incompatibilities, so we remove "-std=" flags from Cflag properties while leaving it in other
  399. // cases.
  400. ca.copts.SetSelectValue(axis, config, parseCommandLineFlags(props.Cflags, filterOutStdFlag, filterOutClangUnknownCflags))
  401. ca.asFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Asflags, nil))
  402. ca.conlyFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Conlyflags, filterOutClangUnknownCflags))
  403. ca.cppFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Cppflags, filterOutClangUnknownCflags))
  404. ca.rtti.SetSelectValue(axis, config, props.Rtti)
  405. }
  406. func (ca *compilerAttributes) convertStlProps(ctx android.ArchVariantContext, module *Module) {
  407. bp2BuildPropParseHelper(ctx, module, &StlProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
  408. if stlProps, ok := props.(*StlProperties); ok {
  409. if stlProps.Stl == nil {
  410. return
  411. }
  412. if ca.stl == nil {
  413. stl := deduplicateStlInput(*stlProps.Stl)
  414. ca.stl = &stl
  415. } else if ca.stl != stlProps.Stl {
  416. ctx.ModuleErrorf("Unsupported conversion: module with different stl for different variants: %s and %s", *ca.stl, stlProps.Stl)
  417. }
  418. }
  419. })
  420. }
  421. func (ca *compilerAttributes) convertProductVariables(ctx android.BazelConversionPathContext, productVariableProps android.ProductConfigProperties) {
  422. productVarPropNameToAttribute := map[string]*bazel.StringListAttribute{
  423. "Cflags": &ca.copts,
  424. "Asflags": &ca.asFlags,
  425. "CppFlags": &ca.cppFlags,
  426. }
  427. for propName, attr := range productVarPropNameToAttribute {
  428. if productConfigProps, exists := productVariableProps[propName]; exists {
  429. for productConfigProp, prop := range productConfigProps {
  430. flags, ok := prop.([]string)
  431. if !ok {
  432. ctx.ModuleErrorf("Could not convert product variable %s property", proptools.PropertyNameForField(propName))
  433. }
  434. newFlags, _ := bazel.TryVariableSubstitutions(flags, productConfigProp.Name)
  435. attr.SetSelectValue(productConfigProp.ConfigurationAxis(), productConfigProp.SelectKey(), newFlags)
  436. }
  437. }
  438. }
  439. }
  440. func (ca *compilerAttributes) finalize(ctx android.BazelConversionPathContext, implementationHdrs bazel.LabelListAttribute) {
  441. ca.srcs.ResolveExcludes()
  442. partitionedSrcs := groupSrcsByExtension(ctx, ca.srcs)
  443. ca.protoSrcs = partitionedSrcs[protoSrcPartition]
  444. ca.aidlSrcs = partitionedSrcs[aidlSrcPartition]
  445. for p, lla := range partitionedSrcs {
  446. // if there are no sources, there is no need for headers
  447. if lla.IsEmpty() {
  448. continue
  449. }
  450. lla.Append(implementationHdrs)
  451. partitionedSrcs[p] = lla
  452. }
  453. ca.srcs = partitionedSrcs[cppSrcPartition]
  454. ca.cSrcs = partitionedSrcs[cSrcPartition]
  455. ca.asSrcs = partitionedSrcs[asSrcPartition]
  456. ca.asmSrcs = partitionedSrcs[asmSrcPartition]
  457. ca.lSrcs = partitionedSrcs[lSrcPartition]
  458. ca.llSrcs = partitionedSrcs[llSrcPartition]
  459. ca.syspropSrcs = partitionedSrcs[syspropSrcPartition]
  460. ca.absoluteIncludes.DeduplicateAxesFromBase()
  461. ca.localIncludes.DeduplicateAxesFromBase()
  462. }
  463. // Parse srcs from an arch or OS's props value.
  464. func parseSrcs(ctx android.BazelConversionPathContext, props *BaseCompilerProperties) (bazel.LabelList, bool) {
  465. anySrcs := false
  466. // Add srcs-like dependencies such as generated files.
  467. // First create a LabelList containing these dependencies, then merge the values with srcs.
  468. generatedSrcsLabelList := android.BazelLabelForModuleDepsExcludes(ctx, props.Generated_sources, props.Exclude_generated_sources)
  469. if len(props.Generated_sources) > 0 || len(props.Exclude_generated_sources) > 0 {
  470. anySrcs = true
  471. }
  472. allSrcsLabelList := android.BazelLabelForModuleSrcExcludes(ctx, props.Srcs, props.Exclude_srcs)
  473. if len(props.Srcs) > 0 || len(props.Exclude_srcs) > 0 {
  474. anySrcs = true
  475. }
  476. return bazel.AppendBazelLabelLists(allSrcsLabelList, generatedSrcsLabelList), anySrcs
  477. }
  478. func bp2buildStdVal(std *string, prefix string, useGnu bool) *string {
  479. defaultVal := prefix + "_std_default"
  480. // If c{,pp}std properties are not specified, don't generate them in the BUILD file.
  481. // Defaults are handled by the toolchain definition.
  482. // However, if gnu_extensions is false, then the default gnu-to-c version must be specified.
  483. stdVal := proptools.StringDefault(std, defaultVal)
  484. if stdVal == "experimental" || stdVal == defaultVal {
  485. if stdVal == "experimental" {
  486. stdVal = prefix + "_std_experimental"
  487. }
  488. if !useGnu {
  489. stdVal += "_no_gnu"
  490. }
  491. } else if !useGnu {
  492. stdVal = gnuToCReplacer.Replace(stdVal)
  493. }
  494. if stdVal == defaultVal {
  495. return nil
  496. }
  497. return &stdVal
  498. }
  499. func bp2buildResolveCppStdValue(c_std *string, cpp_std *string, gnu_extensions *bool) (*string, *string) {
  500. useGnu := useGnuExtensions(gnu_extensions)
  501. return bp2buildStdVal(c_std, "c", useGnu), bp2buildStdVal(cpp_std, "cpp", useGnu)
  502. }
  503. // packageFromLabel extracts package from a fully-qualified or relative Label and whether the label
  504. // is fully-qualified.
  505. // e.g. fully-qualified "//a/b:foo" -> "a/b", true, relative: ":bar" -> ".", false
  506. func packageFromLabel(label string) (string, bool) {
  507. split := strings.Split(label, ":")
  508. if len(split) != 2 {
  509. return "", false
  510. }
  511. if split[0] == "" {
  512. return ".", false
  513. }
  514. // remove leading "//"
  515. return split[0][2:], true
  516. }
  517. // includesFromLabelList extracts relative/absolute includes from a bazel.LabelList>
  518. func includesFromLabelList(labelList bazel.LabelList) (relative, absolute []string) {
  519. for _, hdr := range labelList.Includes {
  520. if pkg, hasPkg := packageFromLabel(hdr.Label); hasPkg {
  521. absolute = append(absolute, pkg)
  522. } else if pkg != "" {
  523. relative = append(relative, pkg)
  524. }
  525. }
  526. return relative, absolute
  527. }
  528. type YasmAttributes struct {
  529. Srcs bazel.LabelListAttribute
  530. Flags bazel.StringListAttribute
  531. Include_dirs bazel.StringListAttribute
  532. }
  533. func bp2BuildYasm(ctx android.Bp2buildMutatorContext, m *Module, ca compilerAttributes) *bazel.LabelAttribute {
  534. if ca.asmSrcs.IsEmpty() {
  535. return nil
  536. }
  537. // Yasm needs the include directories from both local_includes and
  538. // export_include_dirs. We don't care about actually exporting them from the
  539. // yasm rule though, because they will also be present on the cc_ rule that
  540. // wraps this yasm rule.
  541. includes := ca.localIncludes.Clone()
  542. bp2BuildPropParseHelper(ctx, m, &FlagExporterProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
  543. if flagExporterProperties, ok := props.(*FlagExporterProperties); ok {
  544. if len(flagExporterProperties.Export_include_dirs) > 0 {
  545. x := bazel.StringListAttribute{}
  546. x.SetSelectValue(axis, config, flagExporterProperties.Export_include_dirs)
  547. includes.Append(x)
  548. }
  549. }
  550. })
  551. ctx.CreateBazelTargetModule(
  552. bazel.BazelTargetModuleProperties{
  553. Rule_class: "yasm",
  554. Bzl_load_location: "//build/bazel/rules/cc:yasm.bzl",
  555. },
  556. android.CommonAttributes{Name: m.Name() + "_yasm"},
  557. &YasmAttributes{
  558. Srcs: ca.asmSrcs,
  559. Flags: ca.asFlags,
  560. Include_dirs: *includes,
  561. })
  562. // We only want to add a dependency on the _yasm target if there are asm
  563. // sources in the current configuration. If there are unconfigured asm
  564. // sources, always add the dependency. Otherwise, add the dependency only
  565. // on the configuration axes and values that had asm sources.
  566. if len(ca.asmSrcs.Value.Includes) > 0 {
  567. return bazel.MakeLabelAttribute(":" + m.Name() + "_yasm")
  568. }
  569. ret := &bazel.LabelAttribute{}
  570. for _, axis := range ca.asmSrcs.SortedConfigurationAxes() {
  571. for config := range ca.asmSrcs.ConfigurableValues[axis] {
  572. ret.SetSelectValue(axis, config, bazel.Label{Label: ":" + m.Name() + "_yasm"})
  573. }
  574. }
  575. return ret
  576. }
  577. // bp2BuildParseBaseProps returns all compiler, linker, library attributes of a cc module..
  578. func bp2BuildParseBaseProps(ctx android.Bp2buildMutatorContext, module *Module) baseAttributes {
  579. archVariantCompilerProps := module.GetArchVariantProperties(ctx, &BaseCompilerProperties{})
  580. archVariantLinkerProps := module.GetArchVariantProperties(ctx, &BaseLinkerProperties{})
  581. archVariantLibraryProperties := module.GetArchVariantProperties(ctx, &LibraryProperties{})
  582. var implementationHdrs bazel.LabelListAttribute
  583. axisToConfigs := map[bazel.ConfigurationAxis]map[string]bool{}
  584. allAxesAndConfigs := func(cp android.ConfigurationAxisToArchVariantProperties) {
  585. for axis, configMap := range cp {
  586. if _, ok := axisToConfigs[axis]; !ok {
  587. axisToConfigs[axis] = map[string]bool{}
  588. }
  589. for config, _ := range configMap {
  590. axisToConfigs[axis][config] = true
  591. }
  592. }
  593. }
  594. allAxesAndConfigs(archVariantCompilerProps)
  595. allAxesAndConfigs(archVariantLinkerProps)
  596. allAxesAndConfigs(archVariantLibraryProperties)
  597. compilerAttrs := compilerAttributes{}
  598. linkerAttrs := linkerAttributes{}
  599. for axis, configs := range axisToConfigs {
  600. for config, _ := range configs {
  601. var allHdrs []string
  602. if baseCompilerProps, ok := archVariantCompilerProps[axis][config].(*BaseCompilerProperties); ok {
  603. allHdrs = baseCompilerProps.Generated_headers
  604. if baseCompilerProps.Lex != nil {
  605. compilerAttrs.lexopts.SetSelectValue(axis, config, baseCompilerProps.Lex.Flags)
  606. }
  607. (&compilerAttrs).bp2buildForAxisAndConfig(ctx, axis, config, baseCompilerProps)
  608. }
  609. var exportHdrs []string
  610. if baseLinkerProps, ok := archVariantLinkerProps[axis][config].(*BaseLinkerProperties); ok {
  611. exportHdrs = baseLinkerProps.Export_generated_headers
  612. (&linkerAttrs).bp2buildForAxisAndConfig(ctx, module.Binary(), axis, config, baseLinkerProps)
  613. }
  614. headers := maybePartitionExportedAndImplementationsDeps(ctx, !module.Binary(), allHdrs, exportHdrs, android.BazelLabelForModuleDeps)
  615. implementationHdrs.SetSelectValue(axis, config, headers.implementation)
  616. compilerAttrs.hdrs.SetSelectValue(axis, config, headers.export)
  617. exportIncludes, exportAbsoluteIncludes := includesFromLabelList(headers.export)
  618. compilerAttrs.includes.Includes.SetSelectValue(axis, config, exportIncludes)
  619. compilerAttrs.includes.AbsoluteIncludes.SetSelectValue(axis, config, exportAbsoluteIncludes)
  620. includes, absoluteIncludes := includesFromLabelList(headers.implementation)
  621. currAbsoluteIncludes := compilerAttrs.absoluteIncludes.SelectValue(axis, config)
  622. currAbsoluteIncludes = android.FirstUniqueStrings(append(currAbsoluteIncludes, absoluteIncludes...))
  623. compilerAttrs.absoluteIncludes.SetSelectValue(axis, config, currAbsoluteIncludes)
  624. currIncludes := compilerAttrs.localIncludes.SelectValue(axis, config)
  625. currIncludes = android.FirstUniqueStrings(append(currIncludes, includes...))
  626. compilerAttrs.localIncludes.SetSelectValue(axis, config, currIncludes)
  627. if libraryProps, ok := archVariantLibraryProperties[axis][config].(*LibraryProperties); ok {
  628. if axis == bazel.NoConfigAxis {
  629. compilerAttrs.stubsSymbolFile = libraryProps.Stubs.Symbol_file
  630. compilerAttrs.stubsVersions.SetSelectValue(axis, config, libraryProps.Stubs.Versions)
  631. }
  632. if suffix := libraryProps.Suffix; suffix != nil {
  633. compilerAttrs.suffix.SetSelectValue(axis, config, suffix)
  634. }
  635. }
  636. }
  637. }
  638. compilerAttrs.convertStlProps(ctx, module)
  639. (&linkerAttrs).convertStripProps(ctx, module)
  640. if module.coverage != nil && module.coverage.Properties.Native_coverage != nil &&
  641. !Bool(module.coverage.Properties.Native_coverage) {
  642. // Native_coverage is arch neutral
  643. (&linkerAttrs).features.Append(bazel.MakeStringListAttribute([]string{"-coverage"}))
  644. }
  645. productVariableProps := android.ProductVariableProperties(ctx)
  646. (&compilerAttrs).convertProductVariables(ctx, productVariableProps)
  647. (&linkerAttrs).convertProductVariables(ctx, productVariableProps)
  648. (&compilerAttrs).finalize(ctx, implementationHdrs)
  649. (&linkerAttrs).finalize(ctx)
  650. (&compilerAttrs.srcs).Add(bp2BuildYasm(ctx, module, compilerAttrs))
  651. protoDep := bp2buildProto(ctx, module, compilerAttrs.protoSrcs)
  652. // bp2buildProto will only set wholeStaticLib or implementationWholeStaticLib, but we don't know
  653. // which. This will add the newly generated proto library to the appropriate attribute and nothing
  654. // to the other
  655. (&linkerAttrs).wholeArchiveDeps.Add(protoDep.wholeStaticLib)
  656. (&linkerAttrs).implementationWholeArchiveDeps.Add(protoDep.implementationWholeStaticLib)
  657. aidlDep := bp2buildCcAidlLibrary(ctx, module, compilerAttrs.aidlSrcs, linkerAttrs)
  658. if aidlDep != nil {
  659. if lib, ok := module.linker.(*libraryDecorator); ok {
  660. if proptools.Bool(lib.Properties.Aidl.Export_aidl_headers) {
  661. (&linkerAttrs).wholeArchiveDeps.Add(aidlDep)
  662. } else {
  663. (&linkerAttrs).implementationWholeArchiveDeps.Add(aidlDep)
  664. }
  665. }
  666. }
  667. convertedLSrcs := bp2BuildLex(ctx, module.Name(), compilerAttrs)
  668. (&compilerAttrs).srcs.Add(&convertedLSrcs.srcName)
  669. (&compilerAttrs).cSrcs.Add(&convertedLSrcs.cSrcName)
  670. if !compilerAttrs.syspropSrcs.IsEmpty() {
  671. (&linkerAttrs).wholeArchiveDeps.Add(bp2buildCcSysprop(ctx, module.Name(), module.Properties.Min_sdk_version, compilerAttrs.syspropSrcs))
  672. }
  673. features := compilerAttrs.features.Clone().Append(linkerAttrs.features)
  674. features.DeduplicateAxesFromBase()
  675. return baseAttributes{
  676. compilerAttrs,
  677. linkerAttrs,
  678. *features,
  679. protoDep.protoDep,
  680. aidlDep,
  681. }
  682. }
  683. func bp2buildCcAidlLibrary(
  684. ctx android.Bp2buildMutatorContext,
  685. m *Module,
  686. aidlLabelList bazel.LabelListAttribute,
  687. linkerAttrs linkerAttributes,
  688. ) *bazel.LabelAttribute {
  689. if !aidlLabelList.IsEmpty() {
  690. aidlLibs, aidlSrcs := aidlLabelList.Partition(func(src bazel.Label) bool {
  691. if fg, ok := android.ToFileGroupAsLibrary(ctx, src.OriginalModuleName); ok &&
  692. fg.ShouldConvertToAidlLibrary(ctx) {
  693. return true
  694. }
  695. return false
  696. })
  697. if !aidlSrcs.IsEmpty() {
  698. aidlLibName := m.Name() + "_aidl_library"
  699. ctx.CreateBazelTargetModule(
  700. bazel.BazelTargetModuleProperties{
  701. Rule_class: "aidl_library",
  702. Bzl_load_location: "//build/bazel/rules/aidl:library.bzl",
  703. },
  704. android.CommonAttributes{Name: aidlLibName},
  705. &aidlLibraryAttributes{
  706. Srcs: aidlSrcs,
  707. },
  708. )
  709. aidlLibs.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + aidlLibName}})
  710. }
  711. if !aidlLibs.IsEmpty() {
  712. ccAidlLibrarylabel := m.Name() + "_cc_aidl_library"
  713. // Since cc_aidl_library only needs the dynamic deps (aka shared libs) from the parent cc library for compiling,
  714. // we err on the side of not re-exporting the headers of the dynamic deps from cc_aidl_lirary
  715. // because the parent cc library already has all the dynamic deps
  716. implementationDynamicDeps := bazel.MakeLabelListAttribute(
  717. bazel.AppendBazelLabelLists(
  718. linkerAttrs.dynamicDeps.Value,
  719. linkerAttrs.implementationDynamicDeps.Value,
  720. ),
  721. )
  722. ctx.CreateBazelTargetModule(
  723. bazel.BazelTargetModuleProperties{
  724. Rule_class: "cc_aidl_library",
  725. Bzl_load_location: "//build/bazel/rules/cc:cc_aidl_library.bzl",
  726. },
  727. android.CommonAttributes{Name: ccAidlLibrarylabel},
  728. &ccAidlLibraryAttributes{
  729. Deps: aidlLibs,
  730. Implementation_dynamic_deps: implementationDynamicDeps,
  731. },
  732. )
  733. label := &bazel.LabelAttribute{
  734. Value: &bazel.Label{
  735. Label: ":" + ccAidlLibrarylabel,
  736. },
  737. }
  738. return label
  739. }
  740. }
  741. return nil
  742. }
  743. func bp2BuildParseSdkAttributes(module *Module) sdkAttributes {
  744. return sdkAttributes{
  745. Sdk_version: module.Properties.Sdk_version,
  746. Min_sdk_version: module.Properties.Min_sdk_version,
  747. }
  748. }
  749. type sdkAttributes struct {
  750. Sdk_version *string
  751. Min_sdk_version *string
  752. }
  753. // Convenience struct to hold all attributes parsed from linker properties.
  754. type linkerAttributes struct {
  755. deps bazel.LabelListAttribute
  756. implementationDeps bazel.LabelListAttribute
  757. dynamicDeps bazel.LabelListAttribute
  758. implementationDynamicDeps bazel.LabelListAttribute
  759. runtimeDeps bazel.LabelListAttribute
  760. wholeArchiveDeps bazel.LabelListAttribute
  761. implementationWholeArchiveDeps bazel.LabelListAttribute
  762. systemDynamicDeps bazel.LabelListAttribute
  763. usedSystemDynamicDepAsDynamicDep map[string]bool
  764. linkCrt bazel.BoolAttribute
  765. useLibcrt bazel.BoolAttribute
  766. useVersionLib bazel.BoolAttribute
  767. linkopts bazel.StringListAttribute
  768. additionalLinkerInputs bazel.LabelListAttribute
  769. stripKeepSymbols bazel.BoolAttribute
  770. stripKeepSymbolsAndDebugFrame bazel.BoolAttribute
  771. stripKeepSymbolsList bazel.StringListAttribute
  772. stripAll bazel.BoolAttribute
  773. stripNone bazel.BoolAttribute
  774. features bazel.StringListAttribute
  775. }
  776. var (
  777. soongSystemSharedLibs = []string{"libc", "libm", "libdl"}
  778. versionLib = "libbuildversion"
  779. )
  780. // resolveTargetApex re-adds the shared and static libs in target.apex.exclude_shared|static_libs props to non-apex variant
  781. // since all libs are already excluded by default
  782. func (la *linkerAttributes) resolveTargetApexProp(ctx android.BazelConversionPathContext, isBinary bool, props *BaseLinkerProperties) {
  783. sharedLibsForNonApex := maybePartitionExportedAndImplementationsDeps(
  784. ctx,
  785. true,
  786. props.Target.Apex.Exclude_shared_libs,
  787. props.Export_shared_lib_headers,
  788. bazelLabelForSharedDeps,
  789. )
  790. dynamicDeps := la.dynamicDeps.SelectValue(bazel.InApexAxis, bazel.NonApex)
  791. implDynamicDeps := la.implementationDynamicDeps.SelectValue(bazel.InApexAxis, bazel.NonApex)
  792. (&dynamicDeps).Append(sharedLibsForNonApex.export)
  793. (&implDynamicDeps).Append(sharedLibsForNonApex.implementation)
  794. la.dynamicDeps.SetSelectValue(bazel.InApexAxis, bazel.NonApex, dynamicDeps)
  795. la.implementationDynamicDeps.SetSelectValue(bazel.InApexAxis, bazel.NonApex, implDynamicDeps)
  796. staticLibsForNonApex := maybePartitionExportedAndImplementationsDeps(
  797. ctx,
  798. !isBinary,
  799. props.Target.Apex.Exclude_static_libs,
  800. props.Export_static_lib_headers,
  801. bazelLabelForSharedDeps,
  802. )
  803. deps := la.deps.SelectValue(bazel.InApexAxis, bazel.NonApex)
  804. implDeps := la.implementationDeps.SelectValue(bazel.InApexAxis, bazel.NonApex)
  805. (&deps).Append(staticLibsForNonApex.export)
  806. (&implDeps).Append(staticLibsForNonApex.implementation)
  807. la.deps.SetSelectValue(bazel.InApexAxis, bazel.NonApex, deps)
  808. la.implementationDeps.SetSelectValue(bazel.InApexAxis, bazel.NonApex, implDeps)
  809. }
  810. func (la *linkerAttributes) bp2buildForAxisAndConfig(ctx android.BazelConversionPathContext, isBinary bool, axis bazel.ConfigurationAxis, config string, props *BaseLinkerProperties) {
  811. // Use a single variable to capture usage of nocrt in arch variants, so there's only 1 error message for this module
  812. var axisFeatures []string
  813. wholeStaticLibs := android.FirstUniqueStrings(props.Whole_static_libs)
  814. staticLibs := android.FirstUniqueStrings(android.RemoveListFromList(props.Static_libs, wholeStaticLibs))
  815. if axis == bazel.NoConfigAxis {
  816. la.useVersionLib.SetSelectValue(axis, config, props.Use_version_lib)
  817. if proptools.Bool(props.Use_version_lib) {
  818. versionLibAlreadyInDeps := android.InList(versionLib, wholeStaticLibs)
  819. // remove from static libs so there is no duplicate dependency
  820. _, staticLibs = android.RemoveFromList(versionLib, staticLibs)
  821. // only add the dep if it is not in progress
  822. if !versionLibAlreadyInDeps {
  823. if isBinary {
  824. wholeStaticLibs = append(wholeStaticLibs, versionLib)
  825. } else {
  826. la.implementationWholeArchiveDeps.SetSelectValue(axis, config, bazelLabelForWholeDepsExcludes(ctx, []string{versionLib}, props.Exclude_static_libs))
  827. }
  828. }
  829. }
  830. }
  831. // Excludes to parallel Soong:
  832. // https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/linker.go;l=247-249;drc=088b53577dde6e40085ffd737a1ae96ad82fc4b0
  833. la.wholeArchiveDeps.SetSelectValue(axis, config, bazelLabelForWholeDepsExcludes(ctx, wholeStaticLibs, props.Exclude_static_libs))
  834. staticDeps := maybePartitionExportedAndImplementationsDepsExcludes(
  835. ctx,
  836. !isBinary,
  837. staticLibs,
  838. // Exclude static libs in Exclude_static_libs and Target.Apex.Exclude_static_libs props
  839. append(props.Exclude_static_libs, props.Target.Apex.Exclude_static_libs...),
  840. props.Export_static_lib_headers,
  841. bazelLabelForStaticDepsExcludes,
  842. )
  843. headerLibs := android.FirstUniqueStrings(props.Header_libs)
  844. hDeps := maybePartitionExportedAndImplementationsDeps(ctx, !isBinary, headerLibs, props.Export_header_lib_headers, bazelLabelForHeaderDeps)
  845. (&hDeps.export).Append(staticDeps.export)
  846. la.deps.SetSelectValue(axis, config, hDeps.export)
  847. (&hDeps.implementation).Append(staticDeps.implementation)
  848. la.implementationDeps.SetSelectValue(axis, config, hDeps.implementation)
  849. systemSharedLibs := props.System_shared_libs
  850. // systemSharedLibs distinguishes between nil/empty list behavior:
  851. // nil -> use default values
  852. // empty list -> no values specified
  853. if len(systemSharedLibs) > 0 {
  854. systemSharedLibs = android.FirstUniqueStrings(systemSharedLibs)
  855. }
  856. la.systemDynamicDeps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, systemSharedLibs))
  857. sharedLibs := android.FirstUniqueStrings(props.Shared_libs)
  858. excludeSharedLibs := props.Exclude_shared_libs
  859. usedSystem := android.FilterListPred(sharedLibs, func(s string) bool {
  860. return android.InList(s, soongSystemSharedLibs) && !android.InList(s, excludeSharedLibs)
  861. })
  862. for _, el := range usedSystem {
  863. if la.usedSystemDynamicDepAsDynamicDep == nil {
  864. la.usedSystemDynamicDepAsDynamicDep = map[string]bool{}
  865. }
  866. la.usedSystemDynamicDepAsDynamicDep[el] = true
  867. }
  868. sharedDeps := maybePartitionExportedAndImplementationsDepsExcludes(
  869. ctx,
  870. !isBinary,
  871. sharedLibs,
  872. // Exclude shared libs in Exclude_shared_libs and Target.Apex.Exclude_shared_libs props
  873. append(props.Exclude_shared_libs, props.Target.Apex.Exclude_shared_libs...),
  874. props.Export_shared_lib_headers,
  875. bazelLabelForSharedDepsExcludes,
  876. )
  877. la.dynamicDeps.SetSelectValue(axis, config, sharedDeps.export)
  878. la.implementationDynamicDeps.SetSelectValue(axis, config, sharedDeps.implementation)
  879. la.resolveTargetApexProp(ctx, isBinary, props)
  880. if axis == bazel.NoConfigAxis || (axis == bazel.OsConfigurationAxis && config == bazel.OsAndroid) {
  881. // If a dependency in la.implementationDynamicDeps has stubs, its stub variant should be
  882. // used when the dependency is linked in a APEX. The dependencies in NoConfigAxis and
  883. // OsConfigurationAxis/OsAndroid are grouped by having stubs or not, so Bazel select()
  884. // statement can be used to choose source/stub variants of them.
  885. depsWithStubs := []bazel.Label{}
  886. for _, l := range sharedDeps.implementation.Includes {
  887. dep, _ := ctx.ModuleFromName(l.OriginalModuleName)
  888. if m, ok := dep.(*Module); ok && m.HasStubsVariants() {
  889. depsWithStubs = append(depsWithStubs, l)
  890. }
  891. }
  892. if len(depsWithStubs) > 0 {
  893. implDynamicDeps := bazel.SubtractBazelLabelList(sharedDeps.implementation, bazel.MakeLabelList(depsWithStubs))
  894. la.implementationDynamicDeps.SetSelectValue(axis, config, implDynamicDeps)
  895. stubLibLabels := []bazel.Label{}
  896. for _, l := range depsWithStubs {
  897. l.Label = l.Label + stubsSuffix
  898. stubLibLabels = append(stubLibLabels, l)
  899. }
  900. inApexSelectValue := la.implementationDynamicDeps.SelectValue(bazel.OsAndInApexAxis, bazel.AndroidAndInApex)
  901. nonApexSelectValue := la.implementationDynamicDeps.SelectValue(bazel.OsAndInApexAxis, bazel.AndroidAndNonApex)
  902. defaultSelectValue := la.implementationDynamicDeps.SelectValue(bazel.OsAndInApexAxis, bazel.ConditionsDefaultConfigKey)
  903. if axis == bazel.NoConfigAxis {
  904. (&inApexSelectValue).Append(bazel.MakeLabelList(stubLibLabels))
  905. (&nonApexSelectValue).Append(bazel.MakeLabelList(depsWithStubs))
  906. (&defaultSelectValue).Append(bazel.MakeLabelList(depsWithStubs))
  907. la.implementationDynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, bazel.AndroidAndInApex, bazel.FirstUniqueBazelLabelList(inApexSelectValue))
  908. la.implementationDynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, bazel.AndroidAndNonApex, bazel.FirstUniqueBazelLabelList(nonApexSelectValue))
  909. la.implementationDynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, bazel.ConditionsDefaultConfigKey, bazel.FirstUniqueBazelLabelList(defaultSelectValue))
  910. } else if config == bazel.OsAndroid {
  911. (&inApexSelectValue).Append(bazel.MakeLabelList(stubLibLabels))
  912. (&nonApexSelectValue).Append(bazel.MakeLabelList(depsWithStubs))
  913. la.implementationDynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, bazel.AndroidAndInApex, bazel.FirstUniqueBazelLabelList(inApexSelectValue))
  914. la.implementationDynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, bazel.AndroidAndNonApex, bazel.FirstUniqueBazelLabelList(nonApexSelectValue))
  915. }
  916. }
  917. }
  918. if !BoolDefault(props.Pack_relocations, packRelocationsDefault) {
  919. axisFeatures = append(axisFeatures, "disable_pack_relocations")
  920. }
  921. if Bool(props.Allow_undefined_symbols) {
  922. axisFeatures = append(axisFeatures, "-no_undefined_symbols")
  923. }
  924. var linkerFlags []string
  925. if len(props.Ldflags) > 0 {
  926. linkerFlags = append(linkerFlags, proptools.NinjaEscapeList(props.Ldflags)...)
  927. // binaries remove static flag if -shared is in the linker flags
  928. if isBinary && android.InList("-shared", linkerFlags) {
  929. axisFeatures = append(axisFeatures, "-static_flag")
  930. }
  931. }
  932. // This must happen before the addition of flags for Version Script and
  933. // Dynamic List, as these flags must be split on spaces and those must not
  934. linkerFlags = parseCommandLineFlags(linkerFlags, filterOutClangUnknownCflags)
  935. additionalLinkerInputs := bazel.LabelList{}
  936. if props.Version_script != nil {
  937. label := android.BazelLabelForModuleSrcSingle(ctx, *props.Version_script)
  938. additionalLinkerInputs.Add(&label)
  939. linkerFlags = append(linkerFlags, fmt.Sprintf("-Wl,--version-script,$(location %s)", label.Label))
  940. }
  941. if props.Dynamic_list != nil {
  942. label := android.BazelLabelForModuleSrcSingle(ctx, *props.Dynamic_list)
  943. additionalLinkerInputs.Add(&label)
  944. linkerFlags = append(linkerFlags, fmt.Sprintf("-Wl,--dynamic-list,$(location %s)", label.Label))
  945. }
  946. la.additionalLinkerInputs.SetSelectValue(axis, config, additionalLinkerInputs)
  947. la.linkopts.SetSelectValue(axis, config, linkerFlags)
  948. la.useLibcrt.SetSelectValue(axis, config, props.libCrt())
  949. // it's very unlikely for nocrt to be arch variant, so bp2build doesn't support it.
  950. if props.crt() != nil {
  951. if axis == bazel.NoConfigAxis {
  952. la.linkCrt.SetSelectValue(axis, config, props.crt())
  953. } else if axis == bazel.ArchConfigurationAxis {
  954. ctx.ModuleErrorf("nocrt is not supported for arch variants")
  955. }
  956. }
  957. if axisFeatures != nil {
  958. la.features.SetSelectValue(axis, config, axisFeatures)
  959. }
  960. runtimeDeps := android.BazelLabelForModuleDepsExcludes(ctx, props.Runtime_libs, props.Exclude_runtime_libs)
  961. if !runtimeDeps.IsEmpty() {
  962. la.runtimeDeps.SetSelectValue(axis, config, runtimeDeps)
  963. }
  964. }
  965. func (la *linkerAttributes) convertStripProps(ctx android.BazelConversionPathContext, module *Module) {
  966. bp2BuildPropParseHelper(ctx, module, &StripProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
  967. if stripProperties, ok := props.(*StripProperties); ok {
  968. la.stripKeepSymbols.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols)
  969. la.stripKeepSymbolsList.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols_list)
  970. la.stripKeepSymbolsAndDebugFrame.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols_and_debug_frame)
  971. la.stripAll.SetSelectValue(axis, config, stripProperties.Strip.All)
  972. la.stripNone.SetSelectValue(axis, config, stripProperties.Strip.None)
  973. }
  974. })
  975. }
  976. func (la *linkerAttributes) convertProductVariables(ctx android.BazelConversionPathContext, productVariableProps android.ProductConfigProperties) {
  977. type productVarDep struct {
  978. // the name of the corresponding excludes field, if one exists
  979. excludesField string
  980. // reference to the bazel attribute that should be set for the given product variable config
  981. attribute *bazel.LabelListAttribute
  982. depResolutionFunc func(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList
  983. }
  984. // an intermediate attribute that holds Header_libs info, and will be appended to
  985. // implementationDeps at the end, to solve the confliction that both header_libs
  986. // and static_libs use implementationDeps.
  987. var headerDeps bazel.LabelListAttribute
  988. productVarToDepFields := map[string]productVarDep{
  989. // product variables do not support exclude_shared_libs
  990. "Shared_libs": {attribute: &la.implementationDynamicDeps, depResolutionFunc: bazelLabelForSharedDepsExcludes},
  991. "Static_libs": {"Exclude_static_libs", &la.implementationDeps, bazelLabelForStaticDepsExcludes},
  992. "Whole_static_libs": {"Exclude_static_libs", &la.wholeArchiveDeps, bazelLabelForWholeDepsExcludes},
  993. "Header_libs": {attribute: &headerDeps, depResolutionFunc: bazelLabelForHeaderDepsExcludes},
  994. }
  995. for name, dep := range productVarToDepFields {
  996. props, exists := productVariableProps[name]
  997. excludeProps, excludesExists := productVariableProps[dep.excludesField]
  998. // if neither an include or excludes property exists, then skip it
  999. if !exists && !excludesExists {
  1000. continue
  1001. }
  1002. // Collect all the configurations that an include or exclude property exists for.
  1003. // We want to iterate all configurations rather than either the include or exclude because, for a
  1004. // particular configuration, we may have either only an include or an exclude to handle.
  1005. productConfigProps := make(map[android.ProductConfigProperty]bool, len(props)+len(excludeProps))
  1006. for p := range props {
  1007. productConfigProps[p] = true
  1008. }
  1009. for p := range excludeProps {
  1010. productConfigProps[p] = true
  1011. }
  1012. for productConfigProp := range productConfigProps {
  1013. prop, includesExists := props[productConfigProp]
  1014. excludesProp, excludesExists := excludeProps[productConfigProp]
  1015. var includes, excludes []string
  1016. var ok bool
  1017. // if there was no includes/excludes property, casting fails and that's expected
  1018. if includes, ok = prop.([]string); includesExists && !ok {
  1019. ctx.ModuleErrorf("Could not convert product variable %s property", name)
  1020. }
  1021. if excludes, ok = excludesProp.([]string); excludesExists && !ok {
  1022. ctx.ModuleErrorf("Could not convert product variable %s property", dep.excludesField)
  1023. }
  1024. dep.attribute.EmitEmptyList = productConfigProp.AlwaysEmit()
  1025. dep.attribute.SetSelectValue(
  1026. productConfigProp.ConfigurationAxis(),
  1027. productConfigProp.SelectKey(),
  1028. dep.depResolutionFunc(ctx, android.FirstUniqueStrings(includes), excludes),
  1029. )
  1030. }
  1031. }
  1032. la.implementationDeps.Append(headerDeps)
  1033. }
  1034. func (la *linkerAttributes) finalize(ctx android.BazelConversionPathContext) {
  1035. // if system dynamic deps have the default value, any use of a system dynamic library used will
  1036. // result in duplicate library errors for bionic OSes. Here, we explicitly exclude those libraries
  1037. // from bionic OSes and the no config case as these libraries only build for bionic OSes.
  1038. if la.systemDynamicDeps.IsNil() && len(la.usedSystemDynamicDepAsDynamicDep) > 0 {
  1039. toRemove := bazelLabelForSharedDeps(ctx, android.SortedStringKeys(la.usedSystemDynamicDepAsDynamicDep))
  1040. la.dynamicDeps.Exclude(bazel.NoConfigAxis, "", toRemove)
  1041. la.dynamicDeps.Exclude(bazel.OsConfigurationAxis, "android", toRemove)
  1042. la.dynamicDeps.Exclude(bazel.OsConfigurationAxis, "linux_bionic", toRemove)
  1043. la.implementationDynamicDeps.Exclude(bazel.NoConfigAxis, "", toRemove)
  1044. la.implementationDynamicDeps.Exclude(bazel.OsConfigurationAxis, "android", toRemove)
  1045. la.implementationDynamicDeps.Exclude(bazel.OsConfigurationAxis, "linux_bionic", toRemove)
  1046. la.implementationDynamicDeps.Exclude(bazel.OsAndInApexAxis, bazel.ConditionsDefaultConfigKey, toRemove)
  1047. la.implementationDynamicDeps.Exclude(bazel.OsAndInApexAxis, bazel.AndroidAndNonApex, toRemove)
  1048. stubsToRemove := make([]bazel.Label, 0, len(la.usedSystemDynamicDepAsDynamicDep))
  1049. for _, lib := range toRemove.Includes {
  1050. lib.Label += stubsSuffix
  1051. stubsToRemove = append(stubsToRemove, lib)
  1052. }
  1053. la.implementationDynamicDeps.Exclude(bazel.OsAndInApexAxis, bazel.AndroidAndInApex, bazel.MakeLabelList(stubsToRemove))
  1054. }
  1055. la.deps.ResolveExcludes()
  1056. la.implementationDeps.ResolveExcludes()
  1057. la.dynamicDeps.ResolveExcludes()
  1058. la.implementationDynamicDeps.ResolveExcludes()
  1059. la.wholeArchiveDeps.ResolveExcludes()
  1060. la.systemDynamicDeps.ForceSpecifyEmptyList = true
  1061. }
  1062. // Relativize a list of root-relative paths with respect to the module's
  1063. // directory.
  1064. //
  1065. // include_dirs Soong prop are root-relative (b/183742505), but
  1066. // local_include_dirs, export_include_dirs and export_system_include_dirs are
  1067. // module dir relative. This function makes a list of paths entirely module dir
  1068. // relative.
  1069. //
  1070. // For the `include` attribute, Bazel wants the paths to be relative to the
  1071. // module.
  1072. func bp2BuildMakePathsRelativeToModule(ctx android.BazelConversionPathContext, paths []string) []string {
  1073. var relativePaths []string
  1074. for _, path := range paths {
  1075. // Semantics of filepath.Rel: join(ModuleDir, rel(ModuleDir, path)) == path
  1076. relativePath, err := filepath.Rel(ctx.ModuleDir(), path)
  1077. if err != nil {
  1078. panic(err)
  1079. }
  1080. relativePaths = append(relativePaths, relativePath)
  1081. }
  1082. return relativePaths
  1083. }
  1084. // BazelIncludes contains information about -I and -isystem paths from a module converted to Bazel
  1085. // attributes.
  1086. type BazelIncludes struct {
  1087. AbsoluteIncludes bazel.StringListAttribute
  1088. Includes bazel.StringListAttribute
  1089. SystemIncludes bazel.StringListAttribute
  1090. }
  1091. func bp2BuildParseExportedIncludes(ctx android.BazelConversionPathContext, module *Module, includes *BazelIncludes) BazelIncludes {
  1092. var exported BazelIncludes
  1093. if includes != nil {
  1094. exported = *includes
  1095. } else {
  1096. exported = BazelIncludes{}
  1097. }
  1098. bp2BuildPropParseHelper(ctx, module, &FlagExporterProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
  1099. if flagExporterProperties, ok := props.(*FlagExporterProperties); ok {
  1100. if len(flagExporterProperties.Export_include_dirs) > 0 {
  1101. exported.Includes.SetSelectValue(axis, config, android.FirstUniqueStrings(append(exported.Includes.SelectValue(axis, config), flagExporterProperties.Export_include_dirs...)))
  1102. }
  1103. if len(flagExporterProperties.Export_system_include_dirs) > 0 {
  1104. exported.SystemIncludes.SetSelectValue(axis, config, android.FirstUniqueStrings(append(exported.SystemIncludes.SelectValue(axis, config), flagExporterProperties.Export_system_include_dirs...)))
  1105. }
  1106. }
  1107. })
  1108. exported.AbsoluteIncludes.DeduplicateAxesFromBase()
  1109. exported.Includes.DeduplicateAxesFromBase()
  1110. exported.SystemIncludes.DeduplicateAxesFromBase()
  1111. return exported
  1112. }
  1113. func BazelLabelNameForStaticModule(baseLabel string) string {
  1114. return baseLabel + "_bp2build_cc_library_static"
  1115. }
  1116. func bazelLabelForStaticModule(ctx android.BazelConversionPathContext, m blueprint.Module) string {
  1117. label := android.BazelModuleLabel(ctx, m)
  1118. if ccModule, ok := m.(*Module); ok && ccModule.typ() == fullLibrary && !android.GetBp2BuildAllowList().GenerateCcLibraryStaticOnly(m.Name()) {
  1119. return BazelLabelNameForStaticModule(label)
  1120. }
  1121. return label
  1122. }
  1123. func bazelLabelForSharedModule(ctx android.BazelConversionPathContext, m blueprint.Module) string {
  1124. // cc_library, at it's root name, propagates the shared library, which depends on the static
  1125. // library.
  1126. return android.BazelModuleLabel(ctx, m)
  1127. }
  1128. func bazelLabelForStaticWholeModuleDeps(ctx android.BazelConversionPathContext, m blueprint.Module) string {
  1129. label := bazelLabelForStaticModule(ctx, m)
  1130. if aModule, ok := m.(android.Module); ok {
  1131. if android.IsModulePrebuilt(aModule) {
  1132. label += "_alwayslink"
  1133. }
  1134. }
  1135. return label
  1136. }
  1137. func bazelLabelForWholeDeps(ctx android.BazelConversionPathContext, modules []string) bazel.LabelList {
  1138. return android.BazelLabelForModuleDepsWithFn(ctx, modules, bazelLabelForStaticWholeModuleDeps)
  1139. }
  1140. func bazelLabelForWholeDepsExcludes(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList {
  1141. return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForStaticWholeModuleDeps)
  1142. }
  1143. func bazelLabelForStaticDepsExcludes(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList {
  1144. return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForStaticModule)
  1145. }
  1146. func bazelLabelForStaticDeps(ctx android.BazelConversionPathContext, modules []string) bazel.LabelList {
  1147. return android.BazelLabelForModuleDepsWithFn(ctx, modules, bazelLabelForStaticModule)
  1148. }
  1149. func bazelLabelForSharedDeps(ctx android.BazelConversionPathContext, modules []string) bazel.LabelList {
  1150. return android.BazelLabelForModuleDepsWithFn(ctx, modules, bazelLabelForSharedModule)
  1151. }
  1152. func bazelLabelForHeaderDeps(ctx android.BazelConversionPathContext, modules []string) bazel.LabelList {
  1153. // This is not elegant, but bp2build's shared library targets only propagate
  1154. // their header information as part of the normal C++ provider.
  1155. return bazelLabelForSharedDeps(ctx, modules)
  1156. }
  1157. func bazelLabelForHeaderDepsExcludes(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList {
  1158. // This is only used when product_variable header_libs is processed, to follow
  1159. // the pattern of depResolutionFunc
  1160. return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForSharedModule)
  1161. }
  1162. func bazelLabelForSharedDepsExcludes(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList {
  1163. return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForSharedModule)
  1164. }
  1165. type binaryLinkerAttrs struct {
  1166. Linkshared *bool
  1167. Suffix bazel.StringAttribute
  1168. }
  1169. func bp2buildBinaryLinkerProps(ctx android.BazelConversionPathContext, m *Module) binaryLinkerAttrs {
  1170. attrs := binaryLinkerAttrs{}
  1171. bp2BuildPropParseHelper(ctx, m, &BinaryLinkerProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
  1172. linkerProps := props.(*BinaryLinkerProperties)
  1173. staticExecutable := linkerProps.Static_executable
  1174. if axis == bazel.NoConfigAxis {
  1175. if linkBinaryShared := !proptools.Bool(staticExecutable); !linkBinaryShared {
  1176. attrs.Linkshared = &linkBinaryShared
  1177. }
  1178. } else if staticExecutable != nil {
  1179. // TODO(b/202876379): Static_executable is arch-variant; however, linkshared is a
  1180. // nonconfigurable attribute. Only 4 AOSP modules use this feature, defer handling
  1181. ctx.ModuleErrorf("bp2build cannot migrate a module with arch/target-specific static_executable values")
  1182. }
  1183. if suffix := linkerProps.Suffix; suffix != nil {
  1184. attrs.Suffix.SetSelectValue(axis, config, suffix)
  1185. }
  1186. })
  1187. return attrs
  1188. }