Update examples collection

This commit is contained in:
github-actions[bot] 2025-08-19 09:15:28 +00:00
commit 87d3066428
129 changed files with 21502 additions and 0 deletions

View file

@ -0,0 +1,354 @@
version: 2.1
orbs:
win: circleci/windows@5.0
executors:
ubuntu:
docker:
- image: buildpack-deps:focal
mac_arm64:
environment:
EMSDK_NOTTY: "1"
# Without this, any `brew install` command will result in self-update of
# brew itself which takes more than 4 minutes.
HOMEBREW_NO_AUTO_UPDATE: "1"
macos:
xcode: "13.4.1"
resource_class: macos.m1.medium.gen1
linux_arm64:
machine:
image: ubuntu-2004:2023.07.1
resource_class: arm.medium
commands:
setup-macos:
steps:
- checkout
- run:
name: Install CMake
command: brew install cmake
test-macos:
steps:
- run:
name: test.sh
command: test/test.sh
- run:
name: test.py
command: |
source emsdk_env.sh
test/test.py
test-bazel-linux:
steps:
- checkout
- run:
name: install bazelisk
command: |
wget https://github.com/bazelbuild/bazelisk/releases/download/v1.25.0/bazelisk-linux-amd64
chmod +x bazelisk-linux-amd64
mv bazelisk-linux-amd64 /usr/local/bin/bazel
- run: test/test_bazel.sh
test-bazel-mac:
steps:
- checkout
- run:
name: install bazelisk
command: |
brew install bazelisk
- run: test/test_bazel_mac.sh
test-bazel-windows:
steps:
- checkout
- run:
name: Download Bazelisk
shell: powershell.exe
command: |
$ProgressPreference = "SilentlyContinue"
Invoke-WebRequest -Uri https://github.com/bazelbuild/bazelisk/releases/download/v1.10.1/bazelisk-windows-amd64.exe -OutFile ( New-Item -Path "temp\bazel\bazel.exe" -Force )
- run:
name: Run Tests
shell: powershell.exe
command: |
$env:Path += ";C:\Python27amd64;$pwd\temp\bazel"
.\test\test_bazel.ps1
jobs:
flake8:
executor: ubuntu
steps:
- checkout
- run:
name: install pip
command: |
apt-get update -q
apt-get install -q -y python3-pip
- run: python3 -m pip install --upgrade pip
- run: python3 -m pip install flake8==7.1.1
- run: python3 -m flake8 --show-source --statistics --extend-exclude=./scripts
test-linux:
executor: ubuntu
environment:
EMSDK_NOTTY: "1"
# This is needed because the old gcc-7 that is installed on debian/bionic
# generates warnings about unused variables when doing C++17
# destructuring:
# https://github.com/WebAssembly/binaryen/issues/4353
CXXFLAGS: "-Wno-unused-variable"
# I don't know why circleci VMs pretent to have 36 cores but its a lie.
EMSDK_NUM_CORES: "4"
steps:
- checkout
- run:
name: Install debian packages
command: apt-get update -q && apt-get install -q -y cmake build-essential openjdk-8-jre-headless ksh zsh
- run: test/test_node_path.sh
- run: test/test.sh
- run: test/test_source_env.sh
- run:
name: test.py
command: |
source emsdk_env.sh
test/test.py
test-linux-arm64:
executor: linux_arm64
steps:
- checkout
- run:
name: Install debian packages
command: sudo apt-get update -q && sudo apt-get install -q cmake build-essential openjdk-8-jre-headless
- run: test/test.sh
test-mac-arm64:
executor: mac_arm64
steps:
- setup-macos
- test-macos
test-windows:
executor:
name: win/server-2019
shell: bash.exe
environment:
# We need python installed before we can test anytyhing.
# There seems to be undocument copy of python installed here. Hopefully
# if this disappears there will be another way of getting a re-installed
# version.
PYTHON_BIN: "C:\\Python27amd64"
PYTHONUNBUFFERED: "1"
EMSDK_NOTTY: "1"
steps:
- checkout
- run:
name: Add python to bash path
command: echo "export PATH=\"$PATH:/c/python27amd64/\"" >> $BASH_ENV
- run:
name: Install latest
shell: cmd.exe
command: test\test.bat
- run:
name: test.py
command: |
source emsdk_env.sh
python test/test.py
- run:
name: flagless (process/shell) test
shell: powershell.exe
command: |
test/test_activation.ps1
- run:
name: --permanent test
shell: powershell.exe
command: |
$env:PERMANENT_FLAG="--permanent"
test/test_activation.ps1
- run:
name: --system test
shell: powershell.exe
command: |
$env:SYSTEM_FLAG="--system"
test/test_activation.ps1
- run:
name: Process/Shell PATH preservation test
shell: powershell.exe
command: |
test/test_path_preservation.ps1
- run:
name: User PATH preservation test
shell: powershell.exe
command: |
$env:PERMANENT_FLAG="--permanent"
test/test_path_preservation.ps1
- run:
name: System PATH preservation test
shell: powershell.exe
command: |
$env:SYSTEM_FLAG="--system"
test/test_path_preservation.ps1
build-docker-image-x64:
executor: ubuntu
steps:
- checkout
- run:
name: install docker
command: |
apt-get update -q
apt-get install -q -y ca-certificates curl gnupg lsb-release
mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
apt-get update -q
apt-get install -q -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
- setup_remote_docker
# Build the `latest` version of EMSDK as docker image
- run:
name: build
command: make -C ./docker version=latest build
- run:
name: test
command: make -C ./docker version=latest test
publish-docker-image-x64:
executor: ubuntu
steps:
- checkout
- run:
name: install docker
command: |
apt-get update -q
apt-get install -q -y ca-certificates curl gnupg lsb-release
mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
apt-get update -q
apt-get install -q -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
- setup_remote_docker
- run:
name: build
command: make -C ./docker version=${CIRCLE_TAG} build
- run:
name: test
command: make -C ./docker version=${CIRCLE_TAG} test
- run:
name: push image
command: |
docker login -u "$DOCKER_USER" -p "$DOCKER_PASS"
make -C ./docker version=${CIRCLE_TAG} alias=latest push
publish-docker-image-arm64:
executor: linux_arm64
steps:
- checkout
- run:
name: build
command: make -C ./docker version=${CIRCLE_TAG} build
- run:
name: test
command: make -C ./docker version=${CIRCLE_TAG} test
- run:
name: push image
command: |
docker login -u "$DOCKER_USER" -p "$DOCKER_PASS"
make -C ./docker version=${CIRCLE_TAG} alias=${CIRCLE_TAG}-arm64 only_alias=true push
test-bazel7-linux:
executor: ubuntu
environment:
USE_BAZEL_VERSION: "7.x"
steps:
- test-bazel-linux
test-bazel-latest-linux:
executor: ubuntu
steps:
- test-bazel-linux
test-bazel7-mac-arm64:
executor: mac_arm64
environment:
USE_BAZEL_VERSION: "7.x"
steps:
- test-bazel-mac
test-bazel-latest-mac-arm64:
executor: mac_arm64
steps:
- test-bazel-mac
test-bazel7-windows:
executor:
name: win/server-2019
shell: powershell.exe -ExecutionPolicy Bypass
environment:
PYTHONUNBUFFERED: "1"
EMSDK_NOTTY: "1"
# For some reason version resolution with "7.x" does not work on Windows,
# so we have to specify a full version.
USE_BAZEL_VERSION: "7.6.1"
steps:
- test-bazel-windows
test-bazel-latest-windows:
executor:
name: win/server-2019
shell: powershell.exe -ExecutionPolicy Bypass
environment:
PYTHONUNBUFFERED: "1"
EMSDK_NOTTY: "1"
steps:
- test-bazel-windows
workflows:
flake8:
jobs:
- flake8
test-linux:
jobs:
- test-linux
test-linux-arm64:
jobs:
- test-linux-arm64
test-mac-arm64:
jobs:
- test-mac-arm64
test-windows:
jobs:
- test-windows
build-docker-image:
jobs:
- build-docker-image-x64
- publish-docker-image-x64:
filters:
branches:
ignore: /.*/
tags:
only: /.*/
- publish-docker-image-arm64:
filters:
branches:
ignore: /.*/
tags:
only: /.*/
test-bazel7-linux:
jobs:
- test-bazel7-linux
test-bazel-latest-linux:
jobs:
- test-bazel-latest-linux
test-bazel7-mac-arm64:
jobs:
- test-bazel7-mac-arm64
test-bazel-latest-mac-arm64:
jobs:
- test-bazel-latest-mac-arm64
test-bazel7-windows:
jobs:
- test-bazel7-windows
test-bazel-latest-windows:
jobs:
- test-bazel-latest-windows

