Home Explore Blog Models CI



nixpkgs

1st chunk of `doc/languages-frameworks/emscripten.section.md`
49e552a2b8684c2f2ba736a68ddb172595aa4c8b4b4224c60000000100000b4d
# Emscripten {#emscripten}

[Emscripten](https://github.com/kripken/emscripten): An LLVM-to-JavaScript Compiler

If you want to work with `emcc`, `emconfigure` and `emmake` as you are used to from Ubuntu and similar distributions,

```console
nix-shell -p emscripten
```

A few things to note:

* `export EMCC_DEBUG=2` is nice for debugging
* The build artifact cache in `~/.emscripten` sometimes creates issues and needs to be removed from time to time

## Examples {#declarative-usage}

Let's see two different examples from `pkgs/top-level/emscripten-packages.nix`:

* `pkgs.zlib.override`
* `pkgs.buildEmscriptenPackage`

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.

* 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.

::: {.example #usage-1-pkgs.zlib.override}

# Using `pkgs.zlib.override {}`

This example uses `zlib` from Nixpkgs, but instead of compiling **C** to **ELF** it compiles **C** to **JavaScript** since we were using `pkgs.zlib.override` and changed `stdenv` to `pkgs.emscriptenStdenv`.

A few adaptions and hacks were put in place to make it work.
One advantage is that when `pkgs.zlib` is updated, it will automatically update this package as well.


```nix
(pkgs.zlib.override { stdenv = pkgs.emscriptenStdenv; }).overrideAttrs (old: {
  buildInputs = old.buildInputs ++ [ pkg-config ];
  # we need to reset this setting!
  env = (old.env or { }) // {
    NIX_CFLAGS_COMPILE = "";
  };

  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 = ''
    runHook preBuild

    emmake make

    runHook postBuild
  '';

  installPhase = ''
    runHook preInstall

    emmake make install

    runHook postInstall
  '';

  checkPhase = ''
    runHook preCheck

    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"
    ${pkgs.nodejs}/bin/node ./example.js

    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 ================="

    runHook postCheck
  '';

  postPatch = pkgs.lib.optionalString pkgs.stdenv.hostPlatform.isDarwin ''

Title: Emscripten Usage and Examples in Nixpkgs
Summary
This chunk introduces Emscripten, an LLVM-to-JavaScript compiler, and explains how to use its command-line tools (`emcc`, `emconfigure`, `emmake`) within Nix via `nix-shell -p emscripten`. It provides debugging tips like `export EMCC_DEBUG=2` and addresses common issues such as the `~/.emscripten` cache, recommending `HOME=$TMPDIR` for more deterministic builds. The text then presents two examples from Nixpkgs: `pkgs.zlib.override` and `pkgs.buildEmscriptenPackage`. The `pkgs.zlib.override` example demonstrates compiling Zlib's C code to JavaScript by overriding its `stdenv` to `pkgs.emscriptenStdenv`, detailing necessary adaptations in phases like `configurePhase`, `buildPhase`, `installPhase`, and a custom `checkPhase` that uses `emcc` and `nodejs` to verify functionality. It also notes that `pkgs.buildEmscriptenPackage` requires a `checkPhase` to be implemented with `doCheck = true`.