cc_library_headers_conversion_test.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  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. import (
  16. "testing"
  17. "android/soong/android"
  18. "android/soong/cc"
  19. )
  20. const (
  21. // See cc/testing.go for more context
  22. soongCcLibraryHeadersPreamble = `
  23. cc_defaults {
  24. name: "linux_bionic_supported",
  25. }`
  26. )
  27. func TestCcLibraryHeadersLoadStatement(t *testing.T) {
  28. testCases := []struct {
  29. bazelTargets BazelTargets
  30. expectedLoadStatements string
  31. }{
  32. {
  33. bazelTargets: BazelTargets{
  34. BazelTarget{
  35. name: "cc_library_headers_target",
  36. ruleClass: "cc_library_headers",
  37. // Note: no bzlLoadLocation for native rules
  38. },
  39. },
  40. expectedLoadStatements: ``,
  41. },
  42. }
  43. for _, testCase := range testCases {
  44. actual := testCase.bazelTargets.LoadStatements()
  45. expected := testCase.expectedLoadStatements
  46. if actual != expected {
  47. t.Fatalf("Expected load statements to be %s, got %s", expected, actual)
  48. }
  49. }
  50. }
  51. func registerCcLibraryHeadersModuleTypes(ctx android.RegistrationContext) {
  52. cc.RegisterCCBuildComponents(ctx)
  53. }
  54. func runCcLibraryHeadersTestCase(t *testing.T, tc Bp2buildTestCase) {
  55. t.Helper()
  56. RunBp2BuildTestCase(t, registerCcLibraryHeadersModuleTypes, tc)
  57. }
  58. func TestCcLibraryHeadersSimple(t *testing.T) {
  59. runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
  60. Description: "cc_library_headers test",
  61. ModuleTypeUnderTest: "cc_library_headers",
  62. ModuleTypeUnderTestFactory: cc.LibraryHeaderFactory,
  63. Filesystem: map[string]string{
  64. "lib-1/lib1a.h": "",
  65. "lib-1/lib1b.h": "",
  66. "lib-2/lib2a.h": "",
  67. "lib-2/lib2b.h": "",
  68. "dir-1/dir1a.h": "",
  69. "dir-1/dir1b.h": "",
  70. "dir-2/dir2a.h": "",
  71. "dir-2/dir2b.h": "",
  72. "arch_arm64_exported_include_dir/a.h": "",
  73. "arch_x86_exported_include_dir/b.h": "",
  74. "arch_x86_64_exported_include_dir/c.h": "",
  75. },
  76. Blueprint: soongCcLibraryHeadersPreamble + `
  77. cc_library_headers {
  78. name: "foo_headers",
  79. export_include_dirs: ["dir-1", "dir-2"],
  80. header_libs: ["lib-1", "lib-2"],
  81. arch: {
  82. arm64: {
  83. // We expect dir-1 headers to be dropped, because dir-1 is already in export_include_dirs
  84. export_include_dirs: ["arch_arm64_exported_include_dir", "dir-1"],
  85. },
  86. x86: {
  87. export_include_dirs: ["arch_x86_exported_include_dir"],
  88. },
  89. x86_64: {
  90. export_include_dirs: ["arch_x86_64_exported_include_dir"],
  91. },
  92. },
  93. sdk_version: "current",
  94. min_sdk_version: "29",
  95. // TODO: Also support export_header_lib_headers
  96. }`,
  97. ExpectedBazelTargets: []string{
  98. MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
  99. "export_includes": `select({
  100. "//build/bazel/platforms/arch:arm64": ["arch_arm64_exported_include_dir"],
  101. "//build/bazel/platforms/arch:x86": ["arch_x86_exported_include_dir"],
  102. "//build/bazel/platforms/arch:x86_64": ["arch_x86_64_exported_include_dir"],
  103. "//conditions:default": [],
  104. }) + [
  105. "dir-1",
  106. "dir-2",
  107. ]`,
  108. "sdk_version": `"current"`,
  109. "min_sdk_version": `"29"`,
  110. }),
  111. },
  112. })
  113. }
  114. func TestCcApiHeaders(t *testing.T) {
  115. fs := map[string]string{
  116. "bar/Android.bp": `cc_library_headers { name: "bar_headers", }`,
  117. }
  118. bp := `
  119. cc_library_headers {
  120. name: "foo_headers",
  121. export_include_dirs: ["dir1", "dir2"],
  122. export_header_lib_headers: ["bar_headers"],
  123. arch: {
  124. arm: {
  125. export_include_dirs: ["dir_arm"],
  126. },
  127. x86: {
  128. export_include_dirs: ["dir_x86"],
  129. },
  130. },
  131. target: {
  132. android: {
  133. export_include_dirs: ["dir1", "dir_android"],
  134. },
  135. windows: {
  136. export_include_dirs: ["dir_windows"],
  137. },
  138. }
  139. }
  140. `
  141. expectedBazelTargets := []string{
  142. MakeBazelTarget("cc_api_library_headers", "foo_headers.contribution.arm", AttrNameToString{
  143. "export_includes": `["dir_arm"]`,
  144. "arch": `"arm"`,
  145. }),
  146. MakeBazelTarget("cc_api_library_headers", "foo_headers.contribution.x86", AttrNameToString{
  147. "export_includes": `["dir_x86"]`,
  148. "arch": `"x86"`,
  149. }),
  150. MakeBazelTarget("cc_api_library_headers", "foo_headers.contribution.androidos", AttrNameToString{
  151. "export_includes": `["dir_android"]`, // common includes are deduped
  152. }),
  153. // Windows headers are not exported
  154. MakeBazelTarget("cc_api_library_headers", "foo_headers.contribution", AttrNameToString{
  155. "export_includes": `[
  156. "dir1",
  157. "dir2",
  158. ]`,
  159. "deps": `[
  160. "//bar:bar_headers.contribution",
  161. ":foo_headers.contribution.arm",
  162. ":foo_headers.contribution.x86",
  163. ":foo_headers.contribution.androidos",
  164. ]`,
  165. }),
  166. }
  167. RunApiBp2BuildTestCase(t, cc.RegisterLibraryHeadersBuildComponents, Bp2buildTestCase{
  168. Blueprint: bp,
  169. Description: "Header library contributions to API surfaces",
  170. ExpectedBazelTargets: expectedBazelTargets,
  171. Filesystem: fs,
  172. })
  173. }
  174. // header_libs has "variant_prepend" tag. In bp2build output,
  175. // variant info(select) should go before general info.
  176. func TestCcLibraryHeadersOsSpecificHeader(t *testing.T) {
  177. runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
  178. Description: "cc_library_headers test with os-specific header_libs props",
  179. ModuleTypeUnderTest: "cc_library_headers",
  180. ModuleTypeUnderTestFactory: cc.LibraryHeaderFactory,
  181. Filesystem: map[string]string{},
  182. Blueprint: soongCcLibraryPreamble + `
  183. cc_library_headers {
  184. name: "android-lib",
  185. bazel_module: { bp2build_available: false },
  186. }
  187. cc_library_headers {
  188. name: "base-lib",
  189. bazel_module: { bp2build_available: false },
  190. }
  191. cc_library_headers {
  192. name: "darwin-lib",
  193. bazel_module: { bp2build_available: false },
  194. }
  195. cc_library_headers {
  196. name: "linux-lib",
  197. bazel_module: { bp2build_available: false },
  198. }
  199. cc_library_headers {
  200. name: "linux_bionic-lib",
  201. bazel_module: { bp2build_available: false },
  202. }
  203. cc_library_headers {
  204. name: "windows-lib",
  205. bazel_module: { bp2build_available: false },
  206. }
  207. cc_library_headers {
  208. name: "foo_headers",
  209. header_libs: ["base-lib"],
  210. export_header_lib_headers: ["base-lib"],
  211. target: {
  212. android: {
  213. header_libs: ["android-lib"],
  214. export_header_lib_headers: ["android-lib"],
  215. },
  216. darwin: {
  217. header_libs: ["darwin-lib"],
  218. export_header_lib_headers: ["darwin-lib"],
  219. },
  220. linux_bionic: {
  221. header_libs: ["linux_bionic-lib"],
  222. export_header_lib_headers: ["linux_bionic-lib"],
  223. },
  224. linux_glibc: {
  225. header_libs: ["linux-lib"],
  226. export_header_lib_headers: ["linux-lib"],
  227. },
  228. windows: {
  229. header_libs: ["windows-lib"],
  230. export_header_lib_headers: ["windows-lib"],
  231. },
  232. },
  233. include_build_directory: false,
  234. }`,
  235. ExpectedBazelTargets: []string{
  236. MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
  237. "deps": `select({
  238. "//build/bazel/platforms/os:android": [":android-lib"],
  239. "//build/bazel/platforms/os:darwin": [":darwin-lib"],
  240. "//build/bazel/platforms/os:linux_bionic": [":linux_bionic-lib"],
  241. "//build/bazel/platforms/os:linux_glibc": [":linux-lib"],
  242. "//build/bazel/platforms/os:windows": [":windows-lib"],
  243. "//conditions:default": [],
  244. }) + [":base-lib"]`,
  245. }),
  246. },
  247. })
  248. }
  249. func TestCcLibraryHeadersOsSpecficHeaderLibsExportHeaderLibHeaders(t *testing.T) {
  250. runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
  251. Description: "cc_library_headers test with os-specific header_libs and export_header_lib_headers props",
  252. ModuleTypeUnderTest: "cc_library_headers",
  253. ModuleTypeUnderTestFactory: cc.LibraryHeaderFactory,
  254. Filesystem: map[string]string{},
  255. Blueprint: soongCcLibraryPreamble + `
  256. cc_library_headers {
  257. name: "android-lib",
  258. bazel_module: { bp2build_available: false },
  259. }
  260. cc_library_headers {
  261. name: "exported-lib",
  262. bazel_module: { bp2build_available: false },
  263. }
  264. cc_library_headers {
  265. name: "foo_headers",
  266. target: {
  267. android: {
  268. header_libs: ["android-lib", "exported-lib"],
  269. export_header_lib_headers: ["exported-lib"]
  270. },
  271. },
  272. include_build_directory: false,
  273. }`,
  274. ExpectedBazelTargets: []string{
  275. MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
  276. "deps": `select({
  277. "//build/bazel/platforms/os:android": [":exported-lib"],
  278. "//conditions:default": [],
  279. })`,
  280. }),
  281. },
  282. })
  283. }
  284. func TestCcLibraryHeadersArchAndTargetExportSystemIncludes(t *testing.T) {
  285. runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
  286. Description: "cc_library_headers test with arch-specific and target-specific export_system_include_dirs props",
  287. ModuleTypeUnderTest: "cc_library_headers",
  288. ModuleTypeUnderTestFactory: cc.LibraryHeaderFactory,
  289. Filesystem: map[string]string{},
  290. Blueprint: soongCcLibraryPreamble + `cc_library_headers {
  291. name: "foo_headers",
  292. export_system_include_dirs: [
  293. "shared_include_dir",
  294. ],
  295. target: {
  296. android: {
  297. export_system_include_dirs: [
  298. "android_include_dir",
  299. ],
  300. },
  301. linux_glibc: {
  302. export_system_include_dirs: [
  303. "linux_include_dir",
  304. ],
  305. },
  306. darwin: {
  307. export_system_include_dirs: [
  308. "darwin_include_dir",
  309. ],
  310. },
  311. },
  312. arch: {
  313. arm: {
  314. export_system_include_dirs: [
  315. "arm_include_dir",
  316. ],
  317. },
  318. x86_64: {
  319. export_system_include_dirs: [
  320. "x86_64_include_dir",
  321. ],
  322. },
  323. },
  324. include_build_directory: false,
  325. }`,
  326. ExpectedBazelTargets: []string{
  327. MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
  328. "export_system_includes": `select({
  329. "//build/bazel/platforms/os:android": ["android_include_dir"],
  330. "//build/bazel/platforms/os:darwin": ["darwin_include_dir"],
  331. "//build/bazel/platforms/os:linux_glibc": ["linux_include_dir"],
  332. "//conditions:default": [],
  333. }) + select({
  334. "//build/bazel/platforms/arch:arm": ["arm_include_dir"],
  335. "//build/bazel/platforms/arch:x86_64": ["x86_64_include_dir"],
  336. "//conditions:default": [],
  337. }) + ["shared_include_dir"]`,
  338. }),
  339. },
  340. })
  341. }
  342. func TestCcLibraryHeadersNoCrtIgnored(t *testing.T) {
  343. runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
  344. Description: "cc_library_headers test",
  345. ModuleTypeUnderTest: "cc_library_headers",
  346. ModuleTypeUnderTestFactory: cc.LibraryHeaderFactory,
  347. Filesystem: map[string]string{
  348. "lib-1/lib1a.h": "",
  349. "lib-1/lib1b.h": "",
  350. "lib-2/lib2a.h": "",
  351. "lib-2/lib2b.h": "",
  352. "dir-1/dir1a.h": "",
  353. "dir-1/dir1b.h": "",
  354. "dir-2/dir2a.h": "",
  355. "dir-2/dir2b.h": "",
  356. "arch_arm64_exported_include_dir/a.h": "",
  357. "arch_x86_exported_include_dir/b.h": "",
  358. "arch_x86_64_exported_include_dir/c.h": "",
  359. },
  360. Blueprint: soongCcLibraryHeadersPreamble + `
  361. cc_library_headers {
  362. name: "lib-1",
  363. export_include_dirs: ["lib-1"],
  364. no_libcrt: true,
  365. include_build_directory: false,
  366. }`,
  367. ExpectedBazelTargets: []string{
  368. MakeBazelTarget("cc_library_headers", "lib-1", AttrNameToString{
  369. "export_includes": `["lib-1"]`,
  370. }),
  371. },
  372. })
  373. }
  374. func TestCcLibraryHeadersExportedStaticLibHeadersReexported(t *testing.T) {
  375. runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
  376. Description: "cc_library_headers exported_static_lib_headers is reexported",
  377. ModuleTypeUnderTest: "cc_library_headers",
  378. ModuleTypeUnderTestFactory: cc.LibraryHeaderFactory,
  379. Filesystem: map[string]string{},
  380. Blueprint: soongCcLibraryHeadersPreamble + `
  381. cc_library_headers {
  382. name: "foo_headers",
  383. export_static_lib_headers: ["foo_export"],
  384. static_libs: ["foo_export", "foo_no_reexport"],
  385. bazel_module: { bp2build_available: true },
  386. }
  387. ` + simpleModuleDoNotConvertBp2build("cc_library_headers", "foo_export"),
  388. ExpectedBazelTargets: []string{
  389. MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
  390. "deps": `[":foo_export"]`,
  391. }),
  392. },
  393. })
  394. }
  395. func TestCcLibraryHeadersExportedSharedLibHeadersReexported(t *testing.T) {
  396. runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
  397. Description: "cc_library_headers exported_shared_lib_headers is reexported",
  398. ModuleTypeUnderTest: "cc_library_headers",
  399. ModuleTypeUnderTestFactory: cc.LibraryHeaderFactory,
  400. Filesystem: map[string]string{},
  401. Blueprint: soongCcLibraryHeadersPreamble + `
  402. cc_library_headers {
  403. name: "foo_headers",
  404. export_shared_lib_headers: ["foo_export"],
  405. shared_libs: ["foo_export", "foo_no_reexport"],
  406. bazel_module: { bp2build_available: true },
  407. }
  408. ` + simpleModuleDoNotConvertBp2build("cc_library_headers", "foo_export"),
  409. ExpectedBazelTargets: []string{
  410. MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
  411. "deps": `[":foo_export"]`,
  412. }),
  413. },
  414. })
  415. }
  416. func TestCcLibraryHeadersExportedHeaderLibHeadersReexported(t *testing.T) {
  417. runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
  418. Description: "cc_library_headers exported_header_lib_headers is reexported",
  419. ModuleTypeUnderTest: "cc_library_headers",
  420. ModuleTypeUnderTestFactory: cc.LibraryHeaderFactory,
  421. Filesystem: map[string]string{},
  422. Blueprint: soongCcLibraryHeadersPreamble + `
  423. cc_library_headers {
  424. name: "foo_headers",
  425. export_header_lib_headers: ["foo_export"],
  426. header_libs: ["foo_export", "foo_no_reexport"],
  427. bazel_module: { bp2build_available: true },
  428. }
  429. ` + simpleModuleDoNotConvertBp2build("cc_library_headers", "foo_export"),
  430. ExpectedBazelTargets: []string{
  431. MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
  432. "deps": `[":foo_export"]`,
  433. }),
  434. },
  435. })
  436. }
  437. func TestCcLibraryHeadersWholeStaticLibsReexported(t *testing.T) {
  438. runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
  439. Description: "cc_library_headers whole_static_libs is reexported",
  440. ModuleTypeUnderTest: "cc_library_headers",
  441. ModuleTypeUnderTestFactory: cc.LibraryHeaderFactory,
  442. Filesystem: map[string]string{},
  443. Blueprint: soongCcLibraryHeadersPreamble + `
  444. cc_library_headers {
  445. name: "foo_headers",
  446. whole_static_libs: ["foo_export"],
  447. bazel_module: { bp2build_available: true },
  448. }
  449. ` + simpleModuleDoNotConvertBp2build("cc_library_headers", "foo_export"),
  450. ExpectedBazelTargets: []string{
  451. MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
  452. "deps": `[":foo_export"]`,
  453. }),
  454. },
  455. })
  456. }