mk2rbc_test.go 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967
  1. // Copyright 2021 Google LLC
  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 mk2rbc
  15. import (
  16. "bytes"
  17. "io/fs"
  18. "path/filepath"
  19. "strings"
  20. "testing"
  21. )
  22. var testCases = []struct {
  23. desc string
  24. mkname string
  25. in string
  26. expected string
  27. }{
  28. {
  29. desc: "Comment",
  30. mkname: "product.mk",
  31. in: `
  32. # Comment
  33. # FOO= a\
  34. b
  35. `,
  36. expected: `# Comment
  37. # FOO= a
  38. # b
  39. load("//build/make/core:product_config.rbc", "rblf")
  40. def init(g, handle):
  41. cfg = rblf.cfg(handle)
  42. `,
  43. },
  44. {
  45. desc: "Name conversion",
  46. mkname: "path/bar-baz.mk",
  47. in: `
  48. # Comment
  49. `,
  50. expected: `# Comment
  51. load("//build/make/core:product_config.rbc", "rblf")
  52. def init(g, handle):
  53. cfg = rblf.cfg(handle)
  54. `,
  55. },
  56. {
  57. desc: "Item variable",
  58. mkname: "pixel3.mk",
  59. in: `
  60. PRODUCT_NAME := Pixel 3
  61. PRODUCT_MODEL :=
  62. local_var = foo
  63. `,
  64. expected: `load("//build/make/core:product_config.rbc", "rblf")
  65. def init(g, handle):
  66. cfg = rblf.cfg(handle)
  67. cfg["PRODUCT_NAME"] = "Pixel 3"
  68. cfg["PRODUCT_MODEL"] = ""
  69. _local_var = "foo"
  70. `,
  71. },
  72. {
  73. desc: "List variable",
  74. mkname: "pixel4.mk",
  75. in: `
  76. PRODUCT_PACKAGES = package1 package2
  77. PRODUCT_COPY_FILES += file2:target
  78. PRODUCT_PACKAGES += package3
  79. PRODUCT_COPY_FILES =
  80. `,
  81. expected: `load("//build/make/core:product_config.rbc", "rblf")
  82. def init(g, handle):
  83. cfg = rblf.cfg(handle)
  84. cfg["PRODUCT_PACKAGES"] = [
  85. "package1",
  86. "package2",
  87. ]
  88. rblf.setdefault(handle, "PRODUCT_COPY_FILES")
  89. cfg["PRODUCT_COPY_FILES"] += ["file2:target"]
  90. cfg["PRODUCT_PACKAGES"] += ["package3"]
  91. cfg["PRODUCT_COPY_FILES"] = []
  92. `,
  93. },
  94. {
  95. desc: "Unknown function",
  96. mkname: "product.mk",
  97. in: `
  98. PRODUCT_NAME := $(call foo1, bar)
  99. PRODUCT_NAME := $(call foo0)
  100. `,
  101. expected: `# MK2RBC TRANSLATION ERROR: cannot handle invoking foo1
  102. # PRODUCT_NAME := $(call foo1, bar)
  103. # MK2RBC TRANSLATION ERROR: cannot handle invoking foo0
  104. # PRODUCT_NAME := $(call foo0)
  105. load("//build/make/core:product_config.rbc", "rblf")
  106. def init(g, handle):
  107. cfg = rblf.cfg(handle)
  108. rblf.warning("product.mk", "partially successful conversion")
  109. `,
  110. },
  111. {
  112. desc: "Inherit configuration always",
  113. mkname: "product.mk",
  114. in: `
  115. ifdef PRODUCT_NAME
  116. $(call inherit-product, part.mk)
  117. else # Comment
  118. $(call inherit-product, $(LOCAL_PATH)/part.mk)
  119. endif
  120. `,
  121. expected: `load("//build/make/core:product_config.rbc", "rblf")
  122. load(":part.star", _part_init = "init")
  123. def init(g, handle):
  124. cfg = rblf.cfg(handle)
  125. if g.get("PRODUCT_NAME") != None:
  126. rblf.inherit(handle, "part", _part_init)
  127. else:
  128. # Comment
  129. rblf.inherit(handle, "part", _part_init)
  130. `,
  131. },
  132. {
  133. desc: "Inherit configuration if it exists",
  134. mkname: "product.mk",
  135. in: `
  136. $(call inherit-product-if-exists, part.mk)
  137. `,
  138. expected: `load("//build/make/core:product_config.rbc", "rblf")
  139. load(":part.star|init", _part_init = "init")
  140. def init(g, handle):
  141. cfg = rblf.cfg(handle)
  142. if _part_init:
  143. rblf.inherit(handle, "part", _part_init)
  144. `,
  145. },
  146. {
  147. desc: "Include configuration",
  148. mkname: "product.mk",
  149. in: `
  150. ifdef PRODUCT_NAME
  151. include part.mk
  152. else
  153. -include $(LOCAL_PATH)/part.mk)
  154. endif
  155. `,
  156. expected: `load("//build/make/core:product_config.rbc", "rblf")
  157. load(":part.star|init", _part_init = "init")
  158. def init(g, handle):
  159. cfg = rblf.cfg(handle)
  160. if g.get("PRODUCT_NAME") != None:
  161. _part_init(g, handle)
  162. else:
  163. if _part_init != None:
  164. _part_init(g, handle)
  165. `,
  166. },
  167. {
  168. desc: "Synonymous inherited configurations",
  169. mkname: "path/product.mk",
  170. in: `
  171. $(call inherit-product, */font.mk)
  172. `,
  173. expected: `load("//build/make/core:product_config.rbc", "rblf")
  174. load("//foo:font.star", _font_init = "init")
  175. load("//bar:font.star", _font1_init = "init")
  176. def init(g, handle):
  177. cfg = rblf.cfg(handle)
  178. rblf.inherit(handle, "foo/font", _font_init)
  179. rblf.inherit(handle, "bar/font", _font1_init)
  180. `,
  181. },
  182. {
  183. desc: "Directive define",
  184. mkname: "product.mk",
  185. in: `
  186. define some-macro
  187. $(info foo)
  188. endef
  189. `,
  190. expected: `# MK2RBC TRANSLATION ERROR: define is not supported: some-macro
  191. # define some-macro
  192. # $(info foo)
  193. # endef
  194. load("//build/make/core:product_config.rbc", "rblf")
  195. def init(g, handle):
  196. cfg = rblf.cfg(handle)
  197. rblf.warning("product.mk", "partially successful conversion")
  198. `,
  199. },
  200. {
  201. desc: "Ifdef",
  202. mkname: "product.mk",
  203. in: `
  204. ifdef PRODUCT_NAME
  205. PRODUCT_NAME = gizmo
  206. else
  207. endif
  208. `,
  209. expected: `load("//build/make/core:product_config.rbc", "rblf")
  210. def init(g, handle):
  211. cfg = rblf.cfg(handle)
  212. if g.get("PRODUCT_NAME") != None:
  213. cfg["PRODUCT_NAME"] = "gizmo"
  214. else:
  215. pass
  216. `,
  217. },
  218. {
  219. desc: "Simple functions",
  220. mkname: "product.mk",
  221. in: `
  222. $(warning this is the warning)
  223. $(warning)
  224. $(info this is the info)
  225. $(error this is the error)
  226. PRODUCT_NAME:=$(shell echo *)
  227. `,
  228. expected: `load("//build/make/core:product_config.rbc", "rblf")
  229. def init(g, handle):
  230. cfg = rblf.cfg(handle)
  231. rblf.mkwarning("product.mk", "this is the warning")
  232. rblf.mkwarning("product.mk", "")
  233. rblf.mkinfo("product.mk", "this is the info")
  234. rblf.mkerror("product.mk", "this is the error")
  235. cfg["PRODUCT_NAME"] = rblf.shell("echo *")
  236. `,
  237. },
  238. {
  239. desc: "Empty if",
  240. mkname: "product.mk",
  241. in: `
  242. ifdef PRODUCT_NAME
  243. # Comment
  244. else
  245. TARGET_COPY_OUT_VENDOR := foo
  246. endif
  247. `,
  248. expected: `load("//build/make/core:product_config.rbc", "rblf")
  249. def init(g, handle):
  250. cfg = rblf.cfg(handle)
  251. if g.get("PRODUCT_NAME") != None:
  252. # Comment
  253. pass
  254. else:
  255. # MK2RBC TRANSLATION ERROR: cannot set predefined variable TARGET_COPY_OUT_VENDOR to "foo", its value should be "||VENDOR-PATH-PH||"
  256. pass
  257. rblf.warning("product.mk", "partially successful conversion")
  258. `,
  259. },
  260. {
  261. desc: "if/else/endif",
  262. mkname: "product.mk",
  263. in: `
  264. ifndef PRODUCT_NAME
  265. PRODUCT_NAME=gizmo1
  266. else
  267. PRODUCT_NAME=gizmo2
  268. endif
  269. `,
  270. expected: `load("//build/make/core:product_config.rbc", "rblf")
  271. def init(g, handle):
  272. cfg = rblf.cfg(handle)
  273. if not g.get("PRODUCT_NAME") != None:
  274. cfg["PRODUCT_NAME"] = "gizmo1"
  275. else:
  276. cfg["PRODUCT_NAME"] = "gizmo2"
  277. `,
  278. },
  279. {
  280. desc: "else if",
  281. mkname: "product.mk",
  282. in: `
  283. ifdef PRODUCT_NAME
  284. PRODUCT_NAME = gizmo
  285. else ifndef PRODUCT_PACKAGES # Comment
  286. endif
  287. `,
  288. expected: `load("//build/make/core:product_config.rbc", "rblf")
  289. def init(g, handle):
  290. cfg = rblf.cfg(handle)
  291. if g.get("PRODUCT_NAME") != None:
  292. cfg["PRODUCT_NAME"] = "gizmo"
  293. elif not g.get("PRODUCT_PACKAGES") != None:
  294. # Comment
  295. pass
  296. `,
  297. },
  298. {
  299. desc: "ifeq / ifneq",
  300. mkname: "product.mk",
  301. in: `
  302. ifeq (aosp_arm, $(TARGET_PRODUCT))
  303. PRODUCT_MODEL = pix2
  304. else
  305. PRODUCT_MODEL = pix21
  306. endif
  307. ifneq (aosp_x86, $(TARGET_PRODUCT))
  308. PRODUCT_MODEL = pix3
  309. endif
  310. `,
  311. expected: `load("//build/make/core:product_config.rbc", "rblf")
  312. def init(g, handle):
  313. cfg = rblf.cfg(handle)
  314. if "aosp_arm" == g["TARGET_PRODUCT"]:
  315. cfg["PRODUCT_MODEL"] = "pix2"
  316. else:
  317. cfg["PRODUCT_MODEL"] = "pix21"
  318. if "aosp_x86" != g["TARGET_PRODUCT"]:
  319. cfg["PRODUCT_MODEL"] = "pix3"
  320. `,
  321. },
  322. {
  323. desc: "Check filter result",
  324. mkname: "product.mk",
  325. in: `
  326. ifeq (,$(filter userdebug eng, $(TARGET_BUILD_VARIANT)))
  327. endif
  328. ifneq (,$(filter userdebug,$(TARGET_BUILD_VARIANT))
  329. endif
  330. ifneq (,$(filter plaf,$(PLATFORM_LIST)))
  331. endif
  332. ifeq ($(TARGET_BUILD_VARIANT), $(filter $(TARGET_BUILD_VARIANT), userdebug eng))
  333. endif
  334. ifneq (,$(filter true, $(v1)$(v2)))
  335. endif
  336. `,
  337. expected: `load("//build/make/core:product_config.rbc", "rblf")
  338. def init(g, handle):
  339. cfg = rblf.cfg(handle)
  340. if g["TARGET_BUILD_VARIANT"] not in ["userdebug", "eng"]:
  341. pass
  342. if g["TARGET_BUILD_VARIANT"] == "userdebug":
  343. pass
  344. if "plaf" in g.get("PLATFORM_LIST", []):
  345. pass
  346. if g["TARGET_BUILD_VARIANT"] in ["userdebug", "eng"]:
  347. pass
  348. if "%s%s" % (_v1, _v2) == "true":
  349. pass
  350. `,
  351. },
  352. {
  353. desc: "Get filter result",
  354. mkname: "product.mk",
  355. in: `
  356. PRODUCT_LIST2=$(filter-out %/foo.ko,$(wildcard path/*.ko))
  357. `,
  358. expected: `load("//build/make/core:product_config.rbc", "rblf")
  359. def init(g, handle):
  360. cfg = rblf.cfg(handle)
  361. cfg["PRODUCT_LIST2"] = rblf.filter_out("%/foo.ko", rblf.expand_wildcard("path/*.ko"))
  362. `,
  363. },
  364. {
  365. desc: "filter $(VAR), values",
  366. mkname: "product.mk",
  367. in: `
  368. ifeq (,$(filter $(TARGET_PRODUCT), yukawa_gms yukawa_sei510_gms)
  369. ifneq (,$(filter $(TARGET_PRODUCT), yukawa_gms)
  370. endif
  371. endif
  372. `,
  373. expected: `load("//build/make/core:product_config.rbc", "rblf")
  374. def init(g, handle):
  375. cfg = rblf.cfg(handle)
  376. if g["TARGET_PRODUCT"] not in ["yukawa_gms", "yukawa_sei510_gms"]:
  377. if g["TARGET_PRODUCT"] == "yukawa_gms":
  378. pass
  379. `,
  380. },
  381. {
  382. desc: "filter $(V1), $(V2)",
  383. mkname: "product.mk",
  384. in: `
  385. ifneq (, $(filter $(PRODUCT_LIST), $(TARGET_PRODUCT)))
  386. endif
  387. `,
  388. expected: `load("//build/make/core:product_config.rbc", "rblf")
  389. def init(g, handle):
  390. cfg = rblf.cfg(handle)
  391. if rblf.filter(g.get("PRODUCT_LIST", ""), g["TARGET_PRODUCT"]):
  392. pass
  393. `,
  394. },
  395. {
  396. desc: "ifeq",
  397. mkname: "product.mk",
  398. in: `
  399. ifeq (aosp, $(TARGET_PRODUCT)) # Comment
  400. else ifneq (, $(TARGET_PRODUCT))
  401. endif
  402. `,
  403. expected: `load("//build/make/core:product_config.rbc", "rblf")
  404. def init(g, handle):
  405. cfg = rblf.cfg(handle)
  406. if "aosp" == g["TARGET_PRODUCT"]:
  407. # Comment
  408. pass
  409. elif g["TARGET_PRODUCT"]:
  410. pass
  411. `,
  412. },
  413. {
  414. desc: "Nested if",
  415. mkname: "product.mk",
  416. in: `
  417. ifdef PRODUCT_NAME
  418. PRODUCT_PACKAGES = pack-if0
  419. ifdef PRODUCT_MODEL
  420. PRODUCT_PACKAGES = pack-if-if
  421. else ifdef PRODUCT_NAME
  422. PRODUCT_PACKAGES = pack-if-elif
  423. else
  424. PRODUCT_PACKAGES = pack-if-else
  425. endif
  426. PRODUCT_PACKAGES = pack-if
  427. else ifneq (,$(TARGET_PRODUCT))
  428. PRODUCT_PACKAGES = pack-elif
  429. else
  430. PRODUCT_PACKAGES = pack-else
  431. endif
  432. `,
  433. expected: `load("//build/make/core:product_config.rbc", "rblf")
  434. def init(g, handle):
  435. cfg = rblf.cfg(handle)
  436. if g.get("PRODUCT_NAME") != None:
  437. cfg["PRODUCT_PACKAGES"] = ["pack-if0"]
  438. if g.get("PRODUCT_MODEL") != None:
  439. cfg["PRODUCT_PACKAGES"] = ["pack-if-if"]
  440. elif g.get("PRODUCT_NAME") != None:
  441. cfg["PRODUCT_PACKAGES"] = ["pack-if-elif"]
  442. else:
  443. cfg["PRODUCT_PACKAGES"] = ["pack-if-else"]
  444. cfg["PRODUCT_PACKAGES"] = ["pack-if"]
  445. elif g["TARGET_PRODUCT"]:
  446. cfg["PRODUCT_PACKAGES"] = ["pack-elif"]
  447. else:
  448. cfg["PRODUCT_PACKAGES"] = ["pack-else"]
  449. `,
  450. },
  451. {
  452. desc: "Wildcard",
  453. mkname: "product.mk",
  454. in: `
  455. ifeq (,$(wildcard foo.mk))
  456. endif
  457. ifneq (,$(wildcard foo*.mk))
  458. endif
  459. `,
  460. expected: `load("//build/make/core:product_config.rbc", "rblf")
  461. def init(g, handle):
  462. cfg = rblf.cfg(handle)
  463. if not rblf.file_exists("foo.mk"):
  464. pass
  465. if rblf.file_wildcard_exists("foo*.mk"):
  466. pass
  467. `,
  468. },
  469. {
  470. desc: "ifneq $(X),true",
  471. mkname: "product.mk",
  472. in: `
  473. ifneq ($(VARIABLE),true)
  474. endif
  475. `,
  476. expected: `load("//build/make/core:product_config.rbc", "rblf")
  477. def init(g, handle):
  478. cfg = rblf.cfg(handle)
  479. if g.get("VARIABLE", "") != "true":
  480. pass
  481. `,
  482. },
  483. {
  484. desc: "Const neq",
  485. mkname: "product.mk",
  486. in: `
  487. ifneq (1,0)
  488. endif
  489. `,
  490. expected: `load("//build/make/core:product_config.rbc", "rblf")
  491. def init(g, handle):
  492. cfg = rblf.cfg(handle)
  493. if "1" != "0":
  494. pass
  495. `,
  496. },
  497. {
  498. desc: "is-board calls",
  499. mkname: "product.mk",
  500. in: `
  501. ifeq ($(call is-board-platform-in-list,msm8998), true)
  502. else ifneq ($(call is-board-platform,copper),true)
  503. else ifneq ($(call is-vendor-board-platform,QCOM),true)
  504. else ifeq ($(call is-product-in-list, $(PLATFORM_LIST)), true)
  505. endif
  506. `,
  507. expected: `load("//build/make/core:product_config.rbc", "rblf")
  508. def init(g, handle):
  509. cfg = rblf.cfg(handle)
  510. if g.get("TARGET_BOARD_PLATFORM", "") in ["msm8998"]:
  511. pass
  512. elif g.get("TARGET_BOARD_PLATFORM", "") != "copper":
  513. pass
  514. elif g.get("TARGET_BOARD_PLATFORM", "") not in g["QCOM_BOARD_PLATFORMS"]:
  515. pass
  516. elif g["TARGET_PRODUCT"] in g.get("PLATFORM_LIST", []):
  517. pass
  518. `,
  519. },
  520. {
  521. desc: "findstring call",
  522. mkname: "product.mk",
  523. in: `
  524. ifneq ($(findstring foo,$(PRODUCT_PACKAGES)),)
  525. endif
  526. `,
  527. expected: `load("//build/make/core:product_config.rbc", "rblf")
  528. def init(g, handle):
  529. cfg = rblf.cfg(handle)
  530. if (cfg.get("PRODUCT_PACKAGES", [])).find("foo") != -1:
  531. pass
  532. `,
  533. },
  534. {
  535. desc: "rhs call",
  536. mkname: "product.mk",
  537. in: `
  538. PRODUCT_COPY_FILES = $(call add-to-product-copy-files-if-exists, path:distpath) \
  539. $(call find-copy-subdir-files, *, fromdir, todir) $(wildcard foo.*)
  540. `,
  541. expected: `load("//build/make/core:product_config.rbc", "rblf")
  542. def init(g, handle):
  543. cfg = rblf.cfg(handle)
  544. cfg["PRODUCT_COPY_FILES"] = (rblf.copy_if_exists("path:distpath") +
  545. rblf.find_and_copy("*", "fromdir", "todir") +
  546. rblf.expand_wildcard("foo.*"))
  547. `,
  548. },
  549. {
  550. desc: "inferred type",
  551. mkname: "product.mk",
  552. in: `
  553. HIKEY_MODS := $(wildcard foo/*.ko)
  554. BOARD_VENDOR_KERNEL_MODULES += $(HIKEY_MODS)
  555. `,
  556. expected: `load("//build/make/core:product_config.rbc", "rblf")
  557. def init(g, handle):
  558. cfg = rblf.cfg(handle)
  559. g["HIKEY_MODS"] = rblf.expand_wildcard("foo/*.ko")
  560. g.setdefault("BOARD_VENDOR_KERNEL_MODULES", [])
  561. g["BOARD_VENDOR_KERNEL_MODULES"] += g["HIKEY_MODS"]
  562. `,
  563. },
  564. {
  565. desc: "list with vars",
  566. mkname: "product.mk",
  567. in: `
  568. PRODUCT_COPY_FILES += path1:$(TARGET_PRODUCT)/path1 $(PRODUCT_MODEL)/path2:$(TARGET_PRODUCT)/path2
  569. `,
  570. expected: `load("//build/make/core:product_config.rbc", "rblf")
  571. def init(g, handle):
  572. cfg = rblf.cfg(handle)
  573. rblf.setdefault(handle, "PRODUCT_COPY_FILES")
  574. cfg["PRODUCT_COPY_FILES"] += (("path1:%s/path1" % g["TARGET_PRODUCT"]).split() +
  575. ("%s/path2:%s/path2" % (cfg.get("PRODUCT_MODEL", ""), g["TARGET_PRODUCT"])).split())
  576. `,
  577. },
  578. {
  579. desc: "misc calls",
  580. mkname: "product.mk",
  581. in: `
  582. $(call enforce-product-packages-exist,)
  583. $(call enforce-product-packages-exist, foo)
  584. $(call require-artifacts-in-path, foo, bar)
  585. $(call require-artifacts-in-path-relaxed, foo, bar)
  586. `,
  587. expected: `load("//build/make/core:product_config.rbc", "rblf")
  588. def init(g, handle):
  589. cfg = rblf.cfg(handle)
  590. rblf.enforce_product_packages_exist("")
  591. rblf.enforce_product_packages_exist("foo")
  592. rblf.require_artifacts_in_path("foo", "bar")
  593. rblf.require_artifacts_in_path_relaxed("foo", "bar")
  594. `,
  595. },
  596. {
  597. desc: "list with functions",
  598. mkname: "product.mk",
  599. in: `
  600. PRODUCT_COPY_FILES := $(call find-copy-subdir-files,*.kl,from1,to1) \
  601. $(call find-copy-subdir-files,*.kc,from2,to2) \
  602. foo bar
  603. `,
  604. expected: `load("//build/make/core:product_config.rbc", "rblf")
  605. def init(g, handle):
  606. cfg = rblf.cfg(handle)
  607. cfg["PRODUCT_COPY_FILES"] = (rblf.find_and_copy("*.kl", "from1", "to1") +
  608. rblf.find_and_copy("*.kc", "from2", "to2") +
  609. [
  610. "foo",
  611. "bar",
  612. ])
  613. `,
  614. },
  615. {
  616. desc: "Text functions",
  617. mkname: "product.mk",
  618. in: `
  619. PRODUCT_COPY_FILES := $(addprefix pfx-,a b c)
  620. PRODUCT_COPY_FILES := $(addsuffix .sff, a b c)
  621. PRODUCT_NAME := $(word 1, $(subst ., ,$(TARGET_BOARD_PLATFORM)))
  622. $(info $(patsubst %.pub,%,$(PRODUCT_ADB_KEYS)))
  623. `,
  624. expected: `load("//build/make/core:product_config.rbc", "rblf")
  625. def init(g, handle):
  626. cfg = rblf.cfg(handle)
  627. cfg["PRODUCT_COPY_FILES"] = rblf.addprefix("pfx-", "a b c")
  628. cfg["PRODUCT_COPY_FILES"] = rblf.addsuffix(".sff", "a b c")
  629. cfg["PRODUCT_NAME"] = ((g.get("TARGET_BOARD_PLATFORM", "")).replace(".", " ")).split()[0]
  630. rblf.mkinfo("product.mk", rblf.mkpatsubst("%.pub", "%", g.get("PRODUCT_ADB_KEYS", "")))
  631. `,
  632. },
  633. {
  634. desc: "subst in list",
  635. mkname: "product.mk",
  636. in: `
  637. files = $(call find-copy-subdir-files,*,from,to)
  638. PRODUCT_COPY_FILES += $(subst foo,bar,$(files))
  639. `,
  640. expected: `load("//build/make/core:product_config.rbc", "rblf")
  641. def init(g, handle):
  642. cfg = rblf.cfg(handle)
  643. _files = rblf.find_and_copy("*", "from", "to")
  644. rblf.setdefault(handle, "PRODUCT_COPY_FILES")
  645. cfg["PRODUCT_COPY_FILES"] += rblf.mksubst("foo", "bar", _files)
  646. `,
  647. },
  648. {
  649. desc: "assignment flavors",
  650. mkname: "product.mk",
  651. in: `
  652. PRODUCT_LIST1 := a
  653. PRODUCT_LIST2 += a
  654. PRODUCT_LIST1 += b
  655. PRODUCT_LIST2 += b
  656. PRODUCT_LIST3 ?= a
  657. PRODUCT_LIST1 = c
  658. PLATFORM_LIST += x
  659. PRODUCT_PACKAGES := $(PLATFORM_LIST)
  660. `,
  661. expected: `load("//build/make/core:product_config.rbc", "rblf")
  662. def init(g, handle):
  663. cfg = rblf.cfg(handle)
  664. cfg["PRODUCT_LIST1"] = ["a"]
  665. rblf.setdefault(handle, "PRODUCT_LIST2")
  666. cfg["PRODUCT_LIST2"] += ["a"]
  667. cfg["PRODUCT_LIST1"] += ["b"]
  668. cfg["PRODUCT_LIST2"] += ["b"]
  669. if cfg.get("PRODUCT_LIST3") == None:
  670. cfg["PRODUCT_LIST3"] = ["a"]
  671. cfg["PRODUCT_LIST1"] = ["c"]
  672. g.setdefault("PLATFORM_LIST", [])
  673. g["PLATFORM_LIST"] += ["x"]
  674. cfg["PRODUCT_PACKAGES"] = g["PLATFORM_LIST"][:]
  675. `,
  676. },
  677. {
  678. desc: "assigment flavors2",
  679. mkname: "product.mk",
  680. in: `
  681. PRODUCT_LIST1 = a
  682. ifeq (0,1)
  683. PRODUCT_LIST1 += b
  684. PRODUCT_LIST2 += b
  685. endif
  686. PRODUCT_LIST1 += c
  687. PRODUCT_LIST2 += c
  688. `,
  689. expected: `load("//build/make/core:product_config.rbc", "rblf")
  690. def init(g, handle):
  691. cfg = rblf.cfg(handle)
  692. cfg["PRODUCT_LIST1"] = ["a"]
  693. if "0" == "1":
  694. cfg["PRODUCT_LIST1"] += ["b"]
  695. rblf.setdefault(handle, "PRODUCT_LIST2")
  696. cfg["PRODUCT_LIST2"] += ["b"]
  697. cfg["PRODUCT_LIST1"] += ["c"]
  698. rblf.setdefault(handle, "PRODUCT_LIST2")
  699. cfg["PRODUCT_LIST2"] += ["c"]
  700. `,
  701. },
  702. {
  703. desc: "string split",
  704. mkname: "product.mk",
  705. in: `
  706. PRODUCT_LIST1 = a
  707. local = b
  708. local += c
  709. FOO = d
  710. FOO += e
  711. PRODUCT_LIST1 += $(local)
  712. PRODUCT_LIST1 += $(FOO)
  713. `,
  714. expected: `load("//build/make/core:product_config.rbc", "rblf")
  715. def init(g, handle):
  716. cfg = rblf.cfg(handle)
  717. cfg["PRODUCT_LIST1"] = ["a"]
  718. _local = "b"
  719. _local += " " + "c"
  720. g["FOO"] = "d"
  721. g["FOO"] += " " + "e"
  722. cfg["PRODUCT_LIST1"] += (_local).split()
  723. cfg["PRODUCT_LIST1"] += (g["FOO"]).split()
  724. `,
  725. },
  726. {
  727. desc: "apex_jars",
  728. mkname: "product.mk",
  729. in: `
  730. PRODUCT_BOOT_JARS := $(ART_APEX_JARS) framework-minus-apex
  731. `,
  732. expected: `load("//build/make/core:product_config.rbc", "rblf")
  733. def init(g, handle):
  734. cfg = rblf.cfg(handle)
  735. cfg["PRODUCT_BOOT_JARS"] = (g.get("ART_APEX_JARS", []) +
  736. ["framework-minus-apex"])
  737. `,
  738. },
  739. {
  740. desc: "strip function",
  741. mkname: "product.mk",
  742. in: `
  743. ifeq ($(filter hwaddress,$(PRODUCT_PACKAGES)),)
  744. PRODUCT_PACKAGES := $(strip $(PRODUCT_PACKAGES) hwaddress)
  745. endif
  746. `,
  747. expected: `load("//build/make/core:product_config.rbc", "rblf")
  748. def init(g, handle):
  749. cfg = rblf.cfg(handle)
  750. if "hwaddress" not in cfg.get("PRODUCT_PACKAGES", []):
  751. cfg["PRODUCT_PACKAGES"] = (rblf.mkstrip("%s hwaddress" % " ".join(cfg.get("PRODUCT_PACKAGES", [])))).split()
  752. `,
  753. },
  754. {
  755. desc: "strip func in condition",
  756. mkname: "product.mk",
  757. in: `
  758. ifneq ($(strip $(TARGET_VENDOR)),)
  759. endif
  760. `,
  761. expected: `load("//build/make/core:product_config.rbc", "rblf")
  762. def init(g, handle):
  763. cfg = rblf.cfg(handle)
  764. if rblf.mkstrip(g.get("TARGET_VENDOR", "")):
  765. pass
  766. `,
  767. },
  768. {
  769. desc: "ref after set",
  770. mkname: "product.mk",
  771. in: `
  772. PRODUCT_ADB_KEYS:=value
  773. FOO := $(PRODUCT_ADB_KEYS)
  774. ifneq (,$(PRODUCT_ADB_KEYS))
  775. endif
  776. `,
  777. expected: `load("//build/make/core:product_config.rbc", "rblf")
  778. def init(g, handle):
  779. cfg = rblf.cfg(handle)
  780. g["PRODUCT_ADB_KEYS"] = "value"
  781. g["FOO"] = g["PRODUCT_ADB_KEYS"]
  782. if g["PRODUCT_ADB_KEYS"]:
  783. pass
  784. `,
  785. },
  786. {
  787. desc: "ref before set",
  788. mkname: "product.mk",
  789. in: `
  790. V1 := $(PRODUCT_ADB_KEYS)
  791. ifeq (,$(PRODUCT_ADB_KEYS))
  792. V2 := $(PRODUCT_ADB_KEYS)
  793. PRODUCT_ADB_KEYS:=foo
  794. V3 := $(PRODUCT_ADB_KEYS)
  795. endif`,
  796. expected: `load("//build/make/core:product_config.rbc", "rblf")
  797. def init(g, handle):
  798. cfg = rblf.cfg(handle)
  799. g["V1"] = g.get("PRODUCT_ADB_KEYS", "")
  800. if not g.get("PRODUCT_ADB_KEYS", ""):
  801. g["V2"] = g.get("PRODUCT_ADB_KEYS", "")
  802. g["PRODUCT_ADB_KEYS"] = "foo"
  803. g["V3"] = g["PRODUCT_ADB_KEYS"]
  804. `,
  805. },
  806. {
  807. desc: "Dynamic inherit path",
  808. mkname: "product.mk",
  809. in: `
  810. MY_PATH=foo
  811. $(call inherit-product,vendor/$(MY_PATH)/cfg.mk)
  812. `,
  813. expected: `load("//build/make/core:product_config.rbc", "rblf")
  814. load("//vendor/foo1:cfg.star|init", _cfg_init = "init")
  815. load("//vendor/bar/baz:cfg.star|init", _cfg1_init = "init")
  816. def init(g, handle):
  817. cfg = rblf.cfg(handle)
  818. g["MY_PATH"] = "foo"
  819. _entry = {
  820. "vendor/foo1/cfg.mk": ("_cfg", _cfg_init),
  821. "vendor/bar/baz/cfg.mk": ("_cfg1", _cfg1_init),
  822. }.get("vendor/%s/cfg.mk" % g["MY_PATH"])
  823. (_varmod, _varmod_init) = _entry if _entry else (None, None)
  824. if not _varmod_init:
  825. rblf.mkerror("cannot")
  826. rblf.inherit(handle, _varmod, _varmod_init)
  827. `,
  828. },
  829. }
  830. var known_variables = []struct {
  831. name string
  832. class varClass
  833. starlarkType
  834. }{
  835. {"PRODUCT_NAME", VarClassConfig, starlarkTypeString},
  836. {"PRODUCT_MODEL", VarClassConfig, starlarkTypeString},
  837. {"PRODUCT_PACKAGES", VarClassConfig, starlarkTypeList},
  838. {"PRODUCT_BOOT_JARS", VarClassConfig, starlarkTypeList},
  839. {"PRODUCT_COPY_FILES", VarClassConfig, starlarkTypeList},
  840. {"PRODUCT_IS_64BIT", VarClassConfig, starlarkTypeString},
  841. {"PRODUCT_LIST1", VarClassConfig, starlarkTypeList},
  842. {"PRODUCT_LIST2", VarClassConfig, starlarkTypeList},
  843. {"PRODUCT_LIST3", VarClassConfig, starlarkTypeList},
  844. {"TARGET_PRODUCT", VarClassSoong, starlarkTypeString},
  845. {"TARGET_BUILD_VARIANT", VarClassSoong, starlarkTypeString},
  846. {"TARGET_BOARD_PLATFORM", VarClassSoong, starlarkTypeString},
  847. {"QCOM_BOARD_PLATFORMS", VarClassSoong, starlarkTypeString},
  848. {"PLATFORM_LIST", VarClassSoong, starlarkTypeList}, // TODO(asmundak): make it local instead of soong
  849. }
  850. type testMakefileFinder struct {
  851. fs fs.FS
  852. root string
  853. files []string
  854. }
  855. func (t *testMakefileFinder) Find(root string) []string {
  856. if t.files != nil || root == t.root {
  857. return t.files
  858. }
  859. t.files = make([]string, 0)
  860. fs.WalkDir(t.fs, root, func(path string, d fs.DirEntry, err error) error {
  861. if err != nil {
  862. return err
  863. }
  864. if d.IsDir() {
  865. base := filepath.Base(path)
  866. if base[0] == '.' && len(base) > 1 {
  867. return fs.SkipDir
  868. }
  869. return nil
  870. }
  871. if strings.HasSuffix(path, ".mk") {
  872. t.files = append(t.files, path)
  873. }
  874. return nil
  875. })
  876. return t.files
  877. }
  878. func TestGood(t *testing.T) {
  879. for _, v := range known_variables {
  880. KnownVariables.NewVariable(v.name, v.class, v.starlarkType)
  881. }
  882. fs := NewFindMockFS([]string{
  883. "vendor/foo1/cfg.mk",
  884. "vendor/bar/baz/cfg.mk",
  885. "part.mk",
  886. "foo/font.mk",
  887. "bar/font.mk",
  888. })
  889. for _, test := range testCases {
  890. t.Run(test.desc,
  891. func(t *testing.T) {
  892. ss, err := Convert(Request{
  893. MkFile: test.mkname,
  894. Reader: bytes.NewBufferString(test.in),
  895. RootDir: ".",
  896. OutputSuffix: ".star",
  897. WarnPartialSuccess: true,
  898. SourceFS: fs,
  899. MakefileFinder: &testMakefileFinder{fs: fs},
  900. })
  901. if err != nil {
  902. t.Error(err)
  903. return
  904. }
  905. got := ss.String()
  906. if got != test.expected {
  907. t.Errorf("%q failed\nExpected:\n%s\nActual:\n%s\n", test.desc,
  908. strings.ReplaceAll(test.expected, "\n", "␤\n"),
  909. strings.ReplaceAll(got, "\n", "␤\n"))
  910. }
  911. })
  912. }
  913. }