mirror of
https://github.com/praetorian-inc/wasmforge
synced 2026-06-22 22:52:31 +00:00
96 lines
4.9 KiB
INI
96 lines
4.9 KiB
INI
# Dockerfile.build — wasmforge .NET (NativeAOT-WASI) build environment.
|
|
#
|
|
# Produces a self-contained image that builds wasmforge from mounted source,
|
|
# stages a target .NET project (e.g. Seatbelt), applies patcher rules, builds
|
|
# the WASI WASM via NativeAOT-LLVM, and forges a Windows PE in one invocation.
|
|
#
|
|
# Mounts at runtime:
|
|
# /wasmforge — wasmforge source tree (read-only is fine)
|
|
# /src — target .NET project root (e.g. seatbelt-fresh)
|
|
# /out — output directory for the forged PE
|
|
# /cache — optional named volume for ~/.nuget/packages
|
|
#
|
|
# Usage:
|
|
# docker build -f Dockerfile.build -t wasmforge/build:latest .
|
|
# docker run --rm \
|
|
# -v "$PWD/wasmforge:/wasmforge:ro" \
|
|
# -v "$PWD/seatbelt-fresh:/src:ro" \
|
|
# -v "$PWD/out:/out" \
|
|
# wasmforge/build:latest seatbelt
|
|
|
|
# Pin to amd64 — WASI SDK 24 ships only x86_64 linux binaries, and the
|
|
# wasmforge build target is GOOS=windows GOARCH=amd64. On Apple silicon
|
|
# hosts Docker Desktop emulates this via Rosetta with acceptable overhead.
|
|
FROM --platform=linux/amd64 debian:bookworm-slim
|
|
|
|
# ── Base system + signing tools ────────────────────────────────────────
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
ca-certificates curl git make gcc clang \
|
|
libicu-dev zlib1g \
|
|
osslsigncode \
|
|
xz-utils \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# ── Go toolchain ───────────────────────────────────────────────────────
|
|
ARG GO_VERSION=1.25.3
|
|
RUN curl -fsSL "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz" \
|
|
| tar -xz -C /usr/local
|
|
ENV PATH="/usr/local/go/bin:/root/go/bin:${PATH}"
|
|
ENV GOPATH="/root/go"
|
|
|
|
# ── .NET SDK 10 (RC2 channel — required for NativeAOT-LLVM workload) ──
|
|
# The NativeAOT-LLVM package reference fetches the actual compiler from
|
|
# nuget at restore time; we just need the SDK to drive dotnet publish.
|
|
ENV DOTNET_ROOT="/usr/share/dotnet"
|
|
ENV PATH="${DOTNET_ROOT}:${PATH}"
|
|
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
|
|
ENV DOTNET_NOLOGO=1
|
|
RUN curl -fsSL https://dot.net/v1/dotnet-install.sh -o /tmp/dotnet-install.sh && \
|
|
chmod +x /tmp/dotnet-install.sh && \
|
|
/tmp/dotnet-install.sh --channel 10.0 --quality preview --install-dir "$DOTNET_ROOT" && \
|
|
rm /tmp/dotnet-install.sh
|
|
|
|
# ── WASI SDK 24 ────────────────────────────────────────────────────────
|
|
ARG WASI_SDK_VERSION=24
|
|
RUN curl -fsSL \
|
|
"https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_VERSION}/wasi-sdk-${WASI_SDK_VERSION}.0-x86_64-linux.tar.gz" \
|
|
| tar -xz -C /opt && \
|
|
mv "/opt/wasi-sdk-${WASI_SDK_VERSION}.0-x86_64-linux" /opt/wasi-sdk
|
|
ENV WASI_SDK_PATH=/opt/wasi-sdk
|
|
|
|
# ── wasm-component-ld wrapper ──────────────────────────────────────────
|
|
# NativeAOT-LLVM 10.0.0-rc1 invokes wasm-component-ld with --component-type
|
|
# which then tries to encode the WASM as a WASI P2 component. Our env
|
|
# imports (mod_load, fs_listdir, etc.) aren't declared in any .wit
|
|
# interface so the encoding fails with "module requires an import
|
|
# interface named `env`". The wrapper sidesteps this by:
|
|
# - stripping --component-type / --adapt / --wasm-ld-path args
|
|
# - linking pre-built pthread stubs (libPortableRuntime references
|
|
# pthread_mutex_lock etc. but NativeAOT-WASI is single-threaded)
|
|
# - exporting _start and __main_void so wasmtime/wazero can run it
|
|
#
|
|
# Preserve the original as wasm-component-ld.real for parity with how the
|
|
# WASI SDK ships its binaries.
|
|
COPY scripts/wasm-component-ld-wrapper.sh /tmp/wasm-component-ld-wrapper.sh
|
|
COPY dotnet/bridge/pthread_stubs.c /tmp/pthread_stubs.c
|
|
RUN mv "$WASI_SDK_PATH/bin/wasm-component-ld" "$WASI_SDK_PATH/bin/wasm-component-ld.real" && \
|
|
install -m 0755 /tmp/wasm-component-ld-wrapper.sh "$WASI_SDK_PATH/bin/wasm-component-ld" && \
|
|
"$WASI_SDK_PATH/bin/clang" --target=wasm32-wasip2 -c /tmp/pthread_stubs.c -o /tmp/pthread_stubs.o && \
|
|
rm /tmp/wasm-component-ld-wrapper.sh /tmp/pthread_stubs.c
|
|
|
|
# ── Entry point ────────────────────────────────────────────────────────
|
|
COPY scripts/wasmforge-build.sh /usr/local/bin/wasmforge-build.sh
|
|
RUN chmod +x /usr/local/bin/wasmforge-build.sh
|
|
|
|
# Pre-create work and out paths so the entrypoint doesn't have to.
|
|
RUN mkdir -p /work /out
|
|
|
|
WORKDIR /work
|
|
|
|
# Default entrypoint: build a project. The image can also be used as a
|
|
# generic shell (`docker run --rm -it ... bash`) by overriding entrypoint.
|
|
ENTRYPOINT ["/usr/local/bin/wasmforge-build.sh"]
|
|
|
|
# Default command shows usage if no arg given.
|
|
CMD ["--help"]
|