From 17b8b5a4dc5a49d83d508cb66c6ac2f0bb9fa39b Mon Sep 17 00:00:00 2001 From: sternenseemann Date: Sat, 27 Nov 2021 12:09:31 +0100 Subject: [PATCH] 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. --- pkgs/development/compilers/ghc/8.10.7.nix | 38 ++++++++++------------- pkgs/development/compilers/ghc/8.8.4.nix | 35 ++++++++------------- pkgs/development/compilers/ghc/9.0.1.nix | 38 ++++++++++------------- pkgs/development/compilers/ghc/9.2.1.nix | 38 ++++++++++------------- pkgs/development/compilers/ghc/head.nix | 38 ++++++++++------------- 5 files changed, 77 insertions(+), 110 deletions(-) diff --git a/pkgs/development/compilers/ghc/8.10.7.nix b/pkgs/development/compilers/ghc/8.10.7.nix index bfcd53141fa0..c8ea523be6a7 100644 --- a/pkgs/development/compilers/ghc/8.10.7.nix +++ b/pkgs/development/compilers/ghc/8.10.7.nix @@ -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 = { diff --git a/pkgs/development/compilers/ghc/8.8.4.nix b/pkgs/development/compilers/ghc/8.8.4.nix index c3efc2f2a7ba..ad9a10d33fbc 100644 --- a/pkgs/development/compilers/ghc/8.8.4.nix +++ b/pkgs/development/compilers/ghc/8.8.4.nix @@ -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 = { diff --git a/pkgs/development/compilers/ghc/9.0.1.nix b/pkgs/development/compilers/ghc/9.0.1.nix index e7da05871070..35edd0d4199f 100644 --- a/pkgs/development/compilers/ghc/9.0.1.nix +++ b/pkgs/development/compilers/ghc/9.0.1.nix @@ -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 = { diff --git a/pkgs/development/compilers/ghc/9.2.1.nix b/pkgs/development/compilers/ghc/9.2.1.nix index 2401a8900530..e8422372282e 100644 --- a/pkgs/development/compilers/ghc/9.2.1.nix +++ b/pkgs/development/compilers/ghc/9.2.1.nix @@ -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 = { diff --git a/pkgs/development/compilers/ghc/head.nix b/pkgs/development/compilers/ghc/head.nix index 5be02df13b4a..df8ac642cddf 100644 --- a/pkgs/development/compilers/ghc/head.nix +++ b/pkgs/development/compilers/ghc/head.nix @@ -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 = {