Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 135 additions & 0 deletions projects/emscripten.org/package.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# Emscripten β€” LLVM-based C/C++ β†’ WebAssembly toolchain.
#
# Provides emcc/em++/emar/emranlib wrappers around llvm.org clang
# that target WebAssembly. The emscripten Python toolkit + Node.js
# runtime are required at runtime.
#
# Closes part of pkgxdev/pantry#99 (Top 300 holdout #594).

distributable:
url: https://github.com/emscripten-core/emscripten/archive/refs/tags/{{ version.raw }}.tar.gz
strip-components: 1

versions:
github: emscripten-core/emscripten/tags
match: /^\d+\.\d+\.\d+$/

platforms:
- linux/x86-64
- linux/aarch64
- darwin/x86-64
- darwin/aarch64

dependencies:
python.org: '>=3.9'
nodejs.org: '*'
llvm.org: '*'
github.com/WebAssembly/binaryen: '*'

runtime:
env:
EMSDK: ${{prefix}}
EM_CONFIG: ${{prefix}}/.emscripten
LLVM_ROOT: ${{deps.llvm.org.prefix}}/bin
BINARYEN_ROOT: ${{deps.github.com/WebAssembly/binaryen.prefix}}
NODE_JS: ${{deps.nodejs.org.prefix}}/bin/node
PYTHON: ${{deps.python.org.prefix}}/bin/python3

build:
dependencies:
gnu.org/coreutils: '*'

script:
# Emscripten is a Python toolchain β€” `make install` doesn't exist.
# Copy the entire tree into {{prefix}} and seed a minimal .emscripten
# config that points at llvm.org's clang.
- run: |
mkdir -p "{{prefix}}"
cp -R . "{{prefix}}/"
cat > "{{prefix}}/.emscripten" <<EOF
LLVM_ROOT = "{{deps.llvm.org.prefix}}/bin"
BINARYEN_ROOT = "{{deps.github.com/WebAssembly/binaryen.prefix}}"
NODE_JS = "{{deps.nodejs.org.prefix}}/bin/node"
EMSCRIPTEN_ROOT = "{{prefix}}"
COMPILER_ENGINE = NODE_JS
JS_ENGINES = [NODE_JS]
EOF
# BINARYEN_ROOT points at WebAssembly/binaryen which ships
# wasm-opt. pantry's llvm.org does NOT bundle wasm-opt, so
# emscripten requires binaryen as a separate dep.

# emscripten 5.0.x dropped the bare-name entry points in
# favor of .py-suffixed Python scripts. Wrap each as a small
# shell shim that resolves its own bin/ at runtime so the
# bottle is relocation-safe (the literal +brewing prefix would
# be wrong post-install).
#
# Python comes from a pkgx dep and has a stable path β€” fine to
# hardcode that. Only the bottle-relative .py path needs to be
# runtime-resolved via ${0%/*}.
mkdir -p "{{prefix}}/bin"
PY="{{deps.python.org.prefix}}/bin/python3"
for tool in emcc em++ emar emranlib emcmake emconfigure emmake emrun; do
src="{{prefix}}/$tool.py"
if [ -f "$src" ]; then
# emscripten's default cache is $EMSCRIPTEN_ROOT/cache, i.e.
# under the read-only bottle prefix β€” emcc can't build system
# libs there. Default EM_CACHE to a writable per-user dir (only
# if the user hasn't set it), shell-expanded at run time.
emcache=': "${EM_CACHE:=${XDG_CACHE_HOME:-${HOME:-/tmp}/.cache}/emscripten}"; export EM_CACHE'
# PATH-facing wrapper in bin/ (prefix is one level up).
printf '%s\n%s\n%s\n%s\n%s\n' \
'#!/bin/sh' \
'bindir=$(CDPATH= cd -- "${0%/*}" && pwd)' \
'prefix=$(CDPATH= cd -- "$bindir/.." && pwd)' \
"$emcache" \
"exec \"$PY\" \"\$prefix/$tool.py\" \"\$@\"" > "{{prefix}}/bin/$tool"
chmod 755 "{{prefix}}/bin/$tool"
# Bare top-level entrypoint too: emscripten spawns
# $EMSCRIPTEN_ROOT/{emcc,em++,emar,emranlib} directly
# (tools/shared.py: exe_path_from_root) when it builds its
# system libraries β€” the tag ships only <tool>.py, so without
# these the syslib build dies with FileNotFoundError.
printf '%s\n%s\n%s\n%s\n' \
'#!/bin/sh' \
'prefix=$(CDPATH= cd -- "${0%/*}" && pwd)' \
"$emcache" \
"exec \"$PY\" \"\$prefix/$tool.py\" \"\$@\"" > "{{prefix}}/$tool"
chmod 755 "{{prefix}}/$tool"
else
echo "warn: $src does not exist β€” skipping"
fi
done
ls -la "{{prefix}}/bin/" | head -15
echo "── sample wrapper ──"
cat "{{prefix}}/bin/emcc" 2>/dev/null || true

test:
script:
- run: |
# emscripten's default cache ($EMSCRIPTEN_ROOT/cache) sits under the
# read-only bottle prefix; point it at a writable scratch dir so the
# first compile can build the system libs.
export EM_CACHE="$(mktemp -d)"
# NB: no `| head -1` β€” on a fresh cache emcc prints several lines and
# head closes the pipe early, so emcc (CPython) hits BrokenPipeError
# and exits 120, which `set -o pipefail` turns into a test failure.
emcc --version
cat > hello.c <<'EOF'
#include <stdio.h>
int main() { printf("hello from emscripten\n"); return 0; }
EOF
emcc hello.c -o hello.js
test -f hello.js
test -f hello.wasm
node hello.js

provides:
- bin/emcc
- bin/em++
- bin/emar
- bin/emranlib
- bin/emcmake
- bin/emconfigure
- bin/emmake
- bin/emrun
Loading