Emscripten SDK (emsdk)

repository·main·Indexed 25 days ago

https://github.com/emscripten-core/emsdk

A toolchain manager for the Emscripten compiler and its dependencies (Clang, Python, Node.js, etc.) used to compile C/C++ code to WebAssembly. It provides utilities for installing and activating specific SDK versions, building from source, and integrating with Bazel via Bzlmod using the wasm_cc_binary rule. The SDK also includes a Docker image for compilation without local installation.

Tokens
3.3K
Snippets
15
Records
17
Agent score
87%

What's inside emsdk

  1. Push the Emscripten Docker image to a registry

    main

    To push a built image to a registry, you must be logged in via docker login.

    When pushing a specific version, it is recommended to also tag it as latest so that the most recent version is easily accessible.

    # using docker
    docker push emscripten/emsdk:1.39.17
    
    # using predefined make target
    make version=1.39.17 push
    
    # pushing the latest version using docker cli
    docker tag emscripten/emsdk:1.39.17 emscripten/emsdk:latest
    docker push emscripten/emsdk:latest
    
    # pushing the latest version using make
    make version=1.39.17 alias=latest push
  2. Integrate emsdk as a Bzlmod module

    main

    The emsdk Bazel toolchain is now exclusively supported via Bzlmod. To include it in your project, add the following configuration to your MODULE.bazel file. You can specify the desired SDK version using the emsdk_version variable.

    emsdk_version = "4.0.6"
    bazel_dep(name = "emsdk", version = emsdk_version)
    git_override(
        module_name = "emsdk",
        remote = "https://github.com/emscripten-core/emsdk.git",
        strip_prefix = "bazel",
        tag = emsdk_version,
    )
  3. Use a custom Emscripten GitHub fork with emsdk

    main

    To use your own modifications to the Emscripten toolchain while still utilizing the SDK environment, follow these steps:

    1. Install the sdk-main SDK.
    2. Navigate to the cloned Emscripten directory within the emsdk folder.
    3. Add your fork as a new git remote.
    4. Fetch your fork's changes.
    5. Checkout a new branch tracking your fork's main branch.

    This allows you to switch between your fork and the official repository using standard git checkout commands.

    emsdk install sdk-main-64bit
    emsdk activate sdk-main-64bit
    cd emscripten/main
    git remote add myremote https://github.com/mygituseraccount/emscripten.git
    git fetch myremote
    git checkout -b mymain --track myremote/main
  4. Build the Emscripten Docker image

    main

    You can build the Emscripten Docker image locally. You can specify a specific Emscripten version using the EMSCRIPTEN_VERSION build argument. The minimum supported version is 1.39.0.

    If building via docker build directly, ensure the --tag matches the version of the released Emscripten you are targeting.

    # using docker
    docker build \
        --network host \
        --build-arg=EMSCRIPTEN_VERSION=1.39.17 \
        -t emscripten/emsdk:1.39.17 \
        -f docker/Dockerfile \
        .
  5. Use the Emscripten Docker image to compile code

    main

    You can use the emscripten/emsdk Docker image to compile C++ code without installing the Emscripten SDK on your host system.

    To ensure files produced by the container are accessible to your local user and that paths match between the host and container (which helps IDEs resolve file paths), use the following pattern:

    1. Create your source file (e.g., helloworld.cpp).
    2. Run the docker run command with --rm, -v "$(pwd):$(pwd)", and -u $(id -u):$(id -g) flags.
    3. Execute the emcc command inside the container to generate your output.
    # create helloworld.cpp
    cat << EOF > helloworld.cpp
    #include <iostream>
    int main() {
      std::cout << "Hello World!" << std::endl;
      return 0;
    }
    EOF
    
    # compile with docker image
    docker run \
      --rm \
      -v "$(pwd):$(pwd)" \
      -u $(id -u):$(id -g) \
      emscripten/emsdk \
      emcc helloworld.cpp -o helloworld.js
    
    # execute on host machine
    node helloworld.js
  6. Manage Emscripten tools with emsdk

    main

    The emsdk utility is the manager script for the Emscripten SDK. Most operations follow the pattern emsdk <command>.

    Common Commands

    • List tools: Use emsdk list to see all available tools and SDK versions.
      • INSTALLED indicates the tool is on your disk.
      • A star * indicates the tool is currently active.
      • A star in parentheses (*) indicates the tool is active but the current terminal environment is not configured (run source ./emsdk_env.sh or emsdk_env.bat to fix this).
      • Use emsdk list --old to see archived/old versions.
    • Install: emsdk install <tool/sdk name> downloads and installs a specific tool or SDK.
    • Activate: emsdk activate <tool/sdk name> sets the specified tool/SDK as the active version by updating the .emscripten configuration file.
      • On Windows, use --permanent to register the environment for the current user, or --system for all users.
    • Uninstall: emsdk uninstall <tool/sdk name> deletes the tool/SDK from your local drive.
    • Update: emsdk update fetches new package information for all available tools.
    • Help: emsdk help or emsdk shows all available commands.
    emsdk list
    emsdk install latest
    emsdk activate latest
    emsdk uninstall <name>
    emsdk update
  7. Install the latest Emscripten build

    main

    To get the latest binary builds of Emscripten using the emsdk manager, follow these steps in your terminal:

    1. Update your local emsdk repository.
    2. Install the latest version.
    3. Activate the latest version.

    This method uses pre-compiled binaries rather than compiling from source.

    git pull
    ./emsdk install latest
    ./emsdk activate latest
  8. Build Emscripten from source

    main

    If you need to build the latest WASM SDK from source (e.g., to develop patches for LLVM, Binaryen, or Emscripten), use the sdk-main-64bit target:

    emsdk install sdk-main-64bit
    emsdk activate sdk-main-64bit

    Updating source builds: Because sdk-main and similar targets are based on moving git branches, they can become outdated. To update, simply run emsdk install <target> again. This will perform a git pull and an incremental recompilation.

    Troubleshooting source builds: If CMake errors occur during an update, try deleting the intermediate build directory (e.g., emsdk/clang/fastcomp/build_xxx/) before reissuing the install command.

  9. Extend the Emscripten Docker image

    main

    If you need additional tools (like ninja-build) not provided in the base image, you can create a custom Dockerfile that uses emscripten/emsdk as a base.

    # Point at any base image that you find suitable to extend.
    FROM emscripten/emsdk:1.39.17
    
    # Install required tools that are useful for your project i.e. ninja-build
    RUN apt update && apt install -y ninja-build

    Build and test your extended image

    docker build -t extended_emscripten . docker run --rm extended_emscripten ninja --version

  10. Configure emsdk to use custom Python, Java, or Node.js

    main

    By default, installing an SDK (like sdk-1.35.0-64bit) installs a specific, tested set of tools including Python and Node.js.

    If you prefer to use your system's version of Python or Node.js, you can install only the specific components you need instead of the full SDK metapackage. For example, to install only the compiler and frontend without the bundled Python and Node.js, run:

    emsdk install clang-e1.35.0-64bit emscripten-1.35.0
  11. Use a prebuilt Emscripten cache via HTTP

    main

    If you have manually built an Emscripten cache using embuilder and are serving it from an HTTP server, you can declare it in MODULE.bazel using prebuilt_cache.

    Note: You cannot use both prebuilt_cache and configuration/targets simultaneously; prebuilt_cache will take precedence.

    emscripten_cache = use_extension(
        "@emsdk//:emscripten_cache.bzl",
        "emscripten_cache",
    )
    
    emscripten_cache.prebuilt_cache(
        http_archive_url = "https://my-host.com/my-emsdk-cache-4.0.16.tar.gz",
        sha256 = "3e88abcbd22bac7b05af416c8f1859d12572c8e9356db604a2768fcfda863da8",
        strip_prefix = "my-emsdk-cache",
    )