summaryrefslogtreecommitdiffstats
path: root/src/bootstrap/bootstrap.py
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
commitdc0db358abe19481e475e10c32149b53370f1a1c (patch)
treeab8ce99c4b255ce46f99ef402c27916055b899ee /src/bootstrap/bootstrap.py
parentReleasing progress-linux version 1.71.1+dfsg1-2~progress7.99u1. (diff)
downloadrustc-dc0db358abe19481e475e10c32149b53370f1a1c.tar.xz
rustc-dc0db358abe19481e475e10c32149b53370f1a1c.zip
Merging upstream version 1.72.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/bootstrap/bootstrap.py')
-rw-r--r--src/bootstrap/bootstrap.py172
1 files changed, 103 insertions, 69 deletions
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 58d1926ad..149350e62 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -323,6 +323,7 @@ def default_build_triple(verbose):
cputype_mapper = {
'BePC': 'i686',
'aarch64': 'aarch64',
+ 'aarch64eb': 'aarch64',
'amd64': 'x86_64',
'arm64': 'aarch64',
'i386': 'i686',
@@ -458,23 +459,51 @@ def unpack_component(download_info):
verbose=download_info.verbose,
)
-class RustBuild(object):
- """Provide all the methods required to build Rust"""
+class FakeArgs:
+ """Used for unit tests to avoid updating all call sites"""
def __init__(self):
- self.checksums_sha256 = {}
- self.stage0_compiler = None
- self.download_url = ''
self.build = ''
self.build_dir = ''
self.clean = False
- self.config_toml = ''
- self.rust_root = ''
- self.use_locked_deps = False
- self.use_vendored_sources = False
self.verbose = False
+ self.json_output = False
+ self.color = 'auto'
+ self.warnings = 'default'
+
+class RustBuild(object):
+ """Provide all the methods required to build Rust"""
+ def __init__(self, config_toml="", args=FakeArgs()):
self.git_version = None
self.nix_deps_dir = None
self._should_fix_bins_and_dylibs = None
+ self.rust_root = os.path.abspath(os.path.join(__file__, '../../..'))
+
+ self.config_toml = config_toml
+
+ self.clean = args.clean
+ self.json_output = args.json_output
+ self.verbose = args.verbose
+ self.color = args.color
+ self.warnings = args.warnings
+
+ config_verbose_count = self.get_toml('verbose', 'build')
+ if config_verbose_count is not None:
+ self.verbose = max(self.verbose, int(config_verbose_count))
+
+ self.use_vendored_sources = self.get_toml('vendor', 'build') == 'true'
+ self.use_locked_deps = self.get_toml('locked-deps', 'build') == 'true'
+
+ build_dir = args.build_dir or self.get_toml('build-dir', 'build') or 'build'
+ self.build_dir = os.path.abspath(build_dir)
+
+ with open(os.path.join(self.rust_root, "src", "stage0.json")) as f:
+ data = json.load(f)
+ self.checksums_sha256 = data["checksums_sha256"]
+ self.stage0_compiler = Stage0Toolchain(data["compiler"])
+ self.download_url = os.getenv("RUSTUP_DIST_SERVER") or data["config"]["dist_server"]
+
+ self.build = args.build or self.build_triple()
+
def download_toolchain(self):
"""Fetch the build system for Rust, written in Rust
@@ -620,7 +649,7 @@ class RustBuild(object):
# The latter one does not exist on NixOS when using tmpfs as root.
try:
with open("/etc/os-release", "r") as f:
- if not any(l.strip() in ("ID=nixos", "ID='nixos'", 'ID="nixos"') for l in f):
+ if not any(ln.strip() in ("ID=nixos", "ID='nixos'", 'ID="nixos"') for ln in f):
return False
except FileNotFoundError:
return False
@@ -704,9 +733,10 @@ class RustBuild(object):
"""Return the path for .rustc-stamp at the given stage
>>> rb = RustBuild()
+ >>> rb.build = "host"
>>> rb.build_dir = "build"
- >>> rb.rustc_stamp() == os.path.join("build", "stage0", ".rustc-stamp")
- True
+ >>> expected = os.path.join("build", "host", "stage0", ".rustc-stamp")
+ >>> assert rb.rustc_stamp() == expected, rb.rustc_stamp()
"""
return os.path.join(self.bin_root(), '.rustc-stamp')
@@ -721,15 +751,9 @@ class RustBuild(object):
"""Return the binary root directory for the given stage
>>> rb = RustBuild()
- >>> rb.build_dir = "build"
- >>> rb.bin_root() == os.path.join("build", "stage0")
- True
-
- When the 'build' property is given should be a nested directory:
-
>>> rb.build = "devel"
- >>> rb.bin_root() == os.path.join("build", "devel", "stage0")
- True
+ >>> expected = os.path.abspath(os.path.join("build", "devel", "stage0"))
+ >>> assert rb.bin_root() == expected, rb.bin_root()
"""
subdir = "stage0"
return os.path.join(self.build_dir, self.build, subdir)
@@ -761,9 +785,12 @@ class RustBuild(object):
>>> rb.get_toml("key1")
'true'
"""
+ return RustBuild.get_toml_static(self.config_toml, key, section)
+ @staticmethod
+ def get_toml_static(config_toml, key, section=None):
cur_section = None
- for line in self.config_toml.splitlines():
+ for line in config_toml.splitlines():
section_match = re.match(r'^\s*\[(.*)\]\s*$', line)
if section_match is not None:
cur_section = section_match.group(1)
@@ -772,7 +799,7 @@ class RustBuild(object):
if match is not None:
value = match.group(1)
if section is None or section == cur_section:
- return self.get_string(value) or value.strip()
+ return RustBuild.get_string(value) or value.strip()
return None
def cargo(self):
@@ -835,13 +862,23 @@ class RustBuild(object):
"""
return os.path.join(self.build_dir, "bootstrap", "debug", "bootstrap")
- def build_bootstrap(self, color, verbose_count):
+ def build_bootstrap(self):
"""Build bootstrap"""
env = os.environ.copy()
if "GITHUB_ACTIONS" in env:
print("::group::Building bootstrap")
else:
print("Building bootstrap", file=sys.stderr)
+
+ args = self.build_bootstrap_cmd(env)
+ # Run this from the source directory so cargo finds .cargo/config
+ run(args, env=env, verbose=self.verbose, cwd=self.rust_root)
+
+ if "GITHUB_ACTIONS" in env:
+ print("::endgroup::")
+
+ def build_bootstrap_cmd(self, env):
+ """For tests."""
build_dir = os.path.join(self.build_dir, "bootstrap")
if self.clean and os.path.exists(build_dir):
shutil.rmtree(build_dir)
@@ -872,11 +909,17 @@ class RustBuild(object):
}
for var_name, toml_key in var_data.items():
toml_val = self.get_toml(toml_key, build_section)
- if toml_val != None:
+ if toml_val is not None:
env["{}_{}".format(var_name, host_triple_sanitized)] = toml_val
# preserve existing RUSTFLAGS
env.setdefault("RUSTFLAGS", "")
+ # we need to explicitly add +xgot here so that we can successfully bootstrap
+ # a usable stage1 compiler
+ # FIXME: remove this if condition on the next bootstrap bump
+ # cfg(bootstrap)
+ if self.build_triple().startswith('mips'):
+ env["RUSTFLAGS"] += " -Ctarget-feature=+xgot"
target_features = []
if self.get_toml("crt-static", build_section) == "true":
target_features += ["+crt-static"]
@@ -888,7 +931,11 @@ class RustBuild(object):
if target_linker is not None:
env["RUSTFLAGS"] += " -C linker=" + target_linker
env["RUSTFLAGS"] += " -Wrust_2018_idioms -Wunused_lifetimes"
- if self.get_toml("deny-warnings", "rust") != "false":
+ if self.warnings == "default":
+ deny_warnings = self.get_toml("deny-warnings", "rust") != "false"
+ else:
+ deny_warnings = self.warnings == "deny"
+ if deny_warnings:
env["RUSTFLAGS"] += " -Dwarnings"
env["PATH"] = os.path.join(self.bin_root(), "bin") + \
@@ -898,7 +945,7 @@ class RustBuild(object):
self.cargo()))
args = [self.cargo(), "build", "--manifest-path",
os.path.join(self.rust_root, "src/bootstrap/Cargo.toml")]
- args.extend("--verbose" for _ in range(verbose_count))
+ args.extend("--verbose" for _ in range(self.verbose))
if self.use_locked_deps:
args.append("--locked")
if self.use_vendored_sources:
@@ -908,16 +955,16 @@ class RustBuild(object):
args.append("build-metrics")
if self.json_output:
args.append("--message-format=json")
- if color == "always":
+ if self.color == "always":
args.append("--color=always")
- elif color == "never":
+ elif self.color == "never":
args.append("--color=never")
+ try:
+ args += env["CARGOFLAGS"].split()
+ except KeyError:
+ pass
- # Run this from the source directory so cargo finds .cargo/config
- run(args, env=env, verbose=self.verbose, cwd=self.rust_root)
-
- if "GITHUB_ACTIONS" in env:
- print("::endgroup::")
+ return args
def build_triple(self):
"""Build triple as in LLVM
@@ -967,7 +1014,7 @@ class RustBuild(object):
if os.path.exists(cargo_dir):
shutil.rmtree(cargo_dir)
-def parse_args():
+def parse_args(args):
"""Parse the command line arguments that the python script needs."""
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument('-h', '--help', action='store_true')
@@ -977,18 +1024,14 @@ def parse_args():
parser.add_argument('--color', choices=['always', 'never', 'auto'])
parser.add_argument('--clean', action='store_true')
parser.add_argument('--json-output', action='store_true')
+ parser.add_argument('--warnings', choices=['deny', 'warn', 'default'], default='default')
parser.add_argument('-v', '--verbose', action='count', default=0)
- return parser.parse_known_args(sys.argv)[0]
+ return parser.parse_known_args(args)[0]
def bootstrap(args):
"""Configure, fetch, build and run the initial bootstrap"""
- # Configure initial bootstrap
- build = RustBuild()
- build.rust_root = os.path.abspath(os.path.join(__file__, '../../..'))
- build.verbose = args.verbose != 0
- build.clean = args.clean
- build.json_output = args.json_output
+ rust_root = os.path.abspath(os.path.join(__file__, '../../..'))
# Read from `--config`, then `RUST_BOOTSTRAP_CONFIG`, then `./config.toml`,
# then `config.toml` in the root directory.
@@ -997,52 +1040,43 @@ def bootstrap(args):
if using_default_path:
toml_path = 'config.toml'
if not os.path.exists(toml_path):
- toml_path = os.path.join(build.rust_root, toml_path)
+ toml_path = os.path.join(rust_root, toml_path)
# Give a hard error if `--config` or `RUST_BOOTSTRAP_CONFIG` are set to a missing path,
# but not if `config.toml` hasn't been created.
if not using_default_path or os.path.exists(toml_path):
with open(toml_path) as config:
- build.config_toml = config.read()
+ config_toml = config.read()
+ else:
+ config_toml = ''
- profile = build.get_toml('profile')
+ profile = RustBuild.get_toml_static(config_toml, 'profile')
if profile is not None:
- include_file = 'config.{}.toml'.format(profile)
- include_dir = os.path.join(build.rust_root, 'src', 'bootstrap', 'defaults')
+ # Allows creating alias for profile names, allowing
+ # profiles to be renamed while maintaining back compatibility
+ # Keep in sync with `profile_aliases` in config.rs
+ profile_aliases = {
+ "user": "dist"
+ }
+ include_file = 'config.{}.toml'.format(profile_aliases.get(profile) or profile)
+ include_dir = os.path.join(rust_root, 'src', 'bootstrap', 'defaults')
include_path = os.path.join(include_dir, include_file)
- # HACK: This works because `build.get_toml()` returns the first match it finds for a
+ # HACK: This works because `self.get_toml()` returns the first match it finds for a
# specific key, so appending our defaults at the end allows the user to override them
with open(include_path) as included_toml:
- build.config_toml += os.linesep + included_toml.read()
-
- verbose_count = args.verbose
- config_verbose_count = build.get_toml('verbose', 'build')
- if config_verbose_count is not None:
- verbose_count = max(args.verbose, int(config_verbose_count))
-
- build.use_vendored_sources = build.get_toml('vendor', 'build') == 'true'
- build.use_locked_deps = build.get_toml('locked-deps', 'build') == 'true'
+ config_toml += os.linesep + included_toml.read()
+ # Configure initial bootstrap
+ build = RustBuild(config_toml, args)
build.check_vendored_status()
- build_dir = args.build_dir or build.get_toml('build-dir', 'build') or 'build'
- build.build_dir = os.path.abspath(build_dir)
-
- with open(os.path.join(build.rust_root, "src", "stage0.json")) as f:
- data = json.load(f)
- build.checksums_sha256 = data["checksums_sha256"]
- build.stage0_compiler = Stage0Toolchain(data["compiler"])
- build.download_url = os.getenv("RUSTUP_DIST_SERVER") or data["config"]["dist_server"]
-
- build.build = args.build or build.build_triple()
-
if not os.path.exists(build.build_dir):
os.makedirs(build.build_dir)
# Fetch/build the bootstrap
build.download_toolchain()
sys.stdout.flush()
- build.build_bootstrap(args.color, verbose_count)
+ build.build_bootstrap()
sys.stdout.flush()
# Run the bootstrap
@@ -1062,7 +1096,7 @@ def main():
if len(sys.argv) > 1 and sys.argv[1] == 'help':
sys.argv[1] = '-h'
- args = parse_args()
+ args = parse_args(sys.argv)
help_triggered = args.help or len(sys.argv) == 1
# If the user is asking for help, let them know that the whole download-and-build