22import argparse
33import contextlib
44import datetime
5- import distutils .version
65import hashlib
76import json
87import os
1312import tarfile
1413import tempfile
1514
16- from time import time , sleep
15+ from time import time
1716
18- def support_xz () :
19- try :
20- with tempfile . NamedTemporaryFile ( delete = False ) as temp_file :
21- temp_path = temp_file . name
22- with tarfile . open ( temp_path , "w:xz" ):
23- pass
24- return True
25- except tarfile . CompressionError :
26- return False
17+ try :
18+ import lzma
19+ except ImportError :
20+ lzma = None
21+
22+ if sys . platform == 'win32' :
23+ EXE_SUFFIX = ".exe"
24+ else :
25+ EXE_SUFFIX = ""
2726
2827def get (base , url , path , checksums , verbose = False ):
2928 with tempfile .NamedTemporaryFile (delete = False ) as temp_file :
@@ -61,7 +60,7 @@ def get(base, url, path, checksums, verbose=False):
6160
6261
6362def download (path , url , probably_big , verbose ):
64- for _ in range (0 , 4 ):
63+ for _ in range (4 ):
6564 try :
6665 _download (path , url , probably_big , verbose , True )
6766 return
@@ -395,15 +394,15 @@ class RustBuild(object):
395394 def __init__ (self ):
396395 self .checksums_sha256 = {}
397396 self .stage0_compiler = None
398- self ._download_url = ''
397+ self .download_url = ''
399398 self .build = ''
400399 self .build_dir = ''
401400 self .clean = False
402401 self .config_toml = ''
403402 self .rust_root = ''
404- self .use_locked_deps = ''
405- self .use_vendored_sources = ''
406- self .verbose = False
403+ self .use_locked_deps = False
404+ self .use_vendored_sources = False
405+ self .verbose = 0
407406 self .git_version = None
408407 self .nix_deps_dir = None
409408
@@ -426,7 +425,7 @@ def download_toolchain(self):
426425 self .program_out_of_date (self .rustc_stamp (), key )):
427426 if os .path .exists (bin_root ):
428427 shutil .rmtree (bin_root )
429- tarball_suffix = '.tar.xz ' if support_xz () else '.tar.gz '
428+ tarball_suffix = '.tar.gz ' if lzma is None else '.tar.xz '
430429 filename = "rust-std-{}-{}{}" .format (
431430 rustc_channel , self .build , tarball_suffix )
432431 pattern = "rust-std-{}" .format (self .build )
@@ -437,15 +436,17 @@ def download_toolchain(self):
437436 filename = "cargo-{}-{}{}" .format (rustc_channel , self .build ,
438437 tarball_suffix )
439438 self ._download_component_helper (filename , "cargo" , tarball_suffix )
440- self .fix_bin_or_dylib ("{}/bin/cargo" .format (bin_root ))
441-
442- self .fix_bin_or_dylib ("{}/bin/rustc" .format (bin_root ))
443- self .fix_bin_or_dylib ("{}/bin/rustdoc" .format (bin_root ))
444- self .fix_bin_or_dylib ("{}/libexec/rust-analyzer-proc-macro-srv" .format (bin_root ))
445- lib_dir = "{}/lib" .format (bin_root )
446- for lib in os .listdir (lib_dir ):
447- if lib .endswith (".so" ):
448- self .fix_bin_or_dylib (os .path .join (lib_dir , lib ))
439+ if self .should_fix_bins_and_dylibs ():
440+ self .fix_bin_or_dylib ("{}/bin/cargo" .format (bin_root ))
441+
442+ self .fix_bin_or_dylib ("{}/bin/rustc" .format (bin_root ))
443+ self .fix_bin_or_dylib ("{}/bin/rustdoc" .format (bin_root ))
444+ self .fix_bin_or_dylib ("{}/libexec/rust-analyzer-proc-macro-srv" .format (bin_root ))
445+ lib_dir = "{}/lib" .format (bin_root )
446+ for lib in os .listdir (lib_dir ):
447+ if lib .endswith (".so" ):
448+ self .fix_bin_or_dylib (os .path .join (lib_dir , lib ))
449+
449450 with output (self .rustc_stamp ()) as rust_stamp :
450451 rust_stamp .write (key )
451452
@@ -458,60 +459,64 @@ def _download_component_helper(
458459 if not os .path .exists (rustc_cache ):
459460 os .makedirs (rustc_cache )
460461
461- base = self ._download_url
462- url = "dist/{}" .format (key )
463462 tarball = os .path .join (rustc_cache , filename )
464463 if not os .path .exists (tarball ):
465464 get (
466- base ,
467- "{}/{}" .format (url , filename ),
465+ self . download_url ,
466+ "dist/ {}/{}" .format (key , filename ),
468467 tarball ,
469468 self .checksums_sha256 ,
470- verbose = self .verbose ,
469+ verbose = self .verbose != 0 ,
471470 )
472- unpack (tarball , tarball_suffix , self .bin_root (), match = pattern , verbose = self .verbose )
473-
474- def fix_bin_or_dylib (self , fname ):
475- """Modifies the interpreter section of 'fname' to fix the dynamic linker,
476- or the RPATH section, to fix the dynamic library search path
477-
478- This method is only required on NixOS and uses the PatchELF utility to
479- change the interpreter/RPATH of ELF executables.
471+ unpack (tarball , tarball_suffix , self .bin_root (), match = pattern , verbose = self .verbose != 0 )
480472
481- Please see https://nixos.org/patchelf.html for more information
473+ def should_fix_bins_and_dylibs (self ):
474+ """Whether or not `fix_bin_or_dylib` needs to be run; can only be True
475+ on NixOS.
482476 """
483477 default_encoding = sys .getdefaultencoding ()
484478 try :
485479 ostype = subprocess .check_output (
486480 ['uname' , '-s' ]).strip ().decode (default_encoding )
487481 except subprocess .CalledProcessError :
488- return
482+ return False
489483 except OSError as reason :
490484 if getattr (reason , 'winerror' , None ) is not None :
491- return
485+ return False
492486 raise reason
493487
494488 if ostype != "Linux" :
495- return
489+ return False
496490
497491 # If the user has asked binaries to be patched for Nix, then
498- # don't check for NixOS or `/lib`, just continue to the patching.
499- if self .get_toml ('patch-binaries-for-nix' , 'build' ) != 'true' :
500- # Use `/etc/os-release` instead of `/etc/NIXOS`.
501- # The latter one does not exist on NixOS when using tmpfs as root.
502- try :
503- with open ("/etc/os-release" , "r" ) as f :
504- if not any (l .strip () in ["ID=nixos" , "ID='nixos'" , 'ID="nixos"' ] for l in f ):
505- return
506- except FileNotFoundError :
507- return
508- if os .path .exists ("/lib" ):
509- return
492+ # don't check for NixOS or `/lib`.
493+ if self .get_toml ("patch-binaries-for-nix" , "build" ) == "true" :
494+ return True
510495
511- # At this point we're pretty sure the user is running NixOS or
512- # using Nix
513- nix_os_msg = "info: you seem to be using Nix. Attempting to patch"
514- print (nix_os_msg , fname )
496+ # Use `/etc/os-release` instead of `/etc/NIXOS`.
497+ # The latter one does not exist on NixOS when using tmpfs as root.
498+ try :
499+ with open ("/etc/os-release" , "r" ) as f :
500+ if not any (l .strip () in ("ID=nixos" , "ID='nixos'" , 'ID="nixos"' ) for l in f ):
501+ return False
502+ except FileNotFoundError :
503+ return False
504+ if os .path .exists ("/lib" ):
505+ return False
506+
507+ print ("info: You seem to be using Nix." )
508+ return True
509+
510+ def fix_bin_or_dylib (self , fname ):
511+ """Modifies the interpreter section of 'fname' to fix the dynamic linker,
512+ or the RPATH section, to fix the dynamic library search path
513+
514+ This method is only required on NixOS and uses the PatchELF utility to
515+ change the interpreter/RPATH of ELF executables.
516+
517+ Please see https://nixos.org/patchelf.html for more information
518+ """
519+ print ("attempting to patch" , fname )
515520
516521 # Only build `.nix-deps` once.
517522 nix_deps_dir = self .nix_deps_dir
@@ -666,8 +671,7 @@ def program_config(self, program):
666671 config = self .get_toml (program )
667672 if config :
668673 return os .path .expanduser (config )
669- return os .path .join (self .bin_root (), "bin" , "{}{}" .format (
670- program , self .exe_suffix ()))
674+ return os .path .join (self .bin_root (), "bin" , "{}{}" .format (program , EXE_SUFFIX ))
671675
672676 @staticmethod
673677 def get_string (line ):
@@ -692,13 +696,6 @@ def get_string(line):
692696 return line [start + 1 :end ]
693697 return None
694698
695- @staticmethod
696- def exe_suffix ():
697- """Return a suffix for executables"""
698- if sys .platform == 'win32' :
699- return '.exe'
700- return ''
701-
702699 def bootstrap_binary (self ):
703700 """Return the path of the bootstrap binary
704701
@@ -757,7 +754,6 @@ def build_bootstrap(self, color):
757754 if target_linker is not None :
758755 env ["RUSTFLAGS" ] += " -C linker=" + target_linker
759756 env ["RUSTFLAGS" ] += " -Wrust_2018_idioms -Wunused_lifetimes"
760- env ["RUSTFLAGS" ] += " -Wsemicolon_in_expressions_from_macros"
761757 if self .get_toml ("deny-warnings" , "rust" ) != "false" :
762758 env ["RUSTFLAGS" ] += " -Dwarnings"
763759
@@ -768,8 +764,7 @@ def build_bootstrap(self, color):
768764 self .cargo ()))
769765 args = [self .cargo (), "build" , "--manifest-path" ,
770766 os .path .join (self .rust_root , "src/bootstrap/Cargo.toml" )]
771- for _ in range (0 , self .verbose ):
772- args .append ("--verbose" )
767+ args .extend ("--verbose" for _ in range (self .verbose ))
773768 if self .use_locked_deps :
774769 args .append ("--locked" )
775770 if self .use_vendored_sources :
@@ -783,7 +778,7 @@ def build_bootstrap(self, color):
783778 args .append ("--color=never" )
784779
785780 # Run this from the source directory so cargo finds .cargo/config
786- run (args , env = env , verbose = self .verbose , cwd = self .rust_root )
781+ run (args , env = env , verbose = self .verbose != 0 , cwd = self .rust_root )
787782
788783 def build_triple (self ):
789784 """Build triple as in LLVM
@@ -792,16 +787,7 @@ def build_triple(self):
792787 so use `self.build` where possible.
793788 """
794789 config = self .get_toml ('build' )
795- if config :
796- return config
797- return default_build_triple (self .verbose )
798-
799- def set_dist_environment (self , url ):
800- """Set download URL for normal environment"""
801- if 'RUSTUP_DIST_SERVER' in os .environ :
802- self ._download_url = os .environ ['RUSTUP_DIST_SERVER' ]
803- else :
804- self ._download_url = url
790+ return config or default_build_triple (self .verbose != 0 )
805791
806792 def check_vendored_status (self ):
807793 """Check that vendoring is configured properly"""
@@ -891,7 +877,6 @@ def bootstrap(help_triggered):
891877 build .verbose = max (build .verbose , int (config_verbose ))
892878
893879 build .use_vendored_sources = build .get_toml ('vendor' , 'build' ) == 'true'
894-
895880 build .use_locked_deps = build .get_toml ('locked-deps' , 'build' ) == 'true'
896881
897882 build .check_vendored_status ()
@@ -903,8 +888,7 @@ def bootstrap(help_triggered):
903888 data = json .load (f )
904889 build .checksums_sha256 = data ["checksums_sha256" ]
905890 build .stage0_compiler = Stage0Toolchain (data ["compiler" ])
906-
907- build .set_dist_environment (data ["config" ]["dist_server" ])
891+ build .download_url = os .getenv ("RUSTUP_DIST_SERVER" ) or data ["config" ]["dist_server" ]
908892
909893 build .build = args .build or build .build_triple ()
910894
@@ -932,7 +916,7 @@ def main():
932916
933917 # x.py help <cmd> ...
934918 if len (sys .argv ) > 1 and sys .argv [1 ] == 'help' :
935- sys .argv = [ sys . argv [ 0 ], '-h' ] + sys . argv [ 2 :]
919+ sys .argv [ 1 ] = '-h'
936920
937921 help_triggered = (
938922 '-h' in sys .argv ) or ('--help' in sys .argv ) or (len (sys .argv ) == 1 )
0 commit comments