View file

@ -0,0 +1,21 @@
# Ignore everything
*
# Allow the entrypoint/test script inside the Docker container
!/docker/entrypoint.sh
!/docker/test_dockerimage.sh
# Allow license file
!LICENSE
# Allow necessary build files in top-level directory
!emscripten-releases-tags.json
!emsdk
!emsdk.py
!emsdk_env.sh
!emsdk_manifest.json
# Allow files required to install legacy versions
!legacy-binaryen-tags.txt
!legacy-emscripten-tags.txt
!llvm-tags-64bit.txt

View file

@ -0,0 +1,24 @@
[flake8]
extend-exclude =
./.*,
./binaryen,
./clang,
./crunch,
./downloads,
./emscripten,
./fastcomp-clang,
./fastcomp,
./git,
./gnu,
./llvm,
./node,
./python,
./releases,
./temp,
./upstream,
# E111: Indentation is not a multiple of four
# E114: Indentation is not a multiple of four (comment)
extend-ignore = E111, E114
max-line-length = 326

View file

@ -0,0 +1,18 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 365
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 30
# Issues with these labels will never be considered stale
exemptLabels:
- pinned
- security
# Label to use when marking an issue as stale
staleLabel: wontfix
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because there has been no
activity in the past year. It will be closed automatically if no further
activity occurs in the next 30 days. Feel free to re-open at any time if this
issue is still relevant.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

View file

@ -0,0 +1,40 @@
name: Create Release PR
on:
workflow_dispatch:
inputs:
lto-sha:
required: true
type: string
nonlto-sha:
required: true
type: string
jobs:
create-release-pr:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Run create_release.py
run: python3 scripts/create_release.py -r ${{ inputs.lto-sha }} -a ${{ inputs.nonlto-sha }} --gh-action
- name: Create PR
id: cpr
uses: peter-evans/create-pull-request@v6
with:
token: ${{ secrets.EMSCRIPTEN_BOT_TOKEN }}
title: Release ${{ env.RELEASE_VERSION }}
commit-message: |
Release ${{ env.RELEASE_VERSION }}
team-reviewers: release-reviewers
labels: release
body: |
With emscripten-releases revisions:
https://chromium.googlesource.com/emscripten-releases/+/${{ inputs.lto-sha }} (LTO)
https://chromium.googlesource.com/emscripten-releases/+/${{ inputs.nonlto-sha }} (asserts)
branch: release_${{ env.RELEASE_VERSION }}
delete-branch: true
- name: Enable auto-merge
run: gh pr merge --squash --auto "${{ steps.cpr.outputs.pull-request-number }}"
env:
GH_TOKEN: ${{ secrets.EMSCRIPTEN_BOT_TOKEN }}

