Skip to content

Commit 5d7ed34

Browse files
hamishmackangerman
andauthored
Add JS cross compilation for GHC 9.6.1 (#1881)
Co-authored-by: Moritz Angermann <moritz.angermann@gmail.com>
1 parent 835c1b5 commit 5d7ed34

File tree

54 files changed

+15508
-44
lines changed

Some content is hidden

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

54 files changed

+15508
-44
lines changed

ci.nix

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@
6565
# of 'lib.systems.examples' are not understood between all versions
6666
let lib = nixpkgs.lib;
6767
in lib.optionalAttrs (nixpkgsName == "unstable"
68-
&& ((system == "x86_64-linux" && __elem compiler-nix-name ["ghc865" "ghc884" "ghc8107"])
69-
|| (system == "x86_64-darwin" && __elem compiler-nix-name ["ghc8107"]))) {
68+
&& ((system == "x86_64-linux" && __elem compiler-nix-name ["ghc865" "ghc884" "ghc8107" "ghc961"])
69+
|| (system == "x86_64-darwin" && __elem compiler-nix-name ["ghc8107" "ghc961"]))) {
7070
inherit (lib.systems.examples) ghcjs;
7171
} // lib.optionalAttrs (nixpkgsName == "unstable"
7272
&& ((system == "x86_64-linux" && __elem compiler-nix-name ["ghc8107" "ghc902" "ghc926" "ghc927" "ghc944" "ghc961"])

compiler/ghc/default.nix

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ let self =
2020
, # GHC can be built with system libffi or a bundled one.
2121
libffi ? null
2222

23-
, useLLVM ? !stdenv.targetPlatform.isx86
23+
, useLLVM ? !stdenv.targetPlatform.isx86 && !stdenv.targetPlatform.isGhcjs
2424
, # LLVM is conceptually a run-time-only dependency, but for
2525
# non-x86, we need LLVM to bootstrap later stages, so it becomes a
2626
# build-time dependency too.
@@ -121,8 +121,10 @@ let
121121

122122
# TODO(@Ericson2314) Make unconditional
123123
targetPrefix = lib.optionalString
124-
(targetPlatform != hostPlatform)
125-
"${targetPlatform.config}-";
124+
(targetPlatform != hostPlatform) (
125+
if useHadrian && targetPlatform.isGhcjs
126+
then "javascript-unknown-ghcjs-"
127+
else "${targetPlatform.config}-");
126128

127129
buildMK = ''
128130
BuildFlavour = ${ghcFlavour}
@@ -177,13 +179,13 @@ let
177179
# `--with` flags for libraries needed for RTS linker
178180
configureFlags = [
179181
"--datadir=$doc/share/doc/ghc"
180-
"--with-curses-includes=${targetPackages.ncurses.dev}/include" "--with-curses-libraries=${targetPackages.ncurses.out}/lib"
181-
] ++ lib.optionals (targetLibffi != null) ["--with-system-libffi" "--with-ffi-includes=${targetLibffi.dev}/include" "--with-ffi-libraries=${targetLibffi.out}/lib"
182-
] ++ lib.optionals (!enableIntegerSimple) [
182+
] ++ lib.optionals (!targetPlatform.isGhcjs) ["--with-curses-includes=${targetPackages.ncurses.dev}/include" "--with-curses-libraries=${targetPackages.ncurses.out}/lib"
183+
] ++ lib.optionals (targetLibffi != null && !targetPlatform.isGhcjs) ["--with-system-libffi" "--with-ffi-includes=${targetLibffi.dev}/include" "--with-ffi-libraries=${targetLibffi.out}/lib"
184+
] ++ lib.optionals (!enableIntegerSimple && !targetPlatform.isGhcjs) [
183185
"--with-gmp-includes=${targetGmp.dev}/include" "--with-gmp-libraries=${targetGmp.out}/lib"
184186
] ++ lib.optionals (targetPlatform == hostPlatform && hostPlatform.libc != "glibc" && !targetPlatform.isWindows) [
185187
"--with-iconv-includes=${libiconv}/include" "--with-iconv-libraries=${libiconv}/lib"
186-
] ++ lib.optionals (targetPlatform != hostPlatform) [
188+
] ++ lib.optionals (targetPlatform != hostPlatform && !targetPlatform.isGhcjs) [
187189
"--with-iconv-includes=${targetIconv}/include" "--with-iconv-libraries=${targetIconv}/lib"
188190
] ++ lib.optionals (targetPlatform != hostPlatform) [
189191
"--enable-bootstrap-with-devel-snapshot"
@@ -198,21 +200,23 @@ let
198200
"--enable-dwarf-unwind"
199201
"--with-libdw-includes=${lib.getDev elfutils}/include"
200202
"--with-libdw-libraries=${lib.getLib elfutils}/lib"
201-
];
203+
] ++ lib.optional (targetPlatform.isGhcjs) "--target=javascript-unknown-ghcjs"; # TODO use configurePlatforms once tripple is updated in nixpkgs
202204

203205
# Splicer will pull out correct variations
204-
libDeps = platform: lib.optional enableTerminfo [ targetPackages.ncurses targetPackages.ncurses.dev ]
205-
++ [targetLibffi]
206-
++ lib.optional (!enableIntegerSimple) gmp
206+
libDeps = platform: lib.optional (enableTerminfo && !targetPlatform.isGhcjs) [ targetPackages.ncurses targetPackages.ncurses.dev ]
207+
++ lib.optional (!targetPlatform.isGhcjs) targetLibffi
208+
++ lib.optional (!enableIntegerSimple && !targetPlatform.isGhcjs) gmp
207209
++ lib.optional (platform.libc != "glibc" && !targetPlatform.isWindows) libiconv
208210
++ lib.optional (enableNUMA && platform.isLinux && !platform.isAarch32 && !platform.isAndroid) numactl
209211
# Even with terminfo disabled some older ghc cross arm and windows compilers do not build unless `ncurses` is found and they seem to want the buildPlatform version
210212
++ lib.optional (!enableTerminfo && haskell-nix.haskellLib.isCrossTarget && (stdenv.targetPlatform.isAarch64 || stdenv.targetPlatform.isWindows) && builtins.compareVersions ghc-version "8.10" < 0) ncurses.dev
211213
++ lib.optional enableDWARF (lib.getLib elfutils);
212214

213215
toolsForTarget =
214-
if hostPlatform == buildPlatform then
215-
[ targetPackages.stdenv.cc ] ++ lib.optional useLLVM llvmPackages.llvm
216+
if targetPlatform.isGhcjs
217+
then [ buildPackages.emscripten ]
218+
else if hostPlatform == buildPlatform
219+
then [ targetPackages.stdenv.cc ] ++ lib.optional useLLVM llvmPackages.llvm
216220
else assert targetPlatform == hostPlatform; # build != host == target
217221
[ stdenv.cc ] ++ lib.optional useLLVM buildLlvmPackages.llvm;
218222

@@ -252,9 +256,10 @@ let
252256
# For build flavours and flavour transformers
253257
# see https://gitlab.haskell.org/ghc/ghc/blob/master/hadrian/doc/flavours.md
254258
hadrianArgs = "--flavour=${
255-
"default"
259+
(if targetPlatform.isGhcjs then "quick" else "default")
256260
+ lib.optionalString (!enableShared) "+no_dynamic_ghc"
257261
+ lib.optionalString useLLVM "+llvm"
262+
+ lib.optionalString targetPlatform.isGhcjs "+native_bignum+no_profiled_libs"
258263
} --docs=no-sphinx -j --verbose";
259264

