@@ -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 #
@@ -496,27 +501,26 @@ def downloading_llvm(self):
496501 or (opt == "if-available" and self .build in supported_platforms )
497502
498503 def _download_component_helper (
499- self , filename , pattern , tarball_suffix , download_rustc = False , key = None
504+ self , filename , pattern , tarball_suffix , stage0 = True , key = None
500505 ):
501506 if key is None :
502- if download_rustc :
503- key = self .rustc_commit
504- else :
507+ if stage0 :
505508 key = self .date
509+ else :
510+ key = self .rustc_commit
506511 cache_dst = os .path .join (self .build_dir , "cache" )
507512 rustc_cache = os .path .join (cache_dst , key )
508513 if not os .path .exists (rustc_cache ):
509514 os .makedirs (rustc_cache )
510515
511- if download_rustc :
512- url = "https://ci-artifacts.rust-lang.org/rustc-builds/{}" .format (self .rustc_commit )
513- else :
516+ if stage0 :
514517 url = "{}/dist/{}" .format (self ._download_url , key )
518+ else :
519+ url = "https://ci-artifacts.rust-lang.org/rustc-builds/{}" .format (self .rustc_commit )
515520 tarball = os .path .join (rustc_cache , filename )
516521 if not os .path .exists (tarball ):
517- do_verify = not download_rustc
518- get ("{}/{}" .format (url , filename ), tarball , verbose = self .verbose , do_verify = do_verify )
519- unpack (tarball , tarball_suffix , self .bin_root (), match = pattern , verbose = self .verbose )
522+ get ("{}/{}" .format (url , filename ), tarball , verbose = self .verbose , do_verify = stage0 )
523+ unpack (tarball , tarball_suffix , self .bin_root (stage0 ), match = pattern , verbose = self .verbose )
520524
521525 def _download_ci_llvm (self , llvm_sha , llvm_assertions ):
522526 cache_prefix = "llvm-{}-{}" .format (llvm_sha , llvm_assertions )
@@ -574,10 +578,10 @@ def fix_bin_or_dylib(self, fname, rpath_libz=False):
574578 nix_os_msg = "info: you seem to be running NixOS. Attempting to patch"
575579 print (nix_os_msg , fname )
576580
577- # Only build `stage0/ .nix-deps` once.
581+ # Only build `.nix-deps` once.
578582 nix_deps_dir = self .nix_deps_dir
579583 if not nix_deps_dir :
580- nix_deps_dir = "{}/ .nix-deps" . format ( self . bin_root ())
584+ nix_deps_dir = ".nix-deps"
581585 if not os .path .exists (nix_deps_dir ):
582586 os .makedirs (nix_deps_dir )
583587
@@ -635,8 +639,8 @@ def fix_bin_or_dylib(self, fname, rpath_libz=False):
635639 print ("warning: failed to call patchelf:" , reason )
636640 return
637641
638- # Return the stage1 compiler to download, if any.
639- def maybe_download_rustc (self ):
642+ # If `download-rustc` is set, download the most recent commit with CI artifacts
643+ def maybe_download_ci_toolchain (self ):
640644 # If `download-rustc` is not set, default to rebuilding.
641645 if self .get_toml ("download-rustc" , section = "rust" ) != "true" :
642646 return None
@@ -656,17 +660,23 @@ def maybe_download_rustc(self):
656660 if status != 0 :
657661 print ("warning: `download-rustc` is enabled, but there are changes to compiler/" )
658662
659- return commit
663+ if self .verbose :
664+ print ("using downloaded stage1 artifacts from CI (commit {})" .format (commit ))
665+ self .rustc_commit = commit
666+ # FIXME: support downloading artifacts from the beta channel
667+ self .download_toolchain (False , "nightly" )
660668
661- def rustc_stamp (self ):
662- """Return the path for .rustc-stamp
669+ def rustc_stamp (self , stage0 ):
670+ """Return the path for .rustc-stamp at the given stage
663671
664672 >>> rb = RustBuild()
665673 >>> rb.build_dir = "build"
666- >>> rb.rustc_stamp() == os.path.join("build", "stage0", ".rustc-stamp")
674+ >>> rb.rustc_stamp(True) == os.path.join("build", "stage0", ".rustc-stamp")
675+ True
676+ >>> rb.rustc_stamp(False) == os.path.join("build", "ci-rustc", ".rustc-stamp")
667677 True
668678 """
669- return os .path .join (self .bin_root (), '.rustc-stamp' )
679+ return os .path .join (self .bin_root (stage0 ), '.rustc-stamp' )
670680
671681 def rustfmt_stamp (self ):
672682 """Return the path for .rustfmt-stamp
@@ -676,7 +686,7 @@ def rustfmt_stamp(self):
676686 >>> rb.rustfmt_stamp() == os.path.join("build", "stage0", ".rustfmt-stamp")
677687 True
678688 """
679- return os .path .join (self .bin_root (), '.rustfmt-stamp' )
689+ return os .path .join (self .bin_root (True ), '.rustfmt-stamp' )
680690
681691 def llvm_stamp (self ):
682692 """Return the path for .rustfmt-stamp
@@ -696,21 +706,27 @@ def program_out_of_date(self, stamp_path, key):
696706 with open (stamp_path , 'r' ) as stamp :
697707 return key != stamp .read ()
698708
699- def bin_root (self ):
700- """Return the binary root directory
709+ def bin_root (self , stage0 ):
710+ """Return the binary root directory for the given stage
701711
702712 >>> rb = RustBuild()
703713 >>> rb.build_dir = "build"
704- >>> rb.bin_root() == os.path.join("build", "stage0")
714+ >>> rb.bin_root(True) == os.path.join("build", "stage0")
715+ True
716+ >>> rb.bin_root(False) == os.path.join("build", "ci-rustc")
705717 True
706718
707719 When the 'build' property is given should be a nested directory:
708720
709721 >>> rb.build = "devel"
710- >>> rb.bin_root() == os.path.join("build", "devel", "stage0")
722+ >>> rb.bin_root(True ) == os.path.join("build", "devel", "stage0")
711723 True
712724 """
713- return os .path .join (self .build_dir , self .build , "stage0" )
725+ if stage0 :
726+ subdir = "stage0"
727+ else :
728+ subdir = "ci-rustc"
729+ return os .path .join (self .build_dir , self .build , subdir )
714730
715731 def llvm_root (self ):
716732 """Return the CI LLVM root directory
@@ -773,33 +789,37 @@ def cargo(self):
773789 """Return config path for cargo"""
774790 return self .program_config ('cargo' )
775791
776- def rustc (self ):
792+ def rustc (self , stage0 ):
777793 """Return config path for rustc"""
778- return self .program_config ('rustc' )
794+ return self .program_config ('rustc' , stage0 )
779795
780796 def rustfmt (self ):
781797 """Return config path for rustfmt"""
782798 if not self .rustfmt_channel :
783799 return None
784800 return self .program_config ('rustfmt' )
785801
786- def program_config (self , program ):
787- """Return config path for the given program
802+ def program_config (self , program , stage0 = True ):
803+ """Return config path for the given program at the given stage
788804
789805 >>> rb = RustBuild()
790806 >>> rb.config_toml = 'rustc = "rustc"\\ n'
791807 >>> rb.program_config('rustc')
792808 'rustc'
793809 >>> rb.config_toml = ''
794- >>> cargo_path = rb.program_config('cargo')
795- >>> cargo_path.rstrip(".exe") == os.path.join(rb.bin_root(),
810+ >>> cargo_path = rb.program_config('cargo', True)
811+ >>> cargo_path.rstrip(".exe") == os.path.join(rb.bin_root(True),
812+ ... "bin", "cargo")
813+ True
814+ >>> cargo_path = rb.program_config('cargo', False)
815+ >>> cargo_path.rstrip(".exe") == os.path.join(rb.bin_root(False),
796816 ... "bin", "cargo")
797817 True
798818 """
799819 config = self .get_toml (program )
800820 if config :
801821 return os .path .expanduser (config )
802- return os .path .join (self .bin_root (), "bin" , "{}{}" .format (
822+ return os .path .join (self .bin_root (stage0 ), "bin" , "{}{}" .format (
803823 program , self .exe_suffix ()))
804824
805825 @staticmethod
@@ -854,14 +874,14 @@ def build_bootstrap(self):
854874 if "CARGO_BUILD_TARGET" in env :
855875 del env ["CARGO_BUILD_TARGET" ]
856876 env ["CARGO_TARGET_DIR" ] = build_dir
857- env ["RUSTC" ] = self .rustc ()
858- env ["LD_LIBRARY_PATH" ] = os .path .join (self .bin_root (), "lib" ) + \
877+ env ["RUSTC" ] = self .rustc (True )
878+ env ["LD_LIBRARY_PATH" ] = os .path .join (self .bin_root (True ), "lib" ) + \
859879 (os .pathsep + env ["LD_LIBRARY_PATH" ]) \
860880 if "LD_LIBRARY_PATH" in env else ""
861- env ["DYLD_LIBRARY_PATH" ] = os .path .join (self .bin_root (), "lib" ) + \
881+ env ["DYLD_LIBRARY_PATH" ] = os .path .join (self .bin_root (True ), "lib" ) + \
862882 (os .pathsep + env ["DYLD_LIBRARY_PATH" ]) \
863883 if "DYLD_LIBRARY_PATH" in env else ""
864- env ["LIBRARY_PATH" ] = os .path .join (self .bin_root (), "lib" ) + \
884+ env ["LIBRARY_PATH" ] = os .path .join (self .bin_root (True ), "lib" ) + \
865885 (os .pathsep + env ["LIBRARY_PATH" ]) \
866886 if "LIBRARY_PATH" in env else ""
867887 # preserve existing RUSTFLAGS
@@ -884,7 +904,7 @@ def build_bootstrap(self):
884904 if self .get_toml ("deny-warnings" , "rust" ) != "false" :
885905 env ["RUSTFLAGS" ] += " -Dwarnings"
886906
887- env ["PATH" ] = os .path .join (self .bin_root (), "bin" ) + \
907+ env ["PATH" ] = os .path .join (self .bin_root (True ), "bin" ) + \
888908 os .pathsep + env ["PATH" ]
889909 if not os .path .isfile (self .cargo ()):
890910 raise Exception ("no cargo executable found at `{}`" .format (
@@ -1135,14 +1155,9 @@ def bootstrap(help_triggered):
11351155 build .update_submodules ()
11361156
11371157 # Fetch/build the bootstrap
1138- build .rustc_commit = build .maybe_download_rustc ()
1139- if build .rustc_commit is not None :
1140- if build .verbose :
1141- commit = build .rustc_commit
1142- print ("using downloaded stage1 artifacts from CI (commit {})" .format (commit ))
1143- # FIXME: support downloading artifacts from the beta channel
1144- build .rustc_channel = "nightly"
1145- build .download_stage0 ()
1158+ build .download_toolchain ()
1159+ # Download the master compiler if `download-rustc` is set
1160+ build .maybe_download_ci_toolchain ()
11461161 sys .stdout .flush ()
11471162 build .ensure_vendored ()
11481163 build .build_bootstrap ()
0 commit comments