diff --git a/builder/comp-builder.nix b/builder/comp-builder.nix index 9cd2b9f90d..ef67241ba4 100644 --- a/builder/comp-builder.nix +++ b/builder/comp-builder.nix @@ -41,7 +41,7 @@ , hardeningDisable ? component.hardeningDisable , enableStatic ? component.enableStatic -, enableShared ? ghc.enableShared && component.enableShared && !haskellLib.isCrossHost +, enableShared ? ghc.enableShared && component.enableShared && (!haskellLib.isCrossHost || stdenv.hostPlatform.isWasm) , enableExecutableDynamic ? component.enableExecutableDynamic && !stdenv.hostPlatform.isMusl , enableDeadCodeElimination ? component.enableDeadCodeElimination , writeHieFiles ? component.writeHieFiles @@ -284,7 +284,7 @@ let # lld -r --whole-archive ... will _not_ drop lazy symbols. However the # --whole-archive flag needs to come _before_ the objects, it's applied in # sequence. The proper fix is thusly to add --while-archive to Cabal. - (enableFeature (enableLibraryForGhci && !stdenv.hostPlatform.isGhcjs && !stdenv.hostPlatform.isAndroid) "library-for-ghci") + (enableFeature (enableLibraryForGhci && !stdenv.hostPlatform.isGhcjs && !stdenv.hostPlatform.isWasm && !stdenv.hostPlatform.isAndroid) "library-for-ghci") ] ++ lib.optionals (stdenv.hostPlatform.isMusl && (haskellLib.isExecutableType componentId)) [ # These flags will make sure the resulting executable is statically linked. # If it uses other libraries it may be necessary for to add more @@ -348,8 +348,11 @@ let if builtins.isFunction shellHook then shellHook { inherit package shellWrappers; } else abort "shellHook should be a string or a function"; - exeExt = if stdenv.hostPlatform.isGhcjs && builtins.compareVersions defaults.ghc.version "9.8" < 0 - then ".jsexe/all.js" + exeExt = + if stdenv.hostPlatform.isWasm + then ".wasm" + else if stdenv.hostPlatform.isGhcjs && builtins.compareVersions defaults.ghc.version "9.8" < 0 + then ".jsexe/all.js" else stdenv.hostPlatform.extensions.executable; exeName = componentId.cname + exeExt; testExecutable = "dist/build/${componentId.cname}/${exeName}"; diff --git a/ci.nix b/ci.nix index 0dae1a25ac..87f875dfc9 100644 --- a/ci.nix +++ b/ci.nix @@ -89,6 +89,10 @@ && (__match ".*llvm" compiler-nix-name == null) && !builtins.elem compiler-nix-name ["ghc9102"]) { inherit (lib.systems.examples) ghcjs; + } // lib.optionalAttrs (nixpkgsName == "unstable" + && (__match ".*llvm" compiler-nix-name == null) + && !builtins.elem compiler-nix-name ["ghc967" "ghc984" "ghc9102"]) { + inherit (lib.systems.examples) wasi32; } // lib.optionalAttrs (nixpkgsName == "unstable" && (__match ".*llvm" compiler-nix-name == null) && ((system == "x86_64-linux" && !builtins.elem compiler-nix-name ["ghc902" "ghc928"]) diff --git a/compiler/ghc/default.nix b/compiler/ghc/default.nix index 3a22a8d6db..5cad20dd32 100644 --- a/compiler/ghc/default.nix +++ b/compiler/ghc/default.nix @@ -21,7 +21,7 @@ let self = libffi ? null , # we don't need LLVM for x86, aarch64, or ghcjs - useLLVM ? with stdenv.targetPlatform; !(isx86 || isAarch64 || isGhcjs) + useLLVM ? with stdenv.targetPlatform; !(isx86 || isAarch64 || isGhcjs || isWasm) , # LLVM is conceptually a run-time-only dependency, but for # non-x86, we need LLVM to bootstrap later stages, so it becomes a # build-time dependency too. @@ -39,7 +39,7 @@ let self = , # Whether to build dynamic libs for the standard library (on the target # platform). Static libs are always built. - enableShared ? !haskell-nix.haskellLib.isCrossTarget && !stdenv.targetPlatform.isStatic + enableShared ? !haskell-nix.haskellLib.isCrossTarget && !stdenv.targetPlatform.isStatic || stdenv.targetPlatform.isWasm , enableLibraryProfiling ? true @@ -119,6 +119,34 @@ let INTEGER_LIBRARY = ${if enableIntegerSimple then "integer-simple" else "integer-gmp"} ''; + libffi-wasm = buildPackages.runCommand "libffi-wasm" { + nativeBuildInputs = [ + (buildPackages.haskell-nix.tool "ghc912" "libffi-wasm" { + src = buildPackages.haskell-nix.sources.libffi-wasm; + }) + targetPackages.buildPackages.llvmPackages.clang + targetPackages.buildPackages.llvmPackages.llvm + targetPackages.buildPackages.binaryen + ]; + outputs = ["dev" "out"]; + NIX_NO_SELF_RPATH = true; + } '' + mkdir cbits + cp ${buildPackages.haskell-nix.sources.libffi-wasm}/cbits/* cbits/ + libffi-wasm + wasm32-unknown-wasi-clang -Wall -Wextra -mcpu=mvp -Oz -DNDEBUG -Icbits -c cbits/ffi.c -o cbits/ffi.o + wasm32-unknown-wasi-clang -Wall -Wextra -mcpu=mvp -Oz -DNDEBUG -Icbits -c cbits/ffi_call.c -o cbits/ffi_call.o + wasm32-unknown-wasi-clang -Wall -Wextra -mcpu=mvp -Oz -DNDEBUG -Icbits -c cbits/ffi_closure.c -o cbits/ffi_closure.o + + mkdir -p $dev/include + cp cbits/*.h $dev/include + mkdir -p $out/lib + llvm-ar -r $out/lib/libffi.a cbits/*.o + + 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 + wasm-opt --low-memory-unused --converge --debuginfo --flatten --rereloop --gufa -O4 -Oz libffi.so -o $out/lib/libffi.so + ''; + # TODO check if this possible fix for segfaults works or not. targetLibffi = # on native platforms targetPlatform.{libffi, gmp} do not exist; thus fall back @@ -126,7 +154,9 @@ let let targetLibffi = targetPackages.libffi or libffi; in # we need to set `dontDisableStatic` for musl for libffi to work. if stdenv.targetPlatform.isMusl - then targetLibffi.overrideAttrs (_old: { dontDisableStatic = true; }) + then targetLibffi.overrideAttrs (_old: { dontDisableStatic = true; }) + else if stdenv.targetPlatform.isWasm + then libffi-wasm else targetLibffi; targetGmp = targetPackages.gmp or gmp; @@ -197,14 +227,16 @@ let # `--with` flags for libraries needed for RTS linker configureFlags = [ "--datadir=$doc/share/doc/ghc" - ] ++ lib.optionals (!targetPlatform.isGhcjs && !targetPlatform.isAndroid) ["--with-curses-includes=${targetPackages.ncurses.dev}/include" "--with-curses-libraries=${targetPackages.ncurses.out}/lib" - ] ++ lib.optionals (targetLibffi != null && !targetPlatform.isGhcjs) ["--with-system-libffi" "--with-ffi-includes=${targetLibffi.dev}/include" "--with-ffi-libraries=${targetLibffi.out}/lib" - ] ++ lib.optionals (!enableIntegerSimple && !targetPlatform.isGhcjs) [ - "--with-gmp-includes=${targetGmp.dev}/include" "--with-gmp-libraries=${targetGmp.out}/lib" + ] ++ lib.optionals (!targetPlatform.isGhcjs && !targetPlatform.isWasm && !targetPlatform.isAndroid) ["--with-curses-includes=${lib.getDev targetPackages.ncurses}/include" "--with-curses-libraries=${lib.getLib targetPackages.ncurses}/lib" + ] ++ 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" + ] ++ lib.optionals (targetPlatform.isWasm) [ + "--with-system-libffi" + ] ++ lib.optionals (!enableIntegerSimple && !targetPlatform.isGhcjs && !targetPlatform.isWasm) [ + "--with-gmp-includes=${lib.getDev targetGmp}/include" "--with-gmp-libraries=${lib.getLib targetGmp}/lib" ] ++ lib.optionals (targetPlatform == hostPlatform && hostPlatform.libc != "glibc" && !targetPlatform.isWindows) [ - "--with-iconv-includes=${libiconv}/include" "--with-iconv-libraries=${libiconv}/lib" - ] ++ lib.optionals (targetPlatform != hostPlatform && !targetPlatform.isGhcjs) [ - "--with-iconv-includes=${targetIconv}/include" "--with-iconv-libraries=${targetIconv}/lib" + "--with-iconv-includes=${lib.getDev libiconv}/include" "--with-iconv-libraries=${lib.getLib libiconv}/lib" + ] ++ lib.optionals (targetPlatform != hostPlatform && !targetPlatform.isGhcjs && !targetPlatform.isWasm) [ + "--with-iconv-includes=${lib.getDev targetIconv}/include" "--with-iconv-libraries=${lib.getLib targetIconv}/lib" ] ++ lib.optionals (targetPlatform != hostPlatform) [ "--enable-bootstrap-with-devel-snapshot" ] ++ lib.optionals (disableLargeAddressSpace) [ @@ -236,10 +268,10 @@ let ; # Splicer will pull out correct variations - libDeps = platform: lib.optional (enableTerminfo && !targetPlatform.isGhcjs && !targetPlatform.isAndroid) [ targetPackages.ncurses targetPackages.ncurses.dev ] + libDeps = platform: lib.optionals (enableTerminfo && !targetPlatform.isGhcjs && !targetPlatform.isWasm && !targetPlatform.isAndroid) [ (lib.getLib targetPackages.ncurses) (lib.getDev targetPackages.ncurses) ] ++ lib.optional (!targetPlatform.isGhcjs) targetLibffi - ++ lib.optional (!enableIntegerSimple && !targetPlatform.isGhcjs) gmp - ++ lib.optional (platform.libc != "glibc" && !targetPlatform.isWindows) libiconv + ++ lib.optional (!enableIntegerSimple && !targetPlatform.isGhcjs && !targetPlatform.isWasm) gmp + ++ lib.optional (platform.libc != "glibc" && !targetPlatform.isWindows && !targetPlatform.isWasm) libiconv ++ lib.optional (enableNUMA && platform.isLinux && !platform.isAarch32 && !platform.isAndroid) numactl ++ lib.optional enableDWARF (lib.getLib elfutils); @@ -327,12 +359,12 @@ let # For build flavours and flavour transformers # see https://gitlab.haskell.org/ghc/ghc/blob/master/hadrian/doc/flavours.md hadrianArgs = "--flavour=${ - (if targetPlatform.isGhcjs then "quick" else "default") + (if targetPlatform.isGhcjs || targetPlatform.isWasm then "quick" else "default") + lib.optionalString (!enableShared) "+no_dynamic_libs+no_dynamic_ghc" + lib.optionalString useLLVM "+llvm" + lib.optionalString enableDWARF "+debug_info" - + lib.optionalString ((enableNativeBignum && hadrianHasNativeBignumFlavour) || targetPlatform.isGhcjs) "+native_bignum" - + lib.optionalString targetPlatform.isGhcjs "+no_profiled_libs" + + lib.optionalString ((enableNativeBignum && hadrianHasNativeBignumFlavour) || targetPlatform.isGhcjs || targetPlatform.isWasm) "+native_bignum" + + lib.optionalString (targetPlatform.isGhcjs || targetPlatform.isWasm) "+no_profiled_libs" } --docs=no-sphinx -j --verbose" # This is needed to prevent $GCC from emitting out of line atomics. # Those would then result in __aarch64_ldadd1_sync and others being referenced, which @@ -344,8 +376,12 @@ let + lib.optionalString (!hostPlatform.isAarch64 && targetPlatform.isLinux && targetPlatform.isAarch64) " '*.rts.ghc.c.opts += -optc-mno-outline-atomics'" # PIC breaks GHC annotations on windows (see test/annotations for a test case) - + lib.optionalString (enableRelocatedStaticLibs && !targetPlatform.isWindows) + + lib.optionalString (enableRelocatedStaticLibs && !targetPlatform.isWindows && !targetPlatform.isWasm) " '*.*.ghc.*.opts += -fPIC' '*.*.cc.*.opts += -fPIC'" + # C options for wasm + + lib.optionalString targetPlatform.isWasm ( + " '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'" + + " 'stage1.*.ghc.cpp.opts += -optc-fno-exceptions'") # `-fexternal-dynamic-refs` causes `undefined reference` errors when building GHC cross compiler for windows + lib.optionalString (enableRelocatedStaticLibs && targetPlatform.isx86_64 && !targetPlatform.isWindows) " '*.*.ghc.*.opts += -fexternal-dynamic-refs'" @@ -450,9 +486,28 @@ haskell-nix.haskellLib.makeCompilerDeps (stdenv.mkDerivation (rec { fi mv config.sub.ghcjs config.sub '') + + lib.optionalString (targetPlatform.isWasm) '' + export CC="${targetCC}/bin/${targetCC.targetPrefix}cc" + export CXX="${targetCC}/bin/${targetCC.targetPrefix}c++" + export LD="${buildPackages.llvmPackages.lld}/bin/wasm-ld" + export AS="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}as" + export AR="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}ar" + export NM="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}nm" + export RANLIB="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}ranlib" + export READELF="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}readelf" + export STRIP="${bintoolsFor.strip}/bin/${bintoolsFor.strip.targetPrefix}strip" + export NIX_CFLAGS_COMPILE_FOR_BUILD+=" -I${lib.getDev libffi}/include -L${lib.getLib libffi}/lib" + export NIX_CFLAGS_COMPILE_FOR_TARGET+=" -I${lib.getDev targetLibffi}/include -L${lib.getLib targetLibffi}/lib" + ${if ghc-version == "9.12.2" + then '' + substituteInPlace compiler/GHC.hs --replace-fail "panic \"corrupted wasi-sdk installation\"" "pure \"${targetPackages.wasilibc}\"" + '' else '' + substituteInPlace compiler/GHC.hs --replace-fail "last <\$> Loader.getGccSearchDirectory logger dflags \"libraries\"" "pure \"${targetPackages.wasilibc}\"" + ''} + '' # GHC is a bit confused on its cross terminology, as these would normally be # the *host* tools. - + lib.optionalString (!targetPlatform.isGhcjs) ('' + + lib.optionalString (!targetPlatform.isGhcjs && !targetPlatform.isWasm) ('' export CC="${targetCC}/bin/${targetCC.targetPrefix}cc" export CXX="${targetCC}/bin/${targetCC.targetPrefix}c++" '' @@ -534,7 +589,22 @@ haskell-nix.haskellLib.makeCompilerDeps (stdenv.mkDerivation (rec { configurePlatforms = [ "build" "host" ] ++ lib.optional (!targetPlatform.isGhcjs) "target"; enableParallelBuilding = true; - postPatch = "patchShebangs ."; + postPatch = lib.optionalString (targetPlatform.isWasm) '' + substituteInPlace utils/jsffi/dyld.mjs \ + --replace-fail \ + "node --disable-warning=ExperimentalWarning --experimental-wasm-type-reflection --no-turbo-fast-api-calls --wasm-lazy-validation" \ + "${buildPackages.writeShellScriptBin "node" '' + exec ${buildPackages.nodejs-with-lto}/bin/node \ + --disable-warning=ExperimentalWarning \ + --experimental-wasm-type-reflection \ + --no-turbo-fast-api-calls \ + --wasm-lazy-validation \ + "$@" + '' + }" + '' + '' + patchShebangs . + ''; outputs = [ "out" "doc" "generated" ]; @@ -548,7 +618,8 @@ haskell-nix.haskellLib.makeCompilerDeps (stdenv.mkDerivation (rec { perl autoconf automake m4 python3 sphinx ghc bootPkgs.alex bootPkgs.happy bootPkgs.hscolour ] ++ lib.optional (patches != []) autoreconfHook - ++ lib.optional useLdLld llvmPackages.bintools; + ++ lib.optional useLdLld llvmPackages.bintools + ++ lib.optional (targetPlatform.isWasm) buildPackages.nodejs-with-lto; # For building runtime libs depsBuildTarget = toolsForTarget; @@ -556,7 +627,9 @@ haskell-nix.haskellLib.makeCompilerDeps (stdenv.mkDerivation (rec { buildInputs = [ perl bash ] ++ (libDeps hostPlatform); depsTargetTarget = lib.optionals (!targetPlatform.isGhcjs) (map lib.getDev (libDeps targetPlatform)); - depsTargetTargetPropagated = lib.optionals (!targetPlatform.isGhcjs) (map (lib.getOutput "out") (libDeps targetPlatform)); + depsTargetTargetPropagated = lib.optionals (!targetPlatform.isGhcjs) (map (lib.getOutput "out") (libDeps targetPlatform)) + # Needs to be propagated for `ffi.h` + ++ lib.optional targetPlatform.isWasm (lib.getDev targetLibffi); # required, because otherwise all symbols from HSffi.o are stripped, and # that in turn causes GHCi to abort diff --git a/flake.lock b/flake.lock index e8b2f3df84..419b1dc4ec 100644 --- a/flake.lock +++ b/flake.lock @@ -100,23 +100,6 @@ "type": "github" } }, - "ghc-8.6.5-iohk": { - "flake": false, - "locked": { - "lastModified": 1600920045, - "narHash": "sha256-DO6kxJz248djebZLpSzTGD6s8WRpNI9BTwUeOf5RwY8=", - "owner": "input-output-hk", - "repo": "ghc", - "rev": "95713a6ecce4551240da7c96b6176f980af75cae", - "type": "github" - }, - "original": { - "owner": "input-output-hk", - "ref": "release/8.6.5-iohk", - "repo": "ghc", - "type": "github" - } - }, "hackage": { "flake": false, "locked": { @@ -405,11 +388,11 @@ "iserv-proxy": { "flake": false, "locked": { - "lastModified": 1750543273, - "narHash": "sha256-WaswH0Y+Fmupvv8AkIlQBlUy/IdD3Inx9PDuE+5iRYY=", + "lastModified": 1755243078, + "narHash": "sha256-GLbl1YaohKdpzZVJFRdcI1O1oE3F3uBer4lFv3Yy0l8=", "owner": "stable-haskell", "repo": "iserv-proxy", - "rev": "a53c57c9a8d22a66a2f0c4c969e806da03f08c28", + "rev": "150605195cb7183a6fb7bed82f23fedf37c6f52a", "type": "github" }, "original": { @@ -485,11 +468,11 @@ }, "nixpkgs-2505": { "locked": { - "lastModified": 1748852332, - "narHash": "sha256-r/wVJWmLYEqvrJKnL48r90Wn9HWX9SHFt6s4LhuTh7k=", + "lastModified": 1754477006, + "narHash": "sha256-suIgZZHXdb4ca9nN4MIcmdjeN+ZWsTwCtYAG4HExqAo=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "a8167f3cc2f991dd4d0055746df53dae5fd0c953", + "rev": "4896699973299bffae27d0d9828226983544d9e9", "type": "github" }, "original": { @@ -501,11 +484,11 @@ }, "nixpkgs-unstable": { "locked": { - "lastModified": 1748856973, - "narHash": "sha256-RlTsJUvvr8ErjPBsiwrGbbHYW8XbB/oek0Gi78XdWKg=", + "lastModified": 1754393734, + "narHash": "sha256-fbnmAwTQkuXHKBlcL5Nq1sMAzd3GFqCOQgEQw6Hy0Ak=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "e4b09e47ace7d87de083786b404bf232eb6c89d8", + "rev": "a683adc19ff5228af548c6539dbc3440509bfed3", "type": "github" }, "original": { @@ -540,7 +523,6 @@ "cabal-36": "cabal-36", "cardano-shell": "cardano-shell", "flake-compat": "flake-compat", - "ghc-8.6.5-iohk": "ghc-8.6.5-iohk", "hackage": "hackage", "hackage-for-stackage": "hackage-for-stackage", "hackage-internal": "hackage-internal", diff --git a/flake.nix b/flake.nix index 721aaf1f3a..65471a45ac 100644 --- a/flake.nix +++ b/flake.nix @@ -55,13 +55,6 @@ url = "github:input-output-hk/cardano-shell"; flake = false; }; - "ghc-8.6.5-iohk" = { - type = "github"; - owner = "input-output-hk"; - repo = "ghc"; - ref = "release/8.6.5-iohk"; - flake = false; - }; hpc-coveralls = { url = "github:sevanspowell/hpc-coveralls"; flake = false; diff --git a/lazy-inputs/default.nix b/lazy-inputs/default.nix index 9552c84685..1fe105262f 100644 --- a/lazy-inputs/default.nix +++ b/lazy-inputs/default.nix @@ -41,6 +41,7 @@ in { inherit ((callFlake { pkgs = final; src = ./ghc9122; }).defaultNix) ghc9122; inherit ((callFlake { pkgs = final; src = ./ghc912X; }).defaultNix) ghc912X; inherit ((callFlake { pkgs = final; src = ./ghc913; }).defaultNix) ghc913; + inherit ((callFlake { pkgs = final; src = ./libffi-wasm; }).defaultNix) libffi-wasm; } // prev.haskell-nix.sources; }; } diff --git a/lazy-inputs/libffi-wasm/flake.lock b/lazy-inputs/libffi-wasm/flake.lock new file mode 100644 index 0000000000..1240847b6a --- /dev/null +++ b/lazy-inputs/libffi-wasm/flake.lock @@ -0,0 +1,29 @@ +{ + "nodes": { + "libffi-wasm": { + "flake": false, + "locked": { + "host": "gitlab.haskell.org", + "lastModified": 1741286406, + "narHash": "sha256-GxC9G+LYRHwKArwXNeU9Enq7u4arvPbFfE4kQj1cHyc=", + "owner": "haskell-wasm", + "repo": "libffi-wasm", + "rev": "e2dbdd8ded953e7a4df42c192da65ab36b9f0345", + "type": "gitlab" + }, + "original": { + "host": "gitlab.haskell.org", + "owner": "haskell-wasm", + "repo": "libffi-wasm", + "type": "gitlab" + } + }, + "root": { + "inputs": { + "libffi-wasm": "libffi-wasm" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/lazy-inputs/libffi-wasm/flake.nix b/lazy-inputs/libffi-wasm/flake.nix new file mode 100644 index 0000000000..447a162aff --- /dev/null +++ b/lazy-inputs/libffi-wasm/flake.nix @@ -0,0 +1,12 @@ +{ + description = "Lazy Input for Haskell.nix"; + + inputs = { + libffi-wasm = { + flake = false; + url = "gitlab:haskell-wasm/libffi-wasm?host=gitlab.haskell.org"; + }; + }; + + outputs = inputs: inputs; +} diff --git a/lib/call-cabal-project-to-nix.nix b/lib/call-cabal-project-to-nix.nix index 42679dffc5..db30a369b4 100644 --- a/lib/call-cabal-project-to-nix.nix +++ b/lib/call-cabal-project-to-nix.nix @@ -331,6 +331,8 @@ let then "OSMinGW32" else if pkgs.stdenv.targetPlatform.isGhcjs then "OSGhcjs" + else if pkgs.stdenv.targetPlatform.isWasi + then "OSWasi" else throw "Unknown target os ${pkgs.stdenv.targetPlatform.config}" }")' echo ',("target arch","${ @@ -346,6 +348,8 @@ let then "ArchAArch32" else if pkgs.stdenv.targetPlatform.isJavaScript then "ArchJavaScript" + else if pkgs.stdenv.targetPlatform.isWasm + then "ArchWasm32" else throw "Unknown target arch ${pkgs.stdenv.targetPlatform.config}" }")' echo ',("target platform string","${platformString pkgs.stdenv.targetPlatform}")' diff --git a/lib/check.nix b/lib/check.nix index 15270975e5..bbce149fe7 100644 --- a/lib/check.nix +++ b/lib/check.nix @@ -35,7 +35,8 @@ in stdenv.mkDerivation (( dwarf = self drv.dwarf; }; - inherit (drv) meta LANG LC_ALL buildInputs; + inherit (drv) LANG LC_ALL buildInputs; + meta = builtins.removeAttrs drv.meta ["mainProgram"]; nativeBuildInputs = drv.nativeBuildInputs ++ [buildPackages.xorg.lndir] diff --git a/lib/host-map.nix b/lib/host-map.nix index b4a529f035..d91970d2ba 100644 --- a/lib/host-map.nix +++ b/lib/host-map.nix @@ -18,6 +18,7 @@ with stdenv.hostPlatform; { if isiOS then "Ios" else if isAndroid then "Android" else if isGhcjs then "Ghcjs" else + if isWasi then "Wasi" else if isAsterius then "Asterius" else throw "Unknown OS"; arch = if isx86 && is32bit then "I386" else diff --git a/modules/component-options.nix b/modules/component-options.nix index 3fbc3cf803..e931266e09 100644 --- a/modules/component-options.nix +++ b/modules/component-options.nix @@ -105,7 +105,7 @@ description = "If set, enables building static libraries and executables."; type = lib.types.bool; # Disabled for ghcjs, see https://gitlab.haskell.org/ghc/ghc/-/issues/23235 - default = !pkgs.stdenv.hostPlatform.isGhcjs; + default = !pkgs.stdenv.hostPlatform.isGhcjs && !pkgs.stdenv.hostPlatform.isWasm; }; enableShared = lib.mkOption { diff --git a/modules/install-plan/non-reinstallable.nix b/modules/install-plan/non-reinstallable.nix index 2e92bbd39f..e0077b6107 100644 --- a/modules/install-plan/non-reinstallable.nix +++ b/modules/install-plan/non-reinstallable.nix @@ -4,9 +4,9 @@ "ghc-bignum"] ++ lib.optionals (builtins.compareVersions config.compiler.version "9.9" >= 0) [ "ghc-internal"] - ++ lib.optionals (pkgs.stdenv.hostPlatform.isGhcjs) ([ + ++ lib.optionals (pkgs.stdenv.hostPlatform.isGhcjs || pkgs.stdenv.hostPlatform.isWasm) ([ # ghci and its dependencies - "ghci" "binary" "bytestring" "containers" "template-haskell" "array" "deepseq" "file-io" "filepath" "ghc-boot" "ghc-boot-th" "ghc-heap" "transformers" "unix" "directory" "time" "ghc-platform" "os-string"] + "ghci" "binary" "bytestring" "containers" "template-haskell" "array" "deepseq" "file-io" "filepath" "ghc-boot" "ghc-boot-th" "ghc-heap" "transformers" "unix" "directory" "time" "ghc-platform" "os-string" "exceptions" "stm" "ghc-experimental"] ++ lib.optionals (builtins.compareVersions config.compiler.version "8.11" < 0) [ "ghcjs-prim" "ghcjs-th"]); } diff --git a/modules/package.nix b/modules/package.nix index 39d9b2809f..1d56dd5282 100644 --- a/modules/package.nix +++ b/modules/package.nix @@ -77,6 +77,7 @@ in synopsis = lib.mkOption { type = types.str; + default = ""; }; description = lib.mkOption { diff --git a/overlays/bootstrap.nix b/overlays/bootstrap.nix index 9b7bda7cc9..c847c3cb9c 100644 --- a/overlays/bootstrap.nix +++ b/overlays/bootstrap.nix @@ -1098,8 +1098,9 @@ in { bootPkgs = bootPkgsGhc94 // { ghc = if final.stdenv.buildPlatform != final.stdenv.targetPlatform - then final.buildPackages.buildPackages.haskell-nix.compiler.ghc9121 - else final.buildPackages.buildPackages.haskell.compiler.ghc9121 + then final.buildPackages.buildPackages.haskell-nix.compiler.${compiler-nix-name} + else final.buildPackages.buildPackages.haskell.compiler.ghc9122 + or final.buildPackages.buildPackages.haskell.compiler.ghc9121 or final.buildPackages.buildPackages.haskell.compiler.ghc9101 or final.buildPackages.buildPackages.haskell.compiler.ghc984 or final.buildPackages.buildPackages.haskell.compiler.ghc983 diff --git a/overlays/default.nix b/overlays/default.nix index 6231016540..e77ea8b2fb 100644 --- a/overlays/default.nix +++ b/overlays/default.nix @@ -96,6 +96,8 @@ let cacheCompilerDeps = import ./cache-compiler-deps.nix; lazy-inputs = import ../lazy-inputs; rcodesign = import ./rcodesign.nix; + wasm = import ./wasm.nix; + node-lto = import ./node-lto.nix; }; composeExtensions = f: g: final: prev: @@ -130,6 +132,8 @@ let cabalPkgConfig gobject-introspection hix + wasm + node-lto # Restore nixpkgs haskell and haskellPackages (_: prev: { inherit (prev.haskell-nix-prev) haskell haskellPackages; }) cacheCompilerDeps diff --git a/overlays/node-lto.nix b/overlays/node-lto.nix new file mode 100644 index 0000000000..62e60b116b --- /dev/null +++ b/overlays/node-lto.nix @@ -0,0 +1,9 @@ +final: prev: { + nodejs-with-lto = final.nodejs_24; +# nodejs-with-lto = final.pkgsStatic.nodejs_24.overrideAttrs (attrs: { +# LDFLAGS="-Wl,-z,stack-size=8388608"; +# VARIATION="static"; +# patches = attrs.patches or [] ++ [./patches/node-lto.patch]; +# configureFlags = ["--enable-lto" "--fully-static"]; +# }); +} diff --git a/overlays/patches/node-lto.patch b/overlays/patches/node-lto.patch new file mode 100644 index 0000000000..8192878c75 --- /dev/null +++ b/overlays/patches/node-lto.patch @@ -0,0 +1,305 @@ +diff --git a/common.gypi b/common.gypi +index a6a79adc..160b6eb6 100644 +--- a/common.gypi ++++ b/common.gypi +@@ -185,9 +185,9 @@ + 'MSVC_runtimeType': 2 # MultiThreadedDLL (/MD) + }], + ['clang==1', { +- 'lto': ' -flto ', # Clang ++ 'lto': ' -flto=thin ', # Clang + }, { +- 'lto': ' -flto=4 -fuse-linker-plugin -ffat-lto-objects ', # GCC ++ 'lto': ' -flto=auto -fuse-linker-plugin -fno-fat-lto-objects ', # GCC + }], + ], + }, +diff --git a/deps/cares/configure b/deps/cares/configure +index d02f117d..468461f7 100755 +--- a/deps/cares/configure ++++ b/deps/cares/configure +@@ -16139,11 +16139,6 @@ _LT_EOF + + + _lt_libdeps_save_CFLAGS=$CFLAGS +-case "$CC $CFLAGS " in #( +-*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +-*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +-*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +-esac + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 +diff --git a/deps/cares/m4/libtool.m4 b/deps/cares/m4/libtool.m4 +index c4c02946..9f3d3662 100755 +--- a/deps/cares/m4/libtool.m4 ++++ b/deps/cares/m4/libtool.m4 +@@ -7537,11 +7537,6 @@ _LT_EOF + ]) + + _lt_libdeps_save_CFLAGS=$CFLAGS +-case "$CC $CFLAGS " in #( +-*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +-*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +-*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +-esac + + dnl Parse the compiler output and extract the necessary + dnl objects, libraries and library flags. +diff --git a/deps/npm/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py b/deps/npm/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py +index 5f2c097f..42dad126 100644 +--- a/deps/npm/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py ++++ b/deps/npm/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py +@@ -638,7 +638,7 @@ class XcodeSettings: + # if the system clang isn't used, DYLD_LIBRARY_PATH needs to contain the + # path to the libLTO.dylib that matches the used clang. + if self._Test("LLVM_LTO", "YES", default="NO"): +- cflags.append("-flto") ++ cflags.append("-flto=thin") + + self._AppendPlatformVersionMinFlags(cflags) + +@@ -1101,7 +1101,7 @@ class XcodeSettings: + # For static libraries, no dSYMs are created. + result = [] + if ( +- self._Test("GCC_GENERATE_DEBUGGING_SYMBOLS", "YES", default="YES") ++ self._Test("GCC_GENERATE_DEBUGGING_SYMBOLS", "YES", default="NO") + and self._Test( + "DEBUG_INFORMATION_FORMAT", "dwarf-with-dsym", default="dwarf" + ) +diff --git a/deps/openssl/openssl-cli.gypi b/deps/openssl/openssl-cli.gypi +index b4c278b4..79cafd6b 100644 +--- a/deps/openssl/openssl-cli.gypi ++++ b/deps/openssl/openssl-cli.gypi +@@ -23,7 +23,7 @@ + }], + # Avoid excessive LTO + ['enable_lto=="true"', { +- 'ldflags': [ '-fno-lto' ], ++ 'ldflags': [], + }], + ], + } +diff --git a/deps/openssl/openssl.gyp b/deps/openssl/openssl.gyp +index ea3a2dc0..ea3780f7 100644 +--- a/deps/openssl/openssl.gyp ++++ b/deps/openssl/openssl.gyp +@@ -75,7 +75,7 @@ + }], + # Avoid excessive LTO + ['enable_lto=="true"', { +- 'ldflags': [ '-fno-lto' ], ++ 'ldflags': [], + }], + ] + }, { +diff --git a/node.gyp b/node.gyp +index a3688b8e..d320299f 100644 +--- a/node.gyp ++++ b/node.gyp +@@ -1069,7 +1069,7 @@ + }], + # Avoid excessive LTO + ['enable_lto=="true"', { +- 'ldflags': [ '-fno-lto' ], ++ 'ldflags': [], + }], + ], + }, # fuzz_env +@@ -1112,7 +1112,7 @@ + }], + # Avoid excessive LTO + ['enable_lto=="true"', { +- 'ldflags': [ '-fno-lto' ], ++ 'ldflags': [], + }], + ], + }, # fuzz_ClientHelloParser.cc +@@ -1157,7 +1157,7 @@ + }], + # Avoid excessive LTO + ['enable_lto=="true"', { +- 'ldflags': [ '-fno-lto' ], ++ 'ldflags': [], + }], + ], + }, # fuzz_strings +@@ -1235,7 +1235,7 @@ + }], + # Avoid excessive LTO + ['enable_lto=="true"', { +- 'ldflags': [ '-fno-lto' ], ++ 'ldflags': [], + }], + ], + }, # cctest +@@ -1291,7 +1291,7 @@ + }], + # Avoid excessive LTO + ['enable_lto=="true"', { +- 'ldflags': [ '-fno-lto' ], ++ 'ldflags': [], + }], + ], + }, # embedtest +@@ -1333,7 +1333,7 @@ + }], + # Avoid excessive LTO + ['enable_lto=="true"', { +- 'ldflags': [ '-fno-lto' ], ++ 'ldflags': [], + }], + ] + }, # overlapped-checker +@@ -1439,7 +1439,7 @@ + }], + # Avoid excessive LTO + ['enable_lto=="true"', { +- 'ldflags': [ '-fno-lto' ], ++ 'ldflags': [], + }], + ], + }, # node_mksnapshot +diff --git a/tools/gyp/pylib/gyp/xcode_emulation.py b/tools/gyp/pylib/gyp/xcode_emulation.py +index aee1a542..162881d1 100644 +--- a/tools/gyp/pylib/gyp/xcode_emulation.py ++++ b/tools/gyp/pylib/gyp/xcode_emulation.py +@@ -638,7 +638,7 @@ class XcodeSettings: + # if the system clang isn't used, DYLD_LIBRARY_PATH needs to contain the + # path to the libLTO.dylib that matches the used clang. + if self._Test("LLVM_LTO", "YES", default="NO"): +- cflags.append("-flto") ++ cflags.append("-flto=thin") + + self._AppendPlatformVersionMinFlags(cflags) + +@@ -1101,7 +1101,7 @@ class XcodeSettings: + # For static libraries, no dSYMs are created. + result = [] + if ( +- self._Test("GCC_GENERATE_DEBUGGING_SYMBOLS", "YES", default="YES") ++ self._Test("GCC_GENERATE_DEBUGGING_SYMBOLS", "YES", default="NO") + and self._Test( + "DEBUG_INFORMATION_FORMAT", "dwarf-with-dsym", default="dwarf" + ) +diff --git a/tools/icu/icu-generic.gyp b/tools/icu/icu-generic.gyp +index f007c652..ac69a873 100644 +--- a/tools/icu/icu-generic.gyp ++++ b/tools/icu/icu-generic.gyp +@@ -454,7 +454,7 @@ + 'conditions': [ + # Avoid excessive LTO + ['enable_lto=="true"', { +- 'ldflags': [ '-fno-lto' ], ++ 'ldflags': [], + }], + ], + }, +@@ -471,7 +471,7 @@ + 'conditions': [ + # Avoid excessive LTO + ['enable_lto=="true"', { +- 'ldflags': [ '-fno-lto' ], ++ 'ldflags': [], + }], + ], + }, +@@ -489,7 +489,7 @@ + 'conditions': [ + # Avoid excessive LTO + ['enable_lto=="true"', { +- 'ldflags': [ '-fno-lto' ], ++ 'ldflags': [], + }], + ], + }, +@@ -506,7 +506,7 @@ + 'conditions': [ + # Avoid excessive LTO + ['enable_lto=="true"', { +- 'ldflags': [ '-fno-lto' ], ++ 'ldflags': [], + }], + ], + }, +diff --git a/tools/v8_gypfiles/d8.gyp b/tools/v8_gypfiles/d8.gyp +index 4dd98972..27165061 100644 +--- a/tools/v8_gypfiles/d8.gyp ++++ b/tools/v8_gypfiles/d8.gyp +@@ -65,7 +65,7 @@ + }], + # Avoid excessive LTO + ['enable_lto=="true"', { +- 'ldflags': [ '-fno-lto' ], ++ 'ldflags': [], + }], + ], + }, +diff --git a/tools/v8_gypfiles/v8.gyp b/tools/v8_gypfiles/v8.gyp +index 88c1297b..a640a7ff 100644 +--- a/tools/v8_gypfiles/v8.gyp ++++ b/tools/v8_gypfiles/v8.gyp +@@ -1690,7 +1690,7 @@ + }], + # Avoid excessive LTO + ['enable_lto=="true"', { +- 'ldflags': [ '-fno-lto' ], ++ 'ldflags': [], + }], + ], + 'defines!': [ +@@ -1752,7 +1752,7 @@ + }], + # Avoid excessive LTO + ['enable_lto=="true"', { +- 'ldflags': [ '-fno-lto' ], ++ 'ldflags': [], + }], + ], + }, # mksnapshot +@@ -1769,7 +1769,7 @@ + }], + # Avoid excessive LTO + ['enable_lto=="true"', { +- 'ldflags': [ '-fno-lto' ], ++ 'ldflags': [], + }], + ], + 'defines!': [ +@@ -1807,7 +1807,7 @@ + }], + # Avoid excessive LTO + ['enable_lto=="true"', { +- 'ldflags': [ '-fno-lto' ], ++ 'ldflags': [], + }], + ], + 'dependencies': [ +@@ -1843,7 +1843,7 @@ + }], + # Avoid excessive LTO + ['enable_lto=="true"', { +- 'ldflags': [ '-fno-lto' ], ++ 'ldflags': [], + }], + ], + 'sources': [ +@@ -1863,7 +1863,7 @@ + }], + # Avoid excessive LTO + ['enable_lto=="true"', { +- 'ldflags': [ '-fno-lto' ], ++ 'ldflags': [], + }], + ], + 'actions': [ +@@ -1931,7 +1931,7 @@ + ], + 'conditions': [ + ['enable_lto=="true"', { +- 'cflags_cc': [ '-fno-lto' ], ++ 'cflags_cc': [], + }], + # Changes in push_registers_asm.cc in V8 v12.8 requires using + # push_registers_masm on Windows even with ClangCL on x64 \ No newline at end of file diff --git a/overlays/patches/wasm/llvm/gnu-install-dirs.patch b/overlays/patches/wasm/llvm/gnu-install-dirs.patch new file mode 100644 index 0000000000..482325452c --- /dev/null +++ b/overlays/patches/wasm/llvm/gnu-install-dirs.patch @@ -0,0 +1,152 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index c9ff3696e22d..bd96aab5e237 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -1133,9 +1133,9 @@ if (NOT TENSORFLOW_AOT_PATH STREQUAL "") + add_subdirectory(${TENSORFLOW_AOT_PATH}/xla_aot_runtime_src + ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/tf_runtime) + install(TARGETS tf_xla_runtime EXPORT LLVMExports +- ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX} COMPONENT tf_xla_runtime) ++ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX} COMPONENT tf_xla_runtime) + install(TARGETS tf_xla_runtime EXPORT LLVMDevelopmentExports +- ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX} COMPONENT tf_xla_runtime) ++ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX} COMPONENT tf_xla_runtime) + set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS tf_xla_runtime) + # Once we add more modules, we should handle this more automatically. + if (DEFINED LLVM_OVERRIDE_MODEL_HEADER_INLINERSIZEMODEL) +diff --git a/cmake/modules/AddLLVM.cmake b/cmake/modules/AddLLVM.cmake +index baf47677b247..81954240a9bf 100644 +--- a/cmake/modules/AddLLVM.cmake ++++ b/cmake/modules/AddLLVM.cmake +@@ -974,8 +974,8 @@ macro(add_llvm_library name) + endif() + install(TARGETS ${name} + ${export_to_llvmexports} +- LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX} COMPONENT ${name} +- ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX} COMPONENT ${name} ++ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX} COMPONENT ${name} ++ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX} COMPONENT ${name} + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT ${name}) + + if (NOT LLVM_ENABLE_IDE) +@@ -2240,7 +2240,7 @@ function(llvm_install_library_symlink name dest type) + set(LLVM_LINK_OR_COPY copy) + endif() + +- set(output_dir lib${LLVM_LIBDIR_SUFFIX}) ++ set(output_dir ${CMAKE_INSTALL_FULL_LIBDIR}${LLVM_LIBDIR_SUFFIX}) + if(WIN32 AND "${type}" STREQUAL "SHARED") + set(output_dir "${CMAKE_INSTALL_BINDIR}") + endif() +@@ -2516,15 +2516,37 @@ function(llvm_setup_rpath name) + + if (APPLE) + set(_install_name_dir INSTALL_NAME_DIR "@rpath") +- set(_install_rpath "@loader_path/../lib${LLVM_LIBDIR_SUFFIX}" ${extra_libdir}) ++ set(_install_rpath ${extra_libdir}) + elseif(${CMAKE_SYSTEM_NAME} MATCHES "AIX" AND BUILD_SHARED_LIBS) + # $ORIGIN is not interpreted at link time by aix ld. + # Since BUILD_SHARED_LIBS is only recommended for use by developers, + # hardcode the rpath to build/install lib dir first in this mode. + # FIXME: update this when there is better solution. +- set(_install_rpath "${LLVM_LIBRARY_OUTPUT_INTDIR}" "${CMAKE_INSTALL_PREFIX}/lib${LLVM_LIBDIR_SUFFIX}" ${extra_libdir}) ++ set(_install_rpath "${LLVM_LIBRARY_OUTPUT_INTDIR}" "${CMAKE_INSTALL_FULL_LIBDIR}${LLVM_LIBDIR_SUFFIX}" ${extra_libdir}) + elseif(UNIX) +- set(_install_rpath "\$ORIGIN/../lib${LLVM_LIBDIR_SUFFIX}" ${extra_libdir}) ++ # Note that we add `extra_libdir` (aka `LLVM_LIBRARY_DIR` in our case) back ++ # to `_install_rpath` here. ++ # ++ # In nixpkgs we do not build and install LLVM alongside rdeps of LLVM (i.e. ++ # clang); instead LLVM is its own package and thus lands at its own nix ++ # store path. This makes it so that the default relative rpath (`../lib/`) ++ # does not point at the LLVM shared objects. ++ # ++ # More discussion here: ++ # - https://github.com/NixOS/nixpkgs/pull/235624#discussion_r1220150329 ++ # - https://reviews.llvm.org/D146918 (16.0.5+) ++ # ++ # Note that we leave `extra_libdir` in `_build_rpath`: without FHS there is ++ # no potential that this will result in us pulling in the "wrong" LLVM. ++ # Adding this to the build rpath means we aren't forced to use ++ # `installCheckPhase` instead of `checkPhase` (i.e. binaries in the build ++ # dir, pre-install, will have the right rpath for LLVM). ++ # ++ # As noted in the differential above, an alternative solution is to have ++ # all rdeps of nixpkgs' LLVM (that use the AddLLVM.cmake machinery) set ++ # `CMAKE_INSTALL_RPATH`. ++ set(_build_rpath "\$ORIGIN/../lib${LLVM_LIBDIR_SUFFIX}" ${extra_libdir}) ++ set(_install_rpath ${extra_libdir}) + if(${CMAKE_SYSTEM_NAME} MATCHES "(FreeBSD|DragonFly)") + set_property(TARGET ${name} APPEND_STRING PROPERTY + LINK_FLAGS " -Wl,-z,origin ") +@@ -2539,9 +2561,9 @@ function(llvm_setup_rpath name) + endif() + + # Enable BUILD_WITH_INSTALL_RPATH unless CMAKE_BUILD_RPATH is set. +- if("${CMAKE_BUILD_RPATH}" STREQUAL "") +- set_property(TARGET ${name} PROPERTY BUILD_WITH_INSTALL_RPATH ON) +- endif() ++ #if("${CMAKE_BUILD_RPATH}" STREQUAL "") ++ # set_property(TARGET ${name} PROPERTY BUILD_WITH_INSTALL_RPATH ON) ++ #endif() + + set_target_properties(${name} PROPERTIES + INSTALL_RPATH "${_install_rpath}" +diff --git a/cmake/modules/AddOCaml.cmake b/cmake/modules/AddOCaml.cmake +index 2d9116b08a52..2dd7cad4ec66 100644 +--- a/cmake/modules/AddOCaml.cmake ++++ b/cmake/modules/AddOCaml.cmake +@@ -147,9 +147,9 @@ function(add_ocaml_library name) + endforeach() + + if( APPLE ) +- set(ocaml_rpath "@executable_path/../../../lib${LLVM_LIBDIR_SUFFIX}") ++ set(ocaml_rpath ${LLVM_LIBRARY_DIR}) + elseif( UNIX ) +- set(ocaml_rpath "\\$ORIGIN/../../../lib${LLVM_LIBDIR_SUFFIX}") ++ set(ocaml_rpath ${LLVM_LIBRARY_DIR}) + endif() + list(APPEND ocaml_flags "-ldopt" "-Wl,-rpath,${ocaml_rpath}") + +diff --git a/cmake/modules/CMakeLists.txt b/cmake/modules/CMakeLists.txt +index ef4cfa3acdb5..7478e157a7c2 100644 +--- a/cmake/modules/CMakeLists.txt ++++ b/cmake/modules/CMakeLists.txt +@@ -130,7 +130,7 @@ set(LLVM_CONFIG_INCLUDE_DIRS + ) + list(REMOVE_DUPLICATES LLVM_CONFIG_INCLUDE_DIRS) + +-extend_path(LLVM_CONFIG_LIBRARY_DIR "\${LLVM_INSTALL_PREFIX}" "lib\${LLVM_LIBDIR_SUFFIX}") ++extend_path(LLVM_CONFIG_LIBRARY_DIR "\${LLVM_INSTALL_PREFIX}" "${CMAKE_INSTALL_LIBDIR}\${LLVM_LIBDIR_SUFFIX}") + set(LLVM_CONFIG_LIBRARY_DIRS + "${LLVM_CONFIG_LIBRARY_DIR}" + # FIXME: Should there be other entries here? +diff --git a/tools/llvm-config/BuildVariables.inc.in b/tools/llvm-config/BuildVariables.inc.in +index 370005cd8d7d..7e790bc52111 100644 +--- a/tools/llvm-config/BuildVariables.inc.in ++++ b/tools/llvm-config/BuildVariables.inc.in +@@ -23,6 +23,7 @@ + #define LLVM_CXXFLAGS "@LLVM_CXXFLAGS@" + #define LLVM_BUILDMODE "@LLVM_BUILDMODE@" + #define LLVM_LIBDIR_SUFFIX "@LLVM_LIBDIR_SUFFIX@" ++#define LLVM_INSTALL_LIBDIR "@CMAKE_INSTALL_LIBDIR@" + #define LLVM_INSTALL_INCLUDEDIR "@CMAKE_INSTALL_INCLUDEDIR@" + #define LLVM_INSTALL_PACKAGE_DIR "@LLVM_INSTALL_PACKAGE_DIR@" + #define LLVM_TARGETS_BUILT "@LLVM_TARGETS_BUILT@" +diff --git a/tools/llvm-config/llvm-config.cpp b/tools/llvm-config/llvm-config.cpp +index d5b76b1bb6c1..1dbdb2a8f10d 100644 +--- a/tools/llvm-config/llvm-config.cpp ++++ b/tools/llvm-config/llvm-config.cpp +@@ -366,7 +366,11 @@ int main(int argc, char **argv) { + sys::fs::make_absolute(ActivePrefix, Path); + ActiveBinDir = std::string(Path); + } +- ActiveLibDir = ActivePrefix + "/lib" + LLVM_LIBDIR_SUFFIX; ++ { ++ SmallString<256> Path(LLVM_INSTALL_LIBDIR LLVM_LIBDIR_SUFFIX); ++ sys::fs::make_absolute(ActivePrefix, Path); ++ ActiveLibDir = std::string(Path); ++ } + { + SmallString<256> Path(LLVM_INSTALL_PACKAGE_DIR); + sys::fs::make_absolute(ActivePrefix, Path); diff --git a/overlays/patches/wasm/llvm/haskell-wasm-llvm-project.patch b/overlays/patches/wasm/llvm/haskell-wasm-llvm-project.patch new file mode 100644 index 0000000000..d45b5d0880 --- /dev/null +++ b/overlays/patches/wasm/llvm/haskell-wasm-llvm-project.patch @@ -0,0 +1,322 @@ +diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp b/clang/lib/Driver/ToolChains/WebAssembly.cpp +index bd25fd1a8933..b906bff5d5c7 100644 +--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp ++++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp +@@ -6,6 +6,8 @@ + // + //===----------------------------------------------------------------------===// + ++#include ++ + #include "WebAssembly.h" + #include "CommonArgs.h" + #include "Gnu.h" +@@ -19,6 +21,7 @@ + #include "llvm/Option/ArgList.h" + #include "llvm/Support/FileSystem.h" + #include "llvm/Support/Path.h" ++#include "llvm/Support/Process.h" + #include "llvm/Support/VirtualFileSystem.h" + + using namespace clang::driver; +@@ -168,21 +171,12 @@ void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA, + CmdArgs.push_back("-o"); + CmdArgs.push_back(Output.getFilename()); + +- // Don't use wasm-opt by default on `wasip2` as it doesn't have support for +- // components at this time. Retain the historical default otherwise, though, +- // of running `wasm-opt` by default. +- bool WasmOptDefault = !TargetBuildsComponents(ToolChain.getTriple()); +- bool RunWasmOpt = Args.hasFlag(options::OPT_wasm_opt, +- options::OPT_no_wasm_opt, WasmOptDefault); +- + // If wasm-opt is enabled and optimizations are happening look for the + // `wasm-opt` program. If it's not found auto-disable it. + std::string WasmOptPath; +- if (RunWasmOpt && Args.getLastArg(options::OPT_O_Group)) { +- WasmOptPath = ToolChain.GetProgramPath("wasm-opt"); +- if (WasmOptPath == "wasm-opt") { +- WasmOptPath = {}; +- } ++ WasmOptPath = ToolChain.GetProgramPath("wasm-opt"); ++ if (WasmOptPath == "wasm-opt") { ++ WasmOptPath = {}; + } + + if (!WasmOptPath.empty()) { +@@ -193,29 +187,27 @@ void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA, + ResponseFileSupport::AtFileCurCP(), + Linker, CmdArgs, Inputs, Output)); + +- if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { +- if (!WasmOptPath.empty()) { +- StringRef OOpt = "s"; +- if (A->getOption().matches(options::OPT_O4) || +- A->getOption().matches(options::OPT_Ofast)) +- OOpt = "4"; +- else if (A->getOption().matches(options::OPT_O0)) +- OOpt = "0"; +- else if (A->getOption().matches(options::OPT_O)) +- OOpt = A->getValue(); +- +- if (OOpt != "0") { +- const char *WasmOpt = Args.MakeArgString(WasmOptPath); +- ArgStringList OptArgs; +- OptArgs.push_back(Output.getFilename()); +- OptArgs.push_back(Args.MakeArgString(llvm::Twine("-O") + OOpt)); +- OptArgs.push_back("-o"); +- OptArgs.push_back(Output.getFilename()); +- C.addCommand(std::make_unique( +- JA, *this, ResponseFileSupport::AtFileCurCP(), WasmOpt, OptArgs, +- Inputs, Output)); +- } ++ if (!WasmOptPath.empty() && Args.hasArg(options::OPT_shared) && ++ llvm::sys::Process::GetEnv("WASM_SO_OPT")) { ++ const char *WasmOpt = Args.MakeArgString(WasmOptPath); ++ ArgStringList OptArgs; ++ OptArgs.push_back(Output.getFilename()); ++ OptArgs.push_back("-o"); ++ OptArgs.push_back(Output.getFilename()); ++ ++ std::istringstream iss(llvm::sys::Process::GetEnv("WASM_SO_OPT").value()); ++ std::string arg; ++ ++ while (iss >> arg) { ++ auto *arg_heap = new char[arg.size() + 1]; ++ std::copy(arg.begin(), arg.end(), arg_heap); ++ arg_heap[arg.size()] = '\0'; ++ OptArgs.push_back(arg_heap); + } ++ ++ C.addCommand(std::make_unique(JA, *this, ++ ResponseFileSupport::AtFileCurCP(), ++ WasmOpt, OptArgs, Inputs, Output)); + } + } + +diff --git a/compiler-rt/cmake/Modules/AddCompilerRT.cmake b/compiler-rt/cmake/Modules/AddCompilerRT.cmake +index c3e734f72392..282a321fd70b 100644 +--- a/compiler-rt/cmake/Modules/AddCompilerRT.cmake ++++ b/compiler-rt/cmake/Modules/AddCompilerRT.cmake +@@ -382,8 +382,8 @@ function(add_compiler_rt_runtime name type) + target_link_libraries(${libname} PRIVATE ${builtins_${libname}}) + endif() + if(${type} STREQUAL "SHARED") +- if(APPLE OR WIN32) +- set_property(TARGET ${libname} PROPERTY BUILD_WITH_INSTALL_RPATH ON) ++ if(COMMAND llvm_setup_rpath) ++ llvm_setup_rpath(${libname}) + endif() + if(WIN32 AND NOT CYGWIN AND NOT MINGW) + set_target_properties(${libname} PROPERTIES IMPORT_PREFIX "") +diff --git a/lld/wasm/InputChunks.cpp b/lld/wasm/InputChunks.cpp +index 0e6c4e691be1..bfa438505d98 100644 +--- a/lld/wasm/InputChunks.cpp ++++ b/lld/wasm/InputChunks.cpp +@@ -361,12 +361,11 @@ uint64_t InputChunk::getVA(uint64_t offset) const { + // Generate code to apply relocations to the data section at runtime. + // This is only called when generating shared libraries (PIC) where address are + // not known at static link time. +-bool InputChunk::generateRelocationCode(raw_ostream &os) const { ++void InputChunk::generateRelocationCode(std::vector &funcs) const { + LLVM_DEBUG(dbgs() << "generating runtime relocations: " << name + << " count=" << relocations.size() << "\n"); + + bool is64 = ctx.arg.is64.value_or(false); +- bool generated = false; + unsigned opcode_ptr_const = is64 ? WASM_OPCODE_I64_CONST + : WASM_OPCODE_I32_CONST; + unsigned opcode_ptr_add = is64 ? WASM_OPCODE_I64_ADD +@@ -385,6 +384,14 @@ bool InputChunk::generateRelocationCode(raw_ostream &os) const { + if (!requiresRuntimeReloc) + continue; + ++ if (funcs.empty() || funcs.back().size() >= 7654300) { ++ funcs.emplace_back(std::string()); ++ raw_string_ostream os(funcs.back()); ++ writeUleb128(os, 0, "num locals"); ++ } ++ ++ raw_string_ostream os(funcs.back()); ++ + LLVM_DEBUG(dbgs() << "gen reloc: type=" << relocTypeToString(rel.Type) + << " addend=" << rel.Addend << " index=" << rel.Index + << " output offset=" << offset << "\n"); +@@ -439,9 +446,7 @@ bool InputChunk::generateRelocationCode(raw_ostream &os) const { + writeU8(os, opcode_reloc_store, "I32_STORE"); + writeUleb128(os, 2, "align"); + writeUleb128(os, 0, "offset"); +- generated = true; + } +- return generated; + } + + // Split WASM_SEG_FLAG_STRINGS section. Such a section is a sequence of +diff --git a/lld/wasm/InputChunks.h b/lld/wasm/InputChunks.h +index f545449e1246..d231382a5f5e 100644 +--- a/lld/wasm/InputChunks.h ++++ b/lld/wasm/InputChunks.h +@@ -78,7 +78,7 @@ public: + + size_t getNumRelocations() const { return relocations.size(); } + void writeRelocations(llvm::raw_ostream &os) const; +- bool generateRelocationCode(raw_ostream &os) const; ++ void generateRelocationCode(std::vector &funcs) const; + + bool isTLS() const { return flags & llvm::wasm::WASM_SEG_FLAG_TLS; } + bool isRetained() const { return flags & llvm::wasm::WASM_SEG_FLAG_RETAIN; } +diff --git a/lld/wasm/SyntheticSections.cpp b/lld/wasm/SyntheticSections.cpp +index 0e2aa57e9048..e5df7d8c0be0 100644 +--- a/lld/wasm/SyntheticSections.cpp ++++ b/lld/wasm/SyntheticSections.cpp +@@ -299,6 +299,8 @@ void FunctionSection::writeBody() { + void FunctionSection::addFunction(InputFunction *func) { + if (!func->live) + return; ++ if (func->hasFunctionIndex()) ++ return; + uint32_t functionIndex = + out.importSec->getNumImportedFunctions() + inputFunctions.size(); + inputFunctions.emplace_back(func); +diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp +index 2bf4b370a7db..19fca2616c7a 100644 +--- a/lld/wasm/Writer.cpp ++++ b/lld/wasm/Writer.cpp +@@ -1452,20 +1452,21 @@ void Writer::createStartFunction() { + void Writer::createApplyDataRelocationsFunction() { + LLVM_DEBUG(dbgs() << "createApplyDataRelocationsFunction\n"); + // First write the body's contents to a string. +- std::string bodyContent; ++ std::vector funcs; + { +- raw_string_ostream os(bodyContent); +- writeUleb128(os, 0, "num locals"); +- bool generated = false; + for (const OutputSegment *seg : segments) + if (!ctx.arg.sharedMemory || !seg->isTLS()) + for (const InputChunk *inSeg : seg->inputSegments) +- generated |= inSeg->generateRelocationCode(os); ++ inSeg->generateRelocationCode(funcs); ++ } + +- if (!generated) { +- LLVM_DEBUG(dbgs() << "skipping empty __wasm_apply_data_relocs\n"); +- return; +- } ++ if (funcs.empty()) { ++ LLVM_DEBUG(dbgs() << "skipping empty __wasm_apply_data_relocs\n"); ++ return; ++ } ++ ++ for (auto &func : funcs) { ++ raw_string_ostream os(func); + writeU8(os, WASM_OPCODE_END, "END"); + } + +@@ -1478,24 +1479,67 @@ void Writer::createApplyDataRelocationsFunction() { + make(nullSignature, "__wasm_apply_data_relocs")); + def->markLive(); + +- createFunction(def, bodyContent); ++ if (funcs.size() == 1) { ++ createFunction(def, funcs.back()); ++ return; ++ } ++ ++ std::string body; ++ { ++ raw_string_ostream os(body); ++ writeUleb128(os, 0, "num locals"); ++ ++ for (std::size_t i = 0; i < funcs.size(); ++i) { ++ auto &name = ++ *make("__wasm_apply_data_relocs_" + std::to_string(i)); ++ auto *func = make(nullSignature, name); ++ auto *def = symtab->addSyntheticFunction( ++ name, WASM_SYMBOL_VISIBILITY_HIDDEN, func); ++ def->markLive(); ++ // Normally this shouldn't be called manually for a synthetic ++ // function, since the function indices in ++ // ctx.syntheticFunctions will be calculated later (check ++ // functionSec->addFunction call hierarchy for details). ++ // However, at this point we already need the correct index. The ++ // solution is to place the new synthetic function eagerly, and ++ // also making addFunction idempotent by skipping when there's ++ // already a function index. ++ out.functionSec->addFunction(func); ++ createFunction(def, funcs[i]); ++ ++ writeU8(os, WASM_OPCODE_CALL, "CALL"); ++ writeUleb128(os, def->getFunctionIndex(), "function index"); ++ } ++ ++ writeU8(os, WASM_OPCODE_END, "END"); ++ } ++ createFunction(def, body); + } + + void Writer::createApplyTLSRelocationsFunction() { + LLVM_DEBUG(dbgs() << "createApplyTLSRelocationsFunction\n"); +- std::string bodyContent; ++ std::vector funcs; + { +- raw_string_ostream os(bodyContent); +- writeUleb128(os, 0, "num locals"); + for (const OutputSegment *seg : segments) + if (seg->isTLS()) + for (const InputChunk *inSeg : seg->inputSegments) +- inSeg->generateRelocationCode(os); ++ inSeg->generateRelocationCode(funcs); ++ } + ++ if (funcs.empty()) { ++ funcs.emplace_back(std::string()); ++ raw_string_ostream os(funcs.back()); ++ writeUleb128(os, 0, "num locals"); ++ } ++ ++ for (auto &func : funcs) { ++ raw_string_ostream os(func); + writeU8(os, WASM_OPCODE_END, "END"); + } + +- createFunction(ctx.sym.applyTLSRelocs, bodyContent); ++ assert(funcs.size() == 1); ++ ++ createFunction(ctx.sym.applyTLSRelocs, funcs.back()); + } + + // Similar to createApplyDataRelocationsFunction but generates relocation code +diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake +index d3e9377c8d2f..50a34184919a 100644 +--- a/llvm/cmake/modules/AddLLVM.cmake ++++ b/llvm/cmake/modules/AddLLVM.cmake +@@ -2524,8 +2524,7 @@ function(llvm_setup_rpath name) + # FIXME: update this when there is better solution. + set(_install_rpath "${LLVM_LIBRARY_OUTPUT_INTDIR}" "${CMAKE_INSTALL_PREFIX}/lib${LLVM_LIBDIR_SUFFIX}" ${extra_libdir}) + elseif(UNIX) +- set(_build_rpath "\$ORIGIN/../lib${LLVM_LIBDIR_SUFFIX}" ${extra_libdir}) +- set(_install_rpath "\$ORIGIN/../lib${LLVM_LIBDIR_SUFFIX}") ++ set(_install_rpath "\$ORIGIN/../lib${LLVM_LIBDIR_SUFFIX}" ${extra_libdir}) + if(${CMAKE_SYSTEM_NAME} MATCHES "(FreeBSD|DragonFly)") + set_property(TARGET ${name} APPEND_STRING PROPERTY + LINK_FLAGS " -Wl,-z,origin ") +@@ -2539,16 +2538,9 @@ function(llvm_setup_rpath name) + return() + endif() + +- # Enable BUILD_WITH_INSTALL_RPATH unless CMAKE_BUILD_RPATH is set and not +- # building for macOS or AIX, as those platforms seemingly require it. +- # On AIX, the tool chain doesn't support modifying rpaths/libpaths for XCOFF +- # on install at the moment, so BUILD_WITH_INSTALL_RPATH is required. ++ # Enable BUILD_WITH_INSTALL_RPATH unless CMAKE_BUILD_RPATH is set. + if("${CMAKE_BUILD_RPATH}" STREQUAL "") +- if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin|AIX") +- set_property(TARGET ${name} PROPERTY BUILD_WITH_INSTALL_RPATH ON) +- else() +- set_property(TARGET ${name} APPEND PROPERTY BUILD_RPATH "${_build_rpath}") +- endif() ++ set_property(TARGET ${name} PROPERTY BUILD_WITH_INSTALL_RPATH ON) + endif() + + set_target_properties(${name} PROPERTIES diff --git a/overlays/wasm.nix b/overlays/wasm.nix new file mode 100644 index 0000000000..d944dea365 --- /dev/null +++ b/overlays/wasm.nix @@ -0,0 +1,53 @@ +final: prev: prev.lib.optionalAttrs prev.stdenv.targetPlatform.isWasm { + llvmPackages = final.llvmPackages_20.override { + patchesFn = p: p // { "llvm/gnu-install-dirs.patch" = [{path = ./patches/wasm;}]; }; + monorepoSrc = + final.stdenv.mkDerivation { + pname = "llvm-source"; + version = final.llvmPackages_20.llvm.version + "-haskell"; + src = final.llvmPackages_20.llvm.monorepoSrc; + patches = ./patches/wasm/llvm/haskell-wasm-llvm-project.patch; + buildPhase = "true"; + installPhase = '' + cp -r . $out + ''; + }; + }; + wasilibc = prev.wasilibc.overrideAttrs (old: { + version = "25"; + src = final.buildPackages.fetchFromGitLab { + domain = "gitlab.haskell.org"; + owner = "haskell-wasm"; + repo = "wasi-libc"; + rev = "f8f0d3101e02aa3aaf37c5e31db23de34963053d"; + hash = "sha256-EvqbvVP9EH63C7KUmN4QaYjYbc4yGPU7vNev9u6a46o="; + fetchSubmodules = true; + }; + preBuild = '' + patchShebangs ./scripts + makeFlagsArray+=( + "default" + "libc_so" + ) + ''; + postBuild = '' + mkdir -p ${builtins.placeholder "out"} + mkdir -p ${builtins.placeholder "dev"} + mkdir -p ${builtins.placeholder "share"} + cp -r sysroot/lib/wasm32-wasi ${builtins.placeholder "out"}/lib + cp -r sysroot/include/wasm32-wasi ${builtins.placeholder "dev"}/include + cp -r sysroot/share/wasm32-wasi ${builtins.placeholder "share"}/share + ''; + nativeBuildInputs = old.nativeBuildInputs or [] ++ [ final.buildPackages.lld ]; + }); + + haskell-nix = prev.haskell-nix // ({ + defaultModules = prev.haskell-nix.defaultModules ++ [ + ({ pkgs, ... }: { + testWrapper = ["HOME=$(mktemp -d)" (pkgs.pkgsBuildBuild.wasmtime + "/bin/wasmtime")]; + package-keys = ["clock"]; + packages.clock.ghcOptions = ["-optc-Wno-int-conversion"]; + }) + ]; + }); +} diff --git a/test/cabal.project.local b/test/cabal.project.local index 342d3e3827..c68a1ae4c7 100644 --- a/test/cabal.project.local +++ b/test/cabal.project.local @@ -1,10 +1,3 @@ --- See https://github.com/haskellari/splitmix/pull/97 -source-repository-package - type: git - location: https://github.com/hamishmack/splitmix.git - tag: e3549473b124a7ba078408ac0d2c8aa8111c3888 - --sha256: sha256-o18DEF4+z3/jGhMZbow8PFtYBiIm6+b4B+6o5tM6ez0= - if impl(ghc>=9.12.1) -- allow newer packages, that are bound to be newer due to -- being shipped with a newer compiler. If you extend this @@ -29,7 +22,7 @@ repository head.hackage.ghc.haskell.org f76d08be13e9a61a377a85e2fb63f4c5435d40f8feb3e12eb05905edb8cdea89 26021a13b401500c8eb2761ca95c61f2d625bfef951b939a8124ed12ecf07329 7541f32a4ccca4f97aea3b22f5e593ba2c0267546016b992dfadcd2fe944e55d - --sha256: sha256-6w1dAY7syB11aqT7T3mi/vOupdwL9GT2ztRZJBBG/u8= + --sha256: sha256-cfWuWDU8hzbcPgCx5EH4z+W3/w5IbelbLY0WQs2gqMM= repository ghcjs-overlay url: https://raw.githubusercontent.com/input-output-hk/hackage-overlay-ghcjs/ffb32dce467b9a4d27be759fdd2740a6edd09d0b diff --git a/test/exe-dlls/default.nix b/test/exe-dlls/default.nix index 6d7a7ba475..f16960cbf2 100644 --- a/test/exe-dlls/default.nix +++ b/test/exe-dlls/default.nix @@ -14,7 +14,7 @@ let packages = project.hsPkgs; in recurseIntoAttrs rec { - meta.disabled = stdenv.hostPlatform.isGhcjs; + meta.disabled = stdenv.hostPlatform.isGhcjs || stdenv.hostPlatform.isWasm; ifdInputs = { inherit (project) plan-nix; diff --git a/test/exe-lib-dlls/default.nix b/test/exe-lib-dlls/default.nix index d2a883ca11..467c08afbe 100644 --- a/test/exe-lib-dlls/default.nix +++ b/test/exe-lib-dlls/default.nix @@ -14,7 +14,7 @@ let packages = project.hsPkgs; in recurseIntoAttrs rec { - meta.disabled = stdenv.hostPlatform.isGhcjs; + meta.disabled = stdenv.hostPlatform.isGhcjs || stdenv.hostPlatform.isWasm; ifdInputs = { inherit (project) plan-nix; diff --git a/test/gi-gtk/default.nix b/test/gi-gtk/default.nix index cdab43a1bb..8ceb1e1f69 100644 --- a/test/gi-gtk/default.nix +++ b/test/gi-gtk/default.nix @@ -16,7 +16,7 @@ let packages = project.hsPkgs; in recurseIntoAttrs rec { - meta.disabled = stdenv.hostPlatform.isGhcjs + meta.disabled = stdenv.hostPlatform.isGhcjs || stdenv.hostPlatform.isWasm # Gtk cross compilation seems to be broken in nixpkgs || stdenv.hostPlatform.isWindows # We can't make static libraries for Gtk diff --git a/test/js-template-haskell/js-template-haskell.cabal b/test/js-template-haskell/js-template-haskell.cabal index 550b546918..9758060d78 100644 --- a/test/js-template-haskell/js-template-haskell.cabal +++ b/test/js-template-haskell/js-template-haskell.cabal @@ -12,6 +12,7 @@ library exposed-modules: MyLib build-depends: base , uri-bytestring + , th-orphans hs-source-dirs: src default-language: Haskell2010 diff --git a/test/th-dlls/default.nix b/test/th-dlls/default.nix index f655965768..0f96f0a6bc 100644 --- a/test/th-dlls/default.nix +++ b/test/th-dlls/default.nix @@ -26,7 +26,7 @@ let packages-ei = (project true).hsPkgs; in recurseIntoAttrs { - meta.disabled = stdenv.hostPlatform.isGhcjs + meta.disabled = stdenv.hostPlatform.isGhcjs || stdenv.hostPlatform.isWasm # On aarch64 this test breaks form musl cross compiles on x86_64-linux # Error is: # iserv-proxy-interpreter: internal error: 0x0 address for .LANCHOR1 + 0 of type 562