260265
# When installation is done by copying the stage1 output the directory layout
@@ -314,10 +319,15 @@ stdenv.mkDerivation (rec {
314319
for env in $(env | grep '^TARGET_' | sed -E 's|\+?=.*||'); do
315320
export "''${env#TARGET_}=''${!env}"
316321
done
322+
'' + lib.optionalString (targetPlatform.isGhcjs) ''
323+
export CC="${targetCC}/bin/emcc"
324+
export CXX="${targetCC}/bin/em++"
325+
export LD="${targetCC}/bin/emcc"
326+
export EM_CACHE=$(mktemp -d)
317327
''
318328
# GHC is a bit confused on its cross terminology, as these would normally be
319329
# the *host* tools.
320-
+ ''
330+
+ lib.optionalString (!targetPlatform.isGhcjs) (''
321331
export CC="${targetCC}/bin/${targetCC.targetPrefix}cc"
322332
export CXX="${targetCC}/bin/${targetCC.targetPrefix}c++"
323333
''
@@ -333,7 +343,7 @@ stdenv.mkDerivation (rec {
333343
'' + lib.optionalString (stdenv.targetPlatform.linker == "cctools") ''
334344
export OTOOL="${targetCC.bintools.bintools}/bin/${targetCC.bintools.targetPrefix}otool"
335345
export INSTALL_NAME_TOOL="${bintoolsFor.install_name_tool}/bin/${bintoolsFor.install_name_tool.targetPrefix}install_name_tool"
336-
'' + lib.optionalString (targetPlatform == hostPlatform && useLdGold)
346+
'') + lib.optionalString (targetPlatform == hostPlatform && useLdGold)
337347
# set LD explicitly if we want gold even if we aren't cross compiling
338348
''
339349
export LD="${targetCC.bintools}/bin/ld.gold"
@@ -380,7 +390,7 @@ stdenv.mkDerivation (rec {
380390
./boot
381391
'';
382392

383-
configurePlatforms = [ "build" "host" "target" ];
393+
configurePlatforms = [ "build" "host" ] ++ lib.optional (!targetPlatform.isGhcjs) "target";
384394

385395
enableParallelBuilding = true;
386396
postPatch = "patchShebangs .";
@@ -403,8 +413,8 @@ stdenv.mkDerivation (rec {
403413

404414
buildInputs = [ perl bash ] ++ (libDeps hostPlatform);
405415

406-
depsTargetTarget = map lib.getDev (libDeps targetPlatform);
407-
depsTargetTargetPropagated = map (lib.getOutput "out") (libDeps targetPlatform);
416+
depsTargetTarget = lib.optionals (!targetPlatform.isGhcjs) (map lib.getDev (libDeps targetPlatform));
417+
depsTargetTargetPropagated = lib.optionals (!targetPlatform.isGhcjs) (map (lib.getOutput "out") (libDeps targetPlatform));
408418

409419
# required, because otherwise all symbols from HSffi.o are stripped, and
410420
# that in turn causes GHCi to abort
@@ -442,7 +452,7 @@ stdenv.mkDerivation (rec {
442452
# The ghcprog fixup is for musl (where runhaskell script just needs to point to the correct
443453
# ghc program to work).
444454
sed -i \
445-
-e '2i export PATH="$PATH:${lib.makeBinPath [ targetPackages.stdenv.cc.bintools coreutils ]}"' \
455+
-e '2i export PATH="$PATH:${lib.makeBinPath (lib.optionals (!targetPlatform.isGhcjs) [ targetPackages.stdenv.cc.bintools coreutils ])}"' \
446456
-e 's/ghcprog="ghc-/ghcprog="${targetPrefix}ghc-/' \
447457
$i
448458
done
@@ -666,7 +676,7 @@ stdenv.mkDerivation (rec {
666676
'';
667677
buildPhase = ''
668678
${hadrian}/bin/hadrian ${hadrianArgs}
669-
'' + lib.optionalString installStage1 ''
679+
'' + lib.optionalString (installStage1 && !stdenv.targetPlatform.isGhcjs) ''
670680
${hadrian}/bin/hadrian ${hadrianArgs} stage1:lib:libiserv
671681
'' + lib.optionalString targetPlatform.isMusl ''
672682
${hadrian}/bin/hadrian ${hadrianArgs} stage1:lib:terminfo

materialized/dummy-ghc/aarch64-unknown-linux-gnu-aarch64-unknown-linux-gnu-ghc-9.6.1-x86_64-linux/ghc/info

Lines changed: 0 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

materialized/dummy-ghc/ghc-9.6.1-aarch64-darwin/ghc/info

Lines changed: 0 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)