mk2rbc_test.go 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601
  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. local-var-with-dashes := bar
  64. $(warning local-var-with-dashes: $(local-var-with-dashes))
  65. GLOBAL-VAR-WITH-DASHES := baz
  66. $(warning GLOBAL-VAR-WITH-DASHES: $(GLOBAL-VAR-WITH-DASHES))
  67. `,
  68. expected: `load("//build/make/core:product_config.rbc", "rblf")
  69. def init(g, handle):
  70. cfg = rblf.cfg(handle)
  71. cfg["PRODUCT_NAME"] = "Pixel 3"
  72. cfg["PRODUCT_MODEL"] = ""
  73. _local_var = "foo"
  74. _local_var_with_dashes = "bar"
  75. rblf.mkwarning("pixel3.mk", "local-var-with-dashes: %s" % _local_var_with_dashes)
  76. g["GLOBAL-VAR-WITH-DASHES"] = "baz"
  77. rblf.mkwarning("pixel3.mk", "GLOBAL-VAR-WITH-DASHES: %s" % g["GLOBAL-VAR-WITH-DASHES"])
  78. `,
  79. },
  80. {
  81. desc: "List variable",
  82. mkname: "pixel4.mk",
  83. in: `
  84. PRODUCT_PACKAGES = package1 package2
  85. PRODUCT_COPY_FILES += file2:target
  86. PRODUCT_PACKAGES += package3
  87. PRODUCT_COPY_FILES =
  88. `,
  89. expected: `load("//build/make/core:product_config.rbc", "rblf")
  90. def init(g, handle):
  91. cfg = rblf.cfg(handle)
  92. cfg["PRODUCT_PACKAGES"] = [
  93. "package1",
  94. "package2",
  95. ]
  96. rblf.setdefault(handle, "PRODUCT_COPY_FILES")
  97. cfg["PRODUCT_COPY_FILES"] += ["file2:target"]
  98. cfg["PRODUCT_PACKAGES"] += ["package3"]
  99. cfg["PRODUCT_COPY_FILES"] = []
  100. `,
  101. },
  102. {
  103. desc: "Unknown function",
  104. mkname: "product.mk",
  105. in: `
  106. PRODUCT_NAME := $(call foo1, bar)
  107. PRODUCT_NAME := $(call foo0)
  108. `,
  109. expected: `load("//build/make/core:product_config.rbc", "rblf")
  110. def init(g, handle):
  111. cfg = rblf.cfg(handle)
  112. rblf.mk2rbc_error("product.mk:2", "cannot handle invoking foo1")
  113. rblf.mk2rbc_error("product.mk:3", "cannot handle invoking foo0")
  114. `,
  115. },
  116. {
  117. desc: "Inherit configuration always",
  118. mkname: "product.mk",
  119. in: `
  120. $(call inherit-product, part.mk)
  121. ifdef PRODUCT_NAME
  122. $(call inherit-product, part1.mk)
  123. else # Comment
  124. $(call inherit-product, $(LOCAL_PATH)/part.mk)
  125. endif
  126. `,
  127. expected: `load("//build/make/core:product_config.rbc", "rblf")
  128. load(":part.star", _part_init = "init")
  129. load(":part1.star|init", _part1_init = "init")
  130. def init(g, handle):
  131. cfg = rblf.cfg(handle)
  132. rblf.inherit(handle, "part", _part_init)
  133. if cfg.get("PRODUCT_NAME", ""):
  134. if not _part1_init:
  135. rblf.mkerror("product.mk", "Cannot find %s" % (":part1.star"))
  136. rblf.inherit(handle, "part1", _part1_init)
  137. else:
  138. # Comment
  139. rblf.inherit(handle, "part", _part_init)
  140. `,
  141. },
  142. {
  143. desc: "Inherit configuration if it exists",
  144. mkname: "product.mk",
  145. in: `
  146. $(call inherit-product-if-exists, part.mk)
  147. `,
  148. expected: `load("//build/make/core:product_config.rbc", "rblf")
  149. load(":part.star|init", _part_init = "init")
  150. def init(g, handle):
  151. cfg = rblf.cfg(handle)
  152. if _part_init:
  153. rblf.inherit(handle, "part", _part_init)
  154. `,
  155. },
  156. {
  157. desc: "Include configuration",
  158. mkname: "product.mk",
  159. in: `
  160. include part.mk
  161. ifdef PRODUCT_NAME
  162. include part1.mk
  163. else
  164. -include $(LOCAL_PATH)/part1.mk)
  165. endif
  166. `,
  167. expected: `load("//build/make/core:product_config.rbc", "rblf")
  168. load(":part.star", _part_init = "init")
  169. load(":part1.star|init", _part1_init = "init")
  170. def init(g, handle):
  171. cfg = rblf.cfg(handle)
  172. _part_init(g, handle)
  173. if cfg.get("PRODUCT_NAME", ""):
  174. if not _part1_init:
  175. rblf.mkerror("product.mk", "Cannot find %s" % (":part1.star"))
  176. _part1_init(g, handle)
  177. else:
  178. if _part1_init != None:
  179. _part1_init(g, handle)
  180. `,
  181. },
  182. {
  183. desc: "Synonymous inherited configurations",
  184. mkname: "path/product.mk",
  185. in: `
  186. $(call inherit-product, */font.mk)
  187. `,
  188. expected: `load("//build/make/core:product_config.rbc", "rblf")
  189. load("//foo:font.star", _font_init = "init")
  190. load("//bar:font.star", _font1_init = "init")
  191. def init(g, handle):
  192. cfg = rblf.cfg(handle)
  193. rblf.inherit(handle, "foo/font", _font_init)
  194. rblf.inherit(handle, "bar/font", _font1_init)
  195. `,
  196. },
  197. {
  198. desc: "Directive define",
  199. mkname: "product.mk",
  200. in: `
  201. define some-macro
  202. $(info foo)
  203. endef
  204. `,
  205. expected: `load("//build/make/core:product_config.rbc", "rblf")
  206. def init(g, handle):
  207. cfg = rblf.cfg(handle)
  208. rblf.mk2rbc_error("product.mk:2", "define is not supported: some-macro")
  209. `,
  210. },
  211. {
  212. desc: "Ifdef",
  213. mkname: "product.mk",
  214. in: `
  215. ifdef PRODUCT_NAME
  216. PRODUCT_NAME = gizmo
  217. else
  218. endif
  219. local_var :=
  220. ifdef local_var
  221. endif
  222. `,
  223. expected: `load("//build/make/core:product_config.rbc", "rblf")
  224. def init(g, handle):
  225. cfg = rblf.cfg(handle)
  226. if cfg.get("PRODUCT_NAME", ""):
  227. cfg["PRODUCT_NAME"] = "gizmo"
  228. else:
  229. pass
  230. _local_var = ""
  231. if _local_var:
  232. pass
  233. `,
  234. },
  235. {
  236. desc: "Simple functions",
  237. mkname: "product.mk",
  238. in: `
  239. $(warning this is the warning)
  240. $(warning)
  241. $(warning # this warning starts with a pound)
  242. $(warning this warning has a # in the middle)
  243. $(info this is the info)
  244. $(error this is the error)
  245. PRODUCT_NAME:=$(shell echo *)
  246. `,
  247. expected: `load("//build/make/core:product_config.rbc", "rblf")
  248. def init(g, handle):
  249. cfg = rblf.cfg(handle)
  250. rblf.mkwarning("product.mk", "this is the warning")
  251. rblf.mkwarning("product.mk", "")
  252. rblf.mkwarning("product.mk", "# this warning starts with a pound")
  253. rblf.mkwarning("product.mk", "this warning has a # in the middle")
  254. rblf.mkinfo("product.mk", "this is the info")
  255. rblf.mkerror("product.mk", "this is the error")
  256. cfg["PRODUCT_NAME"] = rblf.shell("echo *")
  257. `,
  258. },
  259. {
  260. desc: "Empty if",
  261. mkname: "product.mk",
  262. in: `
  263. ifdef PRODUCT_NAME
  264. # Comment
  265. else
  266. TARGET_COPY_OUT_RECOVERY := foo
  267. endif
  268. `,
  269. expected: `load("//build/make/core:product_config.rbc", "rblf")
  270. def init(g, handle):
  271. cfg = rblf.cfg(handle)
  272. if cfg.get("PRODUCT_NAME", ""):
  273. # Comment
  274. pass
  275. else:
  276. rblf.mk2rbc_error("product.mk:5", "cannot set predefined variable TARGET_COPY_OUT_RECOVERY to \"foo\", its value should be \"recovery\"")
  277. `,
  278. },
  279. {
  280. desc: "if/else/endif",
  281. mkname: "product.mk",
  282. in: `
  283. ifndef PRODUCT_NAME
  284. PRODUCT_NAME=gizmo1
  285. else
  286. PRODUCT_NAME=gizmo2
  287. endif
  288. `,
  289. expected: `load("//build/make/core:product_config.rbc", "rblf")
  290. def init(g, handle):
  291. cfg = rblf.cfg(handle)
  292. if not cfg.get("PRODUCT_NAME", ""):
  293. cfg["PRODUCT_NAME"] = "gizmo1"
  294. else:
  295. cfg["PRODUCT_NAME"] = "gizmo2"
  296. `,
  297. },
  298. {
  299. desc: "else if",
  300. mkname: "product.mk",
  301. in: `
  302. ifdef PRODUCT_NAME
  303. PRODUCT_NAME = gizmo
  304. else ifndef PRODUCT_PACKAGES # Comment
  305. endif
  306. `,
  307. expected: `load("//build/make/core:product_config.rbc", "rblf")
  308. def init(g, handle):
  309. cfg = rblf.cfg(handle)
  310. if cfg.get("PRODUCT_NAME", ""):
  311. cfg["PRODUCT_NAME"] = "gizmo"
  312. elif not cfg.get("PRODUCT_PACKAGES", []):
  313. # Comment
  314. pass
  315. `,
  316. },
  317. {
  318. desc: "ifeq / ifneq",
  319. mkname: "product.mk",
  320. in: `
  321. ifeq (aosp_arm, $(TARGET_PRODUCT))
  322. PRODUCT_MODEL = pix2
  323. else
  324. PRODUCT_MODEL = pix21
  325. endif
  326. ifneq (aosp_x86, $(TARGET_PRODUCT))
  327. PRODUCT_MODEL = pix3
  328. endif
  329. `,
  330. expected: `load("//build/make/core:product_config.rbc", "rblf")
  331. def init(g, handle):
  332. cfg = rblf.cfg(handle)
  333. if "aosp_arm" == g["TARGET_PRODUCT"]:
  334. cfg["PRODUCT_MODEL"] = "pix2"
  335. else:
  336. cfg["PRODUCT_MODEL"] = "pix21"
  337. if "aosp_x86" != g["TARGET_PRODUCT"]:
  338. cfg["PRODUCT_MODEL"] = "pix3"
  339. `,
  340. },
  341. {
  342. desc: "ifeq with soong_config_get",
  343. mkname: "product.mk",
  344. in: `
  345. ifeq (true,$(call soong_config_get,art_module,source_build))
  346. endif
  347. `,
  348. expected: `load("//build/make/core:product_config.rbc", "rblf")
  349. def init(g, handle):
  350. cfg = rblf.cfg(handle)
  351. if "true" == rblf.soong_config_get(g, "art_module", "source_build"):
  352. pass
  353. `,
  354. },
  355. {
  356. desc: "ifeq with $(NATIVE_COVERAGE)",
  357. mkname: "product.mk",
  358. in: `
  359. ifeq ($(NATIVE_COVERAGE),true)
  360. endif
  361. `,
  362. expected: `load("//build/make/core:product_config.rbc", "rblf")
  363. def init(g, handle):
  364. cfg = rblf.cfg(handle)
  365. if g.get("NATIVE_COVERAGE", False):
  366. pass
  367. `,
  368. },
  369. {
  370. desc: "Check filter result",
  371. mkname: "product.mk",
  372. in: `
  373. ifeq (,$(filter userdebug eng, $(TARGET_BUILD_VARIANT)))
  374. endif
  375. ifneq (,$(filter userdebug,$(TARGET_BUILD_VARIANT))
  376. endif
  377. ifneq (,$(filter plaf,$(PLATFORM_LIST)))
  378. endif
  379. ifeq ($(TARGET_BUILD_VARIANT), $(filter $(TARGET_BUILD_VARIANT), userdebug eng))
  380. endif
  381. ifneq (, $(filter $(TARGET_BUILD_VARIANT), userdebug eng))
  382. endif
  383. ifneq (,$(filter userdebug eng, $(TARGET_BUILD_VARIANT)))
  384. endif
  385. ifneq (,$(filter true, $(v1)$(v2)))
  386. endif
  387. ifeq (,$(filter barbet coral%,$(TARGET_PRODUCT)))
  388. else ifneq (,$(filter barbet%,$(TARGET_PRODUCT)))
  389. endif
  390. ifeq (,$(filter-out sunfish_kasan, $(TARGET_PRODUCT)))
  391. endif
  392. `,
  393. expected: `load("//build/make/core:product_config.rbc", "rblf")
  394. def init(g, handle):
  395. cfg = rblf.cfg(handle)
  396. if not rblf.filter("userdebug eng", g["TARGET_BUILD_VARIANT"]):
  397. pass
  398. if rblf.filter("userdebug", g["TARGET_BUILD_VARIANT"]):
  399. pass
  400. if "plaf" in g.get("PLATFORM_LIST", []):
  401. pass
  402. if g["TARGET_BUILD_VARIANT"] == " ".join(rblf.filter(g["TARGET_BUILD_VARIANT"], "userdebug eng")):
  403. pass
  404. if g["TARGET_BUILD_VARIANT"] in ["userdebug", "eng"]:
  405. pass
  406. if rblf.filter("userdebug eng", g["TARGET_BUILD_VARIANT"]):
  407. pass
  408. if rblf.filter("true", "%s%s" % (_v1, _v2)):
  409. pass
  410. if not rblf.filter("barbet coral%", g["TARGET_PRODUCT"]):
  411. pass
  412. elif rblf.filter("barbet%", g["TARGET_PRODUCT"]):
  413. pass
  414. if not rblf.filter_out("sunfish_kasan", g["TARGET_PRODUCT"]):
  415. pass
  416. `,
  417. },
  418. {
  419. desc: "Get filter result",
  420. mkname: "product.mk",
  421. in: `
  422. PRODUCT_LIST2=$(filter-out %/foo.ko,$(wildcard path/*.ko))
  423. `,
  424. expected: `load("//build/make/core:product_config.rbc", "rblf")
  425. def init(g, handle):
  426. cfg = rblf.cfg(handle)
  427. cfg["PRODUCT_LIST2"] = rblf.filter_out("%/foo.ko", rblf.expand_wildcard("path/*.ko"))
  428. `,
  429. },
  430. {
  431. desc: "filter $(VAR), values",
  432. mkname: "product.mk",
  433. in: `
  434. ifeq (,$(filter $(TARGET_PRODUCT), yukawa_gms yukawa_sei510_gms)
  435. ifneq (,$(filter $(TARGET_PRODUCT), yukawa_gms)
  436. endif
  437. endif
  438. `,
  439. expected: `load("//build/make/core:product_config.rbc", "rblf")
  440. def init(g, handle):
  441. cfg = rblf.cfg(handle)
  442. if g["TARGET_PRODUCT"] not in ["yukawa_gms", "yukawa_sei510_gms"]:
  443. if g["TARGET_PRODUCT"] == "yukawa_gms":
  444. pass
  445. `,
  446. },
  447. {
  448. desc: "filter $(V1), $(V2)",
  449. mkname: "product.mk",
  450. in: `
  451. ifneq (, $(filter $(PRODUCT_LIST), $(TARGET_PRODUCT)))
  452. endif
  453. `,
  454. expected: `load("//build/make/core:product_config.rbc", "rblf")
  455. def init(g, handle):
  456. cfg = rblf.cfg(handle)
  457. if rblf.filter(g.get("PRODUCT_LIST", []), g["TARGET_PRODUCT"]):
  458. pass
  459. `,
  460. },
  461. {
  462. desc: "ifeq",
  463. mkname: "product.mk",
  464. in: `
  465. ifeq (aosp, $(TARGET_PRODUCT)) # Comment
  466. else ifneq (, $(TARGET_PRODUCT))
  467. endif
  468. `,
  469. expected: `load("//build/make/core:product_config.rbc", "rblf")
  470. def init(g, handle):
  471. cfg = rblf.cfg(handle)
  472. if "aosp" == g["TARGET_PRODUCT"]:
  473. # Comment
  474. pass
  475. elif g["TARGET_PRODUCT"]:
  476. pass
  477. `,
  478. },
  479. {
  480. desc: "Nested if",
  481. mkname: "product.mk",
  482. in: `
  483. ifdef PRODUCT_NAME
  484. PRODUCT_PACKAGES = pack-if0
  485. ifdef PRODUCT_MODEL
  486. PRODUCT_PACKAGES = pack-if-if
  487. else ifdef PRODUCT_NAME
  488. PRODUCT_PACKAGES = pack-if-elif
  489. else
  490. PRODUCT_PACKAGES = pack-if-else
  491. endif
  492. PRODUCT_PACKAGES = pack-if
  493. else ifneq (,$(TARGET_PRODUCT))
  494. PRODUCT_PACKAGES = pack-elif
  495. else
  496. PRODUCT_PACKAGES = pack-else
  497. endif
  498. `,
  499. expected: `load("//build/make/core:product_config.rbc", "rblf")
  500. def init(g, handle):
  501. cfg = rblf.cfg(handle)
  502. if cfg.get("PRODUCT_NAME", ""):
  503. cfg["PRODUCT_PACKAGES"] = ["pack-if0"]
  504. if cfg.get("PRODUCT_MODEL", ""):
  505. cfg["PRODUCT_PACKAGES"] = ["pack-if-if"]
  506. elif cfg.get("PRODUCT_NAME", ""):
  507. cfg["PRODUCT_PACKAGES"] = ["pack-if-elif"]
  508. else:
  509. cfg["PRODUCT_PACKAGES"] = ["pack-if-else"]
  510. cfg["PRODUCT_PACKAGES"] = ["pack-if"]
  511. elif g["TARGET_PRODUCT"]:
  512. cfg["PRODUCT_PACKAGES"] = ["pack-elif"]
  513. else:
  514. cfg["PRODUCT_PACKAGES"] = ["pack-else"]
  515. `,
  516. },
  517. {
  518. desc: "Wildcard",
  519. mkname: "product.mk",
  520. in: `
  521. ifeq (,$(wildcard foo.mk))
  522. endif
  523. ifneq (,$(wildcard foo*.mk))
  524. endif
  525. `,
  526. expected: `load("//build/make/core:product_config.rbc", "rblf")
  527. def init(g, handle):
  528. cfg = rblf.cfg(handle)
  529. if not rblf.file_exists("foo.mk"):
  530. pass
  531. if rblf.file_wildcard_exists("foo*.mk"):
  532. pass
  533. `,
  534. },
  535. {
  536. desc: "if with interpolation",
  537. mkname: "product.mk",
  538. in: `
  539. ifeq ($(VARIABLE1)text$(VARIABLE2),true)
  540. endif
  541. `,
  542. expected: `load("//build/make/core:product_config.rbc", "rblf")
  543. def init(g, handle):
  544. cfg = rblf.cfg(handle)
  545. if "%stext%s" % (g.get("VARIABLE1", ""), g.get("VARIABLE2", "")) == "true":
  546. pass
  547. `,
  548. },
  549. {
  550. desc: "ifneq $(X),true",
  551. mkname: "product.mk",
  552. in: `
  553. ifneq ($(VARIABLE),true)
  554. endif
  555. `,
  556. expected: `load("//build/make/core:product_config.rbc", "rblf")
  557. def init(g, handle):
  558. cfg = rblf.cfg(handle)
  559. if g.get("VARIABLE", "") != "true":
  560. pass
  561. `,
  562. },
  563. {
  564. desc: "Const neq",
  565. mkname: "product.mk",
  566. in: `
  567. ifneq (1,0)
  568. endif
  569. `,
  570. expected: `load("//build/make/core:product_config.rbc", "rblf")
  571. def init(g, handle):
  572. cfg = rblf.cfg(handle)
  573. if "1" != "0":
  574. pass
  575. `,
  576. },
  577. {
  578. desc: "is-board calls",
  579. mkname: "product.mk",
  580. in: `
  581. ifeq ($(call is-board-platform-in-list,msm8998), true)
  582. else ifneq ($(call is-board-platform,copper),true)
  583. else ifneq ($(call is-vendor-board-platform,QCOM),true)
  584. else ifeq ($(call is-product-in-list, $(PLATFORM_LIST)), true)
  585. endif
  586. `,
  587. expected: `load("//build/make/core:product_config.rbc", "rblf")
  588. def init(g, handle):
  589. cfg = rblf.cfg(handle)
  590. if rblf.board_platform_in(g, "msm8998"):
  591. pass
  592. elif not rblf.board_platform_is(g, "copper"):
  593. pass
  594. elif g.get("TARGET_BOARD_PLATFORM", "") not in g.get("QCOM_BOARD_PLATFORMS", ""):
  595. pass
  596. elif g["TARGET_PRODUCT"] in g.get("PLATFORM_LIST", []):
  597. pass
  598. `,
  599. },
  600. {
  601. desc: "new is-board calls",
  602. mkname: "product.mk",
  603. in: `
  604. ifneq (,$(call is-board-platform-in-list2,msm8998 $(X))
  605. else ifeq (,$(call is-board-platform2,copper)
  606. else ifneq (,$(call is-vendor-board-qcom))
  607. endif
  608. `,
  609. expected: `load("//build/make/core:product_config.rbc", "rblf")
  610. def init(g, handle):
  611. cfg = rblf.cfg(handle)
  612. if rblf.board_platform_in(g, "msm8998 %s" % g.get("X", "")):
  613. pass
  614. elif not rblf.board_platform_is(g, "copper"):
  615. pass
  616. elif g.get("TARGET_BOARD_PLATFORM", "") in g.get("QCOM_BOARD_PLATFORMS", ""):
  617. pass
  618. `,
  619. },
  620. {
  621. desc: "findstring call",
  622. mkname: "product.mk",
  623. in: `
  624. result := $(findstring a,a b c)
  625. result := $(findstring b,x y z)
  626. `,
  627. expected: `load("//build/make/core:product_config.rbc", "rblf")
  628. def init(g, handle):
  629. cfg = rblf.cfg(handle)
  630. _result = rblf.findstring("a", "a b c")
  631. _result = rblf.findstring("b", "x y z")
  632. `,
  633. },
  634. {
  635. desc: "findstring in if statement",
  636. mkname: "product.mk",
  637. in: `
  638. ifeq ($(findstring foo,$(PRODUCT_PACKAGES)),)
  639. endif
  640. ifneq ($(findstring foo,$(PRODUCT_PACKAGES)),)
  641. endif
  642. ifeq ($(findstring foo,$(PRODUCT_PACKAGES)),foo)
  643. endif
  644. ifneq ($(findstring foo,$(PRODUCT_PACKAGES)),foo)
  645. endif
  646. `,
  647. expected: `load("//build/make/core:product_config.rbc", "rblf")
  648. def init(g, handle):
  649. cfg = rblf.cfg(handle)
  650. if (cfg.get("PRODUCT_PACKAGES", [])).find("foo") == -1:
  651. pass
  652. if (cfg.get("PRODUCT_PACKAGES", [])).find("foo") != -1:
  653. pass
  654. if (cfg.get("PRODUCT_PACKAGES", [])).find("foo") != -1:
  655. pass
  656. if (cfg.get("PRODUCT_PACKAGES", [])).find("foo") == -1:
  657. pass
  658. `,
  659. },
  660. {
  661. desc: "rhs call",
  662. mkname: "product.mk",
  663. in: `
  664. PRODUCT_COPY_FILES = $(call add-to-product-copy-files-if-exists, path:distpath) \
  665. $(call find-copy-subdir-files, *, fromdir, todir) $(wildcard foo.*)
  666. `,
  667. expected: `load("//build/make/core:product_config.rbc", "rblf")
  668. def init(g, handle):
  669. cfg = rblf.cfg(handle)
  670. cfg["PRODUCT_COPY_FILES"] = (rblf.copy_if_exists("path:distpath") +
  671. rblf.find_and_copy("*", "fromdir", "todir") +
  672. rblf.expand_wildcard("foo.*"))
  673. `,
  674. },
  675. {
  676. desc: "inferred type",
  677. mkname: "product.mk",
  678. in: `
  679. HIKEY_MODS := $(wildcard foo/*.ko)
  680. BOARD_VENDOR_KERNEL_MODULES += $(HIKEY_MODS)
  681. `,
  682. expected: `load("//build/make/core:product_config.rbc", "rblf")
  683. def init(g, handle):
  684. cfg = rblf.cfg(handle)
  685. g["HIKEY_MODS"] = rblf.expand_wildcard("foo/*.ko")
  686. g.setdefault("BOARD_VENDOR_KERNEL_MODULES", [])
  687. g["BOARD_VENDOR_KERNEL_MODULES"] += g["HIKEY_MODS"]
  688. `,
  689. },
  690. {
  691. desc: "list with vars",
  692. mkname: "product.mk",
  693. in: `
  694. PRODUCT_COPY_FILES += path1:$(TARGET_PRODUCT)/path1 $(PRODUCT_MODEL)/path2:$(TARGET_PRODUCT)/path2
  695. `,
  696. expected: `load("//build/make/core:product_config.rbc", "rblf")
  697. def init(g, handle):
  698. cfg = rblf.cfg(handle)
  699. rblf.setdefault(handle, "PRODUCT_COPY_FILES")
  700. cfg["PRODUCT_COPY_FILES"] += (("path1:%s/path1" % g["TARGET_PRODUCT"]).split() +
  701. ("%s/path2:%s/path2" % (cfg.get("PRODUCT_MODEL", ""), g["TARGET_PRODUCT"])).split())
  702. `,
  703. },
  704. {
  705. desc: "misc calls",
  706. mkname: "product.mk",
  707. in: `
  708. $(call enforce-product-packages-exist,)
  709. $(call enforce-product-packages-exist, foo)
  710. $(call require-artifacts-in-path, foo, bar)
  711. $(call require-artifacts-in-path-relaxed, foo, bar)
  712. $(call dist-for-goals, goal, from:to)
  713. $(call add-product-dex-preopt-module-config,MyModule,disable)
  714. `,
  715. expected: `load("//build/make/core:product_config.rbc", "rblf")
  716. def init(g, handle):
  717. cfg = rblf.cfg(handle)
  718. rblf.enforce_product_packages_exist("")
  719. rblf.enforce_product_packages_exist("foo")
  720. rblf.require_artifacts_in_path("foo", "bar")
  721. rblf.require_artifacts_in_path_relaxed("foo", "bar")
  722. rblf.mkdist_for_goals(g, "goal", "from:to")
  723. rblf.add_product_dex_preopt_module_config(handle, "MyModule", "disable")
  724. `,
  725. },
  726. {
  727. desc: "list with functions",
  728. mkname: "product.mk",
  729. in: `
  730. PRODUCT_COPY_FILES := $(call find-copy-subdir-files,*.kl,from1,to1) \
  731. $(call find-copy-subdir-files,*.kc,from2,to2) \
  732. foo bar
  733. `,
  734. expected: `load("//build/make/core:product_config.rbc", "rblf")
  735. def init(g, handle):
  736. cfg = rblf.cfg(handle)
  737. cfg["PRODUCT_COPY_FILES"] = (rblf.find_and_copy("*.kl", "from1", "to1") +
  738. rblf.find_and_copy("*.kc", "from2", "to2") +
  739. [
  740. "foo",
  741. "bar",
  742. ])
  743. `,
  744. },
  745. {
  746. desc: "Text functions",
  747. mkname: "product.mk",
  748. in: `
  749. PRODUCT_COPY_FILES := $(addprefix pfx-,a b c)
  750. PRODUCT_COPY_FILES := $(addsuffix .sff, a b c)
  751. PRODUCT_NAME := $(word 1, $(subst ., ,$(TARGET_BOARD_PLATFORM)))
  752. $(info $(patsubst %.pub,$(PRODUCT_NAME)%,$(PRODUCT_ADB_KEYS)))
  753. $(info $$(dir foo/bar): $(dir foo/bar))
  754. $(info $(firstword $(PRODUCT_COPY_FILES)))
  755. $(info $(lastword $(PRODUCT_COPY_FILES)))
  756. $(info $(dir $(lastword $(MAKEFILE_LIST))))
  757. $(info $(dir $(lastword $(PRODUCT_COPY_FILES))))
  758. $(info $(dir $(lastword $(foobar))))
  759. $(info $(abspath foo/bar))
  760. $(info $(notdir foo/bar))
  761. $(call add_soong_config_namespace,snsconfig)
  762. $(call add_soong_config_var_value,snsconfig,imagetype,odm_image)
  763. $(call soong_config_set, snsconfig, foo, foo_value)
  764. $(call soong_config_append, snsconfig, bar, bar_value)
  765. PRODUCT_COPY_FILES := $(call copy-files,$(wildcard foo*.mk),etc)
  766. PRODUCT_COPY_FILES := $(call product-copy-files-by-pattern,from/%,to/%,a b c)
  767. `,
  768. expected: `load("//build/make/core:product_config.rbc", "rblf")
  769. def init(g, handle):
  770. cfg = rblf.cfg(handle)
  771. cfg["PRODUCT_COPY_FILES"] = rblf.addprefix("pfx-", "a b c")
  772. cfg["PRODUCT_COPY_FILES"] = rblf.addsuffix(".sff", "a b c")
  773. cfg["PRODUCT_NAME"] = ((g.get("TARGET_BOARD_PLATFORM", "")).replace(".", " ")).split()[0]
  774. rblf.mkinfo("product.mk", rblf.mkpatsubst("%.pub", "%s%%" % cfg["PRODUCT_NAME"], g.get("PRODUCT_ADB_KEYS", "")))
  775. rblf.mkinfo("product.mk", "$(dir foo/bar): %s" % rblf.dir("foo/bar"))
  776. rblf.mkinfo("product.mk", cfg["PRODUCT_COPY_FILES"][0])
  777. rblf.mkinfo("product.mk", cfg["PRODUCT_COPY_FILES"][-1])
  778. rblf.mkinfo("product.mk", rblf.dir("product.mk"))
  779. rblf.mkinfo("product.mk", rblf.dir(cfg["PRODUCT_COPY_FILES"][-1]))
  780. rblf.mkinfo("product.mk", rblf.dir((_foobar).split()[-1]))
  781. rblf.mkinfo("product.mk", rblf.abspath("foo/bar"))
  782. rblf.mkinfo("product.mk", rblf.notdir("foo/bar"))
  783. rblf.soong_config_namespace(g, "snsconfig")
  784. rblf.soong_config_set(g, "snsconfig", "imagetype", "odm_image")
  785. rblf.soong_config_set(g, "snsconfig", "foo", "foo_value")
  786. rblf.soong_config_append(g, "snsconfig", "bar", "bar_value")
  787. cfg["PRODUCT_COPY_FILES"] = rblf.copy_files(rblf.expand_wildcard("foo*.mk"), "etc")
  788. cfg["PRODUCT_COPY_FILES"] = rblf.product_copy_files_by_pattern("from/%", "to/%", "a b c")
  789. `,
  790. },
  791. {
  792. desc: "subst in list",
  793. mkname: "product.mk",
  794. in: `
  795. files = $(call find-copy-subdir-files,*,from,to)
  796. PRODUCT_COPY_FILES += $(subst foo,bar,$(files))
  797. `,
  798. expected: `load("//build/make/core:product_config.rbc", "rblf")
  799. def init(g, handle):
  800. cfg = rblf.cfg(handle)
  801. _files = rblf.find_and_copy("*", "from", "to")
  802. rblf.setdefault(handle, "PRODUCT_COPY_FILES")
  803. cfg["PRODUCT_COPY_FILES"] += rblf.mksubst("foo", "bar", _files)
  804. `,
  805. },
  806. {
  807. desc: "assignment flavors",
  808. mkname: "product.mk",
  809. in: `
  810. PRODUCT_LIST1 := a
  811. PRODUCT_LIST2 += a
  812. PRODUCT_LIST1 += b
  813. PRODUCT_LIST2 += b
  814. PRODUCT_LIST3 ?= a
  815. PRODUCT_LIST1 = c
  816. PLATFORM_LIST += x
  817. PRODUCT_PACKAGES := $(PLATFORM_LIST)
  818. `,
  819. expected: `load("//build/make/core:product_config.rbc", "rblf")
  820. def init(g, handle):
  821. cfg = rblf.cfg(handle)
  822. cfg["PRODUCT_LIST1"] = ["a"]
  823. rblf.setdefault(handle, "PRODUCT_LIST2")
  824. cfg["PRODUCT_LIST2"] += ["a"]
  825. cfg["PRODUCT_LIST1"] += ["b"]
  826. cfg["PRODUCT_LIST2"] += ["b"]
  827. if cfg.get("PRODUCT_LIST3") == None:
  828. cfg["PRODUCT_LIST3"] = ["a"]
  829. cfg["PRODUCT_LIST1"] = ["c"]
  830. g.setdefault("PLATFORM_LIST", [])
  831. g["PLATFORM_LIST"] += ["x"]
  832. cfg["PRODUCT_PACKAGES"] = g["PLATFORM_LIST"][:]
  833. `,
  834. },
  835. {
  836. desc: "assigment flavors2",
  837. mkname: "product.mk",
  838. in: `
  839. PRODUCT_LIST1 = a
  840. ifeq (0,1)
  841. PRODUCT_LIST1 += b
  842. PRODUCT_LIST2 += b
  843. endif
  844. PRODUCT_LIST1 += c
  845. PRODUCT_LIST2 += c
  846. `,
  847. expected: `load("//build/make/core:product_config.rbc", "rblf")
  848. def init(g, handle):
  849. cfg = rblf.cfg(handle)
  850. cfg["PRODUCT_LIST1"] = ["a"]
  851. if "0" == "1":
  852. cfg["PRODUCT_LIST1"] += ["b"]
  853. rblf.setdefault(handle, "PRODUCT_LIST2")
  854. cfg["PRODUCT_LIST2"] += ["b"]
  855. cfg["PRODUCT_LIST1"] += ["c"]
  856. rblf.setdefault(handle, "PRODUCT_LIST2")
  857. cfg["PRODUCT_LIST2"] += ["c"]
  858. `,
  859. },
  860. {
  861. desc: "assigment setdefaults",
  862. mkname: "product.mk",
  863. in: `
  864. # All of these should have a setdefault because they're self-referential and not defined before
  865. PRODUCT_LIST1 = a $(PRODUCT_LIST1)
  866. PRODUCT_LIST2 ?= a $(PRODUCT_LIST2)
  867. PRODUCT_LIST3 += a
  868. # Now doing them again should not have a setdefault because they've already been set
  869. PRODUCT_LIST1 = a $(PRODUCT_LIST1)
  870. PRODUCT_LIST2 ?= a $(PRODUCT_LIST2)
  871. PRODUCT_LIST3 += a
  872. `,
  873. expected: `# All of these should have a setdefault because they're self-referential and not defined before
  874. load("//build/make/core:product_config.rbc", "rblf")
  875. def init(g, handle):
  876. cfg = rblf.cfg(handle)
  877. rblf.setdefault(handle, "PRODUCT_LIST1")
  878. cfg["PRODUCT_LIST1"] = (["a"] +
  879. cfg.get("PRODUCT_LIST1", []))
  880. if cfg.get("PRODUCT_LIST2") == None:
  881. rblf.setdefault(handle, "PRODUCT_LIST2")
  882. cfg["PRODUCT_LIST2"] = (["a"] +
  883. cfg.get("PRODUCT_LIST2", []))
  884. rblf.setdefault(handle, "PRODUCT_LIST3")
  885. cfg["PRODUCT_LIST3"] += ["a"]
  886. # Now doing them again should not have a setdefault because they've already been set
  887. cfg["PRODUCT_LIST1"] = (["a"] +
  888. cfg["PRODUCT_LIST1"])
  889. if cfg.get("PRODUCT_LIST2") == None:
  890. cfg["PRODUCT_LIST2"] = (["a"] +
  891. cfg["PRODUCT_LIST2"])
  892. cfg["PRODUCT_LIST3"] += ["a"]
  893. `,
  894. },
  895. {
  896. desc: "soong namespace assignments",
  897. mkname: "product.mk",
  898. in: `
  899. SOONG_CONFIG_NAMESPACES += cvd
  900. SOONG_CONFIG_cvd += launch_configs
  901. SOONG_CONFIG_cvd_launch_configs = cvd_config_auto.json
  902. SOONG_CONFIG_cvd += grub_config
  903. SOONG_CONFIG_cvd_grub_config += grub.cfg
  904. x := $(SOONG_CONFIG_cvd_grub_config)
  905. `,
  906. expected: `load("//build/make/core:product_config.rbc", "rblf")
  907. def init(g, handle):
  908. cfg = rblf.cfg(handle)
  909. rblf.soong_config_namespace(g, "cvd")
  910. rblf.soong_config_set(g, "cvd", "launch_configs", "cvd_config_auto.json")
  911. rblf.soong_config_append(g, "cvd", "grub_config", "grub.cfg")
  912. rblf.mk2rbc_error("product.mk:7", "SOONG_CONFIG_ variables cannot be referenced, use soong_config_get instead: SOONG_CONFIG_cvd_grub_config")
  913. `,
  914. }, {
  915. desc: "soong namespace accesses",
  916. mkname: "product.mk",
  917. in: `
  918. SOONG_CONFIG_NAMESPACES += cvd
  919. SOONG_CONFIG_cvd += launch_configs
  920. SOONG_CONFIG_cvd_launch_configs = cvd_config_auto.json
  921. SOONG_CONFIG_cvd += grub_config
  922. SOONG_CONFIG_cvd_grub_config += grub.cfg
  923. x := $(call soong_config_get,cvd,grub_config)
  924. `,
  925. expected: `load("//build/make/core:product_config.rbc", "rblf")
  926. def init(g, handle):
  927. cfg = rblf.cfg(handle)
  928. rblf.soong_config_namespace(g, "cvd")
  929. rblf.soong_config_set(g, "cvd", "launch_configs", "cvd_config_auto.json")
  930. rblf.soong_config_append(g, "cvd", "grub_config", "grub.cfg")
  931. _x = rblf.soong_config_get(g, "cvd", "grub_config")
  932. `,
  933. },
  934. {
  935. desc: "string split",
  936. mkname: "product.mk",
  937. in: `
  938. PRODUCT_LIST1 = a
  939. local = b
  940. local += c
  941. FOO = d
  942. FOO += e
  943. PRODUCT_LIST1 += $(local)
  944. PRODUCT_LIST1 += $(FOO)
  945. `,
  946. expected: `load("//build/make/core:product_config.rbc", "rblf")
  947. def init(g, handle):
  948. cfg = rblf.cfg(handle)
  949. cfg["PRODUCT_LIST1"] = ["a"]
  950. _local = "b"
  951. _local += " " + "c"
  952. g["FOO"] = "d"
  953. g["FOO"] += " " + "e"
  954. cfg["PRODUCT_LIST1"] += (_local).split()
  955. cfg["PRODUCT_LIST1"] += (g["FOO"]).split()
  956. `,
  957. },
  958. {
  959. desc: "apex_jars",
  960. mkname: "product.mk",
  961. in: `
  962. PRODUCT_BOOT_JARS := $(ART_APEX_JARS) framework-minus-apex
  963. `,
  964. expected: `load("//build/make/core:product_config.rbc", "rblf")
  965. def init(g, handle):
  966. cfg = rblf.cfg(handle)
  967. cfg["PRODUCT_BOOT_JARS"] = (g.get("ART_APEX_JARS", []) +
  968. ["framework-minus-apex"])
  969. `,
  970. },
  971. {
  972. desc: "strip function",
  973. mkname: "product.mk",
  974. in: `
  975. ifeq ($(filter hwaddress,$(PRODUCT_PACKAGES)),)
  976. PRODUCT_PACKAGES := $(strip $(PRODUCT_PACKAGES) hwaddress)
  977. endif
  978. `,
  979. expected: `load("//build/make/core:product_config.rbc", "rblf")
  980. def init(g, handle):
  981. cfg = rblf.cfg(handle)
  982. if "hwaddress" not in cfg.get("PRODUCT_PACKAGES", []):
  983. rblf.setdefault(handle, "PRODUCT_PACKAGES")
  984. cfg["PRODUCT_PACKAGES"] = (rblf.mkstrip("%s hwaddress" % " ".join(cfg.get("PRODUCT_PACKAGES", [])))).split()
  985. `,
  986. },
  987. {
  988. desc: "strip func in condition",
  989. mkname: "product.mk",
  990. in: `
  991. ifneq ($(strip $(TARGET_VENDOR)),)
  992. endif
  993. `,
  994. expected: `load("//build/make/core:product_config.rbc", "rblf")
  995. def init(g, handle):
  996. cfg = rblf.cfg(handle)
  997. if rblf.mkstrip(g.get("TARGET_VENDOR", "")):
  998. pass
  999. `,
  1000. },
  1001. {
  1002. desc: "ref after set",
  1003. mkname: "product.mk",
  1004. in: `
  1005. PRODUCT_ADB_KEYS:=value
  1006. FOO := $(PRODUCT_ADB_KEYS)
  1007. ifneq (,$(PRODUCT_ADB_KEYS))
  1008. endif
  1009. `,
  1010. expected: `load("//build/make/core:product_config.rbc", "rblf")
  1011. def init(g, handle):
  1012. cfg = rblf.cfg(handle)
  1013. g["PRODUCT_ADB_KEYS"] = "value"
  1014. g["FOO"] = g["PRODUCT_ADB_KEYS"]
  1015. if g["PRODUCT_ADB_KEYS"]:
  1016. pass
  1017. `,
  1018. },
  1019. {
  1020. desc: "ref before set",
  1021. mkname: "product.mk",
  1022. in: `
  1023. V1 := $(PRODUCT_ADB_KEYS)
  1024. ifeq (,$(PRODUCT_ADB_KEYS))
  1025. V2 := $(PRODUCT_ADB_KEYS)
  1026. PRODUCT_ADB_KEYS:=foo
  1027. V3 := $(PRODUCT_ADB_KEYS)
  1028. endif`,
  1029. expected: `load("//build/make/core:product_config.rbc", "rblf")
  1030. def init(g, handle):
  1031. cfg = rblf.cfg(handle)
  1032. g["V1"] = g.get("PRODUCT_ADB_KEYS", "")
  1033. if not g.get("PRODUCT_ADB_KEYS", ""):
  1034. g["V2"] = g.get("PRODUCT_ADB_KEYS", "")
  1035. g["PRODUCT_ADB_KEYS"] = "foo"
  1036. g["V3"] = g["PRODUCT_ADB_KEYS"]
  1037. `,
  1038. },
  1039. {
  1040. desc: "Dynamic inherit path",
  1041. mkname: "product.mk",
  1042. in: `
  1043. MY_PATH:=foo
  1044. $(call inherit-product,vendor/$(MY_PATH)/cfg.mk)
  1045. `,
  1046. expected: `load("//build/make/core:product_config.rbc", "rblf")
  1047. load("//vendor/foo1:cfg.star|init", _cfg_init = "init")
  1048. load("//vendor/bar/baz:cfg.star|init", _cfg1_init = "init")
  1049. def init(g, handle):
  1050. cfg = rblf.cfg(handle)
  1051. g["MY_PATH"] = "foo"
  1052. _entry = {
  1053. "vendor/foo1/cfg.mk": ("vendor/foo1/cfg", _cfg_init),
  1054. "vendor/bar/baz/cfg.mk": ("vendor/bar/baz/cfg", _cfg1_init),
  1055. }.get("vendor/%s/cfg.mk" % g["MY_PATH"])
  1056. (_varmod, _varmod_init) = _entry if _entry else (None, None)
  1057. if not _varmod_init:
  1058. rblf.mkerror("product.mk", "Cannot find %s" % ("vendor/%s/cfg.mk" % g["MY_PATH"]))
  1059. rblf.inherit(handle, _varmod, _varmod_init)
  1060. `,
  1061. },
  1062. {
  1063. desc: "Dynamic inherit with hint",
  1064. mkname: "product.mk",
  1065. in: `
  1066. MY_PATH:=foo
  1067. #RBC# include_top vendor/foo1
  1068. $(call inherit-product,$(MY_PATH)/cfg.mk)
  1069. `,
  1070. expected: `load("//build/make/core:product_config.rbc", "rblf")
  1071. load("//vendor/foo1:cfg.star|init", _cfg_init = "init")
  1072. def init(g, handle):
  1073. cfg = rblf.cfg(handle)
  1074. g["MY_PATH"] = "foo"
  1075. _entry = {
  1076. "vendor/foo1/cfg.mk": ("vendor/foo1/cfg", _cfg_init),
  1077. }.get("%s/cfg.mk" % g["MY_PATH"])
  1078. (_varmod, _varmod_init) = _entry if _entry else (None, None)
  1079. if not _varmod_init:
  1080. rblf.mkerror("product.mk", "Cannot find %s" % ("%s/cfg.mk" % g["MY_PATH"]))
  1081. rblf.inherit(handle, _varmod, _varmod_init)
  1082. `,
  1083. },
  1084. {
  1085. desc: "Dynamic inherit with duplicated hint",
  1086. mkname: "product.mk",
  1087. in: `
  1088. MY_PATH:=foo
  1089. #RBC# include_top vendor/foo1
  1090. $(call inherit-product,$(MY_PATH)/cfg.mk)
  1091. #RBC# include_top vendor/foo1
  1092. #RBC# include_top vendor/foo1
  1093. $(call inherit-product,$(MY_PATH)/cfg.mk)
  1094. `,
  1095. expected: `load("//build/make/core:product_config.rbc", "rblf")
  1096. load("//vendor/foo1:cfg.star|init", _cfg_init = "init")
  1097. def init(g, handle):
  1098. cfg = rblf.cfg(handle)
  1099. g["MY_PATH"] = "foo"
  1100. _entry = {
  1101. "vendor/foo1/cfg.mk": ("vendor/foo1/cfg", _cfg_init),
  1102. }.get("%s/cfg.mk" % g["MY_PATH"])
  1103. (_varmod, _varmod_init) = _entry if _entry else (None, None)
  1104. if not _varmod_init:
  1105. rblf.mkerror("product.mk", "Cannot find %s" % ("%s/cfg.mk" % g["MY_PATH"]))
  1106. rblf.inherit(handle, _varmod, _varmod_init)
  1107. _entry = {
  1108. "vendor/foo1/cfg.mk": ("vendor/foo1/cfg", _cfg_init),
  1109. }.get("%s/cfg.mk" % g["MY_PATH"])
  1110. (_varmod, _varmod_init) = _entry if _entry else (None, None)
  1111. if not _varmod_init:
  1112. rblf.mkerror("product.mk", "Cannot find %s" % ("%s/cfg.mk" % g["MY_PATH"]))
  1113. rblf.inherit(handle, _varmod, _varmod_init)
  1114. `,
  1115. },
  1116. {
  1117. desc: "Dynamic inherit path that lacks hint",
  1118. mkname: "product.mk",
  1119. in: `
  1120. #RBC# include_top foo
  1121. $(call inherit-product,$(MY_VAR)/font.mk)
  1122. #RBC# include_top foo
  1123. # There's some space and even this comment between the include_top and the inherit-product
  1124. $(call inherit-product,$(MY_VAR)/font.mk)
  1125. $(call inherit-product,$(MY_VAR)/font.mk)
  1126. `,
  1127. expected: `load("//build/make/core:product_config.rbc", "rblf")
  1128. load("//foo:font.star|init", _font_init = "init")
  1129. load("//bar:font.star|init", _font1_init = "init")
  1130. def init(g, handle):
  1131. cfg = rblf.cfg(handle)
  1132. _entry = {
  1133. "foo/font.mk": ("foo/font", _font_init),
  1134. }.get("%s/font.mk" % g.get("MY_VAR", ""))
  1135. (_varmod, _varmod_init) = _entry if _entry else (None, None)
  1136. if not _varmod_init:
  1137. rblf.mkerror("product.mk", "Cannot find %s" % ("%s/font.mk" % g.get("MY_VAR", "")))
  1138. rblf.inherit(handle, _varmod, _varmod_init)
  1139. # There's some space and even this comment between the include_top and the inherit-product
  1140. _entry = {
  1141. "foo/font.mk": ("foo/font", _font_init),
  1142. }.get("%s/font.mk" % g.get("MY_VAR", ""))
  1143. (_varmod, _varmod_init) = _entry if _entry else (None, None)
  1144. if not _varmod_init:
  1145. rblf.mkerror("product.mk", "Cannot find %s" % ("%s/font.mk" % g.get("MY_VAR", "")))
  1146. rblf.inherit(handle, _varmod, _varmod_init)
  1147. rblf.mkwarning("product.mk:11", "Please avoid starting an include path with a variable. See https://source.android.com/setup/build/bazel/product_config/issues/includes for details.")
  1148. _entry = {
  1149. "foo/font.mk": ("foo/font", _font_init),
  1150. "bar/font.mk": ("bar/font", _font1_init),
  1151. }.get("%s/font.mk" % g.get("MY_VAR", ""))
  1152. (_varmod, _varmod_init) = _entry if _entry else (None, None)
  1153. if not _varmod_init:
  1154. rblf.mkerror("product.mk", "Cannot find %s" % ("%s/font.mk" % g.get("MY_VAR", "")))
  1155. rblf.inherit(handle, _varmod, _varmod_init)
  1156. `,
  1157. },
  1158. {
  1159. desc: "Ignore make rules",
  1160. mkname: "product.mk",
  1161. in: `
  1162. foo: foo.c
  1163. gcc -o $@ $*`,
  1164. expected: `load("//build/make/core:product_config.rbc", "rblf")
  1165. def init(g, handle):
  1166. cfg = rblf.cfg(handle)
  1167. rblf.mk2rbc_error("product.mk:2", "unsupported line rule: foo: foo.c\n#gcc -o $@ $*")
  1168. `,
  1169. },
  1170. {
  1171. desc: "Flag override",
  1172. mkname: "product.mk",
  1173. in: `
  1174. override FOO:=`,
  1175. expected: `load("//build/make/core:product_config.rbc", "rblf")
  1176. def init(g, handle):
  1177. cfg = rblf.cfg(handle)
  1178. rblf.mk2rbc_error("product.mk:2", "cannot handle override directive")
  1179. `,
  1180. },
  1181. {
  1182. desc: "Bad expression",
  1183. mkname: "build/product.mk",
  1184. in: `
  1185. ifeq (,$(call foobar))
  1186. endif
  1187. `,
  1188. expected: `load("//build/make/core:product_config.rbc", "rblf")
  1189. def init(g, handle):
  1190. cfg = rblf.cfg(handle)
  1191. if rblf.mk2rbc_error("build/product.mk:2", "cannot handle invoking foobar"):
  1192. pass
  1193. `,
  1194. },
  1195. {
  1196. desc: "if expression",
  1197. mkname: "product.mk",
  1198. in: `
  1199. TEST_VAR := foo
  1200. TEST_VAR_LIST := foo
  1201. TEST_VAR_LIST += bar
  1202. TEST_VAR_2 := $(if $(TEST_VAR),bar)
  1203. TEST_VAR_3 := $(if $(TEST_VAR),bar,baz)
  1204. TEST_VAR_4 := $(if $(TEST_VAR),$(TEST_VAR_LIST))
  1205. `,
  1206. expected: `load("//build/make/core:product_config.rbc", "rblf")
  1207. def init(g, handle):
  1208. cfg = rblf.cfg(handle)
  1209. g["TEST_VAR"] = "foo"
  1210. g["TEST_VAR_LIST"] = ["foo"]
  1211. g["TEST_VAR_LIST"] += ["bar"]
  1212. g["TEST_VAR_2"] = ("bar" if g["TEST_VAR"] else "")
  1213. g["TEST_VAR_3"] = ("bar" if g["TEST_VAR"] else "baz")
  1214. g["TEST_VAR_4"] = (g["TEST_VAR_LIST"] if g["TEST_VAR"] else [])
  1215. `,
  1216. },
  1217. {
  1218. desc: "substitution references",
  1219. mkname: "product.mk",
  1220. in: `
  1221. SOURCES := foo.c bar.c
  1222. OBJECTS := $(SOURCES:.c=.o)
  1223. OBJECTS2 := $(SOURCES:%.c=%.o)
  1224. `,
  1225. expected: `load("//build/make/core:product_config.rbc", "rblf")
  1226. def init(g, handle):
  1227. cfg = rblf.cfg(handle)
  1228. g["SOURCES"] = "foo.c bar.c"
  1229. g["OBJECTS"] = rblf.mkpatsubst("%.c", "%.o", g["SOURCES"])
  1230. g["OBJECTS2"] = rblf.mkpatsubst("%.c", "%.o", g["SOURCES"])
  1231. `,
  1232. },
  1233. {
  1234. desc: "foreach expressions",
  1235. mkname: "product.mk",
  1236. in: `
  1237. BOOT_KERNEL_MODULES := foo.ko bar.ko
  1238. BOOT_KERNEL_MODULES_FILTER := $(foreach m,$(BOOT_KERNEL_MODULES),%/$(m))
  1239. BOOT_KERNEL_MODULES_LIST := foo.ko
  1240. BOOT_KERNEL_MODULES_LIST += bar.ko
  1241. BOOT_KERNEL_MODULES_FILTER_2 := $(foreach m,$(BOOT_KERNEL_MODULES_LIST),%/$(m))
  1242. FOREACH_WITH_IF := $(foreach module,\
  1243. $(BOOT_KERNEL_MODULES_LIST),\
  1244. $(if $(filter $(module),foo.ko),,$(error module "$(module)" has an error!)))
  1245. # Same as above, but not assigning it to a variable allows it to be converted to statements
  1246. $(foreach module,\
  1247. $(BOOT_KERNEL_MODULES_LIST),\
  1248. $(if $(filter $(module),foo.ko),,$(error module "$(module)" has an error!)))
  1249. `,
  1250. expected: `load("//build/make/core:product_config.rbc", "rblf")
  1251. def init(g, handle):
  1252. cfg = rblf.cfg(handle)
  1253. g["BOOT_KERNEL_MODULES"] = "foo.ko bar.ko"
  1254. g["BOOT_KERNEL_MODULES_FILTER"] = ["%%/%s" % m for m in rblf.words(g["BOOT_KERNEL_MODULES"])]
  1255. g["BOOT_KERNEL_MODULES_LIST"] = ["foo.ko"]
  1256. g["BOOT_KERNEL_MODULES_LIST"] += ["bar.ko"]
  1257. g["BOOT_KERNEL_MODULES_FILTER_2"] = ["%%/%s" % m for m in g["BOOT_KERNEL_MODULES_LIST"]]
  1258. g["FOREACH_WITH_IF"] = [("" if rblf.filter(module, "foo.ko") else rblf.mkerror("product.mk", "module \"%s\" has an error!" % module)) for module in g["BOOT_KERNEL_MODULES_LIST"]]
  1259. # Same as above, but not assigning it to a variable allows it to be converted to statements
  1260. for module in g["BOOT_KERNEL_MODULES_LIST"]:
  1261. if not rblf.filter(module, "foo.ko"):
  1262. rblf.mkerror("product.mk", "module \"%s\" has an error!" % module)
  1263. `,
  1264. },
  1265. {
  1266. desc: "List appended to string",
  1267. mkname: "product.mk",
  1268. in: `
  1269. NATIVE_BRIDGE_PRODUCT_PACKAGES := \
  1270. libnative_bridge_vdso.native_bridge \
  1271. native_bridge_guest_app_process.native_bridge \
  1272. native_bridge_guest_linker.native_bridge
  1273. NATIVE_BRIDGE_MODIFIED_GUEST_LIBS := \
  1274. libaaudio \
  1275. libamidi \
  1276. libandroid \
  1277. libandroid_runtime
  1278. NATIVE_BRIDGE_PRODUCT_PACKAGES += \
  1279. $(addsuffix .native_bridge,$(NATIVE_BRIDGE_ORIG_GUEST_LIBS))
  1280. `,
  1281. expected: `load("//build/make/core:product_config.rbc", "rblf")
  1282. def init(g, handle):
  1283. cfg = rblf.cfg(handle)
  1284. g["NATIVE_BRIDGE_PRODUCT_PACKAGES"] = "libnative_bridge_vdso.native_bridge native_bridge_guest_app_process.native_bridge native_bridge_guest_linker.native_bridge"
  1285. g["NATIVE_BRIDGE_MODIFIED_GUEST_LIBS"] = "libaaudio libamidi libandroid libandroid_runtime"
  1286. g["NATIVE_BRIDGE_PRODUCT_PACKAGES"] += " " + " ".join(rblf.addsuffix(".native_bridge", g.get("NATIVE_BRIDGE_ORIG_GUEST_LIBS", "")))
  1287. `,
  1288. },
  1289. {
  1290. desc: "Math functions",
  1291. mkname: "product.mk",
  1292. in: `
  1293. # Test the math functions defined in build/make/common/math.mk
  1294. ifeq ($(call math_max,2,5),5)
  1295. endif
  1296. ifeq ($(call math_min,2,5),2)
  1297. endif
  1298. ifeq ($(call math_gt_or_eq,2,5),true)
  1299. endif
  1300. ifeq ($(call math_gt,2,5),true)
  1301. endif
  1302. ifeq ($(call math_lt,2,5),true)
  1303. endif
  1304. ifeq ($(call math_gt_or_eq,2,5),)
  1305. endif
  1306. ifeq ($(call math_gt,2,5),)
  1307. endif
  1308. ifeq ($(call math_lt,2,5),)
  1309. endif
  1310. ifeq ($(call math_gt_or_eq,$(MY_VAR), 5),true)
  1311. endif
  1312. ifeq ($(call math_gt_or_eq,$(MY_VAR),$(MY_OTHER_VAR)),true)
  1313. endif
  1314. ifeq ($(call math_gt_or_eq,100$(MY_VAR),10),true)
  1315. endif
  1316. `,
  1317. expected: `# Test the math functions defined in build/make/common/math.mk
  1318. load("//build/make/core:product_config.rbc", "rblf")
  1319. def init(g, handle):
  1320. cfg = rblf.cfg(handle)
  1321. if max(2, 5) == 5:
  1322. pass
  1323. if min(2, 5) == 2:
  1324. pass
  1325. if 2 >= 5:
  1326. pass
  1327. if 2 > 5:
  1328. pass
  1329. if 2 < 5:
  1330. pass
  1331. if 2 < 5:
  1332. pass
  1333. if 2 <= 5:
  1334. pass
  1335. if 2 >= 5:
  1336. pass
  1337. if int(g.get("MY_VAR", "")) >= 5:
  1338. pass
  1339. if int(g.get("MY_VAR", "")) >= int(g.get("MY_OTHER_VAR", "")):
  1340. pass
  1341. if int("100%s" % g.get("MY_VAR", "")) >= 10:
  1342. pass
  1343. `,
  1344. },
  1345. {
  1346. desc: "Type hints",
  1347. mkname: "product.mk",
  1348. in: `
  1349. # Test type hints
  1350. #RBC# type_hint list MY_VAR MY_VAR_2
  1351. # Unsupported type
  1352. #RBC# type_hint bool MY_VAR_3
  1353. # Invalid syntax
  1354. #RBC# type_hint list
  1355. # Duplicated variable
  1356. #RBC# type_hint list MY_VAR_2
  1357. #RBC# type_hint list my-local-var-with-dashes
  1358. #RBC# type_hint string MY_STRING_VAR
  1359. MY_VAR := foo
  1360. MY_VAR_UNHINTED := foo
  1361. # Vars set after other statements still get the hint
  1362. MY_VAR_2 := foo
  1363. # You can't specify a type hint after the first statement
  1364. #RBC# type_hint list MY_VAR_4
  1365. MY_VAR_4 := foo
  1366. my-local-var-with-dashes := foo
  1367. MY_STRING_VAR := $(wildcard foo/bar.mk)
  1368. `,
  1369. expected: `# Test type hints
  1370. # Unsupported type
  1371. load("//build/make/core:product_config.rbc", "rblf")
  1372. def init(g, handle):
  1373. cfg = rblf.cfg(handle)
  1374. rblf.mk2rbc_error("product.mk:5", "Invalid type_hint annotation. Only list/string types are accepted, found bool")
  1375. # Invalid syntax
  1376. rblf.mk2rbc_error("product.mk:7", "Invalid type_hint annotation: list. Must be a variable type followed by a list of variables of that type")
  1377. # Duplicated variable
  1378. rblf.mk2rbc_error("product.mk:9", "Duplicate type hint for variable MY_VAR_2")
  1379. g["MY_VAR"] = ["foo"]
  1380. g["MY_VAR_UNHINTED"] = "foo"
  1381. # Vars set after other statements still get the hint
  1382. g["MY_VAR_2"] = ["foo"]
  1383. # You can't specify a type hint after the first statement
  1384. rblf.mk2rbc_error("product.mk:20", "type_hint annotations must come before the first Makefile statement")
  1385. g["MY_VAR_4"] = "foo"
  1386. _my_local_var_with_dashes = ["foo"]
  1387. g["MY_STRING_VAR"] = " ".join(rblf.expand_wildcard("foo/bar.mk"))
  1388. `,
  1389. },
  1390. {
  1391. desc: "Set LOCAL_PATH to my-dir",
  1392. mkname: "product.mk",
  1393. in: `
  1394. LOCAL_PATH := $(call my-dir)
  1395. `,
  1396. expected: `load("//build/make/core:product_config.rbc", "rblf")
  1397. def init(g, handle):
  1398. cfg = rblf.cfg(handle)
  1399. `,
  1400. },
  1401. {
  1402. desc: "Evals",
  1403. mkname: "product.mk",
  1404. in: `
  1405. $(eval)
  1406. $(eval MY_VAR := foo)
  1407. $(eval # This is a test of eval functions)
  1408. $(eval $(TOO_COMPLICATED) := bar)
  1409. $(foreach x,$(MY_LIST_VAR), \
  1410. $(eval PRODUCT_COPY_FILES += foo/bar/$(x):$(TARGET_COPY_OUT_VENDOR)/etc/$(x)) \
  1411. $(if $(MY_OTHER_VAR),$(eval PRODUCT_COPY_FILES += $(MY_OTHER_VAR):foo/bar/$(x))) \
  1412. )
  1413. `,
  1414. expected: `load("//build/make/core:product_config.rbc", "rblf")
  1415. def init(g, handle):
  1416. cfg = rblf.cfg(handle)
  1417. g["MY_VAR"] = "foo"
  1418. # This is a test of eval functions
  1419. rblf.mk2rbc_error("product.mk:5", "Eval expression too complex; only assignments and comments are supported")
  1420. for x in rblf.words(g.get("MY_LIST_VAR", "")):
  1421. rblf.setdefault(handle, "PRODUCT_COPY_FILES")
  1422. cfg["PRODUCT_COPY_FILES"] += ("foo/bar/%s:%s/etc/%s" % (x, g.get("TARGET_COPY_OUT_VENDOR", ""), x)).split()
  1423. if g.get("MY_OTHER_VAR", ""):
  1424. cfg["PRODUCT_COPY_FILES"] += ("%s:foo/bar/%s" % (g.get("MY_OTHER_VAR", ""), x)).split()
  1425. `,
  1426. },
  1427. }
  1428. var known_variables = []struct {
  1429. name string
  1430. class varClass
  1431. starlarkType
  1432. }{
  1433. {"NATIVE_COVERAGE", VarClassSoong, starlarkTypeBool},
  1434. {"PRODUCT_NAME", VarClassConfig, starlarkTypeString},
  1435. {"PRODUCT_MODEL", VarClassConfig, starlarkTypeString},
  1436. {"PRODUCT_PACKAGES", VarClassConfig, starlarkTypeList},
  1437. {"PRODUCT_BOOT_JARS", VarClassConfig, starlarkTypeList},
  1438. {"PRODUCT_COPY_FILES", VarClassConfig, starlarkTypeList},
  1439. {"PRODUCT_IS_64BIT", VarClassConfig, starlarkTypeString},
  1440. {"PRODUCT_LIST1", VarClassConfig, starlarkTypeList},
  1441. {"PRODUCT_LIST2", VarClassConfig, starlarkTypeList},
  1442. {"PRODUCT_LIST3", VarClassConfig, starlarkTypeList},
  1443. {"TARGET_PRODUCT", VarClassSoong, starlarkTypeString},
  1444. {"TARGET_BUILD_VARIANT", VarClassSoong, starlarkTypeString},
  1445. {"TARGET_BOARD_PLATFORM", VarClassSoong, starlarkTypeString},
  1446. {"QCOM_BOARD_PLATFORMS", VarClassSoong, starlarkTypeString},
  1447. {"PLATFORM_LIST", VarClassSoong, starlarkTypeList}, // TODO(asmundak): make it local instead of soong
  1448. }
  1449. type testMakefileFinder struct {
  1450. fs fs.FS
  1451. root string
  1452. files []string
  1453. }
  1454. func (t *testMakefileFinder) Find(root string) []string {
  1455. if t.files != nil || root == t.root {
  1456. return t.files
  1457. }
  1458. t.files = make([]string, 0)
  1459. fs.WalkDir(t.fs, root, func(path string, d fs.DirEntry, err error) error {
  1460. if err != nil {
  1461. return err
  1462. }
  1463. if d.IsDir() {
  1464. base := filepath.Base(path)
  1465. if base[0] == '.' && len(base) > 1 {
  1466. return fs.SkipDir
  1467. }
  1468. return nil
  1469. }
  1470. if strings.HasSuffix(path, ".mk") {
  1471. t.files = append(t.files, path)
  1472. }
  1473. return nil
  1474. })
  1475. return t.files
  1476. }
  1477. func TestGood(t *testing.T) {
  1478. for _, v := range known_variables {
  1479. KnownVariables.NewVariable(v.name, v.class, v.starlarkType)
  1480. }
  1481. fs := NewFindMockFS([]string{
  1482. "vendor/foo1/cfg.mk",
  1483. "vendor/bar/baz/cfg.mk",
  1484. "part.mk",
  1485. "foo/font.mk",
  1486. "bar/font.mk",
  1487. })
  1488. for _, test := range testCases {
  1489. t.Run(test.desc,
  1490. func(t *testing.T) {
  1491. ss, err := Convert(Request{
  1492. MkFile: test.mkname,
  1493. Reader: bytes.NewBufferString(test.in),
  1494. OutputSuffix: ".star",
  1495. SourceFS: fs,
  1496. MakefileFinder: &testMakefileFinder{fs: fs},
  1497. })
  1498. if err != nil {
  1499. t.Error(err)
  1500. return
  1501. }
  1502. got := ss.String()
  1503. if got != test.expected {
  1504. t.Errorf("%q failed\nExpected:\n%s\nActual:\n%s\n", test.desc,
  1505. strings.ReplaceAll(test.expected, "\n", "␤\n"),
  1506. strings.ReplaceAll(got, "\n", "␤\n"))
  1507. }
  1508. })
  1509. }
  1510. }