From f320f2e0e15799d93f3ec68cd4c351c93abee237 Mon Sep 17 00:00:00 2001 From: Mike Hommey <mh+mozilla@glandium.org> Date: Fri, 17 Dec 2021 22:47:50 +0000 Subject: [PATCH] Bug 1743832 - Move bootstrap-related configure code to a separate file. r=firefox-build-system-reviewers,andi Differential Revision: https://phabricator.services.mozilla.com/D134117 --- build/moz.configure/bootstrap.configure | 213 ++++++++++++++++++++++++ moz.configure | 209 +---------------------- 2 files changed, 214 insertions(+), 208 deletions(-) create mode 100755 build/moz.configure/bootstrap.configure diff --git a/build/moz.configure/bootstrap.configure b/build/moz.configure/bootstrap.configure new file mode 100755 index 0000000000000..8f5662904cbf2 --- /dev/null +++ b/build/moz.configure/bootstrap.configure @@ -0,0 +1,213 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +option( + env="MOZ_FETCHES_DIR", + nargs=1, + when="MOZ_AUTOMATION", + help="Directory containing fetched artifacts", +) + + +@depends("MOZ_FETCHES_DIR", when="MOZ_AUTOMATION") +def moz_fetches_dir(value): + if value: + return value[0] + + +@depends(vcs_checkout_type, milestone.is_nightly, "MOZ_AUTOMATION") +def bootstrap_default(vcs_checkout_type, is_nightly, automation): + if automation: + return False + # We only enable if building off a VCS checkout of central. + if is_nightly and vcs_checkout_type: + return True + + +option( + "--enable-bootstrap", + default=bootstrap_default, + help="{Automatically bootstrap or update some toolchains|Disable bootstrap or update of toolchains}", +) + + +@depends(developer_options, "--enable-bootstrap", moz_fetches_dir) +def bootstrap_search_path_order(developer_options, bootstrap, moz_fetches_dir): + if moz_fetches_dir: + log.debug("Prioritizing MOZ_FETCHES_DIR in toolchain path.") + return "prepend" + + if bootstrap: + log.debug( + "Prioritizing mozbuild state dir in toolchain paths because " + "bootstrap mode is enabled." + ) + return "prepend" + + if developer_options: + log.debug( + "Prioritizing mozbuild state dir in toolchain paths because " + "you are not building in release mode." + ) + return "prepend" + + log.debug( + "Prioritizing system over mozbuild state dir in " + "toolchain paths because you are building in " + "release mode." + ) + return "append" + + +toolchains_base_dir = moz_fetches_dir | mozbuild_state_path + + +@dependable +@imports("os") +@imports(_from="os", _import="environ") +def original_path(): + return environ["PATH"].split(os.pathsep) + + +@depends(host, when="--enable-bootstrap") +@imports("os") +@imports("traceback") +@imports(_from="mozbuild.toolchains", _import="toolchain_task_definitions") +@imports(_from="__builtin__", _import="Exception") +def bootstrap_toolchain_tasks(host): + prefix = { + ("x86_64", "GNU", "Linux"): "linux64", + ("x86_64", "OSX", "Darwin"): "macosx64", + ("aarch64", "OSX", "Darwin"): "macosx64-aarch64", + ("x86_64", "WINNT", "WINNT"): "win64", + }.get((host.cpu, host.os, host.kernel)) + try: + return namespace(prefix=prefix, tasks=toolchain_task_definitions()) + except Exception as e: + message = traceback.format_exc() + log.warning(str(e)) + log.debug(message) + return None + + +@template +def bootstrap_path(path, **kwargs): + when = kwargs.pop("when", None) + if kwargs: + configure_error("bootstrap_path only takes `when` as a keyword argument") + + @depends( + "--enable-bootstrap", + toolchains_base_dir, + bootstrap_toolchain_tasks, + shell, + check_build_environment, + dependable(path), + when=when, + ) + @imports("os") + @imports("subprocess") + @imports(_from="mozbuild.util", _import="ensureParentDir") + @imports(_from="__builtin__", _import="open") + @imports(_from="__builtin__", _import="Exception") + def bootstrap_path(bootstrap, toolchains_base_dir, tasks, shell, build_env, path): + path_parts = path.split("/") + + def try_bootstrap(exists): + if not tasks: + return False + prefixes = [""] + if tasks.prefix: + prefixes.insert(0, "{}-".format(tasks.prefix)) + for prefix in prefixes: + label = "toolchain-{}{}".format(prefix, path_parts[0]) + task = tasks.tasks.get(label) + if task: + break + log.debug("Trying to bootstrap %s", label) + if not task: + return False + task_index = task.optimization.get("index-search") + if not task_index: + return False + log.debug("Resolved %s to %s", label, task_index[0]) + task_index = task_index[0].split(".")[-1] + artifact = task.attributes["toolchain-artifact"] + # `mach artifact toolchain` doesn't support authentication for + # private artifacts. + if not artifact.startswith("public/"): + log.debug("Cannot bootstrap %s: not a public artifact", label) + return False + index_file = os.path.join(toolchains_base_dir, "indices", path_parts[0]) + try: + with open(index_file) as fh: + index = fh.read().strip() + except Exception: + index = None + if index == task_index and exists: + log.debug("%s is up-to-date", label) + return True + log.info( + "%s bootstrapped toolchain in %s", + "Updating" if exists else "Installing", + os.path.join(toolchains_base_dir, path_parts[0]), + ) + os.makedirs(toolchains_base_dir, exist_ok=True) + subprocess.run( + [ + shell, + os.path.join(build_env.topsrcdir, "mach"), + "--log-no-times", + "artifact", + "toolchain", + "--from-build", + label, + ], + cwd=toolchains_base_dir, + check=True, + ) + ensureParentDir(index_file) + with open(index_file, "w") as fh: + fh.write(task_index) + return True + + path = os.path.join(toolchains_base_dir, *path_parts) + if bootstrap: + try: + if not try_bootstrap(os.path.exists(path)): + # If there aren't toolchain artifacts to use for this build, + # don't return a path. + return None + except Exception as e: + log.error("%s", e) + die("If you can't fix the above, retry with --disable-bootstrap.") + # We re-test whether the path exists because it may have been created by + # try_bootstrap. Automation will not have gone through the bootstrap + # process, but we want to return the path if it exists. + if os.path.exists(path): + return path + + return bootstrap_path + + +@template +def bootstrap_search_path(path, paths=original_path, **kwargs): + @depends( + bootstrap_path(path, **kwargs), + bootstrap_search_path_order, + paths, + original_path, + ) + def bootstrap_search_path(path, order, paths, original_path): + if paths is None: + paths = original_path + if not path: + return paths + if order == "prepend": + return [path] + paths + return paths + [path] + + return bootstrap_search_path diff --git a/moz.configure b/moz.configure index 042853133953a..e7a37cd89e349 100755 --- a/moz.configure +++ b/moz.configure @@ -190,214 +190,7 @@ option( set_config("ENABLE_UNIFIED_BUILD", True, when="--disable-unified-build") -option( - env="MOZ_FETCHES_DIR", - nargs=1, - when="MOZ_AUTOMATION", - help="Directory containing fetched artifacts", -) - - -@depends("MOZ_FETCHES_DIR", when="MOZ_AUTOMATION") -def moz_fetches_dir(value): - if value: - return value[0] - - -@depends(vcs_checkout_type, milestone.is_nightly, "MOZ_AUTOMATION") -def bootstrap_default(vcs_checkout_type, is_nightly, automation): - if automation: - return False - # We only enable if building off a VCS checkout of central. - if is_nightly and vcs_checkout_type: - return True - - -option( - "--enable-bootstrap", - default=bootstrap_default, - help="{Automatically bootstrap or update some toolchains|Disable bootstrap or update of toolchains}", -) - - -@depends(developer_options, "--enable-bootstrap", moz_fetches_dir) -def bootstrap_search_path_order(developer_options, bootstrap, moz_fetches_dir): - if moz_fetches_dir: - log.debug("Prioritizing MOZ_FETCHES_DIR in toolchain path.") - return "prepend" - - if bootstrap: - log.debug( - "Prioritizing mozbuild state dir in toolchain paths because " - "bootstrap mode is enabled." - ) - return "prepend" - - if developer_options: - log.debug( - "Prioritizing mozbuild state dir in toolchain paths because " - "you are not building in release mode." - ) - return "prepend" - - log.debug( - "Prioritizing system over mozbuild state dir in " - "toolchain paths because you are building in " - "release mode." - ) - return "append" - - -toolchains_base_dir = moz_fetches_dir | mozbuild_state_path - - -@dependable -@imports("os") -@imports(_from="os", _import="environ") -def original_path(): - return environ["PATH"].split(os.pathsep) - - -@depends(host, when="--enable-bootstrap") -@imports("os") -@imports("traceback") -@imports(_from="mozbuild.toolchains", _import="toolchain_task_definitions") -@imports(_from="__builtin__", _import="Exception") -def bootstrap_toolchain_tasks(host): - prefix = { - ("x86_64", "GNU", "Linux"): "linux64", - ("x86_64", "OSX", "Darwin"): "macosx64", - ("aarch64", "OSX", "Darwin"): "macosx64-aarch64", - ("x86_64", "WINNT", "WINNT"): "win64", - }.get((host.cpu, host.os, host.kernel)) - try: - return namespace(prefix=prefix, tasks=toolchain_task_definitions()) - except Exception as e: - message = traceback.format_exc() - log.warning(str(e)) - log.debug(message) - return None - - -@template -def bootstrap_path(path, **kwargs): - when = kwargs.pop("when", None) - if kwargs: - configure_error("bootstrap_path only takes `when` as a keyword argument") - - @depends( - "--enable-bootstrap", - toolchains_base_dir, - bootstrap_toolchain_tasks, - shell, - check_build_environment, - dependable(path), - when=when, - ) - @imports("os") - @imports("subprocess") - @imports(_from="mozbuild.util", _import="ensureParentDir") - @imports(_from="__builtin__", _import="open") - @imports(_from="__builtin__", _import="Exception") - def bootstrap_path(bootstrap, toolchains_base_dir, tasks, shell, build_env, path): - path_parts = path.split("/") - - def try_bootstrap(exists): - if not tasks: - return False - prefixes = [""] - if tasks.prefix: - prefixes.insert(0, "{}-".format(tasks.prefix)) - for prefix in prefixes: - label = "toolchain-{}{}".format(prefix, path_parts[0]) - task = tasks.tasks.get(label) - if task: - break - log.debug("Trying to bootstrap %s", label) - if not task: - return False - task_index = task.optimization.get("index-search") - if not task_index: - return False - log.debug("Resolved %s to %s", label, task_index[0]) - task_index = task_index[0].split(".")[-1] - artifact = task.attributes["toolchain-artifact"] - # `mach artifact toolchain` doesn't support authentication for - # private artifacts. - if not artifact.startswith("public/"): - log.debug("Cannot bootstrap %s: not a public artifact", label) - return False - index_file = os.path.join(toolchains_base_dir, "indices", path_parts[0]) - try: - with open(index_file) as fh: - index = fh.read().strip() - except Exception: - index = None - if index == task_index and exists: - log.debug("%s is up-to-date", label) - return True - log.info( - "%s bootstrapped toolchain in %s", - "Updating" if exists else "Installing", - os.path.join(toolchains_base_dir, path_parts[0]), - ) - os.makedirs(toolchains_base_dir, exist_ok=True) - subprocess.run( - [ - shell, - os.path.join(build_env.topsrcdir, "mach"), - "--log-no-times", - "artifact", - "toolchain", - "--from-build", - label, - ], - cwd=toolchains_base_dir, - check=True, - ) - ensureParentDir(index_file) - with open(index_file, "w") as fh: - fh.write(task_index) - return True - - path = os.path.join(toolchains_base_dir, *path_parts) - if bootstrap: - try: - if not try_bootstrap(os.path.exists(path)): - # If there aren't toolchain artifacts to use for this build, - # don't return a path. - return None - except Exception as e: - log.error("%s", e) - die("If you can't fix the above, retry with --disable-bootstrap.") - # We re-test whether the path exists because it may have been created by - # try_bootstrap. Automation will not have gone through the bootstrap - # process, but we want to return the path if it exists. - if os.path.exists(path): - return path - - return bootstrap_path - - -@template -def bootstrap_search_path(path, paths=original_path, **kwargs): - @depends( - bootstrap_path(path, **kwargs), - bootstrap_search_path_order, - paths, - original_path, - ) - def bootstrap_search_path(path, order, paths, original_path): - if paths is None: - paths = original_path - if not path: - return paths - if order == "prepend": - return [path] + paths - return paths + [path] - - return bootstrap_search_path - +include("build/moz.configure/bootstrap.configure") # The execution model of the configure sandbox doesn't allow for # check_prog to use bootstrap_search_path directly because check_prog -- GitLab