Skip to content

Commit f104621

Browse files
Add support for WASM backend (#2351)
* Use libffi-wasm when building for wasi32 * Update dummy-ghc code * Bump nixpkgs pins * Use haskell-wasm versions llvm and wasilibc * Unpin nodejs * Fix wine * Fix wine * Update overlays/wine.nix Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * nix flake update iserv-proxy * Fix broken symlink issue * Use lazy-inputs to load libffi-wasm * Add wasi os to host-map * Disable broken tests * Update supported-languages.nix * Bump head.hackage * Update llvm patch for 20.1.5 * Update llvm patch for 20.1.5 * Fix clang and llvm version used for libffi-wasm * Only build wasm for GHC >=9.12 * Fix missing libiconv on darwin * Use libiconvReal to fix darwin wasm GHC build * Try targetPackages.libiconv * targetIconv * Fix for GHC HEAD * Bump head.hackage * Use ghc HEAD to build ghc HEAD cross compilers * Try building wasm cross without libiconv dependency * Update head.hackage * Disable library-for-ghci for wasm * Disable static for wasm * Fix missing ffi.h * Fix `cabal-simple` test * Enable shared libs for wasm * Remove splitmix SRP (upstream is fixed) * Fix wasm and ghcjs TH code * nix flake update nixpkgs-unstable * nix flake update nixpkgs-2505 * Fix postPatch * Fix NIX_MAIN_PROGRAM issue * Use lto patch for node for wasm backend * Add default to "synopsis" * Update head.hackage * Add upper bound on iserv-proxy:network See haskell/network#604 * Disable node lto to check what fails * Bump head.hackage * Bump head.hackage * nix flake update iserv-proxy * Bump head.hackage * Fixes for wasm TH * Fix missing `__wasm_apply_data_relocs` issue * Skip some broken tests * Fix supported languages * Fix for wasm and GHC >9.12 * Skip broken tests * Fix more tests * Fix GHC 9.12 wasm * Fix typo * Remove iserv-proxy-interpreter from wasm roots * Disable -threaded on wasm * Fix test * Fix test * Patches for back porting fixes to 9.12 * Remove node-lto overlay * Bump head.hackage * Bump wasi-libc * Set BUILTINS_LIB * Fix cross platfrom plan evaluation * Bump head.hackage * cd nix-tools && nix flake update haskellNix * Set `evalSystem` to linux for nix-tools hydra jobs * Avoid non current system platform in the recursive nix * Use the hadrian eval packages for libffi-wasm eval too * s/hadrianEvalPackages/toolEvalPackages and add comments * Revert "s/hadrianEvalPackages/toolEvalPackages and add comments" This reverts commit 220155e. * Bump head.hackage * s/hadrianEvalPackages/ghcEvalPackages --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent d41e23c commit f104621

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+10024
-144
lines changed

builder/comp-builder.nix

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
, hardeningDisable ? component.hardeningDisable
4242

4343
, enableStatic ? component.enableStatic
44-
, enableShared ? ghc.enableShared && component.enableShared && !haskellLib.isCrossHost
44+
, enableShared ? ghc.enableShared && component.enableShared && (!haskellLib.isCrossHost || stdenv.hostPlatform.isWasm)
4545
, enableExecutableDynamic ? component.enableExecutableDynamic && !stdenv.hostPlatform.isMusl
4646
, enableDeadCodeElimination ? component.enableDeadCodeElimination
4747
, writeHieFiles ? component.writeHieFiles
@@ -284,7 +284,7 @@ let
284284
# lld -r --whole-archive ... will _not_ drop lazy symbols. However the
285285
# --whole-archive flag needs to come _before_ the objects, it's applied in
286286
# sequence. The proper fix is thusly to add --while-archive to Cabal.
287-
(enableFeature (enableLibraryForGhci && !stdenv.hostPlatform.isGhcjs && !stdenv.hostPlatform.isAndroid) "library-for-ghci")
287+
(enableFeature (enableLibraryForGhci && !stdenv.hostPlatform.isGhcjs && !stdenv.hostPlatform.isWasm && !stdenv.hostPlatform.isAndroid) "library-for-ghci")
288288
] ++ lib.optionals (stdenv.hostPlatform.isMusl && (haskellLib.isExecutableType componentId)) [
289289
# These flags will make sure the resulting executable is statically linked.
290290
# If it uses other libraries it may be necessary for to add more
@@ -348,8 +348,11 @@ let
348348
if builtins.isFunction shellHook then shellHook { inherit package shellWrappers; }
349349
else abort "shellHook should be a string or a function";
350350

351-
exeExt = if stdenv.hostPlatform.isGhcjs && builtins.compareVersions defaults.ghc.version "9.8" < 0
352-
then ".jsexe/all.js"
351+
exeExt =
352+
if stdenv.hostPlatform.isWasm
353+
then ".wasm"
354+
else if stdenv.hostPlatform.isGhcjs && builtins.compareVersions defaults.ghc.version "9.8" < 0
355+
then ".jsexe/all.js"
353356
else stdenv.hostPlatform.extensions.executable;
354357
exeName = componentId.cname + exeExt;
355358
testExecutable = "dist/build/${componentId.cname}/${exeName}";

builder/ghc-for-component-wrapper.nix

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,12 @@ let
132132
ln -s $wrappedGhc/bin/${ghcCommand}-iserv $wrappedGhc/bin/ghc-iserv
133133
ln -s $wrappedGhc/bin/${ghcCommand}-iserv-prof $wrappedGhc/bin/ghc-iserv-prof
134134
''
135+
# These scripts break if symlinked (they check import.meta.filename against args)
136+
# Also for some reason `libdl.so` is missing `__wasm_apply_data_relocs`
137+
+ lib.optionalString (stdenv.hostPlatform.isWasm) ''
138+
rm $wrappedGhc/lib/*.mjs
139+
cp $unwrappedGhc/lib/*.mjs $wrappedGhc/lib/
140+
''
135141
# Wrap haddock, if the base GHC provides it.
136142
+ ''
137143
if [[ -x "${haddock}/bin/haddock" ]]; then

ci.nix

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@
8989
&& (__match ".*llvm" compiler-nix-name == null)
9090
&& !builtins.elem compiler-nix-name ["ghc9102"]) {
9191
inherit (lib.systems.examples) ghcjs;
92+
} // lib.optionalAttrs (nixpkgsName == "unstable"
93+
&& (__match ".*llvm" compiler-nix-name == null)
94+
&& !builtins.elem compiler-nix-name ["ghc967" "ghc984" "ghc9102"]) {
95+
inherit (lib.systems.examples) wasi32;
9296
} // lib.optionalAttrs (nixpkgsName == "unstable"
9397
&& (__match ".*llvm" compiler-nix-name == null)
9498
&& ((system == "x86_64-linux" && !builtins.elem compiler-nix-name ["ghc902" "ghc928"])
@@ -151,7 +155,7 @@ dimension "Nixpkgs version" nixpkgsVersions (nixpkgsName: pinnedNixpkgsSrc:
151155
build = import ./build.nix { inherit pkgs evalPackages ifdLevel compiler-nix-name haskellNix; };
152156
in pkgs.recurseIntoAttrs (pkgs.lib.optionalAttrs (ifdLevel >= 1) ({
153157
roots = pkgs.haskell-nix.roots' { inherit compiler-nix-name evalPackages; } ifdLevel // {
154-
ghc = pkgs.buildPackages.haskell-nix.compiler.${compiler-nix-name}.override { hadrianEvalPackages = evalPackages; };
158+
ghc = pkgs.buildPackages.haskell-nix.compiler.${compiler-nix-name}.override { ghcEvalPackages = evalPackages; };
155159
};
156160
# TODO: look into cross compiling ghc itself
157161
# ghc = pkgs.haskell-nix.compiler.${compiler-nix-name};
@@ -161,7 +165,7 @@ dimension "Nixpkgs version" nixpkgsVersions (nixpkgsName: pinnedNixpkgsSrc:
161165
inherit (build) tests;
162166
})
163167
# GHCJS builds its own template haskell runner.
164-
// pkgs.lib.optionalAttrs (ifdLevel >= 2 && crossSystemName != "ghcjs")
168+
// pkgs.lib.optionalAttrs (ifdLevel >= 2 && !builtins.elem crossSystemName ["ghcjs" "wasi32"])
165169
pkgs.haskell-nix.iserv-proxy-exes.${compiler-nix-name}
166170
// pkgs.lib.optionalAttrs (ifdLevel >= 3) {
167171
hello = (pkgs.haskell-nix.hackage-package { name = "hello"; version = "1.0.0.2"; inherit evalPackages compiler-nix-name; }).getComponent "exe:hello";

compiler/ghc/default.nix

Lines changed: 127 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ let self =
2121
libffi ? null
2222

2323
, # we don't need LLVM for x86, aarch64, or ghcjs
24-
useLLVM ? with stdenv.targetPlatform; !(isx86 || isAarch64 || isGhcjs)
24+
useLLVM ? with stdenv.targetPlatform; !(isx86 || isAarch64 || isGhcjs || isWasm)
2525
, # LLVM is conceptually a run-time-only dependency, but for
2626
# non-x86, we need LLVM to bootstrap later stages, so it becomes a
2727
# build-time dependency too.
@@ -39,7 +39,7 @@ let self =
3939

4040
, # Whether to build dynamic libs for the standard library (on the target
4141
# platform). Static libs are always built.
42-
enableShared ? !haskell-nix.haskellLib.isCrossTarget && !stdenv.targetPlatform.isStatic
42+
enableShared ? !haskell-nix.haskellLib.isCrossTarget && !stdenv.targetPlatform.isStatic || stdenv.targetPlatform.isWasm
4343

4444
, enableLibraryProfiling ? true
4545

@@ -86,7 +86,16 @@ let self =
8686
# extra values we want to have available as passthru values.
8787
, extra-passthru ? {}
8888

89-
, hadrianEvalPackages ? buildPackages
89+
# For running IFDs (used to evaluate build plans of tools involved in building GHC).
90+
#
91+
# Currently used for:
92+
# * hadrian
93+
# * libffi-wasm
94+
# * cabal (if we start using `cabal` to build GHC)
95+
#
96+
# We use this instead of `buildPackages` so that plan evaluation
97+
# can work on platforms other than the `buildPlatform`.
98+
, ghcEvalPackages ? buildPackages
9099
}@args:
91100

92101
assert !(enableIntegerSimple || enableNativeBignum) -> gmp != null;
@@ -104,7 +113,7 @@ let
104113
inherit (haskell-nix.haskellLib) isCrossTarget;
105114

106115
ghc = if bootPkgs.ghc.isHaskellNixCompiler or false
107-
then bootPkgs.ghc.override { inherit hadrianEvalPackages; }
116+
then bootPkgs.ghc.override { inherit ghcEvalPackages; }
108117
else bootPkgs.ghc;
109118

110119
ghcHasNativeBignum = builtins.compareVersions ghc-version "9.0" >= 0;
@@ -119,14 +128,52 @@ let
119128
INTEGER_LIBRARY = ${if enableIntegerSimple then "integer-simple" else "integer-gmp"}
120129
'';
121130

131+
nodejs = buildPackages.nodejs_24;
132+
133+
libffi-wasm = buildPackages.runCommand "libffi-wasm" {
134+
nativeBuildInputs = [
135+
(buildPackages.haskell-nix.tool "ghc912" "libffi-wasm" {
136+
src = buildPackages.haskell-nix.sources.libffi-wasm;
137+
evalPackages = ghcEvalPackages;
138+
})
139+
targetPackages.buildPackages.llvmPackages.clang
140+
targetPackages.buildPackages.llvmPackages.llvm
141+
targetPackages.buildPackages.binaryen
142+
];
143+
outputs = ["out" "dev"];
144+
NIX_NO_SELF_RPATH = true;
145+
} ''
146+
mkdir cbits
147+
cp ${buildPackages.haskell-nix.sources.libffi-wasm}/cbits/* cbits/
148+
libffi-wasm
149+
wasm32-unknown-wasi-clang -Wall -Wextra -mcpu=mvp -Oz -DNDEBUG -Icbits -c cbits/ffi.c -o cbits/ffi.o
150+
wasm32-unknown-wasi-clang -Wall -Wextra -mcpu=mvp -Oz -DNDEBUG -Icbits -c cbits/ffi_call.c -o cbits/ffi_call.o
151+
wasm32-unknown-wasi-clang -Wall -Wextra -mcpu=mvp -Oz -DNDEBUG -Icbits -c cbits/ffi_closure.c -o cbits/ffi_closure.o
152+
153+
mkdir -p $dev/include
154+
cp cbits/*.h $dev/include
155+
mkdir -p $out/lib
156+
llvm-ar -r $out/lib/libffi.a cbits/*.o
157+
158+
wasm32-unknown-wasi-clang -Wall -Wextra -mcpu=mvp -Oz -DNDEBUG -Icbits -fPIC -fvisibility=default -shared -Wl,--keep-section=target_features,--strip-debug cbits/*.c -o libffi.so
159+
wasm-opt --low-memory-unused --converge --debuginfo --flatten --rereloop --gufa -O4 -Oz libffi.so -o $out/lib/libffi.so
160+
'';
161+
162+
lib-wasm = buildPackages.symlinkJoin {
163+
name = "lib-wasm";
164+
paths = [ targetPackages.wasilibc libffi-wasm ];
165+
};
166+
122167
# TODO check if this possible fix for segfaults works or not.
123168
targetLibffi =
124169
# on native platforms targetPlatform.{libffi, gmp} do not exist; thus fall back
125170
# to the non-targetPlatform version in those cases.
126171
let targetLibffi = targetPackages.libffi or libffi; in
127172
# we need to set `dontDisableStatic` for musl for libffi to work.
128173
if stdenv.targetPlatform.isMusl
129-
then targetLibffi.overrideAttrs (_old: { dontDisableStatic = true; })
174+
then targetLibffi.overrideAttrs (_old: { dontDisableStatic = true; })
175+
else if stdenv.targetPlatform.isWasm
176+
then libffi-wasm
130177
else targetLibffi;
131178

132179
targetGmp = targetPackages.gmp or gmp;
@@ -197,14 +244,16 @@ let
197244
# `--with` flags for libraries needed for RTS linker
198245
configureFlags = [
199246
"--datadir=$doc/share/doc/ghc"
200-
] ++ lib.optionals (!targetPlatform.isGhcjs && !targetPlatform.isAndroid) ["--with-curses-includes=${targetPackages.ncurses.dev}/include" "--with-curses-libraries=${targetPackages.ncurses.out}/lib"
201-
] ++ lib.optionals (targetLibffi != null && !targetPlatform.isGhcjs) ["--with-system-libffi" "--with-ffi-includes=${targetLibffi.dev}/include" "--with-ffi-libraries=${targetLibffi.out}/lib"
202-
] ++ lib.optionals (!enableIntegerSimple && !targetPlatform.isGhcjs) [
203-
"--with-gmp-includes=${targetGmp.dev}/include" "--with-gmp-libraries=${targetGmp.out}/lib"
247+
] ++ lib.optionals (!targetPlatform.isGhcjs && !targetPlatform.isWasm && !targetPlatform.isAndroid) ["--with-curses-includes=${lib.getDev targetPackages.ncurses}/include" "--with-curses-libraries=${lib.getLib targetPackages.ncurses}/lib"
248+
] ++ lib.optionals (targetLibffi != null && !targetPlatform.isGhcjs && !targetPlatform.isWasm) ["--with-system-libffi" "--with-ffi-includes=${lib.getDev targetLibffi}/include" "--with-ffi-libraries=${lib.getLib targetLibffi}/lib"
249+
] ++ lib.optionals (targetPlatform.isWasm) [
250+
"--with-system-libffi"
251+
] ++ lib.optionals (!enableIntegerSimple && !targetPlatform.isGhcjs && !targetPlatform.isWasm) [
252+
"--with-gmp-includes=${lib.getDev targetGmp}/include" "--with-gmp-libraries=${lib.getLib targetGmp}/lib"
204253
] ++ lib.optionals (targetPlatform == hostPlatform && hostPlatform.libc != "glibc" && !targetPlatform.isWindows) [
205-
"--with-iconv-includes=${libiconv}/include" "--with-iconv-libraries=${libiconv}/lib"
206-
] ++ lib.optionals (targetPlatform != hostPlatform && !targetPlatform.isGhcjs) [
207-
"--with-iconv-includes=${targetIconv}/include" "--with-iconv-libraries=${targetIconv}/lib"
254+
"--with-iconv-includes=${lib.getDev libiconv}/include" "--with-iconv-libraries=${lib.getLib libiconv}/lib"
255+
] ++ lib.optionals (targetPlatform != hostPlatform && !targetPlatform.isGhcjs && !targetPlatform.isWasm) [
256+
"--with-iconv-includes=${lib.getDev targetIconv}/include" "--with-iconv-libraries=${lib.getLib targetIconv}/lib"
208257
] ++ lib.optionals (targetPlatform != hostPlatform) [
209258
"--enable-bootstrap-with-devel-snapshot"
210259
] ++ lib.optionals (disableLargeAddressSpace) [
@@ -236,10 +285,10 @@ let
236285
;
237286

238287
# Splicer will pull out correct variations
239-
libDeps = platform: lib.optional (enableTerminfo && !targetPlatform.isGhcjs && !targetPlatform.isAndroid) [ targetPackages.ncurses targetPackages.ncurses.dev ]
288+
libDeps = platform: lib.optionals (enableTerminfo && !targetPlatform.isGhcjs && !targetPlatform.isWasm && !targetPlatform.isAndroid) [ (lib.getLib targetPackages.ncurses) (lib.getDev targetPackages.ncurses) ]
240289
++ lib.optional (!targetPlatform.isGhcjs) targetLibffi
241-
++ lib.optional (!enableIntegerSimple && !targetPlatform.isGhcjs) gmp
242-
++ lib.optional (platform.libc != "glibc" && !targetPlatform.isWindows) libiconv
290+
++ lib.optional (!enableIntegerSimple && !targetPlatform.isGhcjs && !targetPlatform.isWasm) gmp
291+
++ lib.optional (platform.libc != "glibc" && !targetPlatform.isWindows && !targetPlatform.isWasm) libiconv
243292
++ lib.optional (enableNUMA && platform.isLinux && !platform.isAarch32 && !platform.isAndroid) numactl
244293
++ lib.optional enableDWARF (lib.getLib elfutils);
245294

@@ -276,7 +325,7 @@ let
276325
inherit compiler-nix-name;
277326
name = "hadrian";
278327
compilerSelection = p: p.haskell.compiler;
279-
evalPackages = hadrianEvalPackages;
328+
evalPackages = ghcEvalPackages;
280329
modules = [{
281330
reinstallableLibGhc = false;
282331
# Apply the patches in a way that does not require using something
@@ -327,12 +376,12 @@ let
327376
# For build flavours and flavour transformers
328377
# see https://gitlab.haskell.org/ghc/ghc/blob/master/hadrian/doc/flavours.md
329378
hadrianArgs = "--flavour=${
330-
(if targetPlatform.isGhcjs then "quick" else "default")
379+
(if targetPlatform.isGhcjs || targetPlatform.isWasm then "quick" else "default")
331380
+ lib.optionalString (!enableShared) "+no_dynamic_libs+no_dynamic_ghc"
332381
+ lib.optionalString useLLVM "+llvm"
333382
+ lib.optionalString enableDWARF "+debug_info"
334-
+ lib.optionalString ((enableNativeBignum && hadrianHasNativeBignumFlavour) || targetPlatform.isGhcjs) "+native_bignum"
335-
+ lib.optionalString targetPlatform.isGhcjs "+no_profiled_libs"
383+
+ lib.optionalString ((enableNativeBignum && hadrianHasNativeBignumFlavour) || targetPlatform.isGhcjs || targetPlatform.isWasm) "+native_bignum"
384+
+ lib.optionalString (targetPlatform.isGhcjs || targetPlatform.isWasm) "+no_profiled_libs"
336385
} --docs=no-sphinx -j --verbose"
337386
# This is needed to prevent $GCC from emitting out of line atomics.
338387
# Those would then result in __aarch64_ldadd1_sync and others being referenced, which
@@ -344,8 +393,12 @@ let
344393
+ lib.optionalString (!hostPlatform.isAarch64 && targetPlatform.isLinux && targetPlatform.isAarch64)
345394
" '*.rts.ghc.c.opts += -optc-mno-outline-atomics'"
346395
# PIC breaks GHC annotations on windows (see test/annotations for a test case)
347-
+ lib.optionalString (enableRelocatedStaticLibs && !targetPlatform.isWindows)
396+
+ lib.optionalString (enableRelocatedStaticLibs && !targetPlatform.isWindows && !targetPlatform.isWasm)
348397
" '*.*.ghc.*.opts += -fPIC' '*.*.cc.*.opts += -fPIC'"
398+
# C options for wasm
399+
+ lib.optionalString targetPlatform.isWasm (
400+
" 'stage1.*.ghc.*.opts += -optc-Wno-error=int-conversion -optc-O3 -optc-mcpu=lime1 -optc-mreference-types -optc-msimd128 -optc-mtail-call -optc-DXXH_NO_XXH3'"
401+
+ " 'stage1.*.ghc.cpp.opts += -optc-fno-exceptions'")
349402
# `-fexternal-dynamic-refs` causes `undefined reference` errors when building GHC cross compiler for windows
350403
+ lib.optionalString (enableRelocatedStaticLibs && targetPlatform.isx86_64 && !targetPlatform.isWindows)
351404
" '*.*.ghc.*.opts += -fexternal-dynamic-refs'"
@@ -450,9 +503,28 @@ haskell-nix.haskellLib.makeCompilerDeps (stdenv.mkDerivation (rec {
450503
fi
451504
mv config.sub.ghcjs config.sub
452505
'')
506+
+ lib.optionalString (targetPlatform.isWasm) ''
507+
export CC="${targetCC}/bin/${targetCC.targetPrefix}cc"
508+
export CXX="${targetCC}/bin/${targetCC.targetPrefix}c++"
509+
export LD="${buildPackages.llvmPackages.lld}/bin/wasm-ld"
510+
export AS="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}as"
511+
export AR="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}ar"
512+
export NM="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}nm"
513+
export RANLIB="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}ranlib"
514+
export READELF="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}readelf"
515+
export STRIP="${bintoolsFor.strip}/bin/${bintoolsFor.strip.targetPrefix}strip"
516+
export NIX_CFLAGS_COMPILE_FOR_BUILD+=" -I${lib.getDev libffi}/include -L${lib.getLib libffi}/lib"
517+
export NIX_CFLAGS_COMPILE_FOR_TARGET+=" -I${lib.getDev targetLibffi}/include -L${lib.getLib targetLibffi}/lib"
518+
${if ghc-version == "9.12.2"
519+
then ''
520+
substituteInPlace compiler/GHC.hs --replace-fail "panic \"corrupted wasi-sdk installation\"" "pure \"${targetPackages.wasilibc}\""
521+
'' else ''
522+
substituteInPlace compiler/GHC.hs --replace-fail "last <\$> Loader.getGccSearchDirectory logger dflags \"libraries\"" "pure \"${targetPackages.wasilibc}\""
523+
''}
524+
''
453525
# GHC is a bit confused on its cross terminology, as these would normally be
454526
# the *host* tools.
455-
+ lib.optionalString (!targetPlatform.isGhcjs) (''
527+
+ lib.optionalString (!targetPlatform.isGhcjs && !targetPlatform.isWasm) (''
456528
export CC="${targetCC}/bin/${targetCC.targetPrefix}cc"
457529
export CXX="${targetCC}/bin/${targetCC.targetPrefix}c++"
458530
''
@@ -534,7 +606,34 @@ haskell-nix.haskellLib.makeCompilerDeps (stdenv.mkDerivation (rec {
534606
configurePlatforms = [ "build" "host" ] ++ lib.optional (!targetPlatform.isGhcjs) "target";
535607

536608
enableParallelBuilding = true;
537-
postPatch = "patchShebangs .";
609+
postPatch = ''
610+
patchShebangs .
611+
'' + lib.optionalString (targetPlatform.isWasm) ''
612+
substituteInPlace utils/jsffi/dyld.mjs \
613+
--replace \
614+
"${nodejs}/bin/node --disable-warning=ExperimentalWarning ${
615+
if builtins.compareVersions ghc-version "9.13" < 0
616+
then "--experimental-wasm-type-reflection"
617+
else "--max-old-space-size=65536"} --no-turbo-fast-api-calls --wasm-lazy-validation" \
618+
"${buildPackages.writeShellScriptBin "node" ''
619+
SCRIPT=$1
620+
shift
621+
LIB_WASM=$1
622+
shift
623+
exec ${nodejs}/bin/node \
624+
--disable-warning=ExperimentalWarning \
625+
${
626+
if builtins.compareVersions ghc-version "9.13" < 0
627+
then "--experimental-wasm-type-reflection"
628+
else "--max-old-space-size=65536"} \
629+
--no-turbo-fast-api-calls \
630+
--wasm-lazy-validation \
631+
"$SCRIPT" \
632+
"${lib-wasm}/lib" \
633+
"$@"
634+
''
635+
}/bin/node"
636+
'';
538637

539638
outputs = [ "out" "doc" "generated" ];
540639

@@ -548,15 +647,18 @@ haskell-nix.haskellLib.makeCompilerDeps (stdenv.mkDerivation (rec {
548647
perl autoconf automake m4 python3 sphinx
549648
ghc bootPkgs.alex bootPkgs.happy bootPkgs.hscolour
550649
] ++ lib.optional (patches != []) autoreconfHook
551-
++ lib.optional useLdLld llvmPackages.bintools;
650+
++ lib.optional useLdLld llvmPackages.bintools
651+
++ lib.optional (targetPlatform.isWasm) nodejs;
552652

553653
# For building runtime libs
554654
depsBuildTarget = toolsForTarget;
555655

556656
buildInputs = [ perl bash ] ++ (libDeps hostPlatform);
557657

558658
depsTargetTarget = lib.optionals (!targetPlatform.isGhcjs) (map lib.getDev (libDeps targetPlatform));
559-
depsTargetTargetPropagated = lib.optionals (!targetPlatform.isGhcjs) (map (lib.getOutput "out") (libDeps targetPlatform));
659+
depsTargetTargetPropagated = lib.optionals (!targetPlatform.isGhcjs) (map (lib.getOutput "out") (libDeps targetPlatform))
660+
# Needs to be propagated for `ffi.h`
661+
++ lib.optional targetPlatform.isWasm (lib.getDev targetLibffi);
560662

561663
# required, because otherwise all symbols from HSffi.o are stripped, and
562664
# that in turn causes GHCi to abort
@@ -794,7 +896,7 @@ haskell-nix.haskellLib.makeCompilerDeps (stdenv.mkDerivation (rec {
794896
disableLargeAddressSpace = true;
795897
});
796898
} // extra-passthru // {
797-
buildGHC = extra-passthru.buildGHC.override { inherit hadrianEvalPackages; };
899+
buildGHC = extra-passthru.buildGHC.override { inherit ghcEvalPackages; };
798900
};
799901

800902
meta = {

0 commit comments

Comments
 (0)