@@ -383,7 +383,7 @@ def __init__(self):
383383 self.nix_deps_dir = None
384384 self.rustc_commit = None
385385
386- def download_stage0 (self):
386+ def download_toolchain (self, stage0=True, rustc_channel=None ):
387387 """Fetch the build system for Rust, written in Rust
388388
389389 This method will build a cache directory, then it will fetch the
@@ -393,43 +393,47 @@ def download_stage0(self):
393393 Each downloaded tarball is extracted, after that, the script
394394 will move all the content to the right place.
395395 """
396- rustc_channel = self.rustc_channel
396+ if rustc_channel is None:
397+ rustc_channel = self.rustc_channel
397398 rustfmt_channel = self.rustfmt_channel
398-
399- if self.rustc().startswith(self.bin_root()) and \
400- (not os.path.exists(self.rustc()) or
401- self.program_out_of_date(self.rustc_stamp(), self.date + str(self.rustc_commit))):
402- if os.path.exists(self.bin_root()):
403- shutil.rmtree(self.bin_root())
404- download_rustc = self.rustc_commit is not None
399+ bin_root = self.bin_root(stage0)
400+
401+ key = self.date
402+ if not stage0:
403+ key += str(self.rustc_commit)
404+ if self.rustc(stage0).startswith(bin_root) and \
405+ (not os.path.exists(self.rustc(stage0)) or
406+ self.program_out_of_date(self.rustc_stamp(stage0), key)):
407+ if os.path.exists(bin_root):
408+ shutil.rmtree(bin_root)
405409 tarball_suffix = '.tar.xz' if support_xz() else '.tar.gz'
406410 filename = "rust-std-{}-{}{}".format(
407411 rustc_channel, self.build, tarball_suffix)
408412 pattern = "rust-std-{}".format(self.build)
409- self._download_component_helper(filename, pattern, tarball_suffix, download_rustc )
413+ self._download_component_helper(filename, pattern, tarball_suffix, stage0 )
410414 filename = "rustc-{}-{}{}".format(rustc_channel, self.build,
411415 tarball_suffix)
412- self._download_component_helper(filename, "rustc", tarball_suffix, download_rustc )
416+ self._download_component_helper(filename, "rustc", tarball_suffix, stage0 )
413417 filename = "cargo-{}-{}{}".format(rustc_channel, self.build,
414418 tarball_suffix)
415419 self._download_component_helper(filename, "cargo", tarball_suffix)
416- if self.rustc_commit is not None :
420+ if not stage0 :
417421 filename = "rustc-dev-{}-{}{}".format(rustc_channel, self.build, tarball_suffix)
418422 self._download_component_helper(
419- filename, "rustc-dev", tarball_suffix, download_rustc
423+ filename, "rustc-dev", tarball_suffix, stage0
420424 )
421425
422- self.fix_bin_or_dylib("{}/bin/rustc".format(self. bin_root() ))
423- self.fix_bin_or_dylib("{}/bin/rustdoc".format(self. bin_root() ))
424- self.fix_bin_or_dylib("{}/bin/cargo".format(self. bin_root() ))
425- lib_dir = "{}/lib".format(self. bin_root() )
426+ self.fix_bin_or_dylib("{}/bin/rustc".format(bin_root))
427+ self.fix_bin_or_dylib("{}/bin/rustdoc".format(bin_root))
428+ self.fix_bin_or_dylib("{}/bin/cargo".format(bin_root))
429+ lib_dir = "{}/lib".format(bin_root)
426430 for lib in os.listdir(lib_dir):
427431 if lib.endswith(".so"):
428432 self.fix_bin_or_dylib(os.path.join(lib_dir, lib), rpath_libz=True)
429- with output(self.rustc_stamp()) as rust_stamp:
430- rust_stamp.write(self.date + str(self.rustc_commit) )
433+ with output(self.rustc_stamp(stage0 )) as rust_stamp:
434+ rust_stamp.write(key )
431435
432- if self.rustfmt() and self.rustfmt().startswith(self. bin_root() ) and (
436+ if self.rustfmt() and self.rustfmt().startswith(bin_root) and (
433437 not os.path.exists(self.rustfmt())
434438 or self.program_out_of_date(self.rustfmt_stamp(), self.rustfmt_channel)
435439 ):
@@ -440,12 +444,13 @@ def download_stage0(self):
440444 self._download_component_helper(
441445 filename, "rustfmt-preview", tarball_suffix, key=date
442446 )
443- self.fix_bin_or_dylib("{}/bin/rustfmt".format(self. bin_root() ))
444- self.fix_bin_or_dylib("{}/bin/cargo-fmt".format(self. bin_root() ))
447+ self.fix_bin_or_dylib("{}/bin/rustfmt".format(bin_root))
448+ self.fix_bin_or_dylib("{}/bin/cargo-fmt".format(bin_root))
445449 with output(self.rustfmt_stamp()) as rustfmt_stamp:
446450 rustfmt_stamp.write(self.rustfmt_channel)
447451
448- if self.downloading_llvm():
452+ # Avoid downloading LLVM twice (once for stage0 and once for the master rustc)
453+ if self.downloading_llvm() and stage0:
449454 # We want the most recent LLVM submodule update to avoid downloading
450455 # LLVM more often than necessary.
451456 #
@@ -498,27 +503,26 @@ def downloading_llvm(self):
498503 or (opt == "if-available" and self.build in supported_platforms)
499504
500505 def _download_component_helper(
501- self, filename, pattern, tarball_suffix, download_rustc=False , key=None
506+ self, filename, pattern, tarball_suffix, stage0=True , key=None
502507 ):
503508 if key is None:
504- if download_rustc:
505- key = self.rustc_commit
506- else:
509+ if stage0:
507510 key = self.date
511+ else:
512+ key = self.rustc_commit
508513 cache_dst = os.path.join(self.build_dir, "cache")
509514 rustc_cache = os.path.join(cache_dst, key)
510515 if not os.path.exists(rustc_cache):
511516 os.makedirs(rustc_cache)
512517
513- if download_rustc:
514- url = "https://ci-artifacts.rust-lang.org/rustc-builds/{}".format(self.rustc_commit)
515- else:
518+ if stage0:
516519 url = "{}/dist/{}".format(self._download_url, key)
520+ else:
521+ url = "https://ci-artifacts.rust-lang.org/rustc-builds/{}".format(self.rustc_commit)
517522 tarball = os.path.join(rustc_cache, filename)
518523 if not os.path.exists(tarball):
519- do_verify = not download_rustc
520- get("{}/{}".format(url, filename), tarball, verbose=self.verbose, do_verify=do_verify)
521- unpack(tarball, tarball_suffix, self.bin_root(), match=pattern, verbose=self.verbose)
524+ get("{}/{}".format(url, filename), tarball, verbose=self.verbose, do_verify=stage0)
525+ unpack(tarball, tarball_suffix, self.bin_root(stage0), match=pattern, verbose=self.verbose)
522526
523527 def _download_ci_llvm(self, llvm_sha, llvm_assertions):
524528 cache_prefix = "llvm-{}-{}".format(llvm_sha, llvm_assertions)
@@ -576,10 +580,10 @@ def fix_bin_or_dylib(self, fname, rpath_libz=False):
576580 nix_os_msg = "info: you seem to be running NixOS. Attempting to patch"
577581 print(nix_os_msg, fname)
578582
579- # Only build `stage0/ .nix-deps` once.
583+ # Only build `.nix-deps` once.
580584 nix_deps_dir = self.nix_deps_dir
581585 if not nix_deps_dir:
582- nix_deps_dir = "{}/ .nix-deps".format(self.bin_root())
586+ nix_deps_dir = ".nix-deps"
583587 if not os.path.exists(nix_deps_dir):
584588 os.makedirs(nix_deps_dir)
585589
@@ -637,8 +641,8 @@ def fix_bin_or_dylib(self, fname, rpath_libz=False):
637641 print("warning: failed to call patchelf:", reason)
638642 return
639643
640- # Return the stage1 compiler to download, if any.
641- def maybe_download_rustc (self):
644+ # If `download-rustc` is set, download the most recent commit with CI artifacts
645+ def maybe_download_ci_toolchain (self):
642646 # If `download-rustc` is not set, default to rebuilding.
643647 if self.get_toml("download-rustc", section="rust") != "true":
644648 return None
@@ -658,17 +662,23 @@ def maybe_download_rustc(self):
658662 if status != 0:
659663 print("warning: `download-rustc` is enabled, but there are changes to compiler/")
660664
661- return commit
665+ if self.verbose:
666+ print("using downloaded stage1 artifacts from CI (commit {})".format(commit))
667+ self.rustc_commit = commit
668+ # FIXME: support downloading artifacts from the beta channel
669+ self.download_toolchain(False, "nightly")
662670
663- def rustc_stamp(self):
664- """Return the path for .rustc-stamp
671+ def rustc_stamp(self, stage0 ):
672+ """Return the path for .rustc-stamp at the given stage
665673
666674 >>> rb = RustBuild()
667675 >>> rb.build_dir = "build"
668- >>> rb.rustc_stamp() == os.path.join("build", "stage0", ".rustc-stamp")
676+ >>> rb.rustc_stamp(True) == os.path.join("build", "stage0", ".rustc-stamp")
677+ True
678+ >>> rb.rustc_stamp(False) == os.path.join("build", "ci-rustc", ".rustc-stamp")
669679 True
670680 """
671- return os.path.join(self.bin_root(), '.rustc-stamp')
681+ return os.path.join(self.bin_root(stage0 ), '.rustc-stamp')
672682
673683 def rustfmt_stamp(self):
674684 """Return the path for .rustfmt-stamp
@@ -678,7 +688,7 @@ def rustfmt_stamp(self):
678688 >>> rb.rustfmt_stamp() == os.path.join("build", "stage0", ".rustfmt-stamp")
679689 True
680690 """
681- return os.path.join(self.bin_root(), '.rustfmt-stamp')
691+ return os.path.join(self.bin_root(True ), '.rustfmt-stamp')
682692
683693 def llvm_stamp(self):
684694 """Return the path for .rustfmt-stamp
@@ -698,21 +708,27 @@ def program_out_of_date(self, stamp_path, key):
698708 with open(stamp_path, 'r') as stamp:
699709 return key != stamp.read()
700710
701- def bin_root(self):
702- """Return the binary root directory
711+ def bin_root(self, stage0 ):
712+ """Return the binary root directory for the given stage
703713
704714 >>> rb = RustBuild()
705715 >>> rb.build_dir = "build"
706- >>> rb.bin_root() == os.path.join("build", "stage0")
716+ >>> rb.bin_root(True) == os.path.join("build", "stage0")
717+ True
718+ >>> rb.bin_root(False) == os.path.join("build", "ci-rustc")
707719 True
708720
709721 When the 'build' property is given should be a nested directory:
710722
711723 >>> rb.build = "devel"
712- >>> rb.bin_root() == os.path.join("build", "devel", "stage0")
724+ >>> rb.bin_root(True ) == os.path.join("build", "devel", "stage0")
713725 True
714726 """
715- return os.path.join(self.build_dir, self.build, "stage0")
727+ if stage0:
728+ subdir = "stage0"
729+ else:
730+ subdir = "ci-rustc"
731+ return os.path.join(self.build_dir, self.build, subdir)
716732
717733 def llvm_root(self):
718734 """Return the CI LLVM root directory
@@ -775,33 +791,37 @@ def cargo(self):
775791 """Return config path for cargo"""
776792 return self.program_config('cargo')
777793
778- def rustc(self):
794+ def rustc(self, stage0 ):
779795 """Return config path for rustc"""
780- return self.program_config('rustc')
796+ return self.program_config('rustc', stage0 )
781797
782798 def rustfmt(self):
783799 """Return config path for rustfmt"""
784800 if not self.rustfmt_channel:
785801 return None
786802 return self.program_config('rustfmt')
787803
788- def program_config(self, program):
789- """Return config path for the given program
804+ def program_config(self, program, stage0=True ):
805+ """Return config path for the given program at the given stage
790806
791807 >>> rb = RustBuild()
792808 >>> rb.config_toml = 'rustc = "rustc"\\n'
793809 >>> rb.program_config('rustc')
794810 'rustc'
795811 >>> rb.config_toml = ''
796- >>> cargo_path = rb.program_config('cargo')
797- >>> cargo_path.rstrip(".exe") == os.path.join(rb.bin_root(),
812+ >>> cargo_path = rb.program_config('cargo', True)
813+ >>> cargo_path.rstrip(".exe") == os.path.join(rb.bin_root(True),
814+ ... "bin", "cargo")
815+ True
816+ >>> cargo_path = rb.program_config('cargo', False)
817+ >>> cargo_path.rstrip(".exe") == os.path.join(rb.bin_root(False),
798818 ... "bin", "cargo")
799819 True
800820 """
801821 config = self.get_toml(program)
802822 if config:
803823 return os.path.expanduser(config)
804- return os.path.join(self.bin_root(), "bin", "{}{}".format(
824+ return os.path.join(self.bin_root(stage0 ), "bin", "{}{}".format(
805825 program, self.exe_suffix()))
806826
807827 @staticmethod
@@ -856,14 +876,14 @@ def build_bootstrap(self):
856876 if "CARGO_BUILD_TARGET" in env:
857877 del env["CARGO_BUILD_TARGET"]
858878 env["CARGO_TARGET_DIR"] = build_dir
859- env["RUSTC"] = self.rustc()
860- env["LD_LIBRARY_PATH"] = os.path.join(self.bin_root(), "lib") + \
879+ env["RUSTC"] = self.rustc(True )
880+ env["LD_LIBRARY_PATH"] = os.path.join(self.bin_root(True ), "lib") + \
861881 (os.pathsep + env["LD_LIBRARY_PATH"]) \
862882 if "LD_LIBRARY_PATH" in env else ""
863- env["DYLD_LIBRARY_PATH"] = os.path.join(self.bin_root(), "lib") + \
883+ env["DYLD_LIBRARY_PATH"] = os.path.join(self.bin_root(True ), "lib") + \
864884 (os.pathsep + env["DYLD_LIBRARY_PATH"]) \
865885 if "DYLD_LIBRARY_PATH" in env else ""
866- env["LIBRARY_PATH"] = os.path.join(self.bin_root(), "lib") + \
886+ env["LIBRARY_PATH"] = os.path.join(self.bin_root(True ), "lib") + \
867887 (os.pathsep + env["LIBRARY_PATH"]) \
868888 if "LIBRARY_PATH" in env else ""
869889 # preserve existing RUSTFLAGS
@@ -886,7 +906,7 @@ def build_bootstrap(self):
886906 if self.get_toml("deny-warnings", "rust") != "false":
887907 env["RUSTFLAGS"] += " -Dwarnings"
888908
889- env["PATH"] = os.path.join(self.bin_root(), "bin") + \
909+ env["PATH"] = os.path.join(self.bin_root(True ), "bin") + \
890910 os.pathsep + env["PATH"]
891911 if not os.path.isfile(self.cargo()):
892912 raise Exception("no cargo executable found at `{}`".format(
@@ -1137,14 +1157,9 @@ def bootstrap(help_triggered):
11371157 build.update_submodules()
11381158
11391159 # Fetch/build the bootstrap
1140- build.rustc_commit = build.maybe_download_rustc()
1141- if build.rustc_commit is not None:
1142- if build.verbose:
1143- commit = build.rustc_commit
1144- print("using downloaded stage1 artifacts from CI (commit {})".format(commit))
1145- # FIXME: support downloading artifacts from the beta channel
1146- build.rustc_channel = "nightly"
1147- build.download_stage0()
1160+ build.download_toolchain()
1161+ # Download the master compiler if `download-rustc` is set
1162+ build.maybe_download_ci_toolchain()
11481163 sys.stdout.flush()
11491164 build.ensure_vendored()
11501165 build.build_bootstrap()
0 commit comments