Home Explore Blog Models CI



nixpkgs

2nd chunk of `doc/languages-frameworks/emscripten.section.md`
c1f9bc797e3686553bedc246a331d8e45aa9ef440e73dfd00000000100000ec6
    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 ''
    substituteInPlace configure \
      --replace-fail '/usr/bin/libtool' 'ar' \
      --replace-fail 'AR="libtool"' 'AR="ar"' \
      --replace-fail 'ARFLAGS="-o"' 'ARFLAGS="-r"'
  '';
})
```

:::{.example #usage-2-pkgs.buildemscriptenpackage}

# Using `pkgs.buildEmscriptenPackage {}`

This `xmlmirror` example features an Emscripten package that is defined completely from this context and no `pkgs.zlib.override` is used.

```nix
pkgs.buildEmscriptenPackage {
  pname = "xmlmirror";
  version = "1.2.3";

  buildInputs = [
    pkg-config
    autoconf
    automake
    libtool
    gnumake
    libxml2
    nodejs
    openjdk
    json_c
  ];

  nativeBuildInputs = [
    pkg-config
    writableTmpDirAsHomeHook
    zlib
  ];

  src = pkgs.fetchgit {
    url = "https://gitlab.com/odfplugfest/xmlmirror.git";
    rev = "4fd7e86f7c9526b8f4c1733e5c8b45175860a8fd";
    hash = "sha256-i+QgY+5PYVg5pwhzcDnkfXAznBg3e8sWH2jZtixuWsk=";
  };

  configurePhase = ''
    runHook preConfigure

    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

    runHook postConfigure
  '';

  buildPhase = ''
    runHook preBuild

    make -f Makefile.emEnv

    runHook postBuild
  '';

  outputs = [
    "out"
    "doc"
  ];

  installPhase = ''
    runHook preInstall

    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}

    runHook postInstall
  '';

  checkPhase = ''
    runHook preCheck

    runHook postCheck
  '';
}
```

:::

## Debugging {#declarative-debugging}

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

Title: Emscripten Package Definition and Debugging in Nixpkgs
Summary
This chunk concludes the `pkgs.zlib.override` example by detailing a `postPatch` for Darwin, then introduces a second method for defining Emscripten packages from scratch using `pkgs.buildEmscriptenPackage {}`. An example with `xmlmirror` demonstrates this, specifying build inputs, source fetching, and phase-specific modifications. Notably, the `configurePhase` for `xmlmirror` includes `sed` commands to resolve common Emscripten issues like `TOTAL_MEMORY` settings, linker order, and `EXTRA_EXPORTED_RUNTIME_METHODS` flags. Finally, the chunk provides practical debugging advice, showing how to use `nix-shell` to interactively step through an Emscripten package's build phases (unpack, configure, build) for easier troubleshooting and unit test development.