mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 03:38:29 +00:00
Fix NixOS patching
Moving the `.nix-deps` has resulted in rpath links being broken and therefore bootstrap on NixOS broken entirely. This PR still produces a `.nix-deps` but only for the purposes of producing a gc root. We rpath a symlink-resolved result instead. For purposes of simplicity we also use joinSymlink to produce a single merged output directory so that we don't need to update multiple locations every time we add a library or something.
This commit is contained in:
parent
54dc7cebce
commit
3dabab1c1e
@ -429,7 +429,7 @@ class RustBuild(object):
|
|||||||
lib_dir = "{}/lib".format(bin_root)
|
lib_dir = "{}/lib".format(bin_root)
|
||||||
for lib in os.listdir(lib_dir):
|
for lib in os.listdir(lib_dir):
|
||||||
if lib.endswith(".so"):
|
if lib.endswith(".so"):
|
||||||
self.fix_bin_or_dylib(os.path.join(lib_dir, lib), rpath_libz=True)
|
self.fix_bin_or_dylib(os.path.join(lib_dir, lib))
|
||||||
with output(self.rustc_stamp(stage0)) as rust_stamp:
|
with output(self.rustc_stamp(stage0)) as rust_stamp:
|
||||||
rust_stamp.write(key)
|
rust_stamp.write(key)
|
||||||
|
|
||||||
@ -477,10 +477,10 @@ class RustBuild(object):
|
|||||||
if self.program_out_of_date(self.llvm_stamp(), llvm_sha + str(llvm_assertions)):
|
if self.program_out_of_date(self.llvm_stamp(), llvm_sha + str(llvm_assertions)):
|
||||||
self._download_ci_llvm(llvm_sha, llvm_assertions)
|
self._download_ci_llvm(llvm_sha, llvm_assertions)
|
||||||
for binary in ["llvm-config", "FileCheck"]:
|
for binary in ["llvm-config", "FileCheck"]:
|
||||||
self.fix_bin_or_dylib(os.path.join(llvm_root, "bin", binary), rpath_libz=True)
|
self.fix_bin_or_dylib(os.path.join(llvm_root, "bin", binary))
|
||||||
for lib in os.listdir(llvm_lib):
|
for lib in os.listdir(llvm_lib):
|
||||||
if lib.endswith(".so"):
|
if lib.endswith(".so"):
|
||||||
self.fix_bin_or_dylib(os.path.join(llvm_lib, lib), rpath_libz=True)
|
self.fix_bin_or_dylib(os.path.join(llvm_lib, lib))
|
||||||
with output(self.llvm_stamp()) as llvm_stamp:
|
with output(self.llvm_stamp()) as llvm_stamp:
|
||||||
llvm_stamp.write(llvm_sha + str(llvm_assertions))
|
llvm_stamp.write(llvm_sha + str(llvm_assertions))
|
||||||
|
|
||||||
@ -548,7 +548,7 @@ class RustBuild(object):
|
|||||||
match="rust-dev",
|
match="rust-dev",
|
||||||
verbose=self.verbose)
|
verbose=self.verbose)
|
||||||
|
|
||||||
def fix_bin_or_dylib(self, fname, rpath_libz=False):
|
def fix_bin_or_dylib(self, fname):
|
||||||
"""Modifies the interpreter section of 'fname' to fix the dynamic linker,
|
"""Modifies the interpreter section of 'fname' to fix the dynamic linker,
|
||||||
or the RPATH section, to fix the dynamic library search path
|
or the RPATH section, to fix the dynamic library search path
|
||||||
|
|
||||||
@ -583,56 +583,49 @@ class RustBuild(object):
|
|||||||
# Only build `.nix-deps` once.
|
# Only build `.nix-deps` once.
|
||||||
nix_deps_dir = self.nix_deps_dir
|
nix_deps_dir = self.nix_deps_dir
|
||||||
if not nix_deps_dir:
|
if not nix_deps_dir:
|
||||||
nix_deps_dir = ".nix-deps"
|
|
||||||
if not os.path.exists(nix_deps_dir):
|
|
||||||
os.makedirs(nix_deps_dir)
|
|
||||||
|
|
||||||
nix_deps = [
|
|
||||||
# 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",
|
|
||||||
]
|
|
||||||
|
|
||||||
# Run `nix-build` to "build" each dependency (which will likely reuse
|
# Run `nix-build` to "build" each dependency (which will likely reuse
|
||||||
# the existing `/nix/store` copy, or at most download a pre-built copy).
|
# the existing `/nix/store` copy, or at most download a pre-built copy).
|
||||||
# Importantly, we don't rely on `nix-build` printing the `/nix/store`
|
#
|
||||||
# path on stdout, but use `-o` to symlink it into `stage0/.nix-deps/$dep`,
|
# Importantly, we create a gc-root called `.nix-deps` in the `build/`
|
||||||
# ensuring garbage collection will never remove the `/nix/store` path
|
# directory, but still reference the actual `/nix/store` path in the rpath
|
||||||
# (which would break our patched binaries that hardcode those paths).
|
# as it makes it significantly more robust against changes to the location of
|
||||||
for dep in nix_deps:
|
# the `.nix-deps` location.
|
||||||
try:
|
#
|
||||||
subprocess.check_output([
|
# bintools: Needed for the path of `ld-linux.so` (via `nix-support/dynamic-linker`).
|
||||||
"nix-build", "<nixpkgs>",
|
# zlib: Needed as a system dependency of `libLLVM-*.so`.
|
||||||
"-A", dep,
|
# patchelf: Needed for patching ELF binaries (see doc comment above).
|
||||||
"-o", "{}/{}".format(nix_deps_dir, dep),
|
nix_deps_dir = "{}/{}".format(self.build_dir, ".nix-deps")
|
||||||
])
|
nix_expr = '''
|
||||||
except subprocess.CalledProcessError as reason:
|
with (import <nixpkgs> {});
|
||||||
print("warning: failed to call nix-build:", reason)
|
symlinkJoin {
|
||||||
return
|
name = "rust-stage0-dependencies";
|
||||||
|
paths = [
|
||||||
|
zlib
|
||||||
|
patchelf
|
||||||
|
stdenv.cc.bintools
|
||||||
|
];
|
||||||
|
}
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
subprocess.check_output([
|
||||||
|
"nix-build", "-E", nix_expr, "-o", nix_deps_dir,
|
||||||
|
])
|
||||||
|
except subprocess.CalledProcessError as reason:
|
||||||
|
print("warning: failed to call nix-build:", reason)
|
||||||
|
return
|
||||||
self.nix_deps_dir = nix_deps_dir
|
self.nix_deps_dir = nix_deps_dir
|
||||||
|
|
||||||
patchelf = "{}/patchelf/bin/patchelf".format(nix_deps_dir)
|
patchelf = "{}/bin/patchelf".format(nix_deps_dir)
|
||||||
patchelf_args = []
|
rpath_entries = [
|
||||||
|
# Relative default, all binary and dynamic libraries we ship
|
||||||
if rpath_libz:
|
# appear to have this (even when `../lib` is redundant).
|
||||||
# Patch RPATH to add `zlib` dependency that stems from LLVM
|
"$ORIGIN/../lib",
|
||||||
dylib_deps = ["zlib"]
|
os.path.join(os.path.realpath(nix_deps_dir), "lib")
|
||||||
rpath_entries = [
|
]
|
||||||
# Relative default, all binary and dynamic libraries we ship
|
patchelf_args = ["--set-rpath", ":".join(rpath_entries)]
|
||||||
# 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)]
|
|
||||||
if not fname.endswith(".so"):
|
if not fname.endswith(".so"):
|
||||||
# Finally, set the corret .interp for binaries
|
# Finally, set the corret .interp for binaries
|
||||||
bintools_dir = "{}/stdenv.cc.bintools".format(nix_deps_dir)
|
with open("{}/nix-support/dynamic-linker".format(nix_deps_dir)) as dynamic_linker:
|
||||||
with open("{}/nix-support/dynamic-linker".format(bintools_dir)) as dynamic_linker:
|
|
||||||
patchelf_args += ["--set-interpreter", dynamic_linker.read().rstrip()]
|
patchelf_args += ["--set-interpreter", dynamic_linker.read().rstrip()]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
Loading…
Reference in New Issue
Block a user