Skip to content

Commit b5076fb

Browse files
committed
bootstrap.py: patch RPATH on NixOS to handle the new zlib dependency.
1 parent d866160 commit b5076fb

File tree

1 file changed

+30
-13
lines changed

1 file changed

+30
-13
lines changed

src/bootstrap/bootstrap.py

+30-13
Original file line numberDiff line numberDiff line change
@@ -389,8 +389,12 @@ def support_xz():
389389
filename = "rustc-{}-{}{}".format(rustc_channel, self.build,
390390
tarball_suffix)
391391
self._download_stage0_helper(filename, "rustc", tarball_suffix)
392-
self.fix_executable("{}/bin/rustc".format(self.bin_root()))
393-
self.fix_executable("{}/bin/rustdoc".format(self.bin_root()))
392+
self.fix_bin_or_dylib("{}/bin/rustc".format(self.bin_root()))
393+
self.fix_bin_or_dylib("{}/bin/rustdoc".format(self.bin_root()))
394+
lib_dir = "{}/lib".format(self.bin_root())
395+
for lib in os.listdir(lib_dir):
396+
if lib.endswith(".so"):
397+
self.fix_bin_or_dylib("{}/{}".format(lib_dir, lib))
394398
with output(self.rustc_stamp()) as rust_stamp:
395399
rust_stamp.write(self.date)
396400

@@ -409,7 +413,7 @@ def support_xz():
409413
filename = "cargo-{}-{}{}".format(cargo_channel, self.build,
410414
tarball_suffix)
411415
self._download_stage0_helper(filename, "cargo", tarball_suffix)
412-
self.fix_executable("{}/bin/cargo".format(self.bin_root()))
416+
self.fix_bin_or_dylib("{}/bin/cargo".format(self.bin_root()))
413417
with output(self.cargo_stamp()) as cargo_stamp:
414418
cargo_stamp.write(self.date)
415419

@@ -422,8 +426,8 @@ def support_xz():
422426
[channel, date] = rustfmt_channel.split('-', 1)
423427
filename = "rustfmt-{}-{}{}".format(channel, self.build, tarball_suffix)
424428
self._download_stage0_helper(filename, "rustfmt-preview", tarball_suffix, date)
425-
self.fix_executable("{}/bin/rustfmt".format(self.bin_root()))
426-
self.fix_executable("{}/bin/cargo-fmt".format(self.bin_root()))
429+
self.fix_bin_or_dylib("{}/bin/rustfmt".format(self.bin_root()))
430+
self.fix_bin_or_dylib("{}/bin/cargo-fmt".format(self.bin_root()))
427431
with output(self.rustfmt_stamp()) as rustfmt_stamp:
428432
rustfmt_stamp.write(self.date + self.rustfmt_channel)
429433

@@ -441,11 +445,12 @@ def _download_stage0_helper(self, filename, pattern, tarball_suffix, date=None):
441445
get("{}/{}".format(url, filename), tarball, verbose=self.verbose)
442446
unpack(tarball, tarball_suffix, self.bin_root(), match=pattern, verbose=self.verbose)
443447

444-
def fix_executable(self, fname):
445-
"""Modifies the interpreter section of 'fname' to fix the dynamic linker
448+
def fix_bin_or_dylib(self, fname):
449+
"""Modifies the interpreter section of 'fname' to fix the dynamic linker,
450+
or the RPATH section, to fix the dynamic library search path
446451
447452
This method is only required on NixOS and uses the PatchELF utility to
448-
change the dynamic linker of ELF executables.
453+
change the interpreter/RPATH of ELF executables.
449454
450455
Please see https://nixos.org/patchelf.html for more information
451456
"""
@@ -483,6 +488,9 @@ def fix_executable(self, fname):
483488
# Needed for the path of `ld-linux.so` (via `nix-support/dynamic-linker`).
484489
"stdenv.cc.bintools",
485490

491+
# Needed as a system dependency of `libLLVM-*.so`.
492+
"zlib",
493+
486494
# Needed for patching ELF binaries (see doc comment above).
487495
"patchelf",
488496
]
@@ -507,14 +515,23 @@ def fix_executable(self, fname):
507515
self.nix_deps_dir = nix_deps_dir
508516

509517
patchelf = "{}/patchelf/bin/patchelf".format(nix_deps_dir)
510-
bintools_dir = "{}/stdenv.cc.bintools".format(nix_deps_dir)
511518

512-
with open("{}/nix-support/dynamic-linker".format(bintools_dir)) as dynamic_linker:
513-
interpreter = dynamic_linker.read().rstrip()
519+
if fname.endswith(".so"):
520+
# Dynamic library, patch RPATH to point to system dependencies.
521+
dylib_deps = ["zlib"]
522+
rpath_entries = [
523+
# Relative default, all binary and dynamic libraries we ship
524+
# appear to have this (even when `../lib` is redundant).
525+
"$ORIGIN/../lib",
526+
] + ["{}/{}/lib".format(nix_deps_dir, dep) for dep in dylib_deps]
527+
patchelf_args = ["--set-rpath", ":".join(rpath_entries)]
528+
else:
529+
bintools_dir = "{}/stdenv.cc.bintools".format(nix_deps_dir)
530+
with open("{}/nix-support/dynamic-linker".format(bintools_dir)) as dynamic_linker:
531+
patchelf_args = ["--set-interpreter", dynamic_linker.read().rstrip()]
514532

515533
try:
516-
subprocess.check_output(
517-
[patchelf, "--set-interpreter", interpreter, fname])
534+
subprocess.check_output([patchelf] + patchelf_args + [fname])
518535
except subprocess.CalledProcessError as reason:
519536
print("warning: failed to call patchelf:", reason)
520537
return

0 commit comments

Comments
 (0)