Skip to content

Commit 8eccb03

Browse files
bushidocodesclaude
andcommitted
fix: support Ubuntu noble (24.04) for the Docker and native dev builds
The dev toolchain is pinned to LLVM 13 (aWsm builds against an LLVM-13 binding fork), but apt.llvm.org never published llvm-toolchain-noble-13 and noble dropped libtinfo5, so a plain focal->noble bump failed to build. - install_llvm.sh: on noble, pin the focal apt.llvm.org repo for LLVM 13 and install the focal-era libtinfo5/libffi7 the LLVM 13 packages need; skip lldb-13 (needs the absent libpython3.8). Other releases keep the upstream llvm.sh path. - Dockerfile.x86_64: base on ubuntu:noble; drop libtinfo5 from apt (handled by install_llvm.sh); reuse noble's stock ubuntu user at UID/GID 1000 instead of creating a colliding dev user. - install_deb.sh: drop libtinfo5 from apt (handled by install_llvm.sh). - README: document the validated native build on Ubuntu incl. 24.04 noble, with caveats (update-alternatives repoints default clang; focal-pinned packages). Verified end-to-end on Ubuntu 24.04.4 (noble), x86_64, both in Docker and natively: aWsm, libsledge, the runtime, and all nine sample *.wasm.so modules build and sledgert runs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent d36133a commit 8eccb03

4 files changed

Lines changed: 77 additions & 28 deletions

File tree

Dockerfile.x86_64

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
# using ubuntu 20 docker image
2-
FROM ubuntu:focal
1+
# using ubuntu 24.04 (noble) docker image
2+
FROM ubuntu:noble
33

44
ENV LLVM_VERSION=13
55
ENV WASI_SDK_VERSION=12
@@ -27,7 +27,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
2727
binutils-dev \
2828
cmake \
2929
git \
30-
libtinfo5 \
3130
libtool \
3231
pkg-config
3332

@@ -47,7 +46,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
4746
wget
4847

4948
# Test Script Stuff
50-
# hey is a load generator used by the test workloads (focal ships it in universe;
49+
# hey is a load generator used by the test workloads (noble ships it in universe;
5150
# the previously-used hey-release S3/GCS binaries now return 403)
5251
RUN apt-get update && apt-get install -y --no-install-recommends \
5352
bc \
@@ -86,12 +85,14 @@ RUN ./sledge/install_llvm.sh $LLVM_VERSION
8685
RUN curl -sS -L -O $WASI_SDK_URL && dpkg -i wasi-sdk_$WASI_SDK_VERSION.0_amd64.deb && rm -f wasi-sdk_$WASI_SDK_VERSION.0_amd64.deb
8786
ENV WASI_SDK_PATH=/opt/wasi-sdk
8887

89-
# Create non-root user and add to sudoers
90-
ARG USERNAME=dev
88+
# Non-root user and sudoers.
89+
# Ubuntu noble (24.04) already ships a default non-root login user "ubuntu" at
90+
# UID/GID 1000 (real shell + /home/ubuntu, in the sudo group) intended to be the
91+
# account you work as, so reuse it rather than creating a second user at 1000
92+
# (which would collide on UID 1000 and fail).
93+
ARG USERNAME=ubuntu
9194
ARG USER_UID=1000
9295
ARG USER_GID=$USER_UID
93-
RUN groupadd --gid $USER_GID $USERNAME
94-
RUN useradd --uid $USER_UID --gid $USER_GID -m $USERNAME
9596
RUN apt-get update && apt-get install -y sudo
9697
RUN echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME
9798
RUN chmod 0440 /etc/sudoers.d/$USERNAME
@@ -111,12 +112,12 @@ RUN cd sledge && ./fix_root.sh
111112
# Rust
112113
# Rustup does not cleanly support system installs, so install as non-root user
113114
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --default-toolchain stable --component rustfmt --target wasm32-wasi -y
114-
ENV PATH=/home/dev/.cargo/bin:$PATH
115+
ENV PATH=/home/ubuntu/.cargo/bin:$PATH
115116
# `make install` runs as root (docker exec -u 0), but Rust is installed for the
116-
# dev user. Point rustup/cargo at dev's install so root resolves the default
117+
# ubuntu user. Point rustup/cargo at ubuntu's install so root resolves the default
117118
# toolchain instead of failing with "no default is configured".
118-
ENV RUSTUP_HOME=/home/dev/.rustup
119-
ENV CARGO_HOME=/home/dev/.cargo
119+
ENV RUSTUP_HOME=/home/ubuntu/.rustup
120+
ENV CARGO_HOME=/home/ubuntu/.cargo
120121
RUN cargo install --debug cargo-audit cargo-watch rsign2
121122

122123
# We need to set the locale for pango-view

README.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
SLEdge's `aWsm` compiler is built against a **specific LLVM version (LLVM 13)** via the `llvm-alt` Rust bindings. Those bindings use LLVM C-API functions (e.g. `LLVMBuildCall`, `LLVMBuildLoad`) that were **removed in LLVM 15+**, so the build will fail to link against newer LLVM toolchains.
88

