nixpkgs/pkgs/build-support/libredirect/default.nix
Moritz Angermann 38377ab026
libredirect: build fat library for x86_64, arm64, arm64e on darwin (#153441)
macOS's dyld can be rather picky as to what dylib it accepts. This
even changes across macOS versions. Therefore we now build a fat
dylib with all three architectures (x86_64, arm64, arm64e). This
should then be compatible with pretty much any macOS's dyld.
2022-01-07 18:32:21 -05:00

91 lines
2.8 KiB
Nix

{ lib, stdenv, bintools-unwrapped, llvmPackages_13, coreutils }:
stdenv.mkDerivation rec {
pname = "libredirect";
version = "0";
unpackPhase = ''
cp ${./libredirect.c} libredirect.c
cp ${./test.c} test.c
'';
outputs = ["out" "hook"];
libName = "libredirect" + stdenv.targetPlatform.extensions.sharedLibrary;
buildPhase = ''
runHook preBuild
${if stdenv.isDarwin && stdenv.isAarch64 then ''
# We need the unwrapped binutils and clang:
# We also want to build a fat library with x86_64, arm64, arm64e in there.
# Because we use the unwrapped tools, we need to provide -isystem for headers
# and the library search directory for libdl.
# We can't build this on x86_64, because the libSystem we point to doesn't
# like arm64(e).
PATH=${bintools-unwrapped}/bin:${llvmPackages_13.clang-unwrapped}/bin:$PATH \
clang -arch x86_64 -arch arm64 -arch arm64e \
-isystem ${llvmPackages_13.clang.libc}/include \
-isystem ${llvmPackages_13.libclang.lib}/lib/clang/*/include \
-L${llvmPackages_13.clang.libc}/lib \
-Wl,-install_name,$out/lib/$libName \
-Wall -std=c99 -O3 -fPIC libredirect.c \
-ldl -shared -o "$libName"
'' else if stdenv.isDarwin then ''
$CC -Wall -std=c99 -O3 -fPIC libredirect.c \
-Wl,-install_name,$out/lib/$libName \
-ldl -shared -o "$libName"
'' else ''
$CC -Wall -std=c99 -O3 -fPIC libredirect.c \
-ldl -shared -o "$libName"
''}
if [ -n "$doInstallCheck" ]; then
$CC -Wall -std=c99 -O3 test.c -o test
fi
runHook postBuild
'';
# We want to retain debugging info to be able to use GDB on libredirect.so
# to more easily investigate which function overrides are missing or why
# existing ones do not have the intended effect.
dontStrip = true;
installPhase = ''
runHook preInstall
install -vD "$libName" "$out/lib/$libName"
# Provide a setup hook that injects our library into every process.
mkdir -p "$hook/nix-support"
cat <<SETUP_HOOK > "$hook/nix-support/setup-hook"
${if stdenv.isDarwin then ''
export DYLD_INSERT_LIBRARIES="$out/lib/$libName"
'' else ''
export LD_PRELOAD="$out/lib/$libName"
''}
SETUP_HOOK
runHook postInstall
'';
doInstallCheck = true;
installCheckPhase = ''
(
source "$hook/nix-support/setup-hook"
NIX_REDIRECTS="/foo/bar/test=${coreutils}/bin/true" ./test
)
'';
meta = with lib; {
platforms = platforms.unix;
description = "An LD_PRELOAD library to intercept and rewrite the paths in glibc calls";
longDescription = ''
libredirect is an LD_PRELOAD library to intercept and rewrite the paths in
glibc calls based on the value of $NIX_REDIRECTS, a colon-separated list
of path prefixes to be rewritten, e.g. "/src=/dst:/usr/=/nix/store/".
'';
};
}