mirror of
https://github.com/ilyakooo0/haskell.nix.git
synced 2024-10-26 01:27:40 +03:00
Make DLLs in deps available to wine TH runner (#1405)
This is a better fix to the problem of making DLLs available to the process running in wine that is used to evaluate TH code when cross compiling for Windows. Also fixes macOS loadArchive in TH for ghc 9 Co-authored-by: Michael Peyton Jones <michael.peyton-jones@iohk.io>
This commit is contained in:
parent
2c895a2c41
commit
4b6ee9767d
@ -382,18 +382,26 @@ let
|
||||
runHook postConfigure
|
||||
'';
|
||||
|
||||
buildPhase = if stdenv.hostPlatform.isGhcjs then ''
|
||||
runHook preBuild
|
||||
# https://gitlab.haskell.org/ghc/ghc/issues/9221
|
||||
$SETUP_HS build ${haskellLib.componentTarget componentId} ${lib.concatStringsSep " " setupBuildFlags}
|
||||
runHook postBuild
|
||||
'' else ''
|
||||
runHook preBuild
|
||||
# https://gitlab.haskell.org/ghc/ghc/issues/9221
|
||||
$SETUP_HS build ${haskellLib.componentTarget componentId} -j$(($NIX_BUILD_CORES > 4 ? 4 : $NIX_BUILD_CORES)) ${lib.concatStringsSep " " setupBuildFlags}
|
||||
runHook postBuild
|
||||
''
|
||||
;
|
||||
buildPhase =
|
||||
# It seems that by the time the iserv wrapper specifiec by `--ghc-option=-pgmi` runs
|
||||
# all the array environment variables are removed from the environment. To get a list
|
||||
# of all the locations a DLLs might be present we need access to pkgsHostTarget.
|
||||
# Adding a string version of the list array of nix store paths allows us to get that
|
||||
# list when we need it.
|
||||
(lib.optionalString stdenv.hostPlatform.isWindows ''
|
||||
export pkgsHostTargetAsString="''${pkgsHostTarget[@]}"
|
||||
'') +
|
||||
(if stdenv.hostPlatform.isGhcjs then ''
|
||||
runHook preBuild
|
||||
# https://gitlab.haskell.org/ghc/ghc/issues/9221
|
||||
$SETUP_HS build ${haskellLib.componentTarget componentId} ${lib.concatStringsSep " " setupBuildFlags}
|
||||
runHook postBuild
|
||||
'' else ''
|
||||
runHook preBuild
|
||||
# https://gitlab.haskell.org/ghc/ghc/issues/9221
|
||||
$SETUP_HS build ${haskellLib.componentTarget componentId} -j$(($NIX_BUILD_CORES > 4 ? 4 : $NIX_BUILD_CORES)) ${lib.concatStringsSep " " setupBuildFlags}
|
||||
runHook postBuild
|
||||
'');
|
||||
|
||||
# Note: Cabal does *not* copy test executables during the `install` phase.
|
||||
#
|
||||
|
@ -169,6 +169,8 @@ in {
|
||||
++ fromUntil "8.8.2" "8.9" ./patches/ghc/ghc-8.8.2-reinstallable-lib-ghc.patch
|
||||
++ final.lib.optional (version == "8.6.4") ./patches/ghc/ghc-8.6.4-better-plusSimplCountErrors.patch
|
||||
++ final.lib.optional (versionAtLeast "8.6.4" && versionLessThan "9.0" && final.stdenv.isDarwin) ./patches/ghc/ghc-macOS-loadArchive-fix.patch
|
||||
++ final.lib.optional (versionAtLeast "9.0.0" && versionLessThan "9.2" && final.stdenv.isDarwin) ./patches/ghc/ghc-9.0-macOS-loadArchive-fix.patch
|
||||
++ final.lib.optional (versionAtLeast "9.2.0" && versionLessThan "9.3" && final.stdenv.isDarwin) ./patches/ghc/ghc-9.2-macOS-loadArchive-fix.patch
|
||||
++ final.lib.optional (versionAtLeast "8.4.4" && versionLessThan "8.10" && final.stdenv.isDarwin) ./patches/ghc/ghc-darwin-gcc-version-fix.patch
|
||||
++ final.lib.optional (versionAtLeast "8.10.1" && versionLessThan "9.0.2" && final.stdenv.isDarwin) ./patches/ghc/ghc-8.10-darwin-gcc-version-fix.patch
|
||||
# backport of https://gitlab.haskell.org/ghc/ghc/-/merge_requests/3227
|
||||
|
@ -18,7 +18,7 @@ let
|
||||
|
||||
configureFlags = lib.optional hostPlatform.isWindows "--disable-split-sections";
|
||||
|
||||
wineIservWrapperVanilla = writeScriptBin "iserv-wrapper" ''
|
||||
wineIservWrapperScript = enableProfiling: writeScriptBin ("iserv-wrapper" + lib.optionalString enableProfiling "-prof") ''
|
||||
#!${stdenv.shell}
|
||||
set -euo pipefail
|
||||
# unset the configureFlags.
|
||||
@ -28,7 +28,23 @@ let
|
||||
unset configureFlags
|
||||
PORT=$((5000 + $RANDOM % 5000))
|
||||
(>&2 echo "---> Starting remote-iserv on port $PORT")
|
||||
WINEDLLOVERRIDES="winemac.drv=d" WINEDEBUG=warn-all,fixme-all,-menubuilder,-mscoree,-ole,-secur32,-winediag WINEPREFIX=$TMP ${wine}/bin/wine64 ${remote-iserv}/bin/remote-iserv.exe tmp $PORT &
|
||||
REMOTE_ISERV=$(mktemp -d)
|
||||
ln -s ${if enableProfiling then remote-iserv.override { inherit enableProfiling; } else remote-iserv}/bin/* $REMOTE_ISERV
|
||||
# See coment in comp-builder.nix for where this comes from and why it's here
|
||||
for p in $pkgsHostTargetAsString; do
|
||||
find "$p" -iname '*.dll' -exec ln -s {} $REMOTE_ISERV \;
|
||||
find "$p" -iname '*.dll.a' -exec ln -s {} $REMOTE_ISERV \;
|
||||
done
|
||||
# Some DLLs have a `lib` prefix but we attempt to load them without the prefix.
|
||||
# This was a problem for `double-conversion` package when used in TH code.
|
||||
# Creating links from the `X.dll` to `libX.dll` works around this issue.
|
||||
(
|
||||
cd $REMOTE_ISERV
|
||||
for l in lib*.dll; do
|
||||
ln -s "$l" "''${l#lib}"
|
||||
done
|
||||
)
|
||||
WINEDLLOVERRIDES="winemac.drv=d" WINEDEBUG=warn-all,fixme-all,-menubuilder,-mscoree,-ole,-secur32,-winediag WINEPREFIX=$TMP ${wine}/bin/wine64 $REMOTE_ISERV/remote-iserv.exe tmp $PORT &
|
||||
(>&2 echo "---| remote-iserv should have started on $PORT")
|
||||
RISERV_PID="$!"
|
||||
${iserv-proxy}/bin/iserv-proxy $@ 127.0.0.1 "$PORT"
|
||||
@ -36,25 +52,7 @@ let
|
||||
kill $RISERV_PID
|
||||
'';
|
||||
|
||||
wineIservWrapperProf = writeScriptBin "iserv-wrapper-prof" ''
|
||||
#!${stdenv.shell}
|
||||
set -euo pipefail
|
||||
# unset the configureFlags.
|
||||
# configure should have run already
|
||||
# without restting it, wine might fail
|
||||
# due to a too large environment.
|
||||
unset configureFlags
|
||||
PORT=$((5000 + $RANDOM % 5000))
|
||||
(>&2 echo "---> Starting remote-iserv on port $PORT")
|
||||
WINEDLLOVERRIDES="winemac.drv=d" WINEDEBUG=warn-all,fixme-all,-menubuilder,-mscoree,-ole,-secur32,-winediag WINEPREFIX=$TMP ${wine}/bin/wine64 ${remote-iserv.override { enableProfiling = true; }}/bin/remote-iserv.exe tmp $PORT &
|
||||
(>&2 echo "---| remote-iserv should have started on $PORT")
|
||||
RISERV_PID="$!"
|
||||
${iserv-proxy}/bin/iserv-proxy $@ 127.0.0.1 "$PORT"
|
||||
(>&2 echo "---> killing remote-iserv...")
|
||||
kill $RISERV_PID
|
||||
'';
|
||||
|
||||
wineIservWrapper = symlinkJoin { name = "iserv-wrapper"; paths = [ wineIservWrapperVanilla wineIservWrapperProf ]; };
|
||||
wineIservWrapper = symlinkJoin { name = "iserv-wrapper"; paths = [ (wineIservWrapperScript false) (wineIservWrapperScript true) ]; };
|
||||
|
||||
################################################################################
|
||||
# Build logic (TH support via remote iserv via wine)
|
||||
|
9
overlays/patches/ghc/ghc-9.0-macOS-loadArchive-fix.patch
Normal file
9
overlays/patches/ghc/ghc-9.0-macOS-loadArchive-fix.patch
Normal file
@ -0,0 +1,9 @@
|
||||
--- a/compiler/GHC/Runtime/Linker.hs
|
||||
+++ b/compiler/GHC/Runtime/Linker.hs
|
||||
@@ -1487,7 +1487,6 @@ locateLib hsc_env is_hs lib_dirs gcc_dirs lib
|
||||
dyn_obj_file = lib <.> "dyn_o"
|
||||
arch_files = [ "lib" ++ lib ++ lib_tag <.> "a"
|
||||
, lib <.> "a" -- native code has no lib_tag
|
||||
- , "lib" ++ lib, lib
|
||||
]
|
||||
lib_tag = if is_hs && loading_profiled_hs_libs then "_p" else ""
|
9
overlays/patches/ghc/ghc-9.2-macOS-loadArchive-fix.patch
Normal file
9
overlays/patches/ghc/ghc-9.2-macOS-loadArchive-fix.patch
Normal file
@ -0,0 +1,9 @@
|
||||
--- a/compiler/GHC/Linker/Loader.hs
|
||||
+++ b/compiler/GHC/Linker/Loader.hs
|
||||
@@ -1487,7 +1487,6 @@ locateLib hsc_env is_hs lib_dirs gcc_dirs lib
|
||||
dyn_obj_file = lib <.> "dyn_o"
|
||||
arch_files = [ "lib" ++ lib ++ lib_tag <.> "a"
|
||||
, lib <.> "a" -- native code has no lib_tag
|
||||
- , "lib" ++ lib, lib
|
||||
]
|
||||
lib_tag = if is_hs && loading_profiled_hs_libs then "_p" else ""
|
@ -73,17 +73,11 @@ final: prev:
|
||||
# dependencies) and then placing them somewhere where wine+remote-iserv
|
||||
# will find them.
|
||||
remote-iserv.postInstall = pkgs.lib.optionalString pkgs.stdenv.hostPlatform.isWindows (
|
||||
let extra-libs = [ pkgs.openssl.bin pkgs.libffi pkgs.gmp (pkgs.libsodium-vrf or pkgs.libsodium) pkgs.windows.mcfgthreads pkgs.buildPackages.gcc.cc pkgs.secp256k1 ]; in ''
|
||||
let extra-libs = [ pkgs.libffi pkgs.gmp pkgs.windows.mcfgthreads pkgs.buildPackages.gcc.cc ]; in ''
|
||||
for p in ${lib.concatStringsSep " "extra-libs}; do
|
||||
find "$p" -iname '*.dll' -exec cp {} $out/bin/ \;
|
||||
find "$p" -iname '*.dll.a' -exec cp {} $out/bin/ \;
|
||||
done
|
||||
(
|
||||
cd $out/bin
|
||||
for l in lib*.dll; do
|
||||
ln -s "$l" "''${l#lib}"
|
||||
done
|
||||
)
|
||||
'');
|
||||
|
||||
# Apply https://github.com/haskell/cabal/pull/6055
|
||||
|
@ -202,6 +202,7 @@ let
|
||||
sublib-docs = callTest ./sublib-docs { inherit util compiler-nix-name; };
|
||||
githash = haskell-nix.callPackage ./githash { inherit compiler-nix-name; testSrc = testSrcWithGitDir; };
|
||||
c-ffi = callTest ./c-ffi { inherit util compiler-nix-name; };
|
||||
th-dlls = callTest ./th-dlls { inherit util compiler-nix-name; };
|
||||
|
||||
unit = unitTests;
|
||||
};
|
||||
|
23
test/th-dlls/default.nix
Normal file
23
test/th-dlls/default.nix
Normal file
@ -0,0 +1,23 @@
|
||||
# Test building TH code that needs DLLs when cross compiling for windows
|
||||
{ stdenv, lib, util, project', haskellLib, recurseIntoAttrs, testSrc, compiler-nix-name }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
project = project' {
|
||||
inherit compiler-nix-name;
|
||||
src = testSrc "th-dlls";
|
||||
};
|
||||
|
||||
packages = project.hsPkgs;
|
||||
|
||||
in recurseIntoAttrs {
|
||||
meta.disabled = stdenv.hostPlatform.isGhcjs;
|
||||
|
||||
ifdInputs = {
|
||||
inherit (project) plan-nix;
|
||||
};
|
||||
|
||||
build = packages.th-dlls.components.library;
|
||||
build-profiled = packages.th-dlls.components.library.profiled;
|
||||
}
|
14
test/th-dlls/src/Lib.hs
Normal file
14
test/th-dlls/src/Lib.hs
Normal file
@ -0,0 +1,14 @@
|
||||
{-# LANGUAGE TemplateHaskell #-}
|
||||
module Lib where
|
||||
|
||||
import Control.Monad.IO.Class (liftIO)
|
||||
import OpenSSL (withOpenSSL)
|
||||
import OpenSSL.BN (withBN)
|
||||
import Libsodium (sodium_init)
|
||||
import Language.Haskell.TH.Syntax (Exp(..), Lit(..))
|
||||
import Data.Text as T
|
||||
import Data.Double.Conversion.Text (toShortest)
|
||||
|
||||
x = $(liftIO (withOpenSSL (withBN 0 (\_ -> return (LitE (IntegerL 0))))))
|
||||
y = $(liftIO (sodium_init >> return (LitE (IntegerL 0))))
|
||||
z = $(liftIO (return (LitE (IntegerL (fromIntegral (T.length (toShortest 1.0)))))))
|
18
test/th-dlls/th-dlls.cabal
Normal file
18
test/th-dlls/th-dlls.cabal
Normal file
@ -0,0 +1,18 @@
|
||||
cabal-version: >=1.10
|
||||
name: th-dlls
|
||||
version: 0.1.0.0
|
||||
license: PublicDomain
|
||||
author: Hamish Mackenzie
|
||||
maintainer: Hamish.K.Mackenzie@gmail.com
|
||||
build-type: Simple
|
||||
|
||||
library
|
||||
build-depends: base
|
||||
, HsOpenSSL
|
||||
, libsodium
|
||||
, template-haskell
|
||||
, text
|
||||
, double-conversion
|
||||
exposed-modules: Lib
|
||||
hs-source-dirs: src
|
||||
default-language: Haskell2010
|
Loading…
Reference in New Issue
Block a user