From 0d34ab143a5a261a87c888ba850ec60efa66bac5 Mon Sep 17 00:00:00 2001 From: Bruno Verachten Date: Tue, 7 Apr 2026 18:11:23 +0200 Subject: [PATCH 1/4] ci: add riscv64-linux build via cross-compilation on ubuntu-24.04 Rework from native RISE runner to standard ubuntu-24.04 runner with CMake cross-compilation, following alexcrichton's preference. Changes: - ci/docker/Dockerfile.riscv64-linux: Ubuntu 24.04 with crossbuild-essential-riscv64; sets CC/CXX to riscv64-linux-gnu-gcc so CMake detects cross-compilation and LLVM builds a native tablegen before cross-compiling the rest of the toolchain. - ci/docker-build.sh: use artifact-specific Dockerfile if one exists (ci/docker/Dockerfile.), fall back to default; make the wasmtime volume mount conditional on WASI_SDK_CI_SKIP_SYSROOT. - .github/workflows/main.yml: new riscv64-linux matrix entry on ubuntu-24.04 with cross_cmake_args (-DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR=riscv64 -DWASI_SDK_LLDB=OFF) and WASI_SDK_CI_SKIP_SYSROOT=1; handle cross_cmake_args in the cmake flags step. WASI_SDK_CI_SKIP_SYSROOT=1: the cross-compiled clang runs on riscv64, not on the x86_64 build host, so the wasm sysroot step is skipped. WASI_SDK_LLDB=OFF: avoids cross-compiling libedit/libxml2 in this first iteration; can be re-enabled as a follow-up. Closes #607 Signed-off-by: Bruno Verachten --- .github/workflows/main.yml | 13 +++++++++++++ ci/docker-build.sh | 15 +++++++++++---- ci/docker/Dockerfile.riscv64-linux | 30 ++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 ci/docker/Dockerfile.riscv64-linux diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 14d51b5b2..f61ac435b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -28,6 +28,16 @@ jobs: - artifact: arm64-linux os: ubuntu-22.04-arm + - artifact: riscv64-linux + os: ubuntu-24.04 + rust_target: riscv64-unknown-linux-gnu + cross_cmake_args: >- + -DCMAKE_SYSTEM_NAME=Linux + -DCMAKE_SYSTEM_PROCESSOR=riscv64 + -DWASI_SDK_LLDB=OFF + env: + WASI_SDK_CI_SKIP_SYSROOT: 1 + - artifact: arm64-macos os: macos-14 rust_target: aarch64-apple-darwin @@ -85,6 +95,9 @@ jobs: rustup target add ${{ matrix.rust_target }} cmake_args="$cmake_args -DRUST_TARGET=${{ matrix.rust_target }}" fi + if [ "${{ matrix.cross_cmake_args }}" != "" ]; then + cmake_args="$cmake_args ${{ matrix.cross_cmake_args }}" + fi echo WASI_SDK_CI_TOOLCHAIN_CMAKE_ARGS="$cmake_args" >> $GITHUB_ENV shell: bash diff --git a/ci/docker-build.sh b/ci/docker-build.sh index 7773f7980..2915e286c 100755 --- a/ci/docker-build.sh +++ b/ci/docker-build.sh @@ -15,8 +15,13 @@ fi set -x -# Build the Docker imager -docker build --tag wasi-sdk-builder ci/docker +# Build the Docker image. Use an artifact-specific Dockerfile if one exists +# (e.g. ci/docker/Dockerfile.riscv64-linux), otherwise use the default. +dockerfile=ci/docker/Dockerfile +if [ -f "ci/docker/Dockerfile.$1" ]; then + dockerfile="ci/docker/Dockerfile.$1" +fi +docker build --tag wasi-sdk-builder --file "$dockerfile" ci/docker # Perform the build in `/src`. The current directory is mounted read-write at # this location as well. To ensure that container-created files are reasonable @@ -34,9 +39,11 @@ args="$args --volume $ccache_dir:/ccache:Z --env CCACHE_DIR=/ccache" # Inherit some tools from the host into this container. This ensures that the # decision made on CI of what versions to use is the canonical source of truth -# for theset ools +# for these tools. args="$args --volume `rustc --print sysroot`:/rustc:ro" -args="$args --volume $(dirname $(which wasmtime)):/wasmtime:ro" +if [ "${WASI_SDK_CI_SKIP_SYSROOT:-}" != "1" ]; then + args="$args --volume $(dirname $(command -v wasmtime)):/wasmtime:ro" +fi # Pass through some env vars that `build.sh` reads args="$args --env WASI_SDK_CI_TOOLCHAIN_CMAKE_ARGS" diff --git a/ci/docker/Dockerfile.riscv64-linux b/ci/docker/Dockerfile.riscv64-linux new file mode 100644 index 000000000..a741d54bf --- /dev/null +++ b/ci/docker/Dockerfile.riscv64-linux @@ -0,0 +1,30 @@ +# Ubuntu 24.04 is used here (rather than AlmaLinux 8) because it has +# riscv64 cross-compilation packages in its repositories. +FROM ubuntu:24.04 + +RUN apt-get update && apt-get install -y --no-install-recommends \ + curl \ + ca-certificates \ + crossbuild-essential-riscv64 \ + clang \ + lld \ + python3 \ + git \ + unzip \ + cmake \ + ninja-build \ + ccache \ + && rm -rf /var/lib/apt/lists/* + +# Set the cross-compiler as the default so that cmake picks it up via CC/CXX +# and sets CMAKE_CROSSCOMPILING=TRUE, which causes LLVM to build a native +# tablegen before cross-compiling the rest of the toolchain. +ENV CC=riscv64-linux-gnu-gcc +ENV CXX=riscv64-linux-gnu-g++ + +# Cargo needs an explicit linker when cross-compiling for riscv64. +ENV CARGO_TARGET_RISCV64_UNKNOWN_LINUX_GNU_LINKER=riscv64-linux-gnu-gcc + +# Tell programs to cache in a location that both isn't a `--volume` mounted root +# and isn't `/root` in the container as that won't be writable during the build. +ENV XDG_CACHE_HOME=/tmp/cache From 4dd04b4a47380fa3955b203c72fda9738c2642fa Mon Sep 17 00:00:00 2001 From: Bruno Verachten Date: Wed, 8 Apr 2026 09:55:29 +0200 Subject: [PATCH 2/4] ci: fix riscv64 Rust target triple (riscv64gc-unknown-linux-gnu) The correct Rust target triple for riscv64 Linux is riscv64gc-unknown-linux-gnu, not riscv64-unknown-linux-gnu. The gc suffix denotes the G (general-purpose) + C (compressed) ISA extensions that the standard Linux ABI requires. Also fix the matching CARGO_TARGET_ env var name in the Dockerfile so Cargo picks up the cross linker for the correct target. Signed-off-by: Bruno Verachten --- .github/workflows/main.yml | 2 +- ci/docker/Dockerfile.riscv64-linux | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f61ac435b..78f71143f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -30,7 +30,7 @@ jobs: - artifact: riscv64-linux os: ubuntu-24.04 - rust_target: riscv64-unknown-linux-gnu + rust_target: riscv64gc-unknown-linux-gnu cross_cmake_args: >- -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR=riscv64 diff --git a/ci/docker/Dockerfile.riscv64-linux b/ci/docker/Dockerfile.riscv64-linux index a741d54bf..601256869 100644 --- a/ci/docker/Dockerfile.riscv64-linux +++ b/ci/docker/Dockerfile.riscv64-linux @@ -23,7 +23,7 @@ ENV CC=riscv64-linux-gnu-gcc ENV CXX=riscv64-linux-gnu-g++ # Cargo needs an explicit linker when cross-compiling for riscv64. -ENV CARGO_TARGET_RISCV64_UNKNOWN_LINUX_GNU_LINKER=riscv64-linux-gnu-gcc +ENV CARGO_TARGET_RISCV64GC_UNKNOWN_LINUX_GNU_LINKER=riscv64-linux-gnu-gcc # Tell programs to cache in a location that both isn't a `--volume` mounted root # and isn't `/root` in the container as that won't be writable during the build. From ed26ff6e137500cafe7ac71ebf110c867bdee6b6 Mon Sep 17 00:00:00 2001 From: Bruno Verachten Date: Wed, 8 Apr 2026 10:10:43 +0200 Subject: [PATCH 3/4] ci: fix riscv64 LLVM cross-compilation (tblgen native build) Setting CC/CXX as Docker ENV vars caused LLVM's native tblgen sub-build to also use the riscv64 cross-compiler, producing an riscv64 binary that fails to run on the x86_64 host: Exec format error: llvm-min-tblgen Fix: pass the cross-compiler via CMAKE_C/CXX_COMPILER cmake flags instead (cmake cache vars are not inherited by subprocess cmake invocations, so LLVM's native build finds the host compiler). Also pass CMAKE_SYSTEM_NAME=Linux/CMAKE_SYSTEM_PROCESSOR=riscv64 to LLVM via WASI_SDK_CI_TOOLCHAIN_LLVM_CMAKE_ARGS so LLVM sets CMAKE_CROSSCOMPILING=TRUE and triggers the native/target build split, matching the pattern used by the macOS matrix entries. Signed-off-by: Bruno Verachten --- .github/workflows/main.yml | 5 +++++ ci/docker/Dockerfile.riscv64-linux | 10 ++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 78f71143f..0262f5fec 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -34,9 +34,14 @@ jobs: cross_cmake_args: >- -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR=riscv64 + -DCMAKE_C_COMPILER=riscv64-linux-gnu-gcc + -DCMAKE_CXX_COMPILER=riscv64-linux-gnu-g++ -DWASI_SDK_LLDB=OFF env: WASI_SDK_CI_SKIP_SYSROOT: 1 + WASI_SDK_CI_TOOLCHAIN_LLVM_CMAKE_ARGS: >- + -DCMAKE_SYSTEM_NAME=Linux + -DCMAKE_SYSTEM_PROCESSOR=riscv64 - artifact: arm64-macos os: macos-14 diff --git a/ci/docker/Dockerfile.riscv64-linux b/ci/docker/Dockerfile.riscv64-linux index 601256869..f4456ecf7 100644 --- a/ci/docker/Dockerfile.riscv64-linux +++ b/ci/docker/Dockerfile.riscv64-linux @@ -16,13 +16,11 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ ccache \ && rm -rf /var/lib/apt/lists/* -# Set the cross-compiler as the default so that cmake picks it up via CC/CXX -# and sets CMAKE_CROSSCOMPILING=TRUE, which causes LLVM to build a native -# tablegen before cross-compiling the rest of the toolchain. -ENV CC=riscv64-linux-gnu-gcc -ENV CXX=riscv64-linux-gnu-g++ - # Cargo needs an explicit linker when cross-compiling for riscv64. +# The C/C++ cross-compiler is passed via CMAKE_C/CXX_COMPILER cmake flags +# rather than CC/CXX env vars so that LLVM's native tblgen sub-build can +# still find the host compiler (cmake cache vars are not inherited by +# subprocess cmake invocations, but env vars are). ENV CARGO_TARGET_RISCV64GC_UNKNOWN_LINUX_GNU_LINKER=riscv64-linux-gnu-gcc # Tell programs to cache in a location that both isn't a `--volume` mounted root From 92466fa9b340781337d09e7d7df91a1a55be4283 Mon Sep 17 00:00:00 2001 From: Bruno Verachten Date: Wed, 8 Apr 2026 12:29:17 +0200 Subject: [PATCH 4/4] ci: add riscv64 to merge-artifacts deb architecture map Signed-off-by: Bruno Verachten --- ci/merge-artifacts.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ci/merge-artifacts.sh b/ci/merge-artifacts.sh index e64b68e85..9a1e68386 100755 --- a/ci/merge-artifacts.sh +++ b/ci/merge-artifacts.sh @@ -21,8 +21,9 @@ make_deb() { fi case $build in - dist-x86_64-linux) deb_arch=amd64 ;; - dist-arm64-linux) deb_arch=arm64 ;; + dist-x86_64-linux) deb_arch=amd64 ;; + dist-arm64-linux) deb_arch=arm64 ;; + dist-riscv64-linux) deb_arch=riscv64 ;; *) echo "unknown build $build" exit 1