View file

@ -0,0 +1,78 @@
# When a release commit created by create-release.yml is landed, create the
# corresponding tag.
name: Create release tag
on:
push:
paths:
- emscripten-releases-tags.json
- .github/workflows/tag-release.yml
branches:
- main
workflow_dispatch:
jobs:
tag-release:
# Only activate for commits created by the create-release.yml workflow.
# The assumption is that when manual changes happen, we want to handle
# tagging manually too.
name: Check for release commit and create tag
# The author is emscripten-bot when triggered from Chromium CI, and github-actions when manually triggered.
if: ${{ github.event.head_commit.author.username == 'github-actions[bot]' || github.event.head_commit.author.username == 'emscripten-bot' }}
runs-on: ubuntu-latest
outputs:
is_release: ${{ steps.create-tag.outputs.result }}
steps:
- name: Match message and create tag
id: create-tag
uses: actions/github-script@v7
with:
github-token: ${{ secrets.EMSCRIPTEN_BOT_TOKEN }}
# A commit with the message of the form 'Release X.Y.Z' is expected
# to have been created by create_release.py and update the latest
# release in emscripten-releases-tags.json
script: |
const message = `${{ github.event.head_commit.message }}`
const regex = /Release ([0-9]+.[0-9]+.[0-9]+)/;
const match = message.match(regex);
let is_release = false;
if (match) {
const release = match[1];
console.log(`Matched release ${release}`);
await github.rest.git.createRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: `refs/tags/${release}`,
sha: context.sha
});
is_release = true;
} else {
console.log(`Commit message: '${message}' did not match pattern`);
}
return is_release;
dispatch-emscripten-tag:
name: Dispatch workflow to tag emscripten repo
runs-on: ubuntu-latest
needs: tag-release
if: ${{ needs.tag-release.outputs.is_release == 'true' }}
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Find emscripten revision
# get_emscripten_revision_info.py sets env.EMSCRIPTEN_HASH to the
# emscripten hash associated with the latest release in
# emscripten-releases-tags.json
run: python3 scripts/get_emscripten_revision_info.py
- name: Dispatch emscripten workflow
uses: actions/github-script@v7
with:
github-token: ${{ secrets.EMSCRIPTEN_BOT_TOKEN }}
script: |
await github.rest.actions.createWorkflowDispatch({
owner: context.repo.owner,
repo: 'emscripten',
workflow_id: 'tag-release.yml',
ref: 'main',
inputs: { 'release-sha': '${{ env.EMSCRIPTEN_HASH }}' }
});

35
emsdk-cache/emsdk-main/.gitignore vendored Normal file
View file

@ -0,0 +1,35 @@
*.pyc
__pycache__
# Support for --embedded configs
/.emscripten
/.emscripten.old
/.emscripten_cache
/.emscripten_cache__last_clear
/.emscripten_sanity
/.emscripten_sanity_wasm
# Tags files that get generated at runtime
/emscripten-releases-tot.txt
# File that get download/extracted by emsdk itself
/ccache
/gnu
/upstream
/fastcomp
/fastcomp-clang/
/llvm
/ninja
/releases
/clang
/emscripten
/git
/node
/python
/temp
/downloads
/crunch
/java
/mingw
/spidermonkey
/binaryen

View file

@ -0,0 +1,27 @@
Copyright (c) 2018 Emscripten authors (see AUTHORS in Emscripten)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
----------------------------------------------------------------------------
This is the MIT/Expat Licence. For more information see:
1. http://www.opensource.org/licenses/mit-license.php
2. http://en.wikipedia.org/wiki/MIT_License

View file

