Merge pull request #147361 from sternenseemann/wrap-ghc-more-tightly

haskell.compiler: use wrapper scripts over propagating
This commit is contained in:
sterni
2021-11-25 21:18:31 +01:00
committed by GitHub
9 changed files with 141 additions and 64 deletions
@@ -3,6 +3,8 @@
, ncurses5
, ncurses6, gmp, libiconv, numactl
, llvmPackages
, coreutils
, targetPackages
# minimal = true; will remove files that aren't strictly necessary for
# regular builds and GHC bootstrapping.
@@ -140,6 +142,19 @@ let
libEnvVar = lib.optionalString stdenv.hostPlatform.isDarwin "DY"
+ "LD_LIBRARY_PATH";
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
];
in
stdenv.mkDerivation rec {
@@ -156,7 +171,6 @@ stdenv.mkDerivation rec {
nativeBuildInputs = [ perl ];
propagatedBuildInputs =
lib.optionals useLLVM [ llvmPackages.llvm ]
# Because musl bindists currently provide no way to tell where
# libgmp is (see not [musl bindists have no .buildinfo]), we need
# to propagate `gmp`, otherwise programs built by this ghc will
@@ -177,7 +191,7 @@ stdenv.mkDerivation rec {
# fixing the above-mentioned release issue,
# and for GHC >= 9.* it is not clear as of writing whether that switch
# will be made there too.
++ lib.optionals stdenv.hostPlatform.isMusl [ gmp ]; # musl bindist needs this
lib.optionals stdenv.hostPlatform.isMusl [ gmp ]; # musl bindist needs this
# Set LD_LIBRARY_PATH or equivalent so that the programs running as part
# of the bindist installer can find the libraries they expect.
@@ -278,6 +292,15 @@ stdenv.mkDerivation rec {
# calls install-strip ...
dontBuild = true;
# Patch scripts to include runtime dependencies in $PATH.
postInstall = ''
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
'';
# Apparently necessary for the ghc Alpine (musl) bindist:
# When we strip, and then run the
# patchelf --set-rpath "${libPath}:$(patchelf --print-rpath $p)" $p
@@ -360,7 +383,6 @@ stdenv.mkDerivation rec {
doInstallCheck = true;
installCheckPhase = ''
unset ${libEnvVar}
# Sanity check, can ghc create executables?
cd $TMP
mkdir test-ghc; cd test-ghc
@@ -369,7 +391,9 @@ stdenv.mkDerivation rec {
module Main where
main = putStrLn \$([|"yes"|])
EOF
$out/bin/ghc --make main.hs || exit 1
# can't use env -i here because otherwise we don't find -lgmp on musl
env ${libEnvVar}= PATH= \
$out/bin/ghc --make main.hs || exit 1
echo compilation ok
[ $(./main) == "yes" ]
'';
@@ -3,6 +3,8 @@
, ncurses5
, ncurses6, gmp, libiconv, numactl
, llvmPackages
, coreutils
, targetPackages
# minimal = true; will remove files that aren't strictly necessary for
# regular builds and GHC bootstrapping.
@@ -155,6 +157,19 @@ let
libEnvVar = lib.optionalString stdenv.hostPlatform.isDarwin "DY"
+ "LD_LIBRARY_PATH";
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
];
in
stdenv.mkDerivation rec {
@@ -175,9 +190,6 @@ stdenv.mkDerivation rec {
# and update this comment accordingly.
nativeBuildInputs = [ perl ];
propagatedBuildInputs =
lib.optionals useLLVM [ llvmPackages.llvm ]
;
# Set LD_LIBRARY_PATH or equivalent so that the programs running as part
# of the bindist installer can find the libraries they expect.
@@ -278,6 +290,15 @@ stdenv.mkDerivation rec {
# calls install-strip ...
dontBuild = true;
# Patch scripts to include runtime dependencies in $PATH.
postInstall = ''
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
'';
# Apparently necessary for the ghc Alpine (musl) bindist:
# When we strip, and then run the
# patchelf --set-rpath "${libPath}:$(patchelf --print-rpath $p)" $p
@@ -360,7 +381,6 @@ stdenv.mkDerivation rec {
doInstallCheck = true;
installCheckPhase = ''
unset ${libEnvVar}
# Sanity check, can ghc create executables?
cd $TMP
mkdir test-ghc; cd test-ghc
@@ -369,7 +389,7 @@ stdenv.mkDerivation rec {
module Main where
main = putStrLn \$([|"yes"|])
EOF
$out/bin/ghc --make main.hs || exit 1
env -i $out/bin/ghc --make main.hs || exit 1
echo compilation ok
[ $(./main) == "yes" ]
'';
+11 -8
View File
@@ -132,9 +132,15 @@ 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
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") [
@@ -290,9 +296,6 @@ stdenv.mkDerivation (rec {
buildInputs = [ perl bash ] ++ (libDeps hostPlatform);
propagatedBuildInputs = [ targetPackages.stdenv.cc ]
++ lib.optional useLLVM llvmPackages.llvm;
depsTargetTarget = map lib.getDev (libDeps targetPlatform);
depsTargetTargetPropagated = map (lib.getOutput "out") (libDeps targetPlatform);
@@ -321,11 +324,11 @@ stdenv.mkDerivation (rec {
# Install the bash completion file.
install -D -m 444 utils/completion/ghc.bash $out/share/bash-completion/completions/${targetPrefix}ghc
# Patch scripts to include "readelf" and "cat" in $PATH.
# Patch scripts to include runtime dependencies in $PATH.
for i in "$out/bin/"*; do
test ! -h $i || continue
egrep --quiet '^#!' <(head -n 1 $i) || continue
sed -i -e '2i export PATH="$PATH:${lib.makeBinPath runtimeDeps}"' $i
test ! -h "$i" || continue
isScript "$i" || continue
sed -i -e '2i export PATH="${lib.makeBinPath runtimeDeps}:$PATH"' "$i"
done
'';
@@ -2,6 +2,8 @@
, fetchurl, perl, gcc
, ncurses5, ncurses6, gmp, glibc, libiconv
, llvmPackages
, coreutils
, targetPackages
}:
# Prebuilt only does native
@@ -30,6 +32,19 @@ let
downloadsUrl = "https://downloads.haskell.org/ghc";
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
];
in
stdenv.mkDerivation rec {
@@ -62,7 +77,6 @@ stdenv.mkDerivation rec {
or (throw "cannot bootstrap GHC on this platform"));
nativeBuildInputs = [ perl ];
propagatedBuildInputs = lib.optionals useLLVM [ llvmPackages.llvm ];
# Cannot patchelf beforehand due to relative RPATHs that anticipate
# the final install location/
@@ -130,6 +144,15 @@ stdenv.mkDerivation rec {
# calls install-strip ...
dontBuild = true;
# Patch scripts to include runtime dependencies in $PATH.
postInstall = ''
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
'';
# On Linux, use patchelf to modify the executables so that they can
# find editline/gmp.
postFixup = lib.optionalString stdenv.isLinux ''
@@ -163,7 +186,6 @@ stdenv.mkDerivation rec {
doInstallCheck = true;
installCheckPhase = ''
unset ${libEnvVar}
# Sanity check, can ghc create executables?
cd $TMP
mkdir test-ghc; cd test-ghc
@@ -172,7 +194,7 @@ stdenv.mkDerivation rec {
module Main where
main = putStrLn \$([|"yes"|])
EOF
$out/bin/ghc --make main.hs || exit 1
env -i $out/bin/ghc --make main.hs || exit 1
echo compilation ok
[ $(./main) == "yes" ]
'';
+11 -8
View File
@@ -140,9 +140,15 @@ 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
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") [
@@ -293,9 +299,6 @@ stdenv.mkDerivation (rec {
buildInputs = [ perl bash ] ++ (libDeps hostPlatform);
propagatedBuildInputs = [ targetPackages.stdenv.cc ]
++ lib.optional useLLVM llvmPackages.llvm;
depsTargetTarget = map lib.getDev (libDeps targetPlatform);
depsTargetTargetPropagated = map (lib.getOutput "out") (libDeps targetPlatform);
@@ -320,11 +323,11 @@ stdenv.mkDerivation (rec {
# Install the bash completion file.
install -D -m 444 utils/completion/ghc.bash $out/share/bash-completion/completions/${targetPrefix}ghc
# Patch scripts to include "readelf" and "cat" in $PATH.
# Patch scripts to include runtime dependencies in $PATH.
for i in "$out/bin/"*; do
test ! -h $i || continue
egrep --quiet '^#!' <(head -n 1 $i) || continue
sed -i -e '2i export PATH="$PATH:${lib.makeBinPath runtimeDeps}"' $i
test ! -h "$i" || continue
isScript "$i" || continue
sed -i -e '2i export PATH="${lib.makeBinPath runtimeDeps}:$PATH"' "$i"
done
'';
+11 -8
View File
@@ -127,9 +127,15 @@ 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
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") [
@@ -255,9 +261,6 @@ stdenv.mkDerivation (rec {
buildInputs = [ perl bash ] ++ (libDeps hostPlatform);
propagatedBuildInputs = [ targetPackages.stdenv.cc ]
++ lib.optional useLLVM llvmPackages.llvm;
depsTargetTarget = map lib.getDev (libDeps targetPlatform);
depsTargetTargetPropagated = map (lib.getOutput "out") (libDeps targetPlatform);
@@ -286,11 +289,11 @@ stdenv.mkDerivation (rec {
# Install the bash completion file.
install -D -m 444 utils/completion/ghc.bash $out/share/bash-completion/completions/${targetPrefix}ghc
# Patch scripts to include "readelf" and "cat" in $PATH.
# Patch scripts to include runtime dependencies in $PATH.
for i in "$out/bin/"*; do
test ! -h $i || continue
egrep --quiet '^#!' <(head -n 1 $i) || continue
sed -i -e '2i export PATH="$PATH:${lib.makeBinPath runtimeDeps}"' $i
test ! -h "$i" || continue
isScript "$i" || continue
sed -i -e '2i export PATH="${lib.makeBinPath runtimeDeps}:$PATH"' "$i"
done
'';
+13 -9
View File
@@ -12,7 +12,8 @@
, # GHC can be built with system libffi or a bundled one.
libffi ? null
, useLLVM ? !stdenv.targetPlatform.isx86
, useLLVM ? !(stdenv.targetPlatform.isx86
|| (stdenv.targetPlatform.isAarch64 && stdenv.targetPlatform.isDarwin))
, # LLVM is conceptually a run-time-only depedendency, but for
# non-x86, we need LLVM to bootstrap later stages, so it becomes a
# build-time dependency too.
@@ -126,9 +127,15 @@ 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
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") [
@@ -258,9 +265,6 @@ stdenv.mkDerivation (rec {
buildInputs = [ perl bash ] ++ (libDeps hostPlatform);
propagatedBuildInputs = [ targetPackages.stdenv.cc ]
++ lib.optional useLLVM llvmPackages.llvm;
depsTargetTarget = map lib.getDev (libDeps targetPlatform);
depsTargetTargetPropagated = map (lib.getOutput "out") (libDeps targetPlatform);
@@ -289,11 +293,11 @@ stdenv.mkDerivation (rec {
# Install the bash completion file.
install -D -m 444 utils/completion/ghc.bash $out/share/bash-completion/completions/${targetPrefix}ghc
# Patch scripts to include "readelf" and "cat" in $PATH.
# Patch scripts to include runtime dependencies in $PATH.
for i in "$out/bin/"*; do
test ! -h $i || continue
egrep --quiet '^#!' <(head -n 1 $i) || continue
sed -i -e '2i export PATH="$PATH:${lib.makeBinPath runtimeDeps}"' $i
test ! -h "$i" || continue
isScript "$i" || continue
sed -i -e '2i export PATH="${lib.makeBinPath runtimeDeps}:$PATH"' "$i"
done
'';
+13 -9
View File
@@ -17,7 +17,8 @@
!stdenv.targetPlatform.isWindows
, elfutils # for DWARF support
, useLLVM ? !stdenv.targetPlatform.isx86 || stdenv.targetPlatform.isiOS
, useLLVM ? !(stdenv.targetPlatform.isx86
|| (stdenv.targetPlatform.isAarch64 && stdenv.targetPlatform.isDarwin))
, # LLVM is conceptually a run-time-only depedendency, but for
# non-x86, we need LLVM to bootstrap later stages, so it becomes a
# build-time dependency too.
@@ -140,9 +141,15 @@ 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
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") [
@@ -278,9 +285,6 @@ stdenv.mkDerivation (rec {
buildInputs = [ perl bash ] ++ (libDeps hostPlatform);
propagatedBuildInputs = [ targetPackages.stdenv.cc ]
++ lib.optional useLLVM llvmPackages.llvm;
depsTargetTarget = map lib.getDev (libDeps targetPlatform);
depsTargetTargetPropagated = map (lib.getOutput "out") (libDeps targetPlatform);
@@ -309,11 +313,11 @@ stdenv.mkDerivation (rec {
# Install the bash completion file.
install -D -m 444 utils/completion/ghc.bash $out/share/bash-completion/completions/${targetPrefix}ghc
# Patch scripts to include "readelf" and "cat" in $PATH.
# Patch scripts to include runtime dependencies in $PATH.
for i in "$out/bin/"*; do
test ! -h $i || continue
egrep --quiet '^#!' <(head -n 1 $i) || continue
sed -i -e '2i export PATH="$PATH:${lib.makeBinPath runtimeDeps}"' $i
test ! -h "$i" || continue
isScript "$i" || continue
sed -i -e '2i export PATH="${lib.makeBinPath runtimeDeps}:$PATH"' "$i"
done
'';
@@ -1,14 +1,8 @@
{ lib, stdenv, ghc, llvmPackages, packages, symlinkJoin, makeWrapper
# Include LLVM by default if GHC doesn't have native code generation support
# See https://gitlab.haskell.org/ghc/ghc/-/wikis/platforms
, useLLVM ? !(lib.any lib.id ([
stdenv.targetPlatform.isx86
stdenv.targetPlatform.isPowerPC
stdenv.targetPlatform.isSparc
] ++ lib.optionals (lib.versionAtLeast ghc.version "9.2") [
(stdenv.targetPlatform.isAarch64 && stdenv.targetPlatform.isDarwin)
# TODO(@sternenseemann): Is armv7a supported for iOS?
]))
# GHC will have LLVM available if necessary for the respective target,
# so useLLVM only needs to be changed if -fllvm is to be used for a
# platform that has NCG support
, useLLVM ? false
, postBuild ? ""
, ghcLibdir ? null # only used by ghcjs, when resolving plugins
}: