about summary refs log tree commit diff
path: root/src/bootstrap/bootstrap.py
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-02-17 15:20:11 +0000
committerbors <bors@rust-lang.org>2017-02-17 15:20:11 +0000
commit536a900c471dffad6e33766a2866889000fbfa75 (patch)
treef2d73a288442538b6672c3181a7c9e581fd81dbc /src/bootstrap/bootstrap.py
parentdc0bb3f2839c13ab42feacd423f728fbfd2f2f7a (diff)
parent5e324bdc91415ae222becf362f68ffdebf3ec804 (diff)
downloadrust-536a900c471dffad6e33766a2866889000fbfa75.tar.gz
rust-536a900c471dffad6e33766a2866889000fbfa75.zip
Auto merge of #39578 - canndrew:nixos-bootstrap-fix, r=alexcrichton
Fix for bootstrapping on NixOS

NixOS puts Linux's dynamic loader in wierd place. Detect when we're on NixOS and patch the downloaded bootstrap executables appropriately.
Diffstat (limited to 'src/bootstrap/bootstrap.py')
-rw-r--r--src/bootstrap/bootstrap.py56
1 files changed, 56 insertions, 0 deletions
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index ee3f663dbd5..7ca7ef4bd72 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -173,6 +173,8 @@ class RustBuild(object):
             if not os.path.exists(tarball):
                 get("{}/{}".format(url, filename), tarball, verbose=self.verbose)
             unpack(tarball, self.bin_root(), match="rustc", verbose=self.verbose)
+            self.fix_executable(self.bin_root() + "/bin/rustc")
+            self.fix_executable(self.bin_root() + "/bin/rustdoc")
             with open(self.rustc_stamp(), 'w') as f:
                 f.write(self.stage0_rustc_date())
 
@@ -185,9 +187,63 @@ class RustBuild(object):
             if not os.path.exists(tarball):
                 get("{}/{}".format(url, filename), tarball, verbose=self.verbose)
             unpack(tarball, self.bin_root(), match="cargo", verbose=self.verbose)
+            self.fix_executable(self.bin_root() + "/bin/cargo")
             with open(self.cargo_stamp(), 'w') as f:
                 f.write(self.stage0_cargo_rev())
 
+    def fix_executable(self, fname):
+        # If we're on NixOS we need to change the path to the dynamic loader
+
+        default_encoding = sys.getdefaultencoding()
+        try:
+            ostype = subprocess.check_output(['uname', '-s']).strip().decode(default_encoding)
+        except (subprocess.CalledProcessError, WindowsError):
+            return
+
+        if ostype != "Linux":
+            return
+
+        if not os.path.exists("/etc/NIXOS"):
+            return
+        if os.path.exists("/lib"):
+            return
+
+        # At this point we're pretty sure the user is running NixOS
+        print("info: you seem to be running NixOS. Attempting to patch " + fname)
+
+        try:
+            interpreter = subprocess.check_output(["patchelf", "--print-interpreter", fname])
+            interpreter = interpreter.strip().decode(default_encoding)
+        except subprocess.CalledProcessError as e:
+            print("warning: failed to call patchelf: %s" % e)
+            return
+
+        loader = interpreter.split("/")[-1]
+
+        try:
+            ldd_output = subprocess.check_output(['ldd', '/run/current-system/sw/bin/sh'])
+            ldd_output = ldd_output.strip().decode(default_encoding)
+        except subprocess.CalledProcessError as e:
+            print("warning: unable to call ldd: %s" % e)
+            return
+
+        for line in ldd_output.splitlines():
+            libname = line.split()[0]
+            if libname.endswith(loader):
+                loader_path = libname[:len(libname) - len(loader)]
+                break
+        else:
+            print("warning: unable to find the path to the dynamic linker")
+            return
+
+        correct_interpreter = loader_path + loader
+
+        try:
+            subprocess.check_output(["patchelf", "--set-interpreter", correct_interpreter, fname])
+        except subprocess.CalledProcessError as e:
+            print("warning: failed to call patchelf: %s" % e)
+            return
+
     def stage0_cargo_rev(self):
         return self._cargo_rev