moz.configure (31504B)
1 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- 2 # vim: set filetype=python: 3 # This Source Code Form is subject to the terms of the Mozilla Public 4 # License, v. 2.0. If a copy of the MPL was not distributed with this 5 # file, You can obtain one at http://mozilla.org/MPL/2.0/. 6 7 include("build/moz.configure/init.configure") 8 9 # Note: 10 # - Gecko-specific options and rules should go in toolkit/moz.configure. 11 # - Firefox-specific options and rules should go in browser/moz.configure. 12 # - Fennec-specific options and rules should go in 13 # mobile/android/moz.configure. 14 # - Spidermonkey-specific options and rules should go in js/moz.configure. 15 # - etc. 16 17 imply_option( 18 "--enable-artifact-build-symbols", 19 depends(artifact_builds)(lambda v: False if v is None else None), 20 reason="--disable-artifact-builds", 21 ) 22 23 option( 24 "--enable-artifact-build-symbols", 25 nargs="?", 26 choices=("full",), 27 help="Download symbols when artifact builds are enabled", 28 ) 29 30 31 @depends("--enable-artifact-build-symbols", moz_automation, target) 32 def enable_artifact_build_symbols(value, automation, target): 33 if len(value): 34 return value[0] 35 if bool(value): 36 if target.os == "Android" and not automation: 37 return "full" 38 return True 39 return None 40 41 42 set_config("MOZ_ARTIFACT_BUILD_SYMBOLS", enable_artifact_build_symbols) 43 44 45 @depends("--enable-artifact-builds", build_project) 46 def imply_disable_compile_environment(value, build_project): 47 if value or build_project == "browser/extensions": 48 return False 49 50 51 option( 52 env="MOZ_BUILD_HOOK", 53 nargs=1, 54 help="Path to the moz.build file that will be executed as if it were " 55 "appended to every moz.build in the tree", 56 ) 57 58 59 @depends_if("MOZ_BUILD_HOOK") 60 @imports("os") 61 def moz_build_hook(value): 62 if not os.path.exists(value[0]): 63 die(f"MOZ_BUILD_HOOK set to {value[0]} but the file doesn't exist") 64 return os.path.abspath(value[0]) 65 66 67 set_config("MOZ_BUILD_HOOK", moz_build_hook) 68 69 70 option( 71 env="MOZ_COPY_PDBS", 72 help="For builds that do not support symbols in the normal fashion," 73 " generate and copy them into the resulting build archive", 74 ) 75 76 set_config("MOZ_COPY_PDBS", depends_if("MOZ_COPY_PDBS")(lambda _: True)) 77 78 imply_option( 79 "--enable-compile-environment", imply_disable_compile_environment, reason="default" 80 ) 81 82 option("--disable-compile-environment", help="Disable compiler/library checks") 83 84 85 @depends("--disable-compile-environment") 86 def compile_environment(compile_env): 87 if compile_env: 88 return True 89 90 91 set_config("COMPILE_ENVIRONMENT", compile_environment) 92 93 option("--disable-tests", help="Do not build test libraries & programs") 94 95 96 @depends("--disable-tests") 97 def enable_tests(value): 98 if value: 99 return True 100 101 102 set_config("ENABLE_TESTS", enable_tests) 103 set_define("ENABLE_TESTS", enable_tests) 104 105 106 @depends(enable_tests) 107 def gtest_has_rtti(value): 108 if value: 109 return "0" 110 111 112 set_define("GTEST_HAS_RTTI", gtest_has_rtti) 113 114 115 @depends(target, enable_tests) 116 def linux_gtest_defines(target, enable_tests): 117 if enable_tests and target.os == "Android": 118 return namespace(os_linux_android=True, use_own_tr1_tuple=True, has_clone="0") 119 120 121 set_define("GTEST_OS_LINUX_ANDROID", linux_gtest_defines.os_linux_android) 122 set_define("GTEST_USE_OWN_TR1_TUPLE", linux_gtest_defines.use_own_tr1_tuple) 123 set_define("GTEST_HAS_CLONE", linux_gtest_defines.has_clone) 124 125 set_define("FMT_API", "MFBT_API") 126 set_define("FMT_ENFORCE_COMPILE_STRING", 1) 127 set_define("FMT_USE_EXCEPTIONS", 0) 128 set_define("FMT_USE_WRITE_CONSOLE", 1) 129 set_define("FMT_USE_LOCALE", 0) 130 131 option( 132 "--enable-debug", 133 nargs="?", 134 help="Enable building with developer debug info (using the given compiler flags)", 135 ) 136 137 138 @depends("--enable-debug") 139 def moz_debug(debug): 140 if debug: 141 return bool(debug) 142 143 144 set_config("MOZ_DEBUG", moz_debug) 145 set_define("MOZ_DEBUG", moz_debug) 146 147 148 set_config( 149 "MOZ_DIAGNOSTIC_ASSERT_ENABLED", 150 True, 151 when=moz_debug | milestone.is_early_beta_or_earlier, 152 ) 153 set_define( 154 "MOZ_DIAGNOSTIC_ASSERT_ENABLED", 155 True, 156 when=moz_debug | milestone.is_early_beta_or_earlier, 157 ) 158 159 option( 160 "--with-debug-label", 161 nargs="+", 162 help="Debug DEBUG_<value> for each comma-separated value given", 163 ) 164 165 166 @depends(moz_debug, "--with-debug-label") 167 def debug_defines(debug, labels): 168 if debug: 169 return ["DEBUG"] + ["DEBUG_%s" % label for label in labels] 170 return ["NDEBUG", "TRIMMED"] 171 172 173 set_config("MOZ_DEBUG_DEFINES", debug_defines) 174 175 option(env="MOZ_PGO", help="Build with profile guided optimizations") 176 177 set_config("MOZ_PGO", depends("MOZ_PGO")(lambda x: bool(x))) 178 179 180 # Imply --enable-release when MOZILLA_OFFICIAL is set rather than adjusting the 181 # default so that we can't have both MOZILLA_OFFICIAL and --disable-release set. 182 imply_option("--enable-release", mozilla_official) 183 184 option( 185 "--enable-release", 186 default=milestone.is_release_or_beta | moz_automation, 187 help="{Build|Do not build} with more conservative, release " 188 "engineering-oriented options.{ This may slow down builds.|}", 189 ) 190 191 192 @depends("--enable-release") 193 def developer_options(value): 194 if not value: 195 return True 196 197 198 set_config("DEVELOPER_OPTIONS", developer_options) 199 200 201 # hybrid build handling 202 # ============================================================== 203 204 option( 205 "--disable-unified-build", 206 help="Enable building modules in non unified context", 207 ) 208 209 set_config("ENABLE_UNIFIED_BUILD", True, when="--disable-unified-build") 210 211 212 include("build/moz.configure/bootstrap.configure") 213 214 215 # The execution model of the configure sandbox doesn't allow for 216 # check_prog to use bootstrap_search_path directly because check_prog 217 # comes first, so we use a trick to allow it. Uses of check_prog 218 # happening before here won't allow bootstrap. 219 220 221 @template 222 def check_prog(*args, **kwargs): 223 kwargs["bootstrap_search_path"] = bootstrap_search_path 224 return check_prog(*args, **kwargs) 225 226 227 include("build/moz.configure/toolchain.configure", when="--enable-compile-environment") 228 include("build/moz.configure/basebrowser-resources.configure") 229 include("build/moz.configure/torbrowser-resources.configure") 230 231 include("build/moz.configure/pkg.configure") 232 include("build/moz.configure/memory.configure", when="--enable-compile-environment") 233 include("build/moz.configure/headers.configure", when="--enable-compile-environment") 234 include("build/moz.configure/libraries.configure", when="--enable-compile-environment") 235 include("build/moz.configure/warnings.configure", when="--enable-compile-environment") 236 include("build/moz.configure/flags.configure", when="--enable-compile-environment") 237 include("build/moz.configure/default-flags.configure", when=~compile_environment) 238 include("build/moz.configure/lto-pgo.configure", when="--enable-compile-environment") 239 # rust.configure is included by js/moz.configure. 240 241 242 option("--enable-valgrind", help="Enable Valgrind integration hooks") 243 244 valgrind_h = check_header("valgrind/valgrind.h", when="--enable-valgrind") 245 246 247 @depends("--enable-valgrind", valgrind_h) 248 def check_valgrind(valgrind, valgrind_h): 249 if valgrind: 250 if not valgrind_h: 251 die("--enable-valgrind specified but Valgrind is not installed") 252 return True 253 254 255 set_define("MOZ_VALGRIND", check_valgrind) 256 set_config("MOZ_VALGRIND", check_valgrind) 257 258 259 @depends(target, host) 260 def is_openbsd(target, host): 261 return target.kernel == "OpenBSD" or host.kernel == "OpenBSD" 262 263 264 option( 265 env="SO_VERSION", 266 nargs=1, 267 default="1.0", 268 when=is_openbsd, 269 help="Shared library version for OpenBSD systems", 270 ) 271 272 273 @depends("SO_VERSION", when=is_openbsd) 274 def so_version(value): 275 return value 276 277 278 @template 279 def library_name_info_template(host_or_target): 280 assert host_or_target in {host, target} 281 windows_abi = { 282 host: host_windows_abi, 283 target: target_windows_abi, 284 }[host_or_target] 285 286 @depends(host_or_target, host_or_target.abi | windows_abi, so_version) 287 def library_name_info_impl(host_or_target, windows_abi, so_version): 288 if host_or_target.kernel == "WINNT": 289 # There aren't artifacts for mingw builds, so it's OK that the 290 # results are inaccurate in that case. 291 if windows_abi and windows_abi != "msvc": 292 return namespace( 293 dll=namespace(prefix="", suffix=".dll"), 294 lib=namespace(prefix="lib", suffix="a"), 295 import_lib=namespace(prefix="lib", suffix="a"), 296 obj=namespace(prefix="", suffix="o"), 297 ) 298 299 return namespace( 300 dll=namespace(prefix="", suffix=".dll"), 301 lib=namespace(prefix="", suffix="lib"), 302 import_lib=namespace(prefix="", suffix="lib"), 303 obj=namespace(prefix="", suffix="obj"), 304 ) 305 306 elif host_or_target.kernel == "Darwin": 307 return namespace( 308 dll=namespace(prefix="lib", suffix=".dylib"), 309 lib=namespace(prefix="lib", suffix="a"), 310 import_lib=namespace(prefix=None, suffix=""), 311 obj=namespace(prefix="", suffix="o"), 312 ) 313 elif so_version: 314 so = ".so.%s" % so_version 315 else: 316 so = ".so" 317 318 return namespace( 319 dll=namespace(prefix="lib", suffix=so), 320 lib=namespace(prefix="lib", suffix="a"), 321 import_lib=namespace(prefix=None, suffix=""), 322 obj=namespace(prefix="", suffix="o"), 323 ) 324 325 return library_name_info_impl 326 327 328 host_library_name_info = library_name_info_template(host) 329 library_name_info = library_name_info_template(target) 330 331 set_config("DLL_PREFIX", library_name_info.dll.prefix) 332 set_config("DLL_SUFFIX", library_name_info.dll.suffix) 333 set_config("HOST_DLL_PREFIX", host_library_name_info.dll.prefix) 334 set_config("HOST_DLL_SUFFIX", host_library_name_info.dll.suffix) 335 set_config("LIB_PREFIX", library_name_info.lib.prefix) 336 set_config("LIB_SUFFIX", library_name_info.lib.suffix) 337 set_config("OBJ_SUFFIX", library_name_info.obj.suffix) 338 set_config("IMPORT_LIB_SUFFIX", library_name_info.import_lib.suffix) 339 set_define( 340 "MOZ_DLL_PREFIX", depends(library_name_info.dll.prefix)(lambda s: '"%s"' % s) 341 ) 342 set_define( 343 "MOZ_DLL_SUFFIX", depends(library_name_info.dll.suffix)(lambda s: '"%s"' % s) 344 ) 345 set_config("HOST_LIB_PREFIX", host_library_name_info.lib.prefix) 346 set_config("HOST_IMPORT_LIB_SUFFIX", host_library_name_info.import_lib.suffix) 347 set_config("WASM_OBJ_SUFFIX", "wasm") 348 349 350 @template 351 def bin_suffix(host_or_target): 352 return depends(host_or_target)( 353 lambda host_or_target: ".exe" if host_or_target.os == "WINNT" else "" 354 ) 355 356 357 set_config("BIN_SUFFIX", bin_suffix(target)) 358 set_config("HOST_BIN_SUFFIX", bin_suffix(host)) 359 360 361 @template 362 def plain_llvm_or_prefixed(name, llvm_name=None): 363 # look for a tool, using the following alternatives, in that order: 364 # 1. llvm-${llvm_name}, or llvm-${name} if ${llvm_name} is not provided 365 # 2. ${toolchain_prefix}${name} 366 # 3. ${name} 367 368 @depends(llvm_tool(f"llvm-{llvm_name or name}"), toolchain_prefix) 369 def plain_llvm_or_prefixed(llvm_tool, toolchain_prefix): 370 commands = [llvm_tool[0], name] 371 for prefix in toolchain_prefix or (): 372 commands.insert(1, f"{prefix}{name}") 373 return tuple(commands) 374 375 return plain_llvm_or_prefixed 376 377 378 def validate_readelf(path): 379 # llvm-readelf from llvm < 8 doesn't support the GNU binutils-compatible `-d` 380 # flag. We could try running `$path -d $some_binary` but we might be cross 381 # compiling and not have a binary at hand to run that against. `$path -d` alone 382 # would fail whether the flag is supported or not. So we resort to look for the 383 # option in the `--help` output, which fortunately, s compatible between 384 # llvm-readelf and readelf. 385 retcode, stdout, stderr = get_cmd_output(path, "--help") 386 return retcode == 0 and any(l.startswith(" -d ") for l in stdout.splitlines()) 387 388 389 @depends("--enable-compile-environment", target, host) 390 def readelf_when(compile_env, target, host): 391 return compile_env and any( 392 x.kernel not in ("Darwin", "WINNT") for x in (target, host) 393 ) 394 395 396 readelf = check_prog( 397 "READELF", 398 plain_llvm_or_prefixed("readelf"), 399 when=readelf_when, 400 paths=clang_search_path, 401 validate=validate_readelf, 402 ) 403 404 405 def validate_objcopy(path): 406 if "llvm-objcopy" not in path: 407 return True 408 # llvm-objcopy doesn't support --only-keep-debug before llvm 9.0. 409 retcode, stdout, stderr = get_cmd_output(path, "--help") 410 return retcode == 0 and any( 411 l.startswith(" --only-keep-debug ") for l in stdout.splitlines() 412 ) 413 414 415 check_prog( 416 "OBJCOPY", 417 plain_llvm_or_prefixed("objcopy"), 418 when=readelf_when, 419 paths=clang_search_path, 420 validate=validate_objcopy, 421 ) 422 423 424 # Make `profiling` available to this file even when js/moz.configure 425 # doesn't end up included. 426 profiling = dependable(False) 427 # Same for js_standalone 428 js_standalone = dependable(False) 429 # Same for fold_libs 430 fold_libs = dependable(False) 431 # And dmd 432 dmd = dependable(False) 433 434 # Only available when toolkit/moz.configure is included 435 pack_relative_relocs_flags = dependable(False) 436 real_branding_directory = dependable(None) 437 438 include(include_project_configure) 439 440 441 @template 442 def load_keyvalue_file(location, filename): 443 444 @depends(build_environment, location, "--help", when=location) 445 @checking(f"if configuration file {filename} exists") 446 # This gives access to the sandbox. Don't copy this blindly. 447 @imports("__sandbox__") 448 @imports(_from="mozbuild.configure", _import="confvars") 449 @imports("os.path") 450 def load_keyvalue_file_impl(build_env, location, help): 451 file_path = os.path.join(build_env.topsrcdir, location, filename) 452 if os.path.exists(file_path): 453 helper = __sandbox__._helper 454 # parse confvars 455 try: 456 keyvals = confvars.parse(file_path) 457 except confvars.ConfVarsSyntaxError as e: 458 die(str(e)) 459 for key, value in keyvals.items(): 460 # FIXME: remove test once we no longer load confvars from old-configure. 461 if key in __sandbox__._options: 462 # ~= imply_option, but with an accurate origin 463 helper.add(f"{key}={value}", origin="confvars", args=helper._args) 464 return file_path 465 466 return load_keyvalue_file_impl 467 468 469 load_confvars = load_keyvalue_file(build_project, "confvars.sh") 470 load_brandvars = load_keyvalue_file(real_branding_directory, "configure.sh") 471 472 473 # Final flags validation and gathering 474 # ------------------------------------------------- 475 476 include( 477 "build/moz.configure/finalize-flags.configure", when="--enable-compile-environment" 478 ) 479 480 # ------------------------------------------------- 481 482 483 @depends("--help") 484 @imports(_from="mozbuild.backend", _import="backends") 485 def build_backends_choices(_): 486 return tuple(backends) 487 488 489 @deprecated_option("--enable-build-backend", nargs="+", choices=build_backends_choices) 490 def build_backend(backends): 491 if backends: 492 return tuple("+%s" % b for b in backends) 493 494 495 imply_option("--build-backends", build_backend) 496 497 498 @depends( 499 host, 500 target, 501 "--enable-artifact-builds", 502 "--disable-compile-environment", 503 "--enable-project", 504 "--enable-application", 505 "--help", 506 ) 507 @imports("sys") 508 def build_backend_defaults( 509 host, 510 target, 511 artifact_builds, 512 compile_environment, 513 project, 514 application, 515 _, 516 ): 517 if application: 518 project = application[0] 519 elif project: 520 project = project[0] 521 522 if artifact_builds: 523 all_backends = ["FasterMake+RecursiveMake"] 524 else: 525 all_backends = ["RecursiveMake", "FasterMake"] 526 if ( 527 host.os == "WINNT" 528 and target.os == "WINNT" 529 and compile_environment 530 and project not in ("mobile/android", "memory", "tools/update-programs") 531 ): 532 all_backends.append("VisualStudio") 533 if compile_environment and project not in ("memory", "tools/update-programs"): 534 all_backends.append("Clangd") 535 return tuple(all_backends) or None 536 537 538 option( 539 "--build-backends", 540 nargs="+", 541 default=build_backend_defaults, 542 choices=build_backends_choices, 543 help="Build backends to generate", 544 ) 545 546 547 @depends("--build-backends") 548 def build_backends(backends): 549 return backends 550 551 552 set_config("BUILD_BACKENDS", build_backends) 553 554 555 # Determine whether to build the gtest xul. This happens in automation 556 # on Android and Desktop platforms with the exception of: 557 # - Windows PGO, where linking xul-gtest.dll takes too long; 558 # - Android other than x86_64, where gtest is not required. 559 @depends( 560 build_project, 561 target, 562 moz_automation, 563 enable_tests, 564 when="--enable-compile-environment", 565 ) 566 def build_gtest(build_project, target, automation, enable_tests): 567 return bool( 568 enable_tests 569 and automation 570 and build_project in ("browser", "comm/mail", "mobile/android") 571 and not (target.os == "Android" and target.cpu != "x86_64") 572 ) 573 574 575 option( 576 "--enable-gtest-in-build", 577 default=build_gtest, 578 help="{Enable|Force disable} building the gtest libxul during the build", 579 when="--enable-compile-environment", 580 ) 581 582 set_config("LINK_GTEST_DURING_COMPILE", True, when="--enable-gtest-in-build") 583 584 # Localization 585 # ============================================================== 586 option( 587 "--enable-ui-locale", 588 env="MOZ_UI_LOCALE", 589 default="en-US", 590 help="Select the user interface locale (default: en-US)", 591 ) 592 593 594 @depends("--enable-ui-locale") 595 def moz_ui_locale(value): 596 return value[0] 597 598 599 set_config("MOZ_UI_LOCALE", moz_ui_locale) 600 601 602 # clang-plugin location 603 # ============================================================== 604 include( 605 "build/moz.configure/clang_plugin.configure", when="--enable-compile-environment" 606 ) 607 608 609 # GNU make detection 610 # ============================================================== 611 option(env="MAKE", nargs=1, help="Path to GNU make") 612 613 614 @depends("MAKE", host) 615 def possible_makes(make, host): 616 candidates = [] 617 if make: 618 candidates.append(make[0]) 619 if host.kernel == "WINNT": 620 candidates.extend(("mozmake", "mingw32-make", "make", "gmake")) 621 else: 622 candidates.extend(("gmake", "make")) 623 return candidates 624 625 626 gmake = check_prog("GMAKE", possible_makes, bootstrap="mozmake") 627 628 629 @depends(gmake) 630 @checking("for gmake version") 631 def gmake_version(prog): 632 out = check_cmd_output(prog, "--version") 633 version_line = out.splitlines()[0] 634 if not version_line.startswith("GNU Make"): 635 die("GNU make is required") 636 return Version(version_line[8:].strip()) 637 638 639 @depends(gmake_version) 640 def check_gmake_version(version): 641 make_min_ver = Version("3.81") 642 if version < make_min_ver: 643 die(f"GNU Make {make_min_ver} or higher is required") 644 645 646 # watchman detection 647 # ============================================================== 648 649 option(env="WATCHMAN", nargs=1, help="Path to the watchman program") 650 651 652 @depends(host, "WATCHMAN") 653 @checking("for watchman", callback=lambda w: w.path if w else "not found") 654 def watchman(host, prog): 655 # On Windows, `watchman` is only supported on 64-bit hosts. 656 if host.os == "WINNT" and host.cpu != "x86_64": 657 return 658 659 if not prog: 660 prog = find_program("watchman") 661 662 if not prog: 663 return 664 665 # `watchman version` will talk to the Watchman daemon service. 666 # This can hang due to permissions problems. e.g. 667 # https://github.com/facebook/watchman/issues/376. So use 668 # `watchman --version` to prevent a class of failures. 669 out = check_cmd_output(prog, "--version", onerror=lambda: None) 670 if out is None: 671 return 672 673 return namespace(path=prog, version=Version(out.strip())) 674 675 676 @depends_if(watchman) 677 @checking("for watchman version") 678 def watchman_version(w): 679 return w.version 680 681 682 set_config("WATCHMAN", watchman.path) 683 684 685 @depends_all(hg_version, hg_config, watchman) 686 @checking("for watchman Mercurial integration") 687 @imports("os") 688 def watchman_hg(hg_version, hg_config, watchman): 689 if hg_version < Version("3.8"): 690 return "no (Mercurial 3.8+ required)" 691 692 ext_enabled = False 693 mode_disabled = False 694 695 for k in ("extensions.fsmonitor", "extensions.hgext.fsmonitor"): 696 if k in hg_config and hg_config[k] != "!": 697 ext_enabled = True 698 699 mode_disabled = hg_config.get("fsmonitor.mode") == "off" 700 701 if not ext_enabled: 702 return "no (fsmonitor extension not enabled)" 703 if mode_disabled: 704 return "no (fsmonitor.mode=off disables fsmonitor)" 705 706 return True 707 708 709 # Miscellaneous programs 710 # ============================================================== 711 check_prog("XARGS", ("xargs",)) 712 713 714 @depends(target) 715 def extra_programs(target): 716 if target.kernel == "Darwin": 717 return namespace( 718 MKFSHFS=("newfs_hfs", "mkfs.hfsplus"), 719 HFS_TOOL=("hfsplus",), 720 ) 721 722 723 check_prog("MKFSHFS", extra_programs.MKFSHFS, allow_missing=True) 724 check_prog("HFS_TOOL", extra_programs.HFS_TOOL, allow_missing=True) 725 726 727 nsis = check_prog( 728 "MAKENSISU", 729 ("makensis",), 730 bootstrap="nsis/bin", 731 allow_missing=True, 732 when=target_is_windows, 733 ) 734 735 # Make sure the version of makensis is up to date. 736 737 738 @depends_if(nsis) 739 @checking("for NSIS version") 740 @imports("re") 741 def nsis_version(nsis): 742 nsis_min_version = "3.0b1" 743 744 def onerror(): 745 return die("Failed to get nsis version.") 746 747 out = check_cmd_output(nsis, "-version", onerror=onerror) 748 749 m = re.search(r"(?<=v)[0-9]+\.[0-9]+((a|b|rc)[0-9]+)?", out) 750 751 if not m: 752 raise FatalCheckError("Unknown version of makensis") 753 ver = Version(m.group(0)) 754 755 # Versions comparisons don't quite work well with beta versions, so ensure 756 # it works for the non-beta version. 757 if ver < nsis_min_version and (ver >= "3.0a" or ver < "3"): 758 raise FatalCheckError( 759 "To build the installer you must have NSIS" 760 " version %s or greater in your path" % nsis_min_version 761 ) 762 763 return ver 764 765 766 # And that makensis is 32-bit (but only on Windows). 767 @depends_if(nsis, when=depends(host)(lambda h: h.kernel == "WINNT")) 768 @checking("for 32-bit NSIS") 769 def nsis_binary_type(nsis): 770 bin_type = windows_binary_type(nsis) 771 if bin_type != "win32": 772 raise FatalCheckError("%s is not a 32-bit Windows application" % nsis) 773 774 return "yes" 775 776 777 # And any flags we have to give to makensis 778 @depends(host) 779 def nsis_flags(host): 780 if host.kernel != "WINNT": 781 return "-nocd" 782 return "" 783 784 785 set_config("MAKENSISU_FLAGS", nsis_flags) 786 787 check_prog("7Z", ("7z", "7za"), allow_missing=True, when=target_is_windows) 788 check_prog("UPX", ("upx",), allow_missing=True, when=target_is_windows) 789 790 791 check_prog( 792 "DSYMUTIL", 793 llvm_tool("dsymutil"), 794 when=compile_environment & target_is_darwin, 795 paths=clang_search_path, 796 ) 797 798 799 check_prog( 800 "OTOOL", 801 plain_llvm_or_prefixed("otool"), 802 when=compile_environment & target_is_darwin, 803 paths=clang_search_path, 804 ) 805 806 check_prog( 807 "INSTALL_NAME_TOOL", 808 plain_llvm_or_prefixed("install_name_tool", llvm_name="install-name-tool"), 809 when=compile_environment & target_is_darwin & js_standalone, 810 paths=clang_search_path, 811 ) 812 813 option( 814 "--enable-strip", 815 when=compile_environment, 816 help="Enable stripping of libs & executables", 817 ) 818 819 # This should be handled as a `when` once bug 1617793 is fixed. 820 821 822 @depends("--enable-strip", c_compiler, when=compile_environment) 823 def enable_strip(strip, c_compiler): 824 if strip and c_compiler.type != "clang-cl": 825 return True 826 827 828 set_config("ENABLE_STRIP", enable_strip) 829 830 option( 831 "--disable-install-strip", 832 when=compile_environment, 833 help="Enable stripping of libs & executables when packaging", 834 ) 835 836 # This should be handled as a `when` once bug 1617793 is fixed. 837 838 839 @depends("--enable-install-strip", c_compiler, when=compile_environment) 840 def enable_install_strip(strip, c_compiler): 841 if strip and c_compiler.type != "clang-cl": 842 return True 843 844 845 set_config("PKG_STRIP", enable_install_strip) 846 847 848 @depends("--enable-strip", "--enable-install-strip", when=compile_environment) 849 def strip(strip, install_strip): 850 return strip or install_strip 851 852 853 option(env="STRIP_FLAGS", nargs=1, when=strip, help="Flags for the strip command") 854 855 856 @depends("STRIP_FLAGS", profiling, target, when=strip) 857 def strip_flags(flags, profiling, target): 858 if flags: 859 return flags[0].split() 860 if profiling: 861 # Only strip debug info and symbols when profiling is enabled, keeping 862 # local symbols. 863 if target.kernel == "Darwin": 864 return ["-S"] 865 elif target.os == "Android": 866 # The tooling we use with Android supports detached symbols, and the 867 # size increase caused by local symbols are too much for mobile. So, 868 # don't restrict the amount of stripping with a flag. 869 return 870 else: 871 return ["--strip-debug"] 872 # Otherwise strip everything we can, which happens without flags on non-Darwin. 873 # On Darwin, it tries to strip things it can't, so we need to limit its scope. 874 elif target.kernel == "Darwin": 875 return ["-x", "-S"] 876 877 878 set_config("STRIP_FLAGS", strip_flags) 879 880 881 def validate_strip(path): 882 if "llvm-strip" not in path: 883 return True 884 # llvm-strip doesn't support -S before llvm 8.0. 885 retcode, stdout, stderr = get_cmd_output(path, "--help") 886 return retcode == 0 and any(l.startswith(" -S ") for l in stdout.splitlines()) 887 888 889 @depends("--enable-compile-environment", target, host) 890 def strip_when(compile_env, target, host): 891 return compile_env and any(x.kernel != "WINNT" for x in (target, host)) 892 893 894 check_prog( 895 "STRIP", 896 plain_llvm_or_prefixed("strip"), 897 when=strip_when, 898 paths=clang_search_path, 899 validate=validate_strip, 900 ) 901 902 903 @depends(js_standalone, target) 904 def system_zlib_default(js_standalone, target): 905 return ( 906 js_standalone 907 and target.kernel not in ("WINNT", "Darwin") 908 and target.os != "Android" 909 ) 910 911 912 option( 913 "--with-system-zlib", 914 nargs="?", 915 default=system_zlib_default, 916 help="{Use|Do not use} system libz", 917 when=use_pkg_config, 918 ) 919 920 921 @depends("--with-system-zlib", when=use_pkg_config) 922 def with_system_zlib_option(with_system_zlib): 923 return with_system_zlib 924 925 926 @depends(with_system_zlib_option) 927 def deprecated_system_zlib_path(value): 928 if value and len(value) == 1: 929 die( 930 "--with-system-zlib=PATH is not supported anymore. Please use " 931 "--with-system-zlib and set any necessary pkg-config environment variable." 932 ) 933 934 935 pkg_check_modules("MOZ_ZLIB", "zlib >= 1.2.3", when="--with-system-zlib") 936 937 set_config("MOZ_SYSTEM_ZLIB", True, when="--with-system-zlib") 938 939 option( 940 env="USE_LIBZ_RS", 941 default=milestone.is_early_beta_or_earlier, 942 help="Use libz-rs-sys instead of zlib", 943 when=toolkit & ~with_system_zlib_option, 944 ) 945 946 set_config("USE_LIBZ_RS", True, when="USE_LIBZ_RS") 947 948 with only_when(cross_compiling): 949 option( 950 env="JS_BINARY", 951 nargs=1, 952 help="Host JavaScript runtime, if any, to use during cross compiles", 953 ) 954 set_config("JS_BINARY", depends_if("JS_BINARY")(lambda value: value[0])) 955 956 option( 957 "--with-relative-data-dir", 958 nargs=1, 959 help="Sets the data directories to be relative to the application directory", 960 ) 961 962 963 @depends("--with-relative-data-dir", target) 964 @imports("json") 965 def relative_data_dir(value, target): 966 if value and target.os == "Android": 967 die("--with-relative-data-dir is not supported on Android") 968 if value: 969 return json.dumps(value[0]) 970 971 972 set_define("RELATIVE_DATA_DIR", relative_data_dir) 973 974 975 option( 976 "--with-base-browser-version", 977 nargs=1, 978 help="Set the Base Browser version, e.g., 7.0a1", 979 ) 980 981 982 @depends("--with-base-browser-version") 983 def base_browser_version(value): 984 if not value: 985 die( 986 "--with-base-browser-version is required for Base Browser and derived browsers." 987 ) 988 return value[0] 989 990 991 @depends("--with-base-browser-version") 992 def base_browser_version_quoted(value): 993 if not value: 994 die( 995 "--with-base-browser-version is required for Base Browser and derived browsers." 996 ) 997 if '"' in value or "\\" in value: 998 die('--with-base-browser-version cannot contain " or \\.') 999 return f'"{value[0]}"' 1000 1001 1002 set_define("BASE_BROWSER_VERSION", base_browser_version) 1003 set_define("BASE_BROWSER_VERSION_QUOTED", base_browser_version_quoted) 1004 1005 1006 # Tor Browser additions. 1007 1008 # We always want Tor Browser to be defined. Since we do not need any 1009 # value for it, just always set it to True. 1010 set_define("TOR_BROWSER", True) 1011 1012 1013 # Please do not add configure checks from here on. 1014 1015 1016 # Assuming no other option is declared after this function, handle the 1017 # env options that were injected by mozconfig_options by creating dummy 1018 # Option instances and having the sandbox's CommandLineHelper handle 1019 # them. We only do so for options that haven't been declared so far, 1020 # which should be a proxy for the options that old-configure handles 1021 # and that we don't know anything about. 1022 @depends("--help") 1023 @imports("__sandbox__") 1024 @imports(_from="mozbuild.configure.options", _import="Option") 1025 def remaining_mozconfig_options(_): 1026 helper = __sandbox__._helper 1027 for arg in list(helper): 1028 if helper._origins[arg] != "mozconfig": 1029 continue 1030 name = arg.split("=", 1)[0] 1031 if name.isupper() and name not in __sandbox__._options: 1032 option = Option(env=name, nargs="*", help=name) 1033 helper.handle(option) 1034 1035 1036 @depends(build_environment, configure_cache) 1037 @imports(_import="json") 1038 @imports(_from="pathlib", _import="Path") 1039 def save_cache(build_environment, configure_cache): 1040 cache_file = Path(build_environment.topobjdir) / "configure.cache" 1041 1042 with cache_file.open(mode="w") as fd: 1043 json.dump(configure_cache, fd, indent=4) 1044 1045 1046 @depends(build_environment, build_project) 1047 @imports("__sandbox__") 1048 @imports(_from="os.path", _import="exists") 1049 def config_status_deps(build_env, build_project): 1050 topsrcdir = build_env.topsrcdir 1051 topobjdir = build_env.topobjdir 1052 1053 if not topobjdir.endswith("js/src"): 1054 extra_deps = [os.path.join(topobjdir, ".mozconfig.json")] 1055 else: 1056 # mozconfig changes may impact js configure. 1057 extra_deps = [os.path.join(topobjdir[:-7], ".mozconfig.json")] 1058 1059 confvars = os.path.join(topsrcdir, build_project, "confvars.sh") 1060 if exists(confvars): 1061 extra_deps.append(confvars) 1062 1063 return ( 1064 list(__sandbox__._all_paths) 1065 + extra_deps 1066 + [ 1067 os.path.join(topsrcdir, "CLOBBER"), 1068 os.path.join(topsrcdir, "configure"), 1069 os.path.join(topsrcdir, "js", "src", "configure"), 1070 os.path.join(topsrcdir, "nsprpub", "configure"), 1071 os.path.join(topsrcdir, "config", "milestone.txt"), 1072 os.path.join(topsrcdir, "browser", "config", "version.txt"), 1073 os.path.join(topsrcdir, "browser", "config", "version_display.txt"), 1074 os.path.join(topsrcdir, "python", "sites", "build.txt"), 1075 os.path.join(topsrcdir, "python", "sites", "common.txt"), 1076 os.path.join(topsrcdir, "python", "sites", "mach.txt"), 1077 os.path.join(topsrcdir, "python", "mach", "mach", "site.py"), 1078 ] 1079 ) 1080 1081 1082 set_config("CONFIG_STATUS_DEPS", config_status_deps) 1083 # Please do not add anything after setting config_dep_paths.