2021-01-01 17:45:43 +00:00
# Emscripten {#emscripten}
2018-03-18 12:34:46 +00:00
[Emscripten ](https://github.com/kripken/emscripten ): An LLVM-to-JavaScript Compiler
2023-10-02 14:57:21 +00:00
If you want to work with `emcc` , `emconfigure` and `emmake` as you are used to from Ubuntu and similar distributions,
2018-03-18 12:34:46 +00:00
2023-10-02 14:57:21 +00:00
```console
nix-shell -p emscripten
```
2018-03-18 12:34:46 +00:00
A few things to note:
* `export EMCC_DEBUG=2` is nice for debugging
2023-10-02 14:57:21 +00:00
* The build artifact cache in `~/.emscripten` sometimes creates issues and needs to be removed from time to time
2018-03-18 12:34:46 +00:00
2021-06-05 19:22:45 +00:00
## Declarative usage {#declarative-usage}
2018-03-18 12:34:46 +00:00
Let's see two different examples from `pkgs/top-level/emscripten-packages.nix` :
* `pkgs.zlib.override`
* `pkgs.buildEmscriptenPackage`
2023-10-02 14:57:21 +00:00
A special requirement of the `pkgs.buildEmscriptenPackage` is the `doCheck = true` .
This means each Emscripten package requires that a [`checkPhase` ](#ssec-check-phase ) is implemented.
2018-03-18 12:34:46 +00:00
2023-10-02 14:57:21 +00:00
* Use `export EMCC_DEBUG=2` from within a phase to get more detailed debug output what is going wrong.
* The cache at `~/.emscripten` requires to set `HOME=$TMPDIR` in individual phases.
This makes compilation slower but also more deterministic.
2018-03-18 12:34:46 +00:00
See the `zlib` example:
zlib = (pkgs.zlib.override {
stdenv = pkgs.emscriptenStdenv;
2023-02-23 16:09:09 +00:00
}).overrideAttrs
2018-03-18 12:34:46 +00:00
(old: rec {
2021-01-19 03:19:48 +00:00
buildInputs = old.buildInputs ++ [ pkg-config ];
2018-03-18 12:34:46 +00:00
# we need to reset this setting!
2023-02-20 15:17:34 +00:00
env = (old.env or { }) // { NIX_CFLAGS_COMPILE = ""; };
2018-03-18 12:34:46 +00:00
configurePhase = ''
# FIXME: Some tests require writing at $HOME
HOME=$TMPDIR
runHook preConfigure
#export EMCC_DEBUG=2
emconfigure ./configure --prefix=$out --shared
runHook postConfigure
'';
dontStrip = true;
outputs = [ "out" ];
buildPhase = ''
emmake make
'';
installPhase = ''
emmake make install
'';
checkPhase = ''
echo "================= testing zlib using node ================="
echo "Compiling a custom test"
set -x
emcc -O2 -s EMULATE_FUNCTION_POINTER_CASTS=1 test/example.c -DZ_SOLO \
libz.so.${old.version} -I . -o example.js
echo "Using node to execute the test"
2020-07-31 05:06:53 +00:00
${pkgs.nodejs}/bin/node ./example.js
2018-03-18 12:34:46 +00:00
set +x
if [ $? -ne 0 ]; then
echo "test failed for some reason"
exit 1;
else
echo "it seems to work! very good."
fi
echo "================= /testing zlib using node ================="
'';
2021-01-10 19:08:30 +00:00
postPatch = pkgs.lib.optionalString pkgs.stdenv.isDarwin ''
2018-03-18 12:34:46 +00:00
substituteInPlace configure \
--replace '/usr/bin/libtool' 'ar' \
--replace 'AR="libtool"' 'AR="ar"' \
--replace 'ARFLAGS="-o"' 'ARFLAGS="-r"'
'';
});
2021-06-05 19:22:45 +00:00
### Usage 2: pkgs.buildEmscriptenPackage {#usage-2-pkgs.buildemscriptenpackage}
2018-03-18 12:34:46 +00:00
2020-07-31 05:06:53 +00:00
This `xmlmirror` example features a emscriptenPackage which is defined completely from this context and no `pkgs.zlib.override` is used.
2018-03-18 12:34:46 +00:00
xmlmirror = pkgs.buildEmscriptenPackage rec {
name = "xmlmirror";
2021-01-19 03:19:48 +00:00
buildInputs = [ pkg-config autoconf automake libtool gnumake libxml2 nodejs openjdk json_c ];
nativeBuildInputs = [ pkg-config zlib ];
2018-03-18 12:34:46 +00:00
src = pkgs.fetchgit {
url = "https://gitlab.com/odfplugfest/xmlmirror.git";
rev = "4fd7e86f7c9526b8f4c1733e5c8b45175860a8fd";
doc: use sri hash syntax
The nixpkgs manual contains references to both sri hash and explicit
sha256 attributes. This is at best confusing to new users. Since the
final destination is exclusive use of sri hashes, see nixos/rfcs#131,
might as well push new users in that direction gently.
Notable exceptions to sri hash support are builtins.fetchTarball,
cataclysm-dda, coq, dockerTools.pullimage, elixir.override, and
fetchCrate. None, other than builtins.fetchTarball, are fundamentally
incompatible, but all currently accept explicit sha256 attributes as
input. Because adding backwards compatibility is out of scope for this
change, they have been left intact, but migration to sri format has been
made for any using old hash formats.
All hashes have been manually tested to be accurate, and updates were
only made for missing upstream artefacts or bugs.
2022-12-03 19:49:00 +00:00
hash = "sha256-i+QgY+5PYVg5pwhzcDnkfXAznBg3e8sWH2jZtixuWsk=";
2018-03-18 12:34:46 +00:00
};
configurePhase = ''
rm -f fastXmlLint.js*
# a fix for ERROR:root:For asm.js, TOTAL_MEMORY must be a multiple of 16MB, was 234217728
# https://gitlab.com/odfplugfest/xmlmirror/issues/8
sed -e "s/TOTAL_MEMORY=234217728/TOTAL_MEMORY=268435456/g" -i Makefile.emEnv
# https://github.com/kripken/emscripten/issues/6344
# https://gitlab.com/odfplugfest/xmlmirror/issues/9
sed -e "s/\$(JSONC_LDFLAGS) \$(ZLIB_LDFLAGS) \$(LIBXML20_LDFLAGS)/\$(JSONC_LDFLAGS) \$(LIBXML20_LDFLAGS) \$(ZLIB_LDFLAGS) /g" -i Makefile.emEnv
# https://gitlab.com/odfplugfest/xmlmirror/issues/11
sed -e "s/-o fastXmlLint.js/-s EXTRA_EXPORTED_RUNTIME_METHODS='[\"ccall\", \"cwrap\"]' -o fastXmlLint.js/g" -i Makefile.emEnv
'';
buildPhase = ''
HOME=$TMPDIR
make -f Makefile.emEnv
'';
outputs = [ "out" "doc" ];
installPhase = ''
mkdir -p $out/share
mkdir -p $doc/share/${name}
cp Demo* $out/share
cp -R codemirror-5.12 $out/share
cp fastXmlLint.js* $out/share
cp *.xsd $out/share
cp *.js $out/share
cp *.xhtml $out/share
cp *.html $out/share
cp *.json $out/share
cp *.rng $out/share
cp README.md $doc/share/${name}
'';
checkPhase = ''
'';
2020-07-31 05:06:53 +00:00
};
2018-03-18 12:34:46 +00:00
2021-06-05 19:22:45 +00:00
### Declarative debugging {#declarative-debugging}
2018-03-18 12:34:46 +00:00
Use `nix-shell -I nixpkgs=/some/dir/nixpkgs -A emscriptenPackages.libz` and from there you can go trough the individual steps. This makes it easy to build a good `unit test` or list the files of the project.
1. `nix-shell -I nixpkgs=/some/dir/nixpkgs -A emscriptenPackages.libz`
2. `cd /tmp/`
3. `unpackPhase`
4. cd libz-1.2.3
5. `configurePhase`
6. `buildPhase`
7. ... happy hacking...