about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2020-07-17 16:25:05 +0300
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2020-07-17 16:25:05 +0300
commitb5076fbb9669bd8e29ad58160a2d60ddd6813df7 (patch)
tree886e7b18c63323aae9c76300e03895a2792785b4
parentd866160b85107551c339c35995db4b35c0364264 (diff)
downloadrust-b5076fbb9669bd8e29ad58160a2d60ddd6813df7.tar.gz
rust-b5076fbb9669bd8e29ad58160a2d60ddd6813df7.zip
bootstrap.py: patch RPATH on NixOS to handle the new zlib dependency.
-rw-r--r--src/bootstrap/bootstrap.py43
1 files changed, 30 insertions, 13 deletions
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index bdf3bdf80b6..c3f1bac177d 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -389,8 +389,12 @@ class RustBuild(object):
             filename = "rustc-{}-{}{}".format(rustc_channel, self.build,
                                               tarball_suffix)
             self._download_stage0_helper(filename, "rustc", tarball_suffix)
-            self.fix_executable("{}/bin/rustc".format(self.bin_root()))
-            self.fix_executable("{}/bin/rustdoc".format(self.bin_root()))
+            self.fix_bin_or_dylib("{}/bin/rustc".format(self.bin_root()))
+            self.fix_bin_or_dylib("{}/bin/rustdoc".format(self.bin_root()))
+            lib_dir = "{}/lib".format(self.bin_root())
+            for lib in os.listdir(lib_dir):
+                if lib.endswith(".so"):
+                    self.fix_bin_or_dylib("{}/{}".format(lib_dir, lib))
             with output(self.rustc_stamp()) as rust_stamp:
                 rust_stamp.write(self.date)
 
@@ -409,7 +413,7 @@ class RustBuild(object):
             filename = "cargo-{}-{}{}".format(cargo_channel, self.build,
                                               tarball_suffix)
             self._download_stage0_helper(filename, "cargo", tarball_suffix)
-            self.fix_executable("{}/bin/cargo".format(self.bin_root()))
+            self.fix_bin_or_dylib("{}/bin/cargo".format(self.bin_root()))
             with output(self.cargo_stamp()) as cargo_stamp:
                 cargo_stamp.write(self.date)
 
@@ -422,8 +426,8 @@ class RustBuild(object):
                 [channel, date] = rustfmt_channel.split('-', 1)
                 filename = "rustfmt-{}-{}{}".format(channel, self.build, tarball_suffix)
                 self._download_stage0_helper(filename, "rustfmt-preview", tarball_suffix, date)
-                self.fix_executable("{}/bin/rustfmt".format(self.bin_root()))
-                self.fix_executable("{}/bin/cargo-fmt".format(self.bin_root()))
+                self.fix_bin_or_dylib("{}/bin/rustfmt".format(self.bin_root()))
+                self.fix_bin_or_dylib("{}/bin/cargo-fmt".format(self.bin_root()))
                 with output(self.rustfmt_stamp()) as rustfmt_stamp:
                     rustfmt_stamp.write(self.date + self.rustfmt_channel)
 
@@ -441,11 +445,12 @@ class RustBuild(object):
             get("{}/{}".format(url, filename), tarball, verbose=self.verbose)
         unpack(tarball, tarball_suffix, self.bin_root(), match=pattern, verbose=self.verbose)
 
-    def fix_executable(self, fname):
-        """Modifies the interpreter section of 'fname' to fix the dynamic linker
+    def fix_bin_or_dylib(self, fname):
+        """Modifies the interpreter section of 'fname' to fix the dynamic linker,
+        or the RPATH section, to fix the dynamic library search path
 
         This method is only required on NixOS and uses the PatchELF utility to
-        change the dynamic linker of ELF executables.
+        change the interpreter/RPATH of ELF executables.
 
         Please see https://nixos.org/patchelf.html for more information
         """
@@ -483,6 +488,9 @@ class RustBuild(object):
                 # Needed for the path of `ld-linux.so` (via `nix-support/dynamic-linker`).
                 "stdenv.cc.bintools",
 
+                # Needed as a system dependency of `libLLVM-*.so`.
+                "zlib",
+
                 # Needed for patching ELF binaries (see doc comment above).
                 "patchelf",
             ]
@@ -507,14 +515,23 @@ class RustBuild(object):
             self.nix_deps_dir = nix_deps_dir
 
         patchelf = "{}/patchelf/bin/patchelf".format(nix_deps_dir)
-        bintools_dir = "{}/stdenv.cc.bintools".format(nix_deps_dir)
 
-        with open("{}/nix-support/dynamic-linker".format(bintools_dir)) as dynamic_linker:
-            interpreter = dynamic_linker.read().rstrip()
+        if fname.endswith(".so"):
+            # Dynamic library, patch RPATH to point to system dependencies.
+            dylib_deps = ["zlib"]
+            rpath_entries = [
+                # Relative default, all binary and dynamic libraries we ship
+                # appear to have this (even when `../lib` is redundant).
+                "$ORIGIN/../lib",
+            ] + ["{}/{}/lib".format(nix_deps_dir, dep) for dep in dylib_deps]
+            patchelf_args = ["--set-rpath", ":".join(rpath_entries)]
+        else:
+            bintools_dir = "{}/stdenv.cc.bintools".format(nix_deps_dir)
+            with open("{}/nix-support/dynamic-linker".format(bintools_dir)) as dynamic_linker:
+                patchelf_args = ["--set-interpreter", dynamic_linker.read().rstrip()]
 
         try:
-            subprocess.check_output(
-                [patchelf, "--set-interpreter", interpreter, fname])
+            subprocess.check_output([patchelf] + patchelf_args + [fname])
         except subprocess.CalledProcessError as reason:
             print("warning: failed to call patchelf:", reason)
             return