Skip to content

Commit

Permalink
Make DLLs in deps available to wine TH runner
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
hamishmack committed Mar 17, 2022
1 parent f3f2c08 commit 00b2b69
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 15 deletions.
32 changes: 20 additions & 12 deletions builder/comp-builder.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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.
#
Expand Down
28 changes: 26 additions & 2 deletions overlays/mingw_w64.nix
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,19 @@ 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 ${remote-iserv}/bin/* $REMOTE_ISERV
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
(
cd $REMOTE_ISERV
for l in lib*.dll; do
if [[ ! -e "''${l#lib}" ]]; then ln -s "$l" "''${l#lib}"; fi
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"
Expand All @@ -46,7 +58,19 @@ 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.override { enableProfiling = true; }}/bin/remote-iserv.exe tmp $PORT &
REMOTE_ISERV=$(mktemp -d)
ln -s ${remote-iserv.override { enableProfiling = true; }}/bin/* $REMOTE_ISERV
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
(
cd $REMOTE_ISERV
for l in lib*.dll; do
if [[ ! -e "''${l#lib}" ]]; then ln -s "$l" "''${l#lib}"; fi
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"
Expand Down
2 changes: 1 addition & 1 deletion overlays/windows.nix
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ 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/ \;
Expand Down
1 change: 1 addition & 0 deletions test/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand Down
30 changes: 30 additions & 0 deletions test/th-dlls/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Test a package set
{ stdenv, lib, util, mkCabalProjectPkgSet, project', haskellLib, recurseIntoAttrs, testSrc, compiler-nix-name }:

with lib;

let
modules = [
{
# Package has no exposed modules which causes
# haddock: No input file(s)
packages.cabal-simple.doHaddock = false;
}
];

project = project' {
inherit compiler-nix-name;
src = testSrc "th-dlls";
inherit modules;
};

packages = project.hsPkgs;

in recurseIntoAttrs {
ifdInputs = {
inherit (project) plan-nix;
};

build = packages.th-dlls.components.library;
build-profiled = packages.th-dlls.components.library.profiled;
}
11 changes: 11 additions & 0 deletions test/th-dlls/src/Lib.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{-# 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(..))

x = $(liftIO (withOpenSSL (withBN 0 (\_ -> return (LitE (IntegerL 0))))))
y = $(liftIO (sodium_init >> return (LitE (IntegerL 0))))
16 changes: 16 additions & 0 deletions test/th-dlls/th-dlls.cabal
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
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
exposed-modules: Lib
hs-source-dirs: src
default-language: Haskell2010

0 comments on commit 00b2b69

Please sign in to comment.