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