@@ -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.
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
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
0 commit comments