haskell.compiler.*: pass runtime dependencies via configure script

GHC can actually accept absolute paths for its runtime tools (except for
touch) at configure time which are then saved in
`$out/lib/ghc-${version}/settings`. This allows us to drop the wrapper
entirely if we assume that a POSIX compliant touch is in PATH when we
run GHC later.

The touch problem can presumably be fixed by either patching the
configure file of GHC (although we need to take care not to change the
touch GHC uses during its compilation) or messing with the settings file
after installation.

The rationale for dropping the wrapper PATH entry completely is that
it's always possible to invoke GHC via its library which will bypass the
wrapper completely, leading to subtly different behavior.

Binary GHCs are not touched in this commit, but ideally they'll get a
similar treatment as well, so they are more robust, although we
generally don't need to use them as a library.

Note that GHC 8.8.4 doesn't care about install_name_tool or otool, so
the respective environment variables are not set.
This commit is contained in:
sternenseemann 2021-11-27 12:09:31 +01:00 committed by sterni
parent c83509f73d
commit 17b8b5a4dc
5 changed files with 77 additions and 110 deletions

View File

@ -120,6 +120,8 @@ let
++ lib.optional (!enableIntegerSimple) gmp
++ lib.optional (platform.libc != "glibc" && !targetPlatform.isWindows) libiconv;
# TODO(@sternenseemann): is buildTarget LLVM unnecessary?
# GHC doesn't seem to have {LLC,OPT}_HOST
toolsForTarget = [
pkgsBuildTarget.targetPackages.stdenv.cc
] ++ lib.optional useLLVM buildTargetLlvmPackages.llvm;
@ -132,21 +134,6 @@ let
useLdGold = targetPlatform.linker == "gold" ||
(targetPlatform.linker == "bfd" && (targetPackages.stdenv.cc.bintools.bintools.hasGold or false) && !targetPlatform.isMusl);
# Tools GHC will need to call at runtime. Some of these were handled using
# propagatedBuildInputs before, however this allowed for GHC environment and
# a derivations build environment to interfere, especially when GHC is built.
runtimeDeps = [
targetPackages.stdenv.cc
targetPackages.stdenv.cc.bintools
coreutils # for cat
] ++ lib.optionals useLLVM [
(lib.getBin llvmPackages.llvm)
]
# On darwin, we need unwrapped bintools as well (for otool)
++ lib.optionals (stdenv.targetPlatform.linker == "cctools") [
targetPackages.stdenv.cc.bintools.bintools
];
# Makes debugging easier to see which variant is at play in `nix-store -q --tree`.
variantSuffix = lib.concatStrings [
(lib.optionalString stdenv.hostPlatform.isMusl "-musl")
@ -202,6 +189,7 @@ stdenv.mkDerivation (rec {
postPatch = "patchShebangs .";
# GHC is a bit confused on its cross terminology.
# TODO(@sternenseemann): investigate coreutils dependencies and pass absolute paths
preConfigure = ''
for env in $(env | grep '^TARGET_' | sed -E 's|\+?=.*||'); do
export "''${env#TARGET_}=''${!env}"
@ -218,6 +206,19 @@ stdenv.mkDerivation (rec {
export RANLIB="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}ranlib"
export READELF="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}readelf"
export STRIP="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}strip"
'' + lib.optionalString (stdenv.targetPlatform.linker == "cctools") ''
export OTOOL="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}otool"
export INSTALL_NAME_TOOL="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}install_name_tool"
'' + lib.optionalString useLLVM ''
export LLC="${lib.getBin llvmPackages.llvm}/bin/llc"
export OPT="${lib.getBin llvmPackages.llvm}/bin/opt"
'' + lib.optionalString (targetCC.isClang || (useLLVM && stdenv.targetPlatform.isDarwin)) (let
# LLVM backend on Darwin needs clang, if we are already using clang, might as well set the environment variable.
# See also https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/codegens.html#llvm-code-generator-fllvm
clang = if targetCC.isClang then targetCC else llvmPackages.clang;
in ''
export CLANG="${clang}/bin/${clang.targetPrefix}clang"
'') + ''
echo -n "${buildMK}" > mk/build.mk
sed -i -e 's|-isysroot /Developer/SDKs/MacOSX10.5.sdk||' configure
@ -323,13 +324,6 @@ stdenv.mkDerivation (rec {
postInstall = ''
# Install the bash completion file.
install -D -m 444 utils/completion/ghc.bash $out/share/bash-completion/completions/${targetPrefix}ghc
# Patch scripts to include runtime dependencies in $PATH.
for i in "$out/bin/"*; do
test ! -h "$i" || continue
isScript "$i" || continue
sed -i -e '2i export PATH="${lib.makeBinPath runtimeDeps}:$PATH"' "$i"
done
'';
passthru = {

View File

@ -128,6 +128,8 @@ let
++ lib.optional (!enableIntegerSimple) gmp
++ lib.optional (platform.libc != "glibc" && !targetPlatform.isWindows) libiconv;
# TODO(@sternenseemann): is buildTarget LLVM unnecessary?
# GHC doesn't seem to have {LLC,OPT}_HOST
toolsForTarget = [
pkgsBuildTarget.targetPackages.stdenv.cc
] ++ lib.optional useLLVM buildTargetLlvmPackages.llvm;
@ -140,21 +142,6 @@ let
useLdGold = targetPlatform.linker == "gold" ||
(targetPlatform.linker == "bfd" && (targetPackages.stdenv.cc.bintools.bintools.hasGold or false) && !targetPlatform.isMusl);
# Tools GHC will need to call at runtime. Some of these were handled using
# propagatedBuildInputs before, however this allowed for GHC environment and
# a derivations build environment to interfere, especially when GHC is built.
runtimeDeps = [
targetPackages.stdenv.cc
targetPackages.stdenv.cc.bintools
coreutils # for cat
] ++ lib.optionals useLLVM [
(lib.getBin llvmPackages.llvm)
]
# On darwin, we need unwrapped bintools as well (for otool)
++ lib.optionals (stdenv.targetPlatform.linker == "cctools") [
targetPackages.stdenv.cc.bintools.bintools
];
# Makes debugging easier to see which variant is at play in `nix-store -q --tree`.
variantSuffix = lib.concatStrings [
(lib.optionalString stdenv.hostPlatform.isMusl "-musl")
@ -203,6 +190,7 @@ stdenv.mkDerivation (rec {
postPatch = "patchShebangs .";
# GHC is a bit confused on its cross terminology.
# TODO(@sternenseemann): investigate coreutils dependencies and pass absolute paths
preConfigure =
# Aarch64 allow backward bootstrapping since earlier versions are unstable.
# Same for musl, as earlier versions do not provide a musl bindist for bootstrapping.
@ -226,6 +214,16 @@ stdenv.mkDerivation (rec {
export RANLIB="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}ranlib"
export READELF="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}readelf"
export STRIP="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}strip"
'' + lib.optionalString useLLVM ''
export LLC="${lib.getBin llvmPackages.llvm}/bin/llc"
export OPT="${lib.getBin llvmPackages.llvm}/bin/opt"
'' + lib.optionalString (targetCC.isClang || (useLLVM && stdenv.targetPlatform.isDarwin)) (let
# LLVM backend on Darwin needs clang, if we are already using clang, might as well set the environment variable.
# See also https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/codegens.html#llvm-code-generator-fllvm
clang = if targetCC.isClang then targetCC else llvmPackages.clang;
in ''
export CLANG="${clang}/bin/${clang.targetPrefix}clang"
'') + ''
echo -n "${buildMK dontStrip}" > mk/build.mk
sed -i -e 's|-isysroot /Developer/SDKs/MacOSX10.5.sdk||' configure
@ -322,13 +320,6 @@ stdenv.mkDerivation (rec {
postInstall = ''
# Install the bash completion file.
install -D -m 444 utils/completion/ghc.bash $out/share/bash-completion/completions/${targetPrefix}ghc
# Patch scripts to include runtime dependencies in $PATH.
for i in "$out/bin/"*; do
test ! -h "$i" || continue
isScript "$i" || continue
sed -i -e '2i export PATH="${lib.makeBinPath runtimeDeps}:$PATH"' "$i"
done
'';
passthru = {

View File

@ -115,6 +115,8 @@ let
++ lib.optional (!enableIntegerSimple) gmp
++ lib.optional (platform.libc != "glibc" && !targetPlatform.isWindows) libiconv;
# TODO(@sternenseemann): is buildTarget LLVM unnecessary?
# GHC doesn't seem to have {LLC,OPT}_HOST
toolsForTarget = [
pkgsBuildTarget.targetPackages.stdenv.cc
] ++ lib.optional useLLVM buildTargetLlvmPackages.llvm;
@ -127,21 +129,6 @@ let
useLdGold = targetPlatform.linker == "gold" ||
(targetPlatform.linker == "bfd" && (targetPackages.stdenv.cc.bintools.bintools.hasGold or false) && !targetPlatform.isMusl);
# Tools GHC will need to call at runtime. Some of these were handled using
# propagatedBuildInputs before, however this allowed for GHC environment and
# a derivations build environment to interfere, especially when GHC is built.
runtimeDeps = [
targetPackages.stdenv.cc
targetPackages.stdenv.cc.bintools
coreutils # for cat
] ++ lib.optionals useLLVM [
(lib.getBin llvmPackages.llvm)
]
# On darwin, we need unwrapped bintools as well (for otool)
++ lib.optionals (stdenv.targetPlatform.linker == "cctools") [
targetPackages.stdenv.cc.bintools.bintools
];
# Makes debugging easier to see which variant is at play in `nix-store -q --tree`.
variantSuffix = lib.concatStrings [
(lib.optionalString stdenv.hostPlatform.isMusl "-musl")
@ -168,6 +155,7 @@ stdenv.mkDerivation (rec {
LANG = "en_US.UTF-8";
# GHC is a bit confused on its cross terminology.
# TODO(@sternenseemann): investigate coreutils dependencies and pass absolute paths
preConfigure = ''
for env in $(env | grep '^TARGET_' | sed -E 's|\+?=.*||'); do
export "''${env#TARGET_}=''${!env}"
@ -184,6 +172,19 @@ stdenv.mkDerivation (rec {
export RANLIB="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}ranlib"
export READELF="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}readelf"
export STRIP="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}strip"
'' + lib.optionalString (stdenv.targetPlatform.linker == "cctools") ''
export OTOOL="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}otool"
export INSTALL_NAME_TOOL="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}install_name_tool"
'' + lib.optionalString useLLVM ''
export LLC="${lib.getBin llvmPackages.llvm}/bin/llc"
export OPT="${lib.getBin llvmPackages.llvm}/bin/opt"
'' + lib.optionalString (targetCC.isClang || (useLLVM && stdenv.targetPlatform.isDarwin)) (let
# LLVM backend on Darwin needs clang, if we are already using clang, might as well set the environment variable.
# See also https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/codegens.html#llvm-code-generator-fllvm
clang = if targetCC.isClang then targetCC else llvmPackages.clang;
in ''
export CLANG="${clang}/bin/${clang.targetPrefix}clang"
'') + ''
echo -n "${buildMK}" > mk/build.mk
sed -i -e 's|-isysroot /Developer/SDKs/MacOSX10.5.sdk||' configure
@ -288,13 +289,6 @@ stdenv.mkDerivation (rec {
postInstall = ''
# Install the bash completion file.
install -D -m 444 utils/completion/ghc.bash $out/share/bash-completion/completions/${targetPrefix}ghc
# Patch scripts to include runtime dependencies in $PATH.
for i in "$out/bin/"*; do
test ! -h "$i" || continue
isScript "$i" || continue
sed -i -e '2i export PATH="${lib.makeBinPath runtimeDeps}:$PATH"' "$i"
done
'';
passthru = {

View File

@ -116,6 +116,8 @@ let
++ lib.optional (!enableIntegerSimple) gmp
++ lib.optional (platform.libc != "glibc" && !targetPlatform.isWindows) libiconv;
# TODO(@sternenseemann): is buildTarget LLVM unnecessary?
# GHC doesn't seem to have {LLC,OPT}_HOST
toolsForTarget = [
pkgsBuildTarget.targetPackages.stdenv.cc
] ++ lib.optional useLLVM buildTargetLlvmPackages.llvm;
@ -127,21 +129,6 @@ let
# see #84670 and #49071 for more background.
useLdGold = targetPlatform.linker == "gold" || (targetPlatform.linker == "bfd" && !targetPlatform.isMusl);
# Tools GHC will need to call at runtime. Some of these were handled using
# propagatedBuildInputs before, however this allowed for GHC environment and
# a derivations build environment to interfere, especially when GHC is built.
runtimeDeps = [
targetPackages.stdenv.cc
targetPackages.stdenv.cc.bintools
coreutils # for cat
] ++ lib.optionals useLLVM [
(lib.getBin llvmPackages.llvm)
]
# On darwin, we need unwrapped bintools as well (for otool)
++ lib.optionals (stdenv.targetPlatform.linker == "cctools") [
targetPackages.stdenv.cc.bintools.bintools
];
# Makes debugging easier to see which variant is at play in `nix-store -q --tree`.
variantSuffix = lib.concatStrings [
(lib.optionalString stdenv.hostPlatform.isMusl "-musl")
@ -168,6 +155,7 @@ stdenv.mkDerivation (rec {
LANG = "en_US.UTF-8";
# GHC is a bit confused on its cross terminology.
# TODO(@sternenseemann): investigate coreutils dependencies and pass absolute paths
preConfigure = ''
for env in $(env | grep '^TARGET_' | sed -E 's|\+?=.*||'); do
export "''${env#TARGET_}=''${!env}"
@ -184,6 +172,19 @@ stdenv.mkDerivation (rec {
export RANLIB="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}ranlib"
export READELF="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}readelf"
export STRIP="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}strip"
'' + lib.optionalString (stdenv.targetPlatform.linker == "cctools") ''
export OTOOL="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}otool"
export INSTALL_NAME_TOOL="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}install_name_tool"
'' + lib.optionalString useLLVM ''
export LLC="${lib.getBin llvmPackages.llvm}/bin/llc"
export OPT="${lib.getBin llvmPackages.llvm}/bin/opt"
'' + lib.optionalString (targetCC.isClang || (useLLVM && stdenv.targetPlatform.isDarwin)) (let
# LLVM backend on Darwin needs clang, if we are already using clang, might as well set the environment variable.
# See also https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/codegens.html#llvm-code-generator-fllvm
clang = if targetCC.isClang then targetCC else llvmPackages.clang;
in ''
export CLANG="${clang}/bin/${clang.targetPrefix}clang"
'') + ''
echo -n "${buildMK}" > mk/build.mk
sed -i -e 's|-isysroot /Developer/SDKs/MacOSX10.5.sdk||' configure
@ -292,13 +293,6 @@ stdenv.mkDerivation (rec {
postInstall = ''
# Install the bash completion file.
install -D -m 444 utils/completion/ghc.bash $out/share/bash-completion/completions/${targetPrefix}ghc
# Patch scripts to include runtime dependencies in $PATH.
for i in "$out/bin/"*; do
test ! -h "$i" || continue
isScript "$i" || continue
sed -i -e '2i export PATH="${lib.makeBinPath runtimeDeps}:$PATH"' "$i"
done
'';
passthru = {

View File

@ -129,6 +129,8 @@ let
++ lib.optional (platform.libc != "glibc" && !targetPlatform.isWindows) libiconv
++ lib.optional enableDwarf elfutils;
# TODO(@sternenseemann): is buildTarget LLVM unnecessary?
# GHC doesn't seem to have {LLC,OPT}_HOST
toolsForTarget = [
pkgsBuildTarget.targetPackages.stdenv.cc
] ++ lib.optional useLLVM buildTargetLlvmPackages.llvm;
@ -141,21 +143,6 @@ let
useLdGold = targetPlatform.linker == "gold" ||
(targetPlatform.linker == "bfd" && (targetPackages.stdenv.cc.bintools.bintools.hasGold or false) && !targetPlatform.isMusl);
# Tools GHC will need to call at runtime. Some of these were handled using
# propagatedBuildInputs before, however this allowed for GHC environment and
# a derivations build environment to interfere, especially when GHC is built.
runtimeDeps = [
targetPackages.stdenv.cc
targetPackages.stdenv.cc.bintools
coreutils # for cat
] ++ lib.optionals useLLVM [
(lib.getBin llvmPackages.llvm)
]
# On darwin, we need unwrapped bintools as well (for otool)
++ lib.optionals (stdenv.targetPlatform.linker == "cctools") [
targetPackages.stdenv.cc.bintools.bintools
];
# Makes debugging easier to see which variant is at play in `nix-store -q --tree`.
variantSuffix = lib.concatStrings [
(lib.optionalString stdenv.hostPlatform.isMusl "-musl")
@ -181,6 +168,7 @@ stdenv.mkDerivation (rec {
postPatch = "patchShebangs .";
# GHC is a bit confused on its cross terminology.
# TODO(@sternenseemann): investigate coreutils dependencies and pass absolute paths
preConfigure = ''
for env in $(env | grep '^TARGET_' | sed -E 's|\+?=.*||'); do
export "''${env#TARGET_}=''${!env}"
@ -198,6 +186,19 @@ stdenv.mkDerivation (rec {
export RANLIB="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}ranlib"
export READELF="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}readelf"
export STRIP="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}strip"
'' + lib.optionalString (stdenv.targetPlatform.linker == "cctools") ''
export OTOOL="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}otool"
export INSTALL_NAME_TOOL="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}install_name_tool"
'' + lib.optionalString useLLVM ''
export LLC="${lib.getBin llvmPackages.llvm}/bin/llc"
export OPT="${lib.getBin llvmPackages.llvm}/bin/opt"
'' + lib.optionalString (targetCC.isClang || (useLLVM && stdenv.targetPlatform.isDarwin)) (let
# LLVM backend on Darwin needs clang, if we are already using clang, might as well set the environment variable.
# See also https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/codegens.html#llvm-code-generator-fllvm
clang = if targetCC.isClang then targetCC else llvmPackages.clang;
in ''
export CLANG="${clang}/bin/${clang.targetPrefix}clang"
'') + ''
# otherwise haddock fails when generating the compiler docs
export LANG=C.UTF-8
@ -312,13 +313,6 @@ stdenv.mkDerivation (rec {
postInstall = ''
# Install the bash completion file.
install -D -m 444 utils/completion/ghc.bash $out/share/bash-completion/completions/${targetPrefix}ghc
# Patch scripts to include runtime dependencies in $PATH.
for i in "$out/bin/"*; do
test ! -h "$i" || continue
isScript "$i" || continue
sed -i -e '2i export PATH="${lib.makeBinPath runtimeDeps}:$PATH"' "$i"
done
'';
passthru = {