@@ -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