9-
**For this reason, the Docker environment below is the recommended way to build SLEdge.** It pins the exact Debian + LLVM 13 + WASI SDK toolchain that the compiler needs, and works on any host with Docker (macOS, Windows/WSL2, or a Linux distro other than the one targeted by `install_deb.sh`).
9+
**For this reason, the Docker environment below is the recommended way to build SLEdge.** It pins the exact Ubuntu + LLVM 13 + WASI SDK toolchain that the compiler needs, and works on any host with Docker (macOS, Windows/WSL2, or any Linux distribution). To build directly on a Debian or Ubuntu host instead — including Ubuntu 24.04 (noble) — see [Native build](#native-build-linux-debian-or-ubuntu-including-2404-noble) below.
1010

1111
### Docker (recommended)
1212

@@ -68,11 +68,11 @@ If you are finished working with the SLEdge runtime and wish to remove it, run t
6868

6969
And then simply delete this repository.
7070

71-
### Native build (Debian + LLVM 13 only)
71+
### Native build (Linux: Debian or Ubuntu, including 24.04 noble)
7272

73-
**Caveat:** `install_deb.sh` only works on a host whose package repositories provide **LLVM 13** and `libtinfo5` — in practice a Debian release (or older Ubuntu such as 20.04/22.04) that `apt.llvm.org` still serves LLVM 13 for. It will **not** work on Ubuntu 24.04 (noble) or other distros where LLVM 13 is unavailable: `libtinfo5` has no install candidate, `apt.llvm.org/llvm.sh 13` provides no packages, and the `aWsm` build will fail to link against the newer system LLVM (`undefined symbol: LLVMBuildCall`). Use the Docker route above on those systems.
73+
`install_deb.sh` installs the full toolchain directly on the host — the apt dependencies, **LLVM 13**, the WASI SDK, and a Rust toolchain — after which `make install` builds the runtime and the sample functions.
7474

75-
On a supported host:
75+
On **Ubuntu 24.04 (noble)** neither the distro nor `apt.llvm.org/noble` provides LLVM 13, so `install_llvm.sh` automatically pins the **focal** `apt.llvm.org` repository for LLVM 13 and installs the two focal-era runtime libraries that noble dropped (`libtinfo5`, `libffi7`). This path is validated on Ubuntu 24.04.4 (noble), x86_64: `aWsm`, `libsledge`, the runtime, and all nine sample `*.wasm.so` modules compile, and the resulting `sledgert` binary runs.
7676

7777
```sh
7878
git clone https://github.com/gwsystems/sledge-serverless-framework.git
@@ -83,6 +83,14 @@ make install
8383
make test
8484
```
8585

86+
**Caveats:**
87+
88+
- `install_deb.sh` requires `sudo` and uses `update-alternatives` to point the default `clang`, `wasm-ld`, and `llvm-config` at version 13. On a host that already runs a newer LLVM as its default (e.g. noble's system clang), this changes that default system-wide.
89+
- On noble the toolchain is pinned to focal-era LLVM 13 packages, which are on an older support track; the `apt.llvm.org/focal` and `archive.ubuntu.com` `.deb` URLs it relies on may eventually move or disappear.
90+
- The sample functions are C, compiled with the WASI SDK's clang, so a Rust `wasm32-wasi`/`wasm32-wasip1` target is not required to build them.
91+
92+
On a distribution where neither the native repositories nor the focal fallback provide LLVM 13, use the Docker route above instead.
93+
8694
## Running your first serverless function
8795

8896
An SLEdge serverless function consists of a shared library (\*.so) and a JSON configuration file that determines how the runtime should execute the serverless function. As an example, here is the configuration file for our sample fibonacci function:

install_deb.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ sudo apt-get update && sudo apt-get install -y --no-install-recommends \
4545
jq \
4646
less \
4747
libssl-dev \
48-
libtinfo5 \
4948
libtool \
5049
libz3-4 \
5150
lsb-release \
@@ -64,6 +63,9 @@ sudo apt-get update && sudo apt-get install -y --no-install-recommends \
6463

6564
wget $SHFMT_URL -O shfmt && chmod +x shfmt && sudo mv shfmt /usr/local/bin/shfmt
6665

66+
# Installs LLVM $LLVM_VERSION. On Ubuntu noble this pins the focal apt.llvm.org
67+
# repo and pulls the focal-era libtinfo5/libffi7 the LLVM 13 packages need (noble
68+
# dropped libtinfo5, which is why it is no longer in the apt list above).
6769
sudo ./install_llvm.sh $LLVM_VERSION
6870

6971
curl -sS -L -O $WASI_SDK_URL && sudo dpkg -i wasi-sdk_$WASI_SDK_VERSION.0_amd64.deb && rm -f wasi-sdk_$WASI_SDK_VERSION.0_amd64.deb

install_llvm.sh

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,48 @@
11
#!/bin/bash
2-
# Installs LLVM tooling, delegating the to the LLVM script as much as possible
2+
# Installs LLVM tooling for the SLEdge x86_64 dev image.
3+
#
4+
# On most releases this just delegates to the upstream apt.llvm.org installer.
5+
# On Ubuntu noble (24.04) that doesn't work: apt.llvm.org never published an
6+
# llvm-toolchain-noble-13 repo (only 18/19+), and SLEdge is pinned to LLVM 13
7+
# (awsm builds against an LLVM-13 binding fork). So on noble we pin the *focal*
8+
# apt.llvm.org repo instead, plus the two focal-era runtime libs noble dropped
9+
# (libtinfo5, libffi7) that the focal LLVM packages depend on.
10+
set -e
311

412
LLVM_VERSION=$1
513

614
echo "Installing LLVM $LLVM_VERSION"
715

8-
# Script Installs clang, lldb, lld, and clangd
9-
curl --proto '=https' --tlsv1.2 -sSf https://apt.llvm.org/llvm.sh | bash -s -- "$LLVM_VERSION"
16+
CODENAME="$(. /etc/os-release && echo "$VERSION_CODENAME")"
17+
18+
if [ "$CODENAME" = "noble" ]; then
19+
echo "Detected Ubuntu noble: pinning the focal apt.llvm.org repo for LLVM $LLVM_VERSION"
20+
21+
# focal-era runtime libs no longer shipped by noble, required by focal LLVM debs
22+
cd /tmp
23+
curl -fsSL -o libtinfo5.deb http://archive.ubuntu.com/ubuntu/pool/universe/n/ncurses/libtinfo5_6.2-0ubuntu2.1_amd64.deb
24+
curl -fsSL -o libffi7.deb http://archive.ubuntu.com/ubuntu/pool/main/libf/libffi/libffi7_3.3-4_amd64.deb
25+
dpkg -i libtinfo5.deb libffi7.deb
26+
rm -f libtinfo5.deb libffi7.deb
27+
28+
wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | gpg --dearmor -o /usr/share/keyrings/llvm.gpg
29+
echo "deb [signed-by=/usr/share/keyrings/llvm.gpg] http://apt.llvm.org/focal/ llvm-toolchain-focal-$LLVM_VERSION main" \
30+
> /etc/apt/sources.list.d/llvm.list
31+
apt-get update
32+
33+
# Note: lldb-$LLVM_VERSION is intentionally omitted. The focal lldb package
34+
# depends on libpython3.8, which noble no longer provides, and the debugger is
35+
# not needed to build SLEdge.
36+
apt-get install -y --no-install-recommends \
37+
"clang-$LLVM_VERSION" \
38+
"lld-$LLVM_VERSION" \
39+
"clangd-$LLVM_VERSION" \
40+
"llvm-$LLVM_VERSION" \
41+
"llvm-$LLVM_VERSION-dev"
42+
else
43+
# Upstream installer: installs clang, lldb, lld, and clangd
44+
curl --proto '=https' --tlsv1.2 -sSf https://apt.llvm.org/llvm.sh | bash -s -- "$LLVM_VERSION"
45+
fi
1046

1147
# Installing "libc++-xx-dev" automagically installs "libc++1-xx", "libunwind-xx" and "libunwind-xx-dev"
1248
apt-get install -y --no-install-recommends \
@@ -16,14 +52,16 @@ apt-get install -y --no-install-recommends \
1652
"clang-tidy-$LLVM_VERSION" \
1753
"clang-format-$LLVM_VERSION"
1854

19-
update-alternatives --remove-all wasm-ld
20-
update-alternatives --remove-all llvm-config
21-
update-alternatives --remove-all llvm-objdump
22-
update-alternatives --remove-all llvm-dis
23-
update-alternatives --remove-all clang-format
24-
update-alternatives --remove-all clang
25-
update-alternatives --remove-all clang++
26-
update-alternatives --remove-all clang-tidy
55+
# --remove-all clears any prior registration; harmless if none exists (so do not
56+
# let "no alternatives" abort the script under set -e).
57+
update-alternatives --remove-all wasm-ld 2> /dev/null || true
58+
update-alternatives --remove-all llvm-config 2> /dev/null || true
59+
update-alternatives --remove-all llvm-objdump 2> /dev/null || true
60+
update-alternatives --remove-all llvm-dis 2> /dev/null || true
61+
update-alternatives --remove-all clang-format 2> /dev/null || true
62+
update-alternatives --remove-all clang 2> /dev/null || true
63+
update-alternatives --remove-all clang++ 2> /dev/null || true
64+
update-alternatives --remove-all clang-tidy 2> /dev/null || true
2765

2866
update-alternatives --install /usr/bin/wasm-ld wasm-ld "/usr/bin/wasm-ld-$LLVM_VERSION" 100
2967
update-alternatives --install /usr/bin/llvm-config llvm-config "/usr/bin/llvm-config-$LLVM_VERSION" 100

0 commit comments

Comments
 (0)