at master 4.9 kB view raw
1{ 2 lib, 3 stdenv, 4 fetchFromGitHub, 5 python3, 6 nodejs, 7 closurecompiler, 8 jre, 9 binaryen, 10 llvmPackages, 11 symlinkJoin, 12 makeWrapper, 13 replaceVars, 14 buildNpmPackage, 15 emscripten, 16}: 17 18stdenv.mkDerivation rec { 19 pname = "emscripten"; 20 version = "4.0.12"; 21 22 llvmEnv = symlinkJoin { 23 name = "emscripten-llvm-${version}"; 24 paths = with llvmPackages; [ 25 clang-unwrapped 26 (lib.getLib clang-unwrapped) 27 lld 28 llvm 29 ]; 30 }; 31 32 nodeModules = buildNpmPackage { 33 name = "emscripten-node-modules-${version}"; 34 inherit pname version src; 35 36 npmDepsHash = "sha256-Pos7pSboTIpGKtlBm56hJPYb1lDydmUwW1urHetFfeQ="; 37 38 dontBuild = true; 39 40 # Copy node_modules directly. 41 installPhase = '' 42 cp -r node_modules $out/ 43 ''; 44 }; 45 46 src = fetchFromGitHub { 47 owner = "emscripten-core"; 48 repo = "emscripten"; 49 hash = "sha256-MwCUilfyum1yJb6nHEViYiYWufXlz2+krHZmXw2NAck="; 50 rev = version; 51 }; 52 53 strictDeps = true; 54 55 nativeBuildInputs = [ 56 makeWrapper 57 python3 58 ]; 59 buildInputs = [ 60 nodejs 61 ]; 62 63 patches = [ 64 (replaceVars ./0001-emulate-clang-sysroot-include-logic.patch { 65 resourceDir = "${llvmEnv}/lib/clang/${lib.versions.major llvmPackages.llvm.version}/"; 66 }) 67 ]; 68 69 buildPhase = '' 70 runHook preBuild 71 72 patchShebangs . 73 74 # emscripten 4.0.12 requires LLVM tip-of-tree instead of LLVM 21 75 sed -i -e "s/EXPECTED_LLVM_VERSION = 22/EXPECTED_LLVM_VERSION = 21.1/g" tools/shared.py 76 77 # fixes cmake support 78 sed -i -e "s/print \('emcc (Emscript.*\)/sys.stderr.write(\1); sys.stderr.flush()/g" emcc.py 79 80 sed -i "/^def check_sanity/a\\ return" tools/shared.py 81 82 echo "EMSCRIPTEN_ROOT = '$out/share/emscripten'" > .emscripten 83 echo "LLVM_ROOT = '${llvmEnv}/bin'" >> .emscripten 84 echo "NODE_JS = '${nodejs}/bin/node'" >> .emscripten 85 echo "JS_ENGINES = [NODE_JS]" >> .emscripten 86 echo "CLOSURE_COMPILER = ['${closurecompiler}/bin/closure-compiler']" >> .emscripten 87 echo "JAVA = '${jre}/bin/java'" >> .emscripten 88 # to make the test(s) below work 89 # echo "SPIDERMONKEY_ENGINE = []" >> .emscripten 90 echo "BINARYEN_ROOT = '${binaryen}'" >> .emscripten 91 92 # make emconfigure/emcmake use the correct (wrapped) binaries 93 sed -i "s|^EMCC =.*|EMCC='$out/bin/emcc'|" tools/shared.py 94 sed -i "s|^EMXX =.*|EMXX='$out/bin/em++'|" tools/shared.py 95 sed -i "s|^EMAR =.*|EMAR='$out/bin/emar'|" tools/shared.py 96 sed -i "s|^EMRANLIB =.*|EMRANLIB='$out/bin/emranlib'|" tools/shared.py 97 98 runHook postBuild 99 ''; 100 101 installPhase = '' 102 runHook preInstall 103 104 appdir=$out/share/emscripten 105 mkdir -p $appdir 106 cp -r . $appdir 107 chmod -R +w $appdir 108 109 mkdir -p $appdir/node_modules/.bin 110 cp -r ${nodeModules}/* $appdir/node_modules 111 cp -r ${nodeModules}/* $appdir/node_modules/.bin 112 113 cp ${./locate_cache.sh} $appdir/locate_cache.sh 114 chmod +x $appdir/locate_cache.sh 115 116 export EM_CACHE=$out/share/emscripten/cache 117 118 mkdir -p $out/bin 119 for b in em++ em-config emar embuilder.py emcc emcmake emconfigure emmake emranlib emrun emscons emsize; do 120 makeWrapper $appdir/$b $out/bin/$b \ 121 --set NODE_PATH ${nodeModules} \ 122 --set EM_EXCLUSIVE_CACHE_ACCESS 1 \ 123 --set PYTHON ${python3}/bin/python \ 124 --run "source $appdir/locate_cache.sh" 125 done 126 127 # precompile libc (etc.) in all variants: 128 pushd $TMPDIR 129 echo 'int __main_argc_argv( int a, int b ) { return 42; }' >test.c 130 for LTO in -flto ""; do 131 for BIND in "" "--bind"; do 132 # starting with emscripten 3.1.32+, 133 # if pthreads and relocatable are both used, 134 # _emscripten_thread_exit_joinable must be exported 135 # (see https://github.com/emscripten-core/emscripten/pull/18376) 136 # TODO: get library cache to build with both enabled and function exported 137 $out/bin/emcc $LTO $BIND test.c 138 $out/bin/emcc $LTO $BIND -s RELOCATABLE test.c 139 # starting with emscripten 3.1.48+, 140 # to use pthreads, _emscripten_check_mailbox must be exported 141 # (see https://github.com/emscripten-core/emscripten/pull/20604) 142 # TODO: get library cache to build with pthreads at all 143 # $out/bin/emcc $LTO $BIND -s USE_PTHREADS test.c 144 done 145 done 146 popd 147 148 export PYTHON=${python3}/bin/python 149 export NODE_PATH=${nodeModules} 150 pushd $appdir 151 python test/runner.py test_hello_world 152 popd 153 154 runHook postInstall 155 ''; 156 157 passthru = { 158 # HACK: Make emscripten look more like a cc-wrapper to GHC 159 # when building the javascript backend. 160 targetPrefix = "em"; 161 bintools = emscripten; 162 }; 163 164 meta = with lib; { 165 homepage = "https://github.com/emscripten-core/emscripten"; 166 description = "LLVM-to-JavaScript Compiler"; 167 platforms = platforms.all; 168 maintainers = with maintainers; [ 169 qknight 170 matthewbauer 171 raitobezarius 172 willcohen 173 ]; 174 license = licenses.ncsa; 175 }; 176}