@@ -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