1313import tempfile
1414
1515from time import time
16+ from multiprocessing import Pool , cpu_count
1617
1718try :
1819 import lzma
@@ -406,6 +407,48 @@ def channel(self):
406407 return self .version + "-" + self .date
407408
408409
410+ class DownloadInfo :
411+ """A helper class that can be pickled into a parallel subprocess"""
412+
413+ def __init__ (
414+ self ,
415+ base_download_url ,
416+ download_path ,
417+ bin_root ,
418+ tarball_path ,
419+ tarball_suffix ,
420+ checksums_sha256 ,
421+ pattern ,
422+ verbose ,
423+ ):
424+ self .base_download_url = base_download_url
425+ self .download_path = download_path
426+ self .bin_root = bin_root
427+ self .tarball_path = tarball_path
428+ self .tarball_suffix = tarball_suffix
429+ self .checksums_sha256 = checksums_sha256
430+ self .pattern = pattern
431+ self .verbose = verbose
432+
433+ def download_component (download_info ):
434+ if not os .path .exists (download_info .tarball_path ):
435+ get (
436+ download_info .base_download_url ,
437+ download_info .download_path ,
438+ download_info .tarball_path ,
439+ download_info .checksums_sha256 ,
440+ verbose = download_info .verbose ,
441+ )
442+
443+ def unpack_component (download_info ):
444+ unpack (
445+ download_info .tarball_path ,
446+ download_info .tarball_suffix ,
447+ download_info .bin_root ,
448+ match = download_info .pattern ,
449+ verbose = download_info .verbose ,
450+ )
451+
409452class RustBuild (object ):
410453 """Provide all the methods required to build Rust"""
411454 def __init__ (self ):
@@ -460,17 +503,49 @@ def download_toolchain(self):
460503 )
461504 run_powershell ([script ])
462505 shutil .rmtree (bin_root )
506+
507+ key = self .stage0_compiler .date
508+ cache_dst = os .path .join (self .build_dir , "cache" )
509+ rustc_cache = os .path .join (cache_dst , key )
510+ if not os .path .exists (rustc_cache ):
511+ os .makedirs (rustc_cache )
512+
463513 tarball_suffix = '.tar.gz' if lzma is None else '.tar.xz'
464- filename = "rust-std-{}-{}{}" .format (
465- rustc_channel , self .build , tarball_suffix )
466- pattern = "rust-std-{}" .format (self .build )
467- self ._download_component_helper (filename , pattern , tarball_suffix )
468- filename = "rustc-{}-{}{}" .format (rustc_channel , self .build ,
469- tarball_suffix )
470- self ._download_component_helper (filename , "rustc" , tarball_suffix )
471- filename = "cargo-{}-{}{}" .format (rustc_channel , self .build ,
472- tarball_suffix )
473- self ._download_component_helper (filename , "cargo" , tarball_suffix )
514+
515+ toolchain_suffix = "{}-{}{}" .format (rustc_channel , self .build , tarball_suffix )
516+
517+ tarballs_to_download = [
518+ ("rust-std-{}" .format (toolchain_suffix ), "rust-std-{}" .format (self .build )),
519+ ("rustc-{}" .format (toolchain_suffix ), "rustc" ),
520+ ("cargo-{}" .format (toolchain_suffix ), "cargo" ),
521+ ]
522+
523+ tarballs_download_info = [
524+ DownloadInfo (
525+ base_download_url = self .download_url ,
526+ download_path = "dist/{}/{}" .format (self .stage0_compiler .date , filename ),
527+ bin_root = self .bin_root (),
528+ tarball_path = os .path .join (rustc_cache , filename ),
529+ tarball_suffix = tarball_suffix ,
530+ checksums_sha256 = self .checksums_sha256 ,
531+ pattern = pattern ,
532+ verbose = self .verbose ,
533+ )
534+ for filename , pattern in tarballs_to_download
535+ ]
536+
537+ # Download the components serially to show the progress bars properly.
538+ for download_info in tarballs_download_info :
539+ download_component (download_info )
540+
541+ # Unpack the tarballs in parallle.
542+ # In Python 2.7, Pool cannot be used as a context manager.
543+ p = Pool (min (len (tarballs_download_info ), cpu_count ()))
544+ try :
545+ p .map (unpack_component , tarballs_download_info )
546+ finally :
547+ p .close ()
548+
474549 if self .should_fix_bins_and_dylibs ():
475550 self .fix_bin_or_dylib ("{}/bin/cargo" .format (bin_root ))
476551
@@ -486,13 +561,9 @@ def download_toolchain(self):
486561 rust_stamp .write (key )
487562
488563 def _download_component_helper (
489- self , filename , pattern , tarball_suffix ,
564+ self , filename , pattern , tarball_suffix , rustc_cache ,
490565 ):
491566 key = self .stage0_compiler .date
492- cache_dst = os .path .join (self .build_dir , "cache" )
493- rustc_cache = os .path .join (cache_dst , key )
494- if not os .path .exists (rustc_cache ):
495- os .makedirs (rustc_cache )
496567
497568 tarball = os .path .join (rustc_cache , filename )
498569 if not os .path .exists (tarball ):
0 commit comments