bp2build.go 52 KB

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