testing.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686
  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 bp2build
  15. /*
  16. For shareable/common bp2build testing functionality and dumping ground for
  17. specific-but-shared functionality among tests in package
  18. */
  19. import (
  20. "fmt"
  21. "sort"
  22. "strings"
  23. "testing"
  24. "github.com/google/blueprint/proptools"
  25. "android/soong/android"
  26. "android/soong/android/allowlists"
  27. "android/soong/bazel"
  28. )
  29. var (
  30. buildDir string
  31. )
  32. func checkError(t *testing.T, errs []error, expectedErr error) bool {
  33. t.Helper()
  34. if len(errs) != 1 {
  35. return false
  36. }
  37. if strings.Contains(errs[0].Error(), expectedErr.Error()) {
  38. return true
  39. }
  40. return false
  41. }
  42. func errored(t *testing.T, tc Bp2buildTestCase, errs []error) bool {
  43. t.Helper()
  44. if tc.ExpectedErr != nil {
  45. // Rely on checkErrors, as this test case is expected to have an error.
  46. return false
  47. }
  48. if len(errs) > 0 {
  49. for _, err := range errs {
  50. t.Errorf("%s: %s", tc.Description, err)
  51. }
  52. return true
  53. }
  54. // All good, continue execution.
  55. return false
  56. }
  57. func RunBp2BuildTestCaseSimple(t *testing.T, tc Bp2buildTestCase) {
  58. t.Helper()
  59. RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, tc)
  60. }
  61. type Bp2buildTestCase struct {
  62. Description string
  63. ModuleTypeUnderTest string
  64. ModuleTypeUnderTestFactory android.ModuleFactory
  65. Blueprint string
  66. ExpectedBazelTargets []string
  67. Filesystem map[string]string
  68. Dir string
  69. // An error with a string contained within the string of the expected error
  70. ExpectedErr error
  71. UnconvertedDepsMode unconvertedDepsMode
  72. // For every directory listed here, the BUILD file for that directory will
  73. // be merged with the generated BUILD file. This allows custom BUILD targets
  74. // to be used in tests, or use BUILD files to draw package boundaries.
  75. KeepBuildFileForDirs []string
  76. }
  77. func RunBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc Bp2buildTestCase) {
  78. t.Helper()
  79. bp2buildSetup := android.GroupFixturePreparers(
  80. android.FixtureRegisterWithContext(registerModuleTypes),
  81. SetBp2BuildTestRunner,
  82. )
  83. runBp2BuildTestCaseWithSetup(t, bp2buildSetup, tc)
  84. }
  85. func RunApiBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc Bp2buildTestCase) {
  86. t.Helper()
  87. apiBp2BuildSetup := android.GroupFixturePreparers(
  88. android.FixtureRegisterWithContext(registerModuleTypes),
  89. SetApiBp2BuildTestRunner,
  90. )
  91. runBp2BuildTestCaseWithSetup(t, apiBp2BuildSetup, tc)
  92. }
  93. func runBp2BuildTestCaseWithSetup(t *testing.T, extraPreparer android.FixturePreparer, tc Bp2buildTestCase) {
  94. t.Helper()
  95. dir := "."
  96. filesystem := make(map[string][]byte)
  97. for f, content := range tc.Filesystem {
  98. filesystem[f] = []byte(content)
  99. }
  100. preparers := []android.FixturePreparer{
  101. extraPreparer,
  102. android.FixtureMergeMockFs(filesystem),
  103. android.FixtureWithRootAndroidBp(tc.Blueprint),
  104. android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
  105. ctx.RegisterModuleType(tc.ModuleTypeUnderTest, tc.ModuleTypeUnderTestFactory)
  106. }),
  107. android.FixtureModifyContext(func(ctx *android.TestContext) {
  108. // A default configuration for tests to not have to specify bp2build_available on top level
  109. // targets.
  110. bp2buildConfig := android.NewBp2BuildAllowlist().SetDefaultConfig(
  111. allowlists.Bp2BuildConfig{
  112. android.Bp2BuildTopLevel: allowlists.Bp2BuildDefaultTrueRecursively,
  113. },
  114. )
  115. for _, f := range tc.KeepBuildFileForDirs {
  116. bp2buildConfig.SetKeepExistingBuildFile(map[string]bool{
  117. f: /*recursive=*/ false,
  118. })
  119. }
  120. ctx.RegisterBp2BuildConfig(bp2buildConfig)
  121. }),
  122. android.FixtureModifyEnv(func(env map[string]string) {
  123. if tc.UnconvertedDepsMode == errorModulesUnconvertedDeps {
  124. env["BP2BUILD_ERROR_UNCONVERTED"] = "true"
  125. }
  126. }),
  127. }
  128. preparer := android.GroupFixturePreparers(preparers...)
  129. if tc.ExpectedErr != nil {
  130. pattern := "\\Q" + tc.ExpectedErr.Error() + "\\E"
  131. preparer = preparer.ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(pattern))
  132. }
  133. result := preparer.RunTestWithCustomResult(t).(*BazelTestResult)
  134. if len(result.Errs) > 0 {
  135. return
  136. }
  137. checkDir := dir
  138. if tc.Dir != "" {
  139. checkDir = tc.Dir
  140. }
  141. expectedTargets := map[string][]string{
  142. checkDir: tc.ExpectedBazelTargets,
  143. }
  144. result.CompareAllBazelTargets(t, tc.Description, expectedTargets, true)
  145. }
  146. // SetBp2BuildTestRunner customizes the test fixture mechanism to run tests in Bp2Build mode.
  147. var SetBp2BuildTestRunner = android.FixtureSetTestRunner(&bazelTestRunner{Bp2Build})
  148. // SetApiBp2BuildTestRunner customizes the test fixture mechanism to run tests in ApiBp2build mode.
  149. var SetApiBp2BuildTestRunner = android.FixtureSetTestRunner(&bazelTestRunner{ApiBp2build})
  150. // bazelTestRunner customizes the test fixture mechanism to run tests of the bp2build and
  151. // apiBp2build build modes.
  152. type bazelTestRunner struct {
  153. mode CodegenMode
  154. }
  155. func (b *bazelTestRunner) FinalPreparer(result *android.TestResult) android.CustomTestResult {
  156. ctx := result.TestContext
  157. switch b.mode {
  158. case Bp2Build:
  159. ctx.RegisterForBazelConversion()
  160. case ApiBp2build:
  161. ctx.RegisterForApiBazelConversion()
  162. default:
  163. panic(fmt.Errorf("unknown build mode: %d", b.mode))
  164. }
  165. return &BazelTestResult{TestResult: result}
  166. }
  167. func (b *bazelTestRunner) PostParseProcessor(result android.CustomTestResult) {
  168. bazelResult := result.(*BazelTestResult)
  169. ctx := bazelResult.TestContext
  170. config := bazelResult.Config
  171. _, errs := ctx.ResolveDependencies(config)
  172. if bazelResult.CollateErrs(errs) {
  173. return
  174. }
  175. codegenCtx := NewCodegenContext(config, ctx.Context, Bp2Build, "")
  176. res, errs := GenerateBazelTargets(codegenCtx, false)
  177. if bazelResult.CollateErrs(errs) {
  178. return
  179. }
  180. // Store additional data for access by tests.
  181. bazelResult.conversionResults = res
  182. }
  183. // BazelTestResult is a wrapper around android.TestResult to provide type safe access to the bazel
  184. // specific data stored by the bazelTestRunner.
  185. type BazelTestResult struct {
  186. *android.TestResult
  187. // The result returned by the GenerateBazelTargets function.
  188. conversionResults
  189. }
  190. // CompareAllBazelTargets compares the BazelTargets produced by the test for all the directories
  191. // with the supplied set of expected targets.
  192. //
  193. // If ignoreUnexpected=false then this enforces an exact match where every BazelTarget produced must
  194. // have a corresponding expected BazelTarget.
  195. //
  196. // If ignoreUnexpected=true then it will ignore directories for which there are no expected targets.
  197. func (b BazelTestResult) CompareAllBazelTargets(t *testing.T, description string, expectedTargets map[string][]string, ignoreUnexpected bool) {
  198. t.Helper()
  199. actualTargets := b.buildFileToTargets
  200. // Generate the sorted set of directories to check.
  201. dirsToCheck := android.SortedKeys(expectedTargets)
  202. if !ignoreUnexpected {
  203. // This needs to perform an exact match so add the directories in which targets were
  204. // produced to the list of directories to check.
  205. dirsToCheck = append(dirsToCheck, android.SortedKeys(actualTargets)...)
  206. dirsToCheck = android.SortedUniqueStrings(dirsToCheck)
  207. }
  208. for _, dir := range dirsToCheck {
  209. expected := expectedTargets[dir]
  210. actual := actualTargets[dir]
  211. if expected == nil {
  212. if actual != nil {
  213. t.Errorf("did not expect any bazel modules in %q but found %d", dir, len(actual))
  214. }
  215. } else if actual == nil {
  216. expectedCount := len(expected)
  217. if expectedCount > 0 {
  218. t.Errorf("expected %d bazel modules in %q but did not find any", expectedCount, dir)
  219. }
  220. } else {
  221. b.CompareBazelTargets(t, description, expected, actual)
  222. }
  223. }
  224. }
  225. func (b BazelTestResult) CompareBazelTargets(t *testing.T, description string, expectedContents []string, actualTargets BazelTargets) {
  226. t.Helper()
  227. if actualCount, expectedCount := len(actualTargets), len(expectedContents); actualCount != expectedCount {
  228. t.Errorf("%s: Expected %d bazel target (%s), got %d (%s)",
  229. description, expectedCount, expectedContents, actualCount, actualTargets)
  230. } else {
  231. sort.SliceStable(actualTargets, func(i, j int) bool {
  232. return actualTargets[i].name < actualTargets[j].name
  233. })
  234. sort.SliceStable(expectedContents, func(i, j int) bool {
  235. return getTargetName(expectedContents[i]) < getTargetName(expectedContents[j])
  236. })
  237. for i, actualTarget := range actualTargets {
  238. if w, g := expectedContents[i], actualTarget.content; w != g {
  239. t.Errorf(
  240. "%s[%d]: Expected generated Bazel target to be `%s`, got `%s`",
  241. description, i, w, g)
  242. }
  243. }
  244. }
  245. }
  246. type nestedProps struct {
  247. Nested_prop *string
  248. }
  249. type EmbeddedProps struct {
  250. Embedded_prop *string
  251. }
  252. type OtherEmbeddedProps struct {
  253. Other_embedded_prop *string
  254. }
  255. type customProps struct {
  256. EmbeddedProps
  257. *OtherEmbeddedProps
  258. Bool_prop bool
  259. Bool_ptr_prop *bool
  260. // Ensure that properties tagged `blueprint:mutated` are omitted
  261. Int_prop int `blueprint:"mutated"`
  262. Int64_ptr_prop *int64
  263. String_prop string
  264. String_literal_prop *string `android:"arch_variant"`
  265. String_ptr_prop *string
  266. String_list_prop []string
  267. Nested_props nestedProps
  268. Nested_props_ptr *nestedProps
  269. Arch_paths []string `android:"path,arch_variant"`
  270. Arch_paths_exclude []string `android:"path,arch_variant"`
  271. // Prop used to indicate this conversion should be 1 module -> multiple targets
  272. One_to_many_prop *bool
  273. Api *string // File describing the APIs of this module
  274. Test_config_setting *bool // Used to test generation of config_setting targets
  275. }
  276. type customModule struct {
  277. android.ModuleBase
  278. android.BazelModuleBase
  279. props customProps
  280. }
  281. // OutputFiles is needed because some instances of this module use dist with a
  282. // tag property which requires the module implements OutputFileProducer.
  283. func (m *customModule) OutputFiles(tag string) (android.Paths, error) {
  284. return android.PathsForTesting("path" + tag), nil
  285. }
  286. func (m *customModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
  287. // nothing for now.
  288. }
  289. func customModuleFactoryBase() android.Module {
  290. module := &customModule{}
  291. module.AddProperties(&module.props)
  292. android.InitBazelModule(module)
  293. return module
  294. }
  295. func customModuleFactoryHostAndDevice() android.Module {
  296. m := customModuleFactoryBase()
  297. android.InitAndroidArchModule(m, android.HostAndDeviceSupported, android.MultilibBoth)
  298. return m
  299. }
  300. func customModuleFactoryDeviceSupported() android.Module {
  301. m := customModuleFactoryBase()
  302. android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibBoth)
  303. return m
  304. }
  305. func customModuleFactoryHostSupported() android.Module {
  306. m := customModuleFactoryBase()
  307. android.InitAndroidArchModule(m, android.HostSupported, android.MultilibBoth)
  308. return m
  309. }
  310. func customModuleFactoryHostAndDeviceDefault() android.Module {
  311. m := customModuleFactoryBase()
  312. android.InitAndroidArchModule(m, android.HostAndDeviceDefault, android.MultilibBoth)
  313. return m
  314. }
  315. func customModuleFactoryNeitherHostNorDeviceSupported() android.Module {
  316. m := customModuleFactoryBase()
  317. android.InitAndroidArchModule(m, android.NeitherHostNorDeviceSupported, android.MultilibBoth)
  318. return m
  319. }
  320. type testProps struct {
  321. Test_prop struct {
  322. Test_string_prop string
  323. }
  324. }
  325. type customTestModule struct {
  326. android.ModuleBase
  327. props customProps
  328. test_props testProps
  329. }
  330. func (m *customTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
  331. // nothing for now.
  332. }
  333. func customTestModuleFactoryBase() android.Module {
  334. m := &customTestModule{}
  335. m.AddProperties(&m.props)
  336. m.AddProperties(&m.test_props)
  337. return m
  338. }
  339. func customTestModuleFactory() android.Module {
  340. m := customTestModuleFactoryBase()
  341. android.InitAndroidModule(m)
  342. return m
  343. }
  344. type customDefaultsModule struct {
  345. android.ModuleBase
  346. android.DefaultsModuleBase
  347. }
  348. func customDefaultsModuleFactoryBase() android.DefaultsModule {
  349. module := &customDefaultsModule{}
  350. module.AddProperties(&customProps{})
  351. return module
  352. }
  353. func customDefaultsModuleFactoryBasic() android.Module {
  354. return customDefaultsModuleFactoryBase()
  355. }
  356. func customDefaultsModuleFactory() android.Module {
  357. m := customDefaultsModuleFactoryBase()
  358. android.InitDefaultsModule(m)
  359. return m
  360. }
  361. type EmbeddedAttr struct {
  362. Embedded_attr *string
  363. }
  364. type OtherEmbeddedAttr struct {
  365. Other_embedded_attr *string
  366. }
  367. type customBazelModuleAttributes struct {
  368. EmbeddedAttr
  369. *OtherEmbeddedAttr
  370. String_literal_prop bazel.StringAttribute
  371. String_ptr_prop *string
  372. String_list_prop []string
  373. Arch_paths bazel.LabelListAttribute
  374. Api bazel.LabelAttribute
  375. }
  376. func (m *customModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
  377. if p := m.props.One_to_many_prop; p != nil && *p {
  378. customBp2buildOneToMany(ctx, m)
  379. return
  380. }
  381. paths := bazel.LabelListAttribute{}
  382. strAttr := bazel.StringAttribute{}
  383. for axis, configToProps := range m.GetArchVariantProperties(ctx, &customProps{}) {
  384. for config, props := range configToProps {
  385. if custProps, ok := props.(*customProps); ok {
  386. if custProps.Arch_paths != nil {
  387. paths.SetSelectValue(axis, config, android.BazelLabelForModuleSrcExcludes(ctx, custProps.Arch_paths, custProps.Arch_paths_exclude))
  388. }
  389. if custProps.String_literal_prop != nil {
  390. strAttr.SetSelectValue(axis, config, custProps.String_literal_prop)
  391. }
  392. }
  393. }
  394. }
  395. productVariableProps := android.ProductVariableProperties(ctx, ctx.Module())
  396. if props, ok := productVariableProps["String_literal_prop"]; ok {
  397. for c, p := range props {
  398. if val, ok := p.(*string); ok {
  399. strAttr.SetSelectValue(c.ConfigurationAxis(), c.SelectKey(), val)
  400. }
  401. }
  402. }
  403. paths.ResolveExcludes()
  404. attrs := &customBazelModuleAttributes{
  405. String_literal_prop: strAttr,
  406. String_ptr_prop: m.props.String_ptr_prop,
  407. String_list_prop: m.props.String_list_prop,
  408. Arch_paths: paths,
  409. }
  410. attrs.Embedded_attr = m.props.Embedded_prop
  411. if m.props.OtherEmbeddedProps != nil {
  412. attrs.OtherEmbeddedAttr = &OtherEmbeddedAttr{Other_embedded_attr: m.props.OtherEmbeddedProps.Other_embedded_prop}
  413. }
  414. props := bazel.BazelTargetModuleProperties{
  415. Rule_class: "custom",
  416. }
  417. ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs)
  418. if proptools.Bool(m.props.Test_config_setting) {
  419. m.createConfigSetting(ctx)
  420. }
  421. }
  422. func (m *customModule) createConfigSetting(ctx android.TopDownMutatorContext) {
  423. csa := bazel.ConfigSettingAttributes{
  424. Flag_values: bazel.StringMapAttribute{
  425. "//build/bazel/rules/my_string_setting": m.Name(),
  426. },
  427. }
  428. ca := android.CommonAttributes{
  429. Name: m.Name() + "_config_setting",
  430. }
  431. ctx.CreateBazelConfigSetting(
  432. csa,
  433. ca,
  434. ctx.ModuleDir(),
  435. )
  436. }
  437. var _ android.ApiProvider = (*customModule)(nil)
  438. func (c *customModule) ConvertWithApiBp2build(ctx android.TopDownMutatorContext) {
  439. props := bazel.BazelTargetModuleProperties{
  440. Rule_class: "custom_api_contribution",
  441. }
  442. apiAttribute := bazel.MakeLabelAttribute(
  443. android.BazelLabelForModuleSrcSingle(ctx, proptools.String(c.props.Api)).Label,
  444. )
  445. attrs := &customBazelModuleAttributes{
  446. Api: *apiAttribute,
  447. }
  448. ctx.CreateBazelTargetModule(props,
  449. android.CommonAttributes{Name: c.Name()},
  450. attrs)
  451. }
  452. // A bp2build mutator that uses load statements and creates a 1:M mapping from
  453. // module to target.
  454. func customBp2buildOneToMany(ctx android.TopDownMutatorContext, m *customModule) {
  455. baseName := m.Name()
  456. attrs := &customBazelModuleAttributes{}
  457. myLibraryProps := bazel.BazelTargetModuleProperties{
  458. Rule_class: "my_library",
  459. Bzl_load_location: "//build/bazel/rules:rules.bzl",
  460. }
  461. ctx.CreateBazelTargetModule(myLibraryProps, android.CommonAttributes{Name: baseName}, attrs)
  462. protoLibraryProps := bazel.BazelTargetModuleProperties{
  463. Rule_class: "proto_library",
  464. Bzl_load_location: "//build/bazel/rules:proto.bzl",
  465. }
  466. ctx.CreateBazelTargetModule(protoLibraryProps, android.CommonAttributes{Name: baseName + "_proto_library_deps"}, attrs)
  467. myProtoLibraryProps := bazel.BazelTargetModuleProperties{
  468. Rule_class: "my_proto_library",
  469. Bzl_load_location: "//build/bazel/rules:proto.bzl",
  470. }
  471. ctx.CreateBazelTargetModule(myProtoLibraryProps, android.CommonAttributes{Name: baseName + "_my_proto_library_deps"}, attrs)
  472. }
  473. // Helper method for tests to easily access the targets in a dir.
  474. func generateBazelTargetsForDir(codegenCtx *CodegenContext, dir string) (BazelTargets, []error) {
  475. // TODO: Set generateFilegroups to true and/or remove the generateFilegroups argument completely
  476. res, err := GenerateBazelTargets(codegenCtx, false)
  477. if err != nil {
  478. return BazelTargets{}, err
  479. }
  480. return res.buildFileToTargets[dir], err
  481. }
  482. func registerCustomModuleForBp2buildConversion(ctx *android.TestContext) {
  483. ctx.RegisterModuleType("custom", customModuleFactoryHostAndDevice)
  484. ctx.RegisterForBazelConversion()
  485. }
  486. func simpleModuleDoNotConvertBp2build(typ, name string) string {
  487. return fmt.Sprintf(`
  488. %s {
  489. name: "%s",
  490. bazel_module: { bp2build_available: false },
  491. }`, typ, name)
  492. }
  493. type AttrNameToString map[string]string
  494. func (a AttrNameToString) clone() AttrNameToString {
  495. newAttrs := make(AttrNameToString, len(a))
  496. for k, v := range a {
  497. newAttrs[k] = v
  498. }
  499. return newAttrs
  500. }
  501. // makeBazelTargetNoRestrictions returns bazel target build file definition that can be host or
  502. // device specific, or independent of host/device.
  503. func makeBazelTargetHostOrDevice(typ, name string, attrs AttrNameToString, hod android.HostOrDeviceSupported) string {
  504. if _, ok := attrs["target_compatible_with"]; !ok {
  505. switch hod {
  506. case android.HostSupported:
  507. attrs["target_compatible_with"] = `select({
  508. "//build/bazel/platforms/os:android": ["@platforms//:incompatible"],
  509. "//conditions:default": [],
  510. })`
  511. case android.DeviceSupported:
  512. attrs["target_compatible_with"] = `["//build/bazel/platforms/os:android"]`
  513. }
  514. }
  515. attrStrings := make([]string, 0, len(attrs)+1)
  516. if name != "" {
  517. attrStrings = append(attrStrings, fmt.Sprintf(` name = "%s",`, name))
  518. }
  519. for _, k := range android.SortedKeys(attrs) {
  520. attrStrings = append(attrStrings, fmt.Sprintf(" %s = %s,", k, attrs[k]))
  521. }
  522. return fmt.Sprintf(`%s(
  523. %s
  524. )`, typ, strings.Join(attrStrings, "\n"))
  525. }
  526. // MakeBazelTargetNoRestrictions returns bazel target build file definition that does not add a
  527. // target_compatible_with. This is useful for module types like filegroup and genrule that arch not
  528. // arch variant
  529. func MakeBazelTargetNoRestrictions(typ, name string, attrs AttrNameToString) string {
  530. return makeBazelTargetHostOrDevice(typ, name, attrs, android.HostAndDeviceDefault)
  531. }
  532. // makeBazelTargetNoRestrictions returns bazel target build file definition that is device specific
  533. // as this is the most common default in Soong.
  534. func MakeBazelTarget(typ, name string, attrs AttrNameToString) string {
  535. return makeBazelTargetHostOrDevice(typ, name, attrs, android.DeviceSupported)
  536. }
  537. type ExpectedRuleTarget struct {
  538. Rule string
  539. Name string
  540. Attrs AttrNameToString
  541. Hod android.HostOrDeviceSupported
  542. }
  543. func (ebr ExpectedRuleTarget) String() string {
  544. return makeBazelTargetHostOrDevice(ebr.Rule, ebr.Name, ebr.Attrs, ebr.Hod)
  545. }
  546. func makeCcStubSuiteTargets(name string, attrs AttrNameToString) string {
  547. if _, hasStubs := attrs["stubs_symbol_file"]; !hasStubs {
  548. return ""
  549. }
  550. STUB_SUITE_ATTRS := map[string]string{
  551. "stubs_symbol_file": "symbol_file",
  552. "stubs_versions": "versions",
  553. "soname": "soname",
  554. "source_library_label": "source_library_label",
  555. }
  556. stubSuiteAttrs := AttrNameToString{}
  557. for key, _ := range attrs {
  558. if _, stubSuiteAttr := STUB_SUITE_ATTRS[key]; stubSuiteAttr {
  559. stubSuiteAttrs[STUB_SUITE_ATTRS[key]] = attrs[key]
  560. } else {
  561. panic(fmt.Sprintf("unused cc_stub_suite attr %q\n", key))
  562. }
  563. }
  564. return MakeBazelTarget("cc_stub_suite", name+"_stub_libs", stubSuiteAttrs)
  565. }
  566. func MakeNeverlinkDuplicateTarget(moduleType string, name string) string {
  567. return MakeNeverlinkDuplicateTargetWithAttrs(moduleType, name, AttrNameToString{})
  568. }
  569. func MakeNeverlinkDuplicateTargetWithAttrs(moduleType string, name string, extraAttrs AttrNameToString) string {
  570. attrs := extraAttrs
  571. attrs["neverlink"] = `True`
  572. attrs["exports"] = `[":` + name + `"]`
  573. return MakeBazelTarget(moduleType, name+"-neverlink", attrs)
  574. }
  575. func getTargetName(targetContent string) string {
  576. data := strings.Split(targetContent, "name = \"")
  577. if len(data) < 2 {
  578. return ""
  579. } else {
  580. endIndex := strings.Index(data[1], "\"")
  581. return data[1][:endIndex]
  582. }
  583. }