Skip to content

Commit 303d916

Browse files
committed
Auto merge of #96687 - jyn514:download-rustc, r=Mark-Simulacrum
Move download-rustc from python to rustbuild - Remove download-rustc handling from bootstrap.py - Allow a custom `pattern` in `builder.unpack()` - Only download rustc once another part of bootstrap depends on it. This is somewhat necessary since the download functions rely on having a full `Builder`, which isn't available until after config parsing finishes. Helps with #94829.
2 parents 0acc4a3 + 00bb4df commit 303d916

File tree

8 files changed

+418
-352
lines changed

8 files changed

+418
-352
lines changed

src/bootstrap/bootstrap.py

+38-116
Original file line numberDiff line numberDiff line change
@@ -444,9 +444,8 @@ def __init__(self):
444444
self.verbose = False
445445
self.git_version = None
446446
self.nix_deps_dir = None
447-
self.rustc_commit = None
448447

449-
def download_toolchain(self, stage0=True, rustc_channel=None):
448+
def download_toolchain(self):
450449
"""Fetch the build system for Rust, written in Rust
451450
452451
This method will build a cache directory, then it will fetch the
@@ -456,45 +455,35 @@ def download_toolchain(self, stage0=True, rustc_channel=None):
456455
Each downloaded tarball is extracted, after that, the script
457456
will move all the content to the right place.
458457
"""
459-
if rustc_channel is None:
460-
rustc_channel = self.stage0_compiler.version
461-
bin_root = self.bin_root(stage0)
458+
rustc_channel = self.stage0_compiler.version
459+
bin_root = self.bin_root()
462460

463461
key = self.stage0_compiler.date
464-
if not stage0:
465-
key += str(self.rustc_commit)
466-
if self.rustc(stage0).startswith(bin_root) and \
467-
(not os.path.exists(self.rustc(stage0)) or
468-
self.program_out_of_date(self.rustc_stamp(stage0), key)):
462+
if self.rustc().startswith(bin_root) and \
463+
(not os.path.exists(self.rustc()) or
464+
self.program_out_of_date(self.rustc_stamp(), key)):
469465
if os.path.exists(bin_root):
470466
shutil.rmtree(bin_root)
471467
tarball_suffix = '.tar.xz' if support_xz() else '.tar.gz'
472468
filename = "rust-std-{}-{}{}".format(
473469
rustc_channel, self.build, tarball_suffix)
474470
pattern = "rust-std-{}".format(self.build)
475-
self._download_component_helper(filename, pattern, tarball_suffix, stage0)
471+
self._download_component_helper(filename, pattern, tarball_suffix)
476472
filename = "rustc-{}-{}{}".format(rustc_channel, self.build,
477473
tarball_suffix)
478-
self._download_component_helper(filename, "rustc", tarball_suffix, stage0)
479-
# download-rustc doesn't need its own cargo, it can just use beta's.
480-
if stage0:
481-
filename = "cargo-{}-{}{}".format(rustc_channel, self.build,
482-
tarball_suffix)
483-
self._download_component_helper(filename, "cargo", tarball_suffix)
484-
self.fix_bin_or_dylib("{}/bin/cargo".format(bin_root))
485-
else:
486-
filename = "rustc-dev-{}-{}{}".format(rustc_channel, self.build, tarball_suffix)
487-
self._download_component_helper(
488-
filename, "rustc-dev", tarball_suffix, stage0
489-
)
474+
self._download_component_helper(filename, "rustc", tarball_suffix)
475+
filename = "cargo-{}-{}{}".format(rustc_channel, self.build,
476+
tarball_suffix)
477+
self._download_component_helper(filename, "cargo", tarball_suffix)
478+
self.fix_bin_or_dylib("{}/bin/cargo".format(bin_root))
490479

