1{ lib, stdenv, fetchFromGitHub, python3, nodejs, closurecompiler
2, jre, binaryen
3, llvmPackages_11
4, symlinkJoin, makeWrapper
5, mkYarnModules
6}:
7
8stdenv.mkDerivation rec {
9 pname = "emscripten";
10 version = "2.0.1";
11
12 llvmEnv = symlinkJoin {
13 name = "emscripten-llvm-${version}";
14 paths = with llvmPackages_11; [ clang-unwrapped lld llvm ];
15 };
16
17 nodeModules = mkYarnModules {
18 name = "emscripten-node-modules-${version}";
19 inherit pname version;
20 # it is vitally important the the package.json has name and version fields
21 packageJSON = ./package.json;
22 yarnLock = ./yarn.lock;
23 yarnNix = ./yarn.nix;
24 };
25
26 src = fetchFromGitHub {
27 owner = "emscripten-core";
28 repo = "emscripten";
29 sha256 = "06dsd819qjv4n2ihrz1mpn5aigmbv0gpkm7iw06wrqx30nzphnpk";
30 rev = version;
31 };
32
33 nativeBuildInputs = [ makeWrapper ];
34 buildInputs = [ nodejs python3 ];
35
36 buildPhase = ''
37 patchShebangs .
38
39 # fixes cmake support
40 sed -i -e "s/print \('emcc (Emscript.*\)/sys.stderr.write(\1); sys.stderr.flush()/g" emcc.py
41
42 # disables cache in user home, use installation directory instead
43 sed -i '/^def/!s/root_is_writable()/True/' tools/shared.py
44 sed -i "/^def check_sanity/a\\ return" tools/shared.py
45
46 # required for wasm2c
47 ln -s ${nodeModules}/node_modules .
48
49 echo "EMSCRIPTEN_ROOT = '$appdir'" > .emscripten
50 echo "LLVM_ROOT = '${llvmEnv}/bin'" >> .emscripten
51 echo "NODE_JS = '${nodejs}/bin/node'" >> .emscripten
52 echo "JS_ENGINES = [NODE_JS]" >> .emscripten
53 echo "CLOSURE_COMPILER = ['${closurecompiler}/bin/closure-compiler']" >> .emscripten
54 echo "JAVA = '${jre}/bin/java'" >> .emscripten
55 # to make the test(s) below work
56 # echo "SPIDERMONKEY_ENGINE = []" >> .emscripten
57 echo "BINARYEN_ROOT = '${binaryen}'" >> .emscripten
58
59 # make emconfigure/emcmake use the correct (wrapped) binaries
60 sed -i "s|^EMCC =.*|EMCC='$out/bin/emcc'|" tools/shared.py
61 sed -i "s|^EMXX =.*|EMXX='$out/bin/em++'|" tools/shared.py
62 sed -i "s|^EMAR =.*|EMAR='$out/bin/emar'|" tools/shared.py
63 sed -i "s|^EMRANLIB =.*|EMRANLIB='$out/bin/emranlib'|" tools/shared.py
64
65 # The tests use the C compiler to compile generated C code,
66 # use the wrapped compiler
67 sed -i 's/shared.CLANG_CC/"cc"/' tests/runner.py
68 '';
69
70 installPhase = ''
71 appdir=$out/share/emscripten
72 mkdir -p $appdir
73 cp -r . $appdir
74 chmod -R +w $appdir
75
76 mkdir -p $out/bin
77 for b in em++ em-config emar embuilder.py emcc emcmake emconfigure emlink.py emmake emranlib emrun emscons; do
78 makeWrapper $appdir/$b $out/bin/$b \
79 --set NODE_PATH ${nodeModules}/node_modules \
80 --set EM_EXCLUSIVE_CACHE_ACCESS 1 \
81 --set PYTHON ${python3}/bin/python
82 done
83
84 # precompile libc (etc.) in all variants:
85 pushd $TMPDIR
86 echo 'int main() { return 42; }' >test.c
87 for LTO in -flto ""; do
88 # wasm2c doesn't work with PIC
89 $out/bin/emcc -s WASM2C -s STANDALONE_WASM $LTO test.c
90
91 for RELOCATABLE in "" "-s RELOCATABLE"; do
92 $out/bin/emcc $RELOCATABLE $LTO test.c
93 done
94 done
95 popd
96
97 export PYTHON=${python3}/bin/python
98 export NODE_PATH=${nodeModules}/node_modules
99 pushd $appdir
100 python tests/runner.py test_hello_world
101 popd
102 '';
103
104 meta = with lib; {
105 homepage = "https://github.com/emscripten-core/emscripten";
106 description = "An LLVM-to-JavaScript Compiler";
107 platforms = platforms.all;
108 maintainers = with maintainers; [ qknight matthewbauer ];
109 license = licenses.ncsa;
110 };
111}