Skip to content

Commit ff59feb

Browse files
bushidocodesclaude
andauthored
fix: repair Docker dev-environment build and clarify native setup (#388)
* fix: repair Docker dev-environment build and clarify native setup The documented setup was failing. The native path assumes a Debian host with LLVM 13, but aWsm's llvm-alt bindings call LLVM C-API functions (LLVMBuildCall, LLVMBuildLoad) removed in LLVM 15+, so the build fails to link against newer system LLVM (e.g. LLVM 21 on Ubuntu 24.04). The Docker route exists for exactly this reason but had bit-rotted in several places. Dockerfile.x86_64: - Install `hey` from focal's universe repo instead of downloading the prebuilt binary, whose hey-release S3/GCS URLs now return 403. - Add `git config --system --add safe.directory '*'` so the root-run `make install` doesn't abort with "dubious ownership" on the host-owned, bind-mounted /sledge. - Set RUSTUP_HOME/CARGO_HOME to the dev user's install so the root-run build can resolve the default Rust toolchain instead of failing with "no default is configured". Makefile: - Make the wasm_apps symlink rule idempotent (ln -srfn). The symlink is committed to the repo, so it already exists on a fresh clone and the old `ln -sr` failed with "File exists", breaking `make install`. README.md: - Recommend the Docker route and add an explicit caveat to the native section documenting the LLVM-13/Debian requirement and why Ubuntu 24.04 (and other non-LLVM-13 hosts) cannot use it. Verified end-to-end via `./devenv.sh setup`: aWsm, the runtime, and all benchmark apps build, and the runtime serves fibonacci, gocr, and resize_image requests with correct responses. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * 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> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent d119fc9 commit ff59feb

5 files changed

Lines changed: 105 additions & 38 deletions

File tree

Dockerfile.x86_64

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
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
66

77
ARG DEBIAN_FRONTEND=noninteractive
8-
ARG HEY_URL=https://hey-release.s3.us-east-2.amazonaws.com/hey_linux_amd64
98
ARG WASI_SDK_URL=https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-$WASI_SDK_VERSION/wasi-sdk_$WASI_SDK_VERSION.0_amd64.deb
109
ARG SHFMT_URL=https://github.com/mvdan/sh/releases/download/v3.2.4/shfmt_v3.2.4_linux_amd64
1110
ARG SHELLCHECK_URL=https://github.com/koalaman/shellcheck/releases/download/stable/shellcheck-stable.linux.x86_64.tar.xz
@@ -28,10 +27,14 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
2827
binutils-dev \
2928
cmake \
3029
git \
31-
libtinfo5 \
3230
libtool \
3331
pkg-config
3432

33+
# The repo is bind-mounted from the host, so its files are owned by the host user
34+
# while the build runs as root (docker exec -u 0). Modern git rejects this as
35+
# "dubious ownership", so whitelist any directory for all users in the image.
36+
RUN git config --system --add safe.directory '*'
37+
3538
# Needed to install from http endpoints via curl or wget
3639
RUN apt-get update && apt-get install -y --no-install-recommends \
3740
curl \
@@ -43,12 +46,15 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
4346
wget
4447

4548
# Test Script Stuff
49+
# hey is a load generator used by the test workloads (noble ships it in universe;
50+
# the previously-used hey-release S3/GCS binaries now return 403)
4651
RUN apt-get update && apt-get install -y --no-install-recommends \
4752
bc \
4853
fonts-dejavu \
4954
fonts-cascadia-code \
5055
fonts-roboto \
5156
gnuplot \
57+
hey \
5258
httpie \
5359
imagemagick \
5460
jq \
@@ -57,11 +63,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
5763
pango1.0-tools \
5864
wamerican
5965

60-
# Hey is a load generator we have to recklessly download from the 'net, as it is only published to brew
61-
# Binaries are only provided for AMD64 though, so ARM will have to build from source
62-
# See https://github.com/rakyll/hey
63-
RUN wget $HEY_URL -O hey && chmod +x hey && mv hey /usr/bin/hey
64-
6566
# shfmt is a formatter for shell scripts
6667
RUN wget $SHFMT_URL -O shfmt && chmod +x shfmt && mv shfmt /usr/local/bin/shfmt
6768
RUN wget $SHELLCHECK_URL -O shellcheck && chmod +x shellcheck && mv shellcheck /usr/local/bin/shellcheck
@@ -84,12 +85,14 @@ RUN ./sledge/install_llvm.sh $LLVM_VERSION
8485
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
8586
ENV WASI_SDK_PATH=/opt/wasi-sdk
8687

87-
# Create non-root user and add to sudoers
88-
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
8994
ARG USER_UID=1000
9095
ARG USER_GID=$USER_UID
91-
RUN groupadd --gid $USER_GID $USERNAME
92-
RUN useradd --uid $USER_UID --gid $USER_GID -m $USERNAME
9396
RUN apt-get update && apt-get install -y sudo
9497
RUN echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME
9598
RUN chmod 0440 /etc/sudoers.d/$USERNAME
@@ -109,7 +112,12 @@ RUN cd sledge && ./fix_root.sh
109112
# Rust
110113
# Rustup does not cleanly support system installs, so install as non-root user
111114
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --default-toolchain stable --component rustfmt --target wasm32-wasi -y
112-
ENV PATH=/home/dev/.cargo/bin:$PATH
115+
ENV PATH=/home/ubuntu/.cargo/bin:$PATH
116+
# `make install` runs as root (docker exec -u 0), but Rust is installed for the
117+
# ubuntu user. Point rustup/cargo at ubuntu's install so root resolves the default
118+
# toolchain instead of failing with "no default is configured".
119+
ENV RUSTUP_HOME=/home/ubuntu/.rustup
120+
ENV CARGO_HOME=/home/ubuntu/.cargo
113121
RUN cargo install --debug cargo-audit cargo-watch rsign2
114122

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

Makefile

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,12 @@ applications:
5050
applications.clean:
5151
make -C applications clean
5252

53-
# Instead of having two copies of wasm_apps, just link to the awsm repo's copy
53+
# Instead of having two copies of wasm_apps, just link to the awsm repo's copy.
54+
# -f -n make this idempotent: the symlink is committed to the repo, so it already
55+
# exists on a fresh clone and on rebuilds; without these flags ln fails with
56+
# "File exists" and breaks `make install`.
5457
wasm_apps:
55-
ln -sr awsm/applications/wasm_apps/ applications/
58+
ln -srfn awsm/applications/wasm_apps/ applications/wasm_apps
5659

5760
# Tests
5861
.PHONY: test

README.md

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,11 @@
44

55
## Setting up a development environment
66

7-
### Native on Debian Host
7+
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-
```sh
10-
git clone https://github.com/gwsystems/sledge-serverless-framework.git
11-
cd sledge-serverless-framework
12-
./install_deb.sh
13-
source ~/.bashrc
14-
make install
15-
make test
16-
```
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.
1710

18-
### Docker
11+
### Docker (recommended)
1912

2013
**Note: These steps require Docker. Make sure you've got it installed!**
2114

@@ -75,6 +68,29 @@ If you are finished working with the SLEdge runtime and wish to remove it, run t
7568

7669
And then simply delete this repository.
7770

71+
### Native build (Linux: Debian or Ubuntu, including 24.04 noble)
72+
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.
74+
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.
76+
77+
```sh
78+
git clone https://github.com/gwsystems/sledge-serverless-framework.git
79+
cd sledge-serverless-framework
80+
./install_deb.sh
81+
source ~/.bashrc
82+
make install
83+
make test
84+
```
85+
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+
7894
## Running your first serverless function
7995

8096
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)