491480
self.fix_bin_or_dylib("{}/bin/rustc".format(bin_root))
492481
self.fix_bin_or_dylib("{}/bin/rustdoc".format(bin_root))
493482
lib_dir = "{}/lib".format(bin_root)
494483
for lib in os.listdir(lib_dir):
495484
if lib.endswith(".so"):
496485
self.fix_bin_or_dylib(os.path.join(lib_dir, lib))
497-
with output(self.rustc_stamp(stage0)) as rust_stamp:
486+
with output(self.rustc_stamp()) as rust_stamp:
498487
rust_stamp.write(key)
499488

500489
if self.rustfmt() and self.rustfmt().startswith(bin_root) and (
@@ -518,24 +507,17 @@ def download_toolchain(self, stage0=True, rustc_channel=None):
518507
rustfmt_stamp.write(self.stage0_rustfmt.channel())
519508

520509
def _download_component_helper(
521-
self, filename, pattern, tarball_suffix, stage0=True, key=None
510+
self, filename, pattern, tarball_suffix, key=None
522511
):
523512
if key is None:
524-
if stage0:
525-
key = self.stage0_compiler.date
526-
else:
527-
key = self.rustc_commit
513+
key = self.stage0_compiler.date
528514
cache_dst = os.path.join(self.build_dir, "cache")
529515
rustc_cache = os.path.join(cache_dst, key)
530516
if not os.path.exists(rustc_cache):
531517
os.makedirs(rustc_cache)
532518

533-
if stage0:
534-
base = self._download_url
535-
url = "dist/{}".format(key)
536-
else:
537-
base = "https://ci-artifacts.rust-lang.org"
538-
url = "rustc-builds/{}".format(self.rustc_commit)
519+
base = self._download_url
520+
url = "dist/{}".format(key)
539521
tarball = os.path.join(rustc_cache, filename)
540522
if not os.path.exists(tarball):
541523
get(
@@ -544,9 +526,9 @@ def _download_component_helper(
544526
tarball,
545527
self.checksums_sha256,
546528
verbose=self.verbose,
547-
do_verify=stage0,
529+
do_verify=True,
548530
)
549-
unpack(tarball, tarball_suffix, self.bin_root(stage0), match=pattern, verbose=self.verbose)
531+
unpack(tarball, tarball_suffix, self.bin_root(), match=pattern, verbose=self.verbose)
550532

551533
def fix_bin_or_dylib(self, fname):
552534
"""Modifies the interpreter section of 'fname' to fix the dynamic linker,
@@ -644,62 +626,15 @@ def fix_bin_or_dylib(self, fname):
644626
print("warning: failed to call patchelf:", reason)
645627
return
646628

647-
# If `download-rustc` is set, download the most recent commit with CI artifacts
648-
def maybe_download_ci_toolchain(self):
649-
# If `download-rustc` is not set, default to rebuilding.
650-
download_rustc = self.get_toml("download-rustc", section="rust")
651-
if download_rustc is None or download_rustc == "false":
652-
return None
653-
assert download_rustc == "true" or download_rustc == "if-unchanged", download_rustc
654-
655-
# Handle running from a directory other than the top level
656-
rev_parse = ["git", "rev-parse", "--show-toplevel"]
657-
top_level = subprocess.check_output(rev_parse, universal_newlines=True).strip()
658-
compiler = "{}/compiler/".format(top_level)
659-
library = "{}/library/".format(top_level)
660-
661-
# Look for a version to compare to based on the current commit.
662-
# Only commits merged by bors will have CI artifacts.
663-
merge_base = [
664-
"git", "rev-list", "[email protected]", "-n1",
665-
"--first-parent", "HEAD"
666-
]
667-
commit = subprocess.check_output(merge_base, universal_newlines=True).strip()
668-
if not commit:
669-
print("error: could not find commit hash for downloading rustc")
670-
print("help: maybe your repository history is too shallow?")
671-
print("help: consider disabling `download-rustc`")
672-
print("help: or fetch enough history to include one upstream commit")
673-
exit(1)
674-
675-
# Warn if there were changes to the compiler or standard library since the ancestor commit.
676-
status = subprocess.call(["git", "diff-index", "--quiet", commit, "--", compiler, library])
677-
if status != 0:
678-
if download_rustc == "if-unchanged":
679-
if self.verbose:
680-
print("warning: saw changes to compiler/ or library/ since {}; " \
681-
"ignoring `download-rustc`".format(commit))
682-
return None
683-
print("warning: `download-rustc` is enabled, but there are changes to " \
684-
"compiler/ or library/")
685-
686-
if self.verbose:
687-
print("using downloaded stage2 artifacts from CI (commit {})".format(commit))
688-
self.rustc_commit = commit
689-
# FIXME: support downloading artifacts from the beta channel
690-
self.download_toolchain(False, "nightly")
691-
692-
def rustc_stamp(self, stage0):
629+
def rustc_stamp(self):
693630
"""Return the path for .rustc-stamp at the given stage
694631
695632
>>> rb = RustBuild()
696633
>>> rb.build_dir = "build"
697-
>>> rb.rustc_stamp(True) == os.path.join("build", "stage0", ".rustc-stamp")
698-
True
699-
>>> rb.rustc_stamp(False) == os.path.join("build", "ci-rustc", ".rustc-stamp")
634+
>>> rb.rustc_stamp() == os.path.join("build", "stage0", ".rustc-stamp")
700635
True
701636
"""
702-
return os.path.join(self.bin_root(stage0), '.rustc-stamp')
637+
return os.path.join(self.bin_root(), '.rustc-stamp')
703638

704639
def rustfmt_stamp(self):
705640
"""Return the path for .rustfmt-stamp
@@ -709,7 +644,7 @@ def rustfmt_stamp(self):
709644
>>> rb.rustfmt_stamp() == os.path.join("build", "stage0", ".rustfmt-stamp")
710645
True
711646
"""
712-
return os.path.join(self.bin_root(True), '.rustfmt-stamp')
647+
return os.path.join(self.bin_root(), '.rustfmt-stamp')
713648

714649
def program_out_of_date(self, stamp_path, key):
715650
"""Check if the given program stamp is out of date"""
@@ -718,26 +653,21 @@ def program_out_of_date(self, stamp_path, key):
718653
with open(stamp_path, 'r') as stamp:
719654
return key != stamp.read()
720655

721-
def bin_root(self, stage0):
656+
def bin_root(self):
722657
"""Return the binary root directory for the given stage
723658
724659
>>> rb = RustBuild()
725660
>>> rb.build_dir = "build"
726-
>>> rb.bin_root(True) == os.path.join("build", "stage0")
727-
True
728-
>>> rb.bin_root(False) == os.path.join("build", "ci-rustc")
661+
>>> rb.bin_root() == os.path.join("build", "stage0")
729662
True
730663
731664
When the 'build' property is given should be a nested directory:
732665
733666
>>> rb.build = "devel"
734-
>>> rb.bin_root(True) == os.path.join("build", "devel", "stage0")
667+
>>> rb.bin_root() == os.path.join("build", "devel", "stage0")
735668
True
736669
"""
737-
if stage0:
738-
subdir = "stage0"
739-
else:
740-
subdir = "ci-rustc"
670+
subdir = "stage0"
741671
return os.path.join(self.build_dir, self.build, subdir)
742672

743673
def get_toml(self, key, section=None):
@@ -785,37 +715,33 @@ def cargo(self):
785715
"""Return config path for cargo"""
786716
return self.program_config('cargo')
787717

788-
def rustc(self, stage0):
718+
def rustc(self):
789719
"""Return config path for rustc"""
790-
return self.program_config('rustc', stage0)
720+
return self.program_config('rustc')
791721

792722
def rustfmt(self):
793723
"""Return config path for rustfmt"""
794724
if self.stage0_rustfmt is None:
795725
return None
796726
return self.program_config('rustfmt')
797727

798-
def program_config(self, program, stage0=True):
728+
def program_config(self, program):
799729
"""Return config path for the given program at the given stage
800730
801731
>>> rb = RustBuild()
802732
>>> rb.config_toml = 'rustc = "rustc"\\n'
803733
>>> rb.program_config('rustc')
804734
'rustc'
805735
>>> rb.config_toml = ''
806-
>>> cargo_path = rb.program_config('cargo', True)
807-
>>> cargo_path.rstrip(".exe") == os.path.join(rb.bin_root(True),
808-
... "bin", "cargo")
809-
True
810-
>>> cargo_path = rb.program_config('cargo', False)
811-
>>> cargo_path.rstrip(".exe") == os.path.join(rb.bin_root(False),
736+
>>> cargo_path = rb.program_config('cargo')
737+
>>> cargo_path.rstrip(".exe") == os.path.join(rb.bin_root(),
812738
... "bin", "cargo")
813739
True
814740
"""
815741
config = self.get_toml(program)
816742
if config:
817743
return os.path.expanduser(config)
818-
return os.path.join(self.bin_root(stage0), "bin", "{}{}".format(
744+
return os.path.join(self.bin_root(), "bin", "{}{}".format(
819745
program, self.exe_suffix()))
820746

821747
@staticmethod
@@ -871,14 +797,14 @@ def build_bootstrap(self):
871797
if "CARGO_BUILD_TARGET" in env:
872798
del env["CARGO_BUILD_TARGET"]
873799
env["CARGO_TARGET_DIR"] = build_dir
874-
env["RUSTC"] = self.rustc(True)
875-
env["LD_LIBRARY_PATH"] = os.path.join(self.bin_root(True), "lib") + \
800+
env["RUSTC"] = self.rustc()
801+
env["LD_LIBRARY_PATH"] = os.path.join(self.bin_root(), "lib") + \
876802
(os.pathsep + env["LD_LIBRARY_PATH"]) \
877803
if "LD_LIBRARY_PATH" in env else ""
878-
env["DYLD_LIBRARY_PATH"] = os.path.join(self.bin_root(True), "lib") + \
804+
env["DYLD_LIBRARY_PATH"] = os.path.join(self.bin_root(), "lib") + \
879805
(os.pathsep + env["DYLD_LIBRARY_PATH"]) \
880806
if "DYLD_LIBRARY_PATH" in env else ""
881-
env["LIBRARY_PATH"] = os.path.join(self.bin_root(True), "lib") + \
807+
env["LIBRARY_PATH"] = os.path.join(self.bin_root(), "lib") + \
882808
(os.pathsep + env["LIBRARY_PATH"]) \
883809
if "LIBRARY_PATH" in env else ""
884810

@@ -900,7 +826,7 @@ def build_bootstrap(self):
900826
if self.get_toml("deny-warnings", "rust") != "false":
901827
env["RUSTFLAGS"] += " -Dwarnings"
902828

903-
env["PATH"] = os.path.join(self.bin_root(True), "bin") + \
829+
env["PATH"] = os.path.join(self.bin_root(), "bin") + \
904830
os.pathsep + env["PATH"]
905831
if not os.path.isfile(self.cargo()):
906832
raise Exception("no cargo executable found at `{}`".format(
@@ -1171,8 +1097,6 @@ def bootstrap(help_triggered):
11711097

11721098
# Fetch/build the bootstrap
11731099
build.download_toolchain()
1174-
# Download the master compiler if `download-rustc` is set
1175-
build.maybe_download_ci_toolchain()
11761100
sys.stdout.flush()
11771101
build.ensure_vendored()
11781102
build.build_bootstrap()
@@ -1184,8 +1108,6 @@ def bootstrap(help_triggered):
11841108
env = os.environ.copy()
11851109
env["BOOTSTRAP_PARENT_ID"] = str(os.getpid())
11861110
env["BOOTSTRAP_PYTHON"] = sys.executable
1187-
if build.rustc_commit is not None:
1188-
env["BOOTSTRAP_DOWNLOAD_RUSTC"] = '1'
11891111
run(args, env=env, verbose=build.verbose, is_bootstrap=True)
11901112

11911113

0 commit comments

Comments
 (0)