@ -0,0 +1,245 @@
Emscripten SDK
==============
[![CircleCI](https://circleci.com/gh/emscripten-core/emsdk/tree/main.svg?style=svg)](https://circleci.com/gh/emscripten-core/emsdk/tree/main)
The Emscripten toolchain is distributed as a standalone Emscripten SDK. The SDK
provides all the required tools, such as Clang, Python and Node.js along with an
update mechanism that enables migrating to newer Emscripten versions as they are
released.
You can also set up Emscripten from source, without the pre-built SDK, see
"Installing from Source" below.
## Downloads / How do I get the latest Emscripten build?
To get started with Emscripten development, see the [Emscripten website
documentation](https://emscripten.org/docs/getting_started/downloads.html).
That explains how to use the emsdk to get the latest binary builds (without
compiling from source). Basically, that amounts to
```
git pull
./emsdk install latest
./emsdk activate latest
```
## SDK Concepts
The Emscripten SDK is effectively a small package manager for tools that are
used in conjunction with Emscripten. The following glossary highlights the
important concepts to help understanding the internals of the SDK:
* **Tool**: The basic unit of software bundled in the SDK. A Tool has a name and
a version. For example, 'clang-3.2-32bit' is a Tool that contains the 32-bit
version of the Clang v3.2 compiler.
* **SDK**: A set of tools. For example, 'sdk-1.5.6-32bit' is an SDK consisting
of the tools `clang-3.2-32bit`, `node-0.10.17-32bit`, `python-2.7.5.1-32bit`
and `emscripten-1.5.6`.
* **Active Tool/SDK**: Emscripten SDK stores compiler configuration in a file
called `.emscripten` within the emsdk directory. This file points to paths
for Emscripten, Python, Clang and so on. If the configuration file points to a
Tool in a specific directory, then that tool is denoted as being
**active**. This mechanism allows switching between different installed
tools and SDKs.
* **emsdk**: This is the name of the manager script that Emscripten SDK is
accessed through. Most operations are of the form `emsdk <command>`.
## System Requirements
Using the emsdk pre-compiled packages requires only the minimal set of
dependencies lists below. When building from source a wider set of tools
include git, cmake, and a host compiler are required. See:
https://emscripten.org/docs/building_from_source/toolchain_what_is_needed.html.
### Mac OS X
- For Intel-based Macs, macOS 10.13 or newer. For ARM64 M1 based Macs, macOS
11.0 or newer.
- `java`: For running closure compiler (optional). After installing emscripten
via emsdk, typing 'emcc --help' should pop up a OS X dialog "Java is not
installed. To open java, you need a Java SE 6 runtime. Would you like to
install one now?" that will automatically download a Java runtime to the
system.
### Linux
- `python`: Version 3.8 or above.
- `java`: For running closure compiler (optional)
The emsdk pre-compiled binaries are built against Ubuntu/Focal 20.04 LTS and
therefore depend on system libraries compatible with versions of `glibc` and
`libstdc++` present in that release. If your linux distribution is very old
you may not be able to use the pre-compiled binaries packages.
### Windows
- `java`: For running closure compiler (optional)
## Uninstalling the Emscripten SDK
To remove the Emscripten SDK, simply delete the emsdk directory.
## SDK Maintenance
The following tasks are common with the Emscripten SDK:
### How do I work the emsdk utility?
Run `emsdk help` or just `emsdk` to get information about all available commands.
### How do I check the installation status and version of the SDK and tools?
To get a list of all currently installed tools and SDK versions, and all
available tools, run `emsdk list`.
* A line will be printed for each tool/SDK that is available for installation.
* The text `INSTALLED` will be shown for each tool that has already been
installed.
* If a tool/SDK is currently active, a star * will be shown next to it.
* If a tool/SDK is currently active, but the terminal your are calling emsdk
from does not have `PATH` and environment set up to utilize that tool, a star
in parentheses (\*) will be shown next to it. Run `emsdk_env.bat` (Windows) or
`source ./emsdk_env.sh` (Linux and OS X) to set up the environment for the
calling terminal.
### How do I install a tool/SDK version?
Run the command `emsdk install <tool/sdk name>` to download and install a new
tool or an SDK version.
### How do I remove a tool or an SDK?
Run the command `emsdk uninstall <tool/sdk name>` to delete the given tool or
SDK from the local hard drive completely.
### How do I check for updates to the Emscripten SDK?
`emsdk update` will fetch package information for all the new tools and
SDK versions. After that, run `emsdk install <tool/sdk name>` to install a new
version.
### How do I install an old Emscripten compiler version?
Emsdk contains a history of old compiler versions that you can use to maintain
your migration path. Type `emsdk list --old` to get a list of archived tool and
SDK versions, and `emsdk install <name_of_tool>` to install it.
### I want to build from source!
Some Emsdk Tool and SDK targets refer to packages that are precompiled, and
no compilation is needed when installing them. Other Emsdk Tools and SDK
targets come "from source", meaning that they will fetch the source repositories
using git, and compile the package on demand.
When you run `emsdk list`, it will group the Tools and SDKs under these two
categories.
To obtain and build latest wasm SDK from source, run
```
emsdk install sdk-main-64bit
emsdk activate sdk-main-64bit
```
You can use this target for example to bootstrap developing patches to LLVM,
Binaryen or Emscripten. (After initial installation, use `git remote add`
in the cloned tree to add your own fork to push changes as patches)
If you only intend to contribute to Emscripten repository, and not to LLVM
or Binaryen, you can also use precompiled versions of them, and only git
clone the Emscripten repository. For more details, see
https://emscripten.org/docs/contributing/developers_guide.html?highlight=developer#setting-up
### When working on git branches compiled from source, how do I update to a newer compiler version?
Unlike tags and precompiled versions, a few of the SDK packages are based on
"moving" git branches and compiled from source (e.g. sdk-main,
sdk-main, emscripten-main, binaryen-main). Because of that, the
compiled versions will eventually go out of date as new commits are introduced
to the development branches. To update an old compiled installation of one of
this branches, simply reissue the "emsdk install" command on that tool/SDK. This
will `git pull` the latest changes to the branch and issue an incremental
recompilation of the target in question. This way you can keep calling `emsdk
install` to keep an Emscripten installation up to date with a given git branch.
Note though that if the previously compiled branch is very old, sometimes CMake
gets confused and is unable to properly rebuild a project. This has happened in
the past e.g. when LLVM migrated to requiring a newer CMake version. In cases of
any odd compilation errors, it is advised to try deleting the intermediate build
directory to clear the build (e.g. "emsdk/clang/fastcomp/build_xxx/") before
reissuing `emsdk install`.
### How do I change the currently active SDK version?
You can toggle between different tools and SDK versions by running `emsdk
activate <tool/sdk name>`. Activating a tool will set up `~/.emscripten` to
point to that particular tool. On Windows, you can pass the option `--permanent` to
the `activate` command to register the environment permanently for the current user. Use `--system` to do this for all users.
### How do I track the latest Emscripten development with the SDK?
A common and supported use case of the Emscripten SDK is to enable the workflow
where you directly interact with the github repositories. This allows you to
obtain new features and latest fixes immediately as they are pushed to the
github repository, without having to wait for release to be tagged. You do not
need a github account or a fork of Emscripten to do this. To switch to using the
latest git development branch `main`, run the following:
emsdk install git-1.9.4 # Install git. Skip if the system already has it.
emsdk install sdk-main-64bit # Clone+pull the latest emscripten-core/emscripten/main.
emsdk activate sdk-main-64bit # Set the main SDK as the currently active one.
### How do I use my own Emscripten github fork with the SDK?
It is also possible to use your own fork of the Emscripten repository via the
SDK. This is achieved with standard git machinery, so if you are already
acquainted with working on multiple remotes in a git clone, these steps should
be familiar to you. This is useful in the case when you want to make your own
modifications to the Emscripten toolchain, but still keep using the SDK
environment and tools. To set up your own fork as the currently active
Emscripten toolchain, first install the `sdk-main` SDK like shown in the
previous section, and then run the following commands in the emsdk directory:
cd emscripten/main
# Add a git remote link to your own repository.
git remote add myremote https://github.com/mygituseraccount/emscripten.git
# Obtain the changes in your link.
git fetch myremote
# Switch the emscripten-main tool to use your fork.
git checkout -b mymain --track myremote/main
In this way you can utilize the Emscripten SDK tools while using your own git
fork. You can switch back and forth between remotes via the `git checkout`
command as usual.
### How do I use Emscripten SDK with a custom version of python, java, node.js or some other tool?
The provided Emscripten SDK targets are metapackages that refer to a specific
set of tools that have been tested to work together. For example,
`sdk-1.35.0-64bit` is an alias to the individual packages `clang-e1.35.0-64bit`,
`node-4.1.1-64bit`, `python-2.7.5.3-64bit` and `emscripten-1.35.0`. This means
that if you install this version of the SDK, both python and node.js will be
installed inside emsdk as well. If you want to use your own/system python or
node.js instead, you can opt to install emsdk by specifying the individual set
of packages that you want to use. For example, `emsdk install
clang-e1.35.0-64bit emscripten-1.35.0` will only install the Emscripten
LLVM/Clang compiler and the Emscripten frontend without supplying python and
node.js.
### My installation fails with "fatal error: ld terminated with signal 9 [Killed]"?
This may happen if the system runs out of memory. If you are attempting to build
one of the packages from source and are running in a virtual OS or may have
relatively little RAM and disk space available, then the build might fail. Try
feeding your computer more memory. Another thing to try is to force emsdk
install to build in a singlethreaded mode, which will require less RAM
simultaneously. To do this, pass the `-j1` flag to the `emsdk install` command.
### How do I run Emscripten on 32-bit systems or non-x86-64 systems?
Emscripten SDK releases are no longer packaged or maintained for 32-bit systems.
If you want to run Emscripten on a 32-bit system, you can try manually building
the compiler. Follow the steps in the above section "Building an Emscripten tag
or branch from source" to get started.

View file

@ -0,0 +1,16 @@
# Security Policy
If you have discovered a security vulnerability in this project, please report it
privately. **Do not disclose it as a public issue.** This gives us time to work with you
to fix the issue before public exposure, reducing the chance that the exploit will be
used before a patch is released.
Please submit the report as a [security bug on the Chromium tracker](https://bugs.chromium.org/p/chromium/issues/entry?template=Security%20Bug).
Please provide the following information in your report:
- A description of the vulnerability and its impact
- How to reproduce the issue
- Make it clear that it's an Emscripten SDK bug.
We ask that you give us 90 days to work on a fix before public exposure.

View file

@ -0,0 +1 @@
build --incompatible_enable_cc_toolchain_resolution

View file

@ -0,0 +1 @@
/bazel-*

View file

@ -0,0 +1,79 @@
module(
name = "emsdk",
version = "4.0.13",
)
bazel_dep(name = "platforms", version = "0.0.11")
bazel_dep(name = "bazel_skylib", version = "1.7.1")
bazel_dep(name = "aspect_rules_js", version = "1.42.0")
bazel_dep(name = "rules_nodejs", version = "6.3.2")
bazel_dep(name = "rules_cc", version = "0.1.1")
bazel_dep(name = "rules_python", version = "1.3.0")
python = use_extension("@rules_python//python/extensions:python.bzl", "python")
python.toolchain(
python_version = "3.13",
)
node = use_extension("@rules_nodejs//nodejs:extensions.bzl", "node")
node.toolchain(node_version = "20.18.0")
use_repo(node, "nodejs")
emscripten_deps = use_extension(
"//:emscripten_deps.bzl",
"emscripten_deps",
)
use_repo(emscripten_deps, "emscripten_bin_linux")
use_repo(emscripten_deps, "emscripten_bin_linux_arm64")
use_repo(emscripten_deps, "emscripten_bin_mac")
use_repo(emscripten_deps, "emscripten_bin_mac_arm64")
use_repo(emscripten_deps, "emscripten_bin_win")
npm = use_extension(
"@aspect_rules_js//npm:extensions.bzl",
"npm",
)
npm.npm_translate_lock(
name = "emscripten_npm_linux",
data = ["@emscripten_bin_linux//:emscripten/package.json"],
npm_package_lock = "@emscripten_bin_linux//:emscripten/package-lock.json",
)
npm.npm_translate_lock(
name = "emscripten_npm_linux_arm64",
data = ["@emscripten_bin_linux_arm64//:emscripten/package.json"],
npm_package_lock = "@emscripten_bin_linux_arm64//:emscripten/package-lock.json",
)
npm.npm_translate_lock(
name = "emscripten_npm_mac",
data = ["@emscripten_bin_mac//:emscripten/package.json"],
npm_package_lock = "@emscripten_bin_mac//:emscripten/package-lock.json",
)
npm.npm_translate_lock(
name = "emscripten_npm_mac_arm64",
data = ["@emscripten_bin_mac_arm64//:emscripten/package.json"],
npm_package_lock = "@emscripten_bin_mac_arm64//:emscripten/package-lock.json",
)
npm.npm_translate_lock(
name = "emscripten_npm_win",
data = ["@emscripten_bin_win//:emscripten/package.json"],
npm_package_lock = "@emscripten_bin_win//:emscripten/package-lock.json",
)
use_repo(
npm,
"emscripten_npm_linux",
"emscripten_npm_linux_arm64",
"emscripten_npm_mac",
"emscripten_npm_mac_arm64",
"emscripten_npm_win",
)
emscripten_cache = use_extension("//:emscripten_cache.bzl", "emscripten_cache")
use_repo(emscripten_cache, "emscripten_cache")
register_toolchains(
"//emscripten_toolchain:cc-toolchain-wasm-emscripten_linux",
"//emscripten_toolchain:cc-toolchain-wasm-emscripten_linux_arm64",
"//emscripten_toolchain:cc-toolchain-wasm-emscripten_mac",
"//emscripten_toolchain:cc-toolchain-wasm-emscripten_mac_arm64",
"//emscripten_toolchain:cc-toolchain-wasm-emscripten_win",
)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,90 @@
# Bazel Emscripten toolchain
## Setup Instructions
Support for depending on emsdk with a WORKSPACE file was removed and last available in [emsdk version 4.0.6](https://github.com/emscripten-core/emsdk/tree/24fc909c0da13ef641d5ae75e89b5a97f25e37aa). Now we only support inclusion as a bzlmod module.
In your `MODULE.bazel` file, put:
```starlark
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,
)
```
You can use a different version of this SDK by changing it in your `MODULE.bazel` file. The Emscripten version is by default the same as the SDK version, but you can use a different one as well by adding to your `MODULE.bazel`:
```
emscripten_deps = use_extension(
"@emsdk//:emscripten_deps.bzl",
"emscripten_deps",
)
emscripten_deps.config(version = "4.0.1")
```
## Building
Put the following line into your `.bazelrc`:
```
build --incompatible_enable_cc_toolchain_resolution
```
Then write a new rule wrapping your `cc_binary`.
```starlark
load("@rules_cc//cc:defs.bzl", "cc_binary")
load("@emsdk//emscripten_toolchain:wasm_rules.bzl", "wasm_cc_binary")
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
)
wasm_cc_binary(
name = "hello-world-wasm",
cc_target = ":hello-world",
)
```
Now you can run `bazel build :hello-world-wasm`. The result of this build will
be the individual files produced by emscripten. Note that some of these files
may be empty. This is because bazel has no concept of optional outputs for
rules.
`wasm_cc_binary` uses transition to use emscripten toolchain on `cc_target`
and all of its dependencies, and does not require amending `.bazelrc`. This
is the preferred way, since it also unpacks the resulting tarball.
The Emscripten cache shipped by default does not include LTO, 64-bit or PIC
builds of the system libraries and ports. If you wish to use these features you
will need to declare the cache in your `MODULE.bazel` as follows. Note
that the configuration consists of the same flags that can be passed to
embuilder. If `targets` is not set, all system libraries and ports will be
built, i.e., the `ALL` option to embuilder.
```starlark
emscripten_cache = use_extension(
"@emsdk//:emscripten_cache.bzl",
"emscripten_cache",
)
emscripten_cache.configuration(flags = ["--lto"])
emscripten_cache.targets(targets = [
"crtbegin",
"libprintf_long_double-debug",
"libstubs-debug",
"libnoexit",
"libc-debug",
"libdlmalloc",
"libcompiler_rt",
"libc++-noexcept",
"libc++abi-debug-noexcept",
"libsockets"
])
```
See `test_external/` for an example using [embind](https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html).

View file

@ -0,0 +1,2 @@
build:wasm --incompatible_enable_cc_toolchain_resolution
build:wasm --platforms=@emsdk//:platform_wasm

View file

@ -0,0 +1,93 @@
"""A templated build file for emscripten repositories"""
EMSCRIPTEN_BUILD_FILE_CONTENT_TEMPLATE = """
package(default_visibility = ['//visibility:public'])
filegroup(
name = "all",
srcs = glob(["**"]),
)
filegroup(
name = "includes",
srcs = glob([
"emscripten/cache/sysroot/include/c++/v1/**",
"emscripten/cache/sysroot/include/compat/**",
"emscripten/cache/sysroot/include/**",
"lib/clang/**/include/**",
]),
)
filegroup(
name = "emcc_common",
srcs = [
"emscripten/emcc.py",
"emscripten/embuilder.py",
"emscripten/emscripten-version.txt",
"emscripten/cache/sysroot_install.stamp",
"emscripten/src/settings.js",
"emscripten/src/settings_internal.js",
] + glob(
include = [
"emscripten/third_party/**",
"emscripten/tools/**",
],
exclude = [
"**/__pycache__/**",
],
),
)
filegroup(
name = "compiler_files",
srcs = [
"bin/clang{bin_extension}",
"bin/clang++{bin_extension}",
":emcc_common",
":includes",
],
)
filegroup(
name = "linker_files",
srcs = [
"bin/clang{bin_extension}",
"bin/llvm-ar{bin_extension}",
"bin/llvm-dwarfdump{bin_extension}",
"bin/llvm-nm{bin_extension}",
"bin/llvm-objcopy{bin_extension}",
"bin/wasm-ctor-eval{bin_extension}",
"bin/wasm-emscripten-finalize{bin_extension}",
"bin/wasm-ld{bin_extension}",
"bin/wasm-metadce{bin_extension}",
"bin/wasm-opt{bin_extension}",
"bin/wasm-split{bin_extension}",
"bin/wasm2js{bin_extension}",
":emcc_common",
] + glob(
include = [
"emscripten/cache/sysroot/lib/**",
"emscripten/node_modules/**",
"emscripten/src/**",
],
),
)
filegroup(
name = "ar_files",
srcs = [
"bin/llvm-ar{bin_extension}",
"emscripten/emar.py",
"emscripten/emscripten-version.txt",
"emscripten/src/settings.js",
"emscripten/src/settings_internal.js",
] + glob(
include = [
"emscripten/tools/**",
],
exclude = [
"**/__pycache__/**",
],
),
)
"""

View file

@ -0,0 +1,113 @@
BUILD_FILE_CONTENT_TEMPLATE = """
package(default_visibility = ['//visibility:public'])
exports_files(['emscripten_config'])
"""
EMBUILDER_CONFIG_TEMPLATE = """
CACHE = '{cache}'
BINARYEN_ROOT = '{binaryen_root}'
LLVM_ROOT = '{llvm_root}'
"""
def get_root_and_script_ext(repository_ctx):
if repository_ctx.os.name.startswith("linux"):
if "amd64" in repository_ctx.os.arch or "x86_64" in repository_ctx.os.arch:
return (repository_ctx.path(Label("@emscripten_bin_linux//:BUILD.bazel")).dirname, "")
elif "aarch64" in repository_ctx.os.arch:
return (repository_ctx.path(Label("@emscripten_bin_linux_arm64//:BUILD.bazel")).dirname, "")
else:
fail("Unsupported architecture for Linux")
elif repository_ctx.os.name.startswith("mac"):
if "amd64" in repository_ctx.os.arch or "x86_64" in repository_ctx.os.arch:
return (repository_ctx.path(Label("@emscripten_bin_mac//:BUILD.bazel")).dirname, "")
elif "aarch64" in repository_ctx.os.arch:
return (repository_ctx.path(Label("@emscripten_bin_mac_arm64//:BUILD.bazel")).dirname, "")
else:
fail("Unsupported architecture for MacOS")
elif repository_ctx.os.name.startswith("windows"):
return (repository_ctx.path(Label("@emscripten_bin_win//:BUILD.bazel")).dirname, ".bat")
else:
fail("Unsupported operating system")
def _emscripten_cache_repository_impl(repository_ctx):
# Read the default emscripten configuration file
default_config = repository_ctx.read(
repository_ctx.path(
Label("@emsdk//emscripten_toolchain:default_config"),
),
)
if repository_ctx.attr.targets or repository_ctx.attr.configuration:
root, script_ext = get_root_and_script_ext(repository_ctx)
llvm_root = root.get_child("bin")
cache = repository_ctx.path("cache")
# Create configuration file
embuilder_config_content = EMBUILDER_CONFIG_TEMPLATE.format(
cache = cache,
binaryen_root = root,
llvm_root = llvm_root,
)
repository_ctx.file("embuilder_config", embuilder_config_content)
embuilder_config_path = repository_ctx.path("embuilder_config")
embuilder_path = "{}{}".format(root.get_child("emscripten").get_child("embuilder"), script_ext)
# Prepare the command line
if repository_ctx.attr.targets:
targets = repository_ctx.attr.targets
else:
# If no targets are requested, build everything
targets = ["ALL"]
flags = ["--em-config", embuilder_config_path] + repository_ctx.attr.configuration
embuilder_args = [embuilder_path] + flags + ["build"] + targets
# Run embuilder
repository_ctx.report_progress("Building secondary cache")
result = repository_ctx.execute(
embuilder_args,
quiet = True,
environment = {
"EM_IGNORE_SANITY": "1",
"EM_NODE_JS": "empty",
},
)
if result.return_code != 0:
fail("Embuilder exited with a non-zero return code")
# Override Emscripten's cache with the secondary cache
default_config += "CACHE = '{}'\n".format(cache)
# Create the configuration file for the toolchain and export
repository_ctx.file("emscripten_config", default_config)
repository_ctx.file("BUILD.bazel", BUILD_FILE_CONTENT_TEMPLATE)
_emscripten_cache_repository = repository_rule(
implementation = _emscripten_cache_repository_impl,
attrs = {
"configuration": attr.string_list(),
"targets": attr.string_list(),
},
)
def _emscripten_cache_impl(ctx):
all_configuration = []
all_targets = []
for mod in ctx.modules:
for configuration in mod.tags.configuration:
all_configuration += configuration.flags
for targets in mod.tags.targets:
all_targets += targets.targets
_emscripten_cache_repository(
name = "emscripten_cache",
configuration = all_configuration,
targets = all_targets,
)
emscripten_cache = module_extension(
tag_classes = {
"configuration": tag_class(attrs = {"flags": attr.string_list()}),
"targets": tag_class(attrs = {"targets": attr.string_list()}),
},
implementation = _emscripten_cache_impl,
)

View file

@ -0,0 +1,99 @@
load(":remote_emscripten_repository.bzl", "remote_emscripten_repository")
load(":revisions.bzl", "EMSCRIPTEN_TAGS")
def _parse_version(v):
return [int(u) for u in v.split(".")]
def _empty_repository_impl(ctx):
ctx.file("MODULE.bazel", """module(name = "{}")""".format(ctx.name))
ctx.file("BUILD.bazel", "")
_empty_repository = repository_rule(
implementation = _empty_repository_impl,
)
def emscripten_repo_name(name):
return "emscripten_bin_{}".format(name)
def _emscripten_deps_impl(ctx):
version = None
for mod in ctx.modules:
for config in mod.tags.config:
if config.version and version != None:
fail("More than one emscripten version specified!")
version = config.version
if version == None:
version = "latest"
if version == "latest":
version = reversed(sorted(EMSCRIPTEN_TAGS.keys(), key = _parse_version))[0]
revision = EMSCRIPTEN_TAGS[version]
emscripten_url = "https://storage.googleapis.com/webassembly/emscripten-releases-builds/{}/{}/wasm-binaries{}.{}"
remote_emscripten_repository(
name = emscripten_repo_name("linux"),
bin_extension = "",
sha256 = revision.sha_linux,
strip_prefix = "install",
type = "tar.xz",
url = emscripten_url.format("linux", revision.hash, "", "tar.xz"),
)
# Not all versions have a linux/arm64 release: https://github.com/emscripten-core/emsdk/issues/547
if hasattr(revision, "sha_linux_arm64"):
remote_emscripten_repository(
name = emscripten_repo_name("linux_arm64"),
bin_extension = "",
sha256 = revision.sha_linux_arm64,
strip_prefix = "install",
type = "tar.xz",
url = emscripten_url.format("linux", revision.hash, "-arm64", "tar.xz"),
)
else:
_empty_repository(
name = emscripten_repo_name("linux_arm64"),
)
remote_emscripten_repository(
name = emscripten_repo_name("mac"),
bin_extension = "",
sha256 = revision.sha_mac,
strip_prefix = "install",
type = "tar.xz",
url = emscripten_url.format("mac", revision.hash, "", "tar.xz"),
)
remote_emscripten_repository(
name = emscripten_repo_name("mac_arm64"),
bin_extension = "",
sha256 = revision.sha_mac_arm64,
strip_prefix = "install",
type = "tar.xz",
url = emscripten_url.format("mac", revision.hash, "-arm64", "tar.xz"),
)
remote_emscripten_repository(
name = emscripten_repo_name("win"),
bin_extension = ".exe",
sha256 = revision.sha_win,
strip_prefix = "install",
type = "zip",
url = emscripten_url.format("win", revision.hash, "", "zip"),
)
emscripten_deps = module_extension(
tag_classes = {
"config": tag_class(
attrs = {
"version": attr.string(
doc = "Version to use. 'latest' to use latest.",
values = ["latest"] + EMSCRIPTEN_TAGS.keys(),
),
},
),
},
implementation = _emscripten_deps_impl,
)

View file

@ -0,0 +1,43 @@
load("//:emscripten_deps.bzl", "emscripten_repo_name")
load("//:remote_emscripten_repository.bzl", "create_toolchains", "emscripten_toolchain_name")
load("@rules_python//python:py_binary.bzl", "py_binary")
package(default_visibility = ["//visibility:public"])
# dlmalloc.bc is implicitly added by the emscripten toolchain
cc_library(name = "malloc")
create_toolchains(
name = emscripten_toolchain_name("linux"),
repo_name = emscripten_repo_name("linux"),
exec_compatible_with = [ "@platforms//os:linux", "@platforms//cpu:x86_64"],
)
create_toolchains(
name = emscripten_toolchain_name("linux_arm64"),
repo_name = emscripten_repo_name("linux_arm64"),
exec_compatible_with = ["@platforms//os:linux", "@platforms//cpu:arm64"],
)
create_toolchains(
name = emscripten_toolchain_name("mac"),
repo_name = emscripten_repo_name("mac"),
exec_compatible_with = ["@platforms//os:macos", "@platforms//cpu:x86_64"],
)
create_toolchains(
name = emscripten_toolchain_name("mac_arm64"),
repo_name = emscripten_repo_name("mac_arm64"),
exec_compatible_with = ["@platforms//os:macos", "@platforms//cpu:arm64"],
)
create_toolchains(
name = emscripten_toolchain_name("win"),
repo_name = emscripten_repo_name("win"),
exec_compatible_with = ["@platforms//os:windows", "@platforms//cpu:x86_64"],
)
py_binary(
name = "wasm_binary",
srcs = ["wasm_binary.py"],
)

Some files were not shown because too many files have changed in this diff Show more