@@ -429,7 +429,7 @@ def download_toolchain(self, stage0=True, rustc_channel=None):
429
429
lib_dir = "{}/lib" .format (bin_root )
430
430
for lib in os .listdir (lib_dir ):
431
431
if lib .endswith (".so" ):
432
- self .fix_bin_or_dylib (os .path .join (lib_dir , lib ), rpath_libz = True )
432
+ self .fix_bin_or_dylib (os .path .join (lib_dir , lib ))
433
433
with output (self .rustc_stamp (stage0 )) as rust_stamp :
434
434
rust_stamp .write (key )
435
435
@@ -477,10 +477,10 @@ def download_toolchain(self, stage0=True, rustc_channel=None):
477
477
if self .program_out_of_date (self .llvm_stamp (), llvm_sha + str (llvm_assertions )):
478
478
self ._download_ci_llvm (llvm_sha , llvm_assertions )
479
479
for binary in ["llvm-config" , "FileCheck" ]:
480
- self .fix_bin_or_dylib (os .path .join (llvm_root , "bin" , binary ), rpath_libz = True )
480
+ self .fix_bin_or_dylib (os .path .join (llvm_root , "bin" , binary ))
481
481
for lib in os .listdir (llvm_lib ):
482
482
if lib .endswith (".so" ):
483
- self .fix_bin_or_dylib (os .path .join (llvm_lib , lib ), rpath_libz = True )
483
+ self .fix_bin_or_dylib (os .path .join (llvm_lib , lib ))
484
484
with output (self .llvm_stamp ()) as llvm_stamp :
485
485
llvm_stamp .write (llvm_sha + str (llvm_assertions ))
486
486
@@ -548,7 +548,7 @@ def _download_ci_llvm(self, llvm_sha, llvm_assertions):
548
548
match = "rust-dev" ,
549
549
verbose = self .verbose )
550
550
551
- def fix_bin_or_dylib (self , fname , rpath_libz = False ):
551
+ def fix_bin_or_dylib (self , fname ):
552
552
"""Modifies the interpreter section of 'fname' to fix the dynamic linker,
553
553
or the RPATH section, to fix the dynamic library search path
554
554
@@ -583,56 +583,49 @@ def fix_bin_or_dylib(self, fname, rpath_libz=False):
583
583
# Only build `.nix-deps` once.
584
584
nix_deps_dir = self .nix_deps_dir
585
585
if not nix_deps_dir :
586
- nix_deps_dir = ".nix-deps"
587
- if not os .path .exists (nix_deps_dir ):
588
- os .makedirs (nix_deps_dir )
589
-
590
- nix_deps = [
591
- # Needed for the path of `ld-linux.so` (via `nix-support/dynamic-linker`).
592
- "stdenv.cc.bintools" ,
593
-
594
- # Needed as a system dependency of `libLLVM-*.so`.
595
- "zlib" ,
596
-
597
- # Needed for patching ELF binaries (see doc comment above).
598
- "patchelf" ,
599
- ]
600
-
601
586
# Run `nix-build` to "build" each dependency (which will likely reuse
602
587
# the existing `/nix/store` copy, or at most download a pre-built copy).
603
- # Importantly, we don't rely on `nix-build` printing the `/nix/store`
604
- # path on stdout, but use `-o` to symlink it into `stage0/.nix-deps/$dep`,
605
- # ensuring garbage collection will never remove the `/nix/store` path
606
- # (which would break our patched binaries that hardcode those paths).
607
- for dep in nix_deps :
608
- try :
609
- subprocess .check_output ([
610
- "nix-build" , "<nixpkgs>" ,
611
- "-A" , dep ,
612
- "-o" , "{}/{}" .format (nix_deps_dir , dep ),
613
- ])
614
- except subprocess .CalledProcessError as reason :
615
- print ("warning: failed to call nix-build:" , reason )
616
- return
617
-
588
+ #
589
+ # Importantly, we create a gc-root called `.nix-deps` in the `build/`
590
+ # directory, but still reference the actual `/nix/store` path in the rpath
591
+ # as it makes it significantly more robust against changes to the location of
592
+ # the `.nix-deps` location.
593
+ #
594
+ # bintools: Needed for the path of `ld-linux.so` (via `nix-support/dynamic-linker`).
595
+ # zlib: Needed as a system dependency of `libLLVM-*.so`.
596
+ # patchelf: Needed for patching ELF binaries (see doc comment above).
597
+ nix_deps_dir = "{}/{}" .format (self .build_dir , ".nix-deps" )
598
+ nix_expr = '''
599
+ with (import <nixpkgs> {});
600
+ symlinkJoin {
601
+ name = "rust-stage0-dependencies";
602
+ paths = [
603
+ zlib
604
+ patchelf
605
+ stdenv.cc.bintools
606
+ ];
607
+ }
608
+ '''
609
+ try :
610
+ subprocess .check_output ([
611
+ "nix-build" , "-E" , nix_expr , "-o" , nix_deps_dir ,
612
+ ])
613
+ except subprocess .CalledProcessError as reason :
614
+ print ("warning: failed to call nix-build:" , reason )
615
+ return
618
616
self .nix_deps_dir = nix_deps_dir
619
617
620
- patchelf = "{}/patchelf/bin/patchelf" .format (nix_deps_dir )
621
- patchelf_args = []
622
-
623
- if rpath_libz :
624
- # Patch RPATH to add `zlib` dependency that stems from LLVM
625
- dylib_deps = ["zlib" ]
626
- rpath_entries = [
627
- # Relative default, all binary and dynamic libraries we ship
628
- # appear to have this (even when `../lib` is redundant).
629
- "$ORIGIN/../lib" ,
630
- ] + ["{}/{}/lib" .format (nix_deps_dir , dep ) for dep in dylib_deps ]
631
- patchelf_args += ["--set-rpath" , ":" .join (rpath_entries )]
618
+ patchelf = "{}/bin/patchelf" .format (nix_deps_dir )
619
+ rpath_entries = [
620
+ # Relative default, all binary and dynamic libraries we ship
621
+ # appear to have this (even when `../lib` is redundant).
622
+ "$ORIGIN/../lib" ,
623
+ os .path .join (os .path .realpath (nix_deps_dir ), "lib" )
624
+ ]
625
+ patchelf_args = ["--set-rpath" , ":" .join (rpath_entries )]
632
626
if not fname .endswith (".so" ):
633
627
# Finally, set the corret .interp for binaries
634
- bintools_dir = "{}/stdenv.cc.bintools" .format (nix_deps_dir )
635
- with open ("{}/nix-support/dynamic-linker" .format (bintools_dir )) as dynamic_linker :
628
+ with open ("{}/nix-support/dynamic-linker" .format (nix_deps_dir )) as dynamic_linker :
636
629
patchelf_args += ["--set-interpreter" , dynamic_linker .read ().rstrip ()]
637
630
638
631
try :
0 commit comments