Skip to content

Commit 55e8c7b

Browse files
authored
fix infra LLVM toolchain for RISC-V asm (#663)
* fix infra LLVM toolchain for RISC-V asm * address provisioning review feedback
1 parent 26d4f3f commit 55e8c7b

6 files changed

Lines changed: 61 additions & 9 deletions

File tree

Makefile

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ SYSROOT_URL := https://lambda.alignedlayer.com/lambda-vm-sysroot-rv64im.tar.gz
5656
# $(abspath ...) because the build rule cd's into the program dir before invoking cargo.
5757
SYSROOT_CFLAGS := --target=riscv64 -march=rv64im -mabi=lp64 --sysroot=$(abspath $(SYSROOT_DIR))
5858

59+
CLANG ?= clang
60+
ASM_CFLAGS ?= --target=riscv64 -march=rv64im -mabi=lp64
61+
ASM_LDFLAGS ?= -fuse-ld=lld -nostdlib -Wl,-e,main
62+
5963
# Custom RV64IM target spec location
6064
RV64_TARGET_SPEC=$(CURDIR)/executor/programs/riscv64im-lambda-vm-elf.json
6165

@@ -94,8 +98,8 @@ prepare-sysroot:
9498
compile-programs-asm:
9599
@mkdir -p $(ASM_ARTIFACTS_DIR)
96100
@set -e; for src in $(ASM_PROGRAMS); do \
97-
echo "clang --target=riscv64 -fuse-ld=lld -nostdlib -Wl,-e,main $$src -o $(ASM_ARTIFACTS_DIR)/$$(basename $$src .s).elf"; \
98-
clang --target=riscv64 -fuse-ld=lld -nostdlib -Wl,-e,main $$src -o $(ASM_ARTIFACTS_DIR)/$$(basename $$src .s).elf; \
101+
echo "$(CLANG) $(ASM_CFLAGS) $(ASM_LDFLAGS) $$src -o $(ASM_ARTIFACTS_DIR)/$$(basename $$src .s).elf"; \
102+
$(CLANG) $(ASM_CFLAGS) $(ASM_LDFLAGS) $$src -o $(ASM_ARTIFACTS_DIR)/$$(basename $$src .s).elf; \
99103
done
100104

101105
compile-programs-rust: prepare-sysroot $(RUST_ARTIFACTS)

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ The **[public roadmap](https://yetanotherco.github.io/lambda_vm_roadmap/)** lays
1919
- Rust nightly with `rust-src` component
2020
- Clang with RISC-V target support and LLD linker (used by `make compile-programs-asm`)
2121
- **macOS**: `brew install llvm` (the Homebrew LLVM includes `clang` and `lld` with RISC-V support)
22-
- **Linux**: `apt install clang lld` (or equivalent for your distribution)
22+
- **Linux**: use LLVM 21+ from apt.llvm.org or your distribution; older distro clang packages may reject the assembly fixtures' RISC-V ISA attributes
2323

2424
### Dev dependencies
2525

infra/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ Everything has a working default; override via env var only when needed.
8888
| `READY_TIMEOUT` | `1800` (s) | `rent_baremetal.sh` | How long to wait for `status=ready && install.status=completed`. |
8989
| `PROVISION_FILE` | `<script_dir>/provision.sh` | both wrappers | Path to the remote provisioning script. |
9090
| `SSH_USER` | `root` | `provision_server.sh` | Switch to `admin` for re-runs after sshd hardening. |
91+
| `LLVM_VERSION` | `21` | provisioning scripts | LLVM major installed from apt.llvm.org for RISC-V assembly builds. |
9192

9293
### `SCW_TYPE` options
9394

infra/provision.sh

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ log() { printf '\n=== %s ===\n' "$*"; }
1313
log "apt update + upgrade"
1414
export DEBIAN_FRONTEND=noninteractive
1515
APT_OPTS=(-y -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold)
16+
LLVM_VERSION="${LLVM_VERSION:-21}"
17+
LLVM_GPG_FINGERPRINT="6084F3CF814B57C1CF12EFD515CF4D18AF4F7421"
1618

1719
# Scaleway baremetal Debian ships grub-cloud-amd64; its postinst (fired as a
1820
# trigger by initramfs-tools / shim-signed / kernel upgrades) runs grub-install
@@ -24,11 +26,46 @@ apt-get update -y
2426
apt-get upgrade "${APT_OPTS[@]}"
2527

2628
# --- 2. apt packages ---------------------------------------------------------
27-
log "apt install base packages + clang/lld/llvm + xz-utils"
29+
log "apt install base packages + xz-utils"
2830
apt-get install "${APT_OPTS[@]}" \
2931
ca-certificates curl wget gnupg vim git zip unzip openssl libssl-dev jq \
30-
build-essential rsyslog htop rsync pkg-config locales ufw \
31-
clang lld llvm xz-utils
32+
build-essential rsyslog htop rsync pkg-config locales ufw xz-utils
33+
34+
# Debian's default clang can lag behind RISC-V ISA attribute syntax emitted by
35+
# the checked-in assembly fixtures. Use a pinned apt.llvm.org toolchain.
36+
log "LLVM $LLVM_VERSION toolchain from apt.llvm.org"
37+
. /etc/os-release
38+
LLVM_CODENAME="${VERSION_CODENAME:-}"
39+
if [ -z "$LLVM_CODENAME" ]; then
40+
echo "ERROR: could not determine Debian/Ubuntu codename from /etc/os-release" >&2
41+
exit 1
42+
fi
43+
install -d -m 0755 /etc/apt/keyrings
44+
wget -qO /etc/apt/keyrings/apt.llvm.org.asc https://apt.llvm.org/llvm-snapshot.gpg.key
45+
if ! LLVM_ACTUAL_FINGERPRINT="$(gpg --show-keys --with-colons /etc/apt/keyrings/apt.llvm.org.asc 2>/dev/null \
46+
| awk -F: '/^fpr:/ { print $10; exit }')"; then
47+
echo "ERROR: could not read apt.llvm.org GPG key fingerprint" >&2
48+
exit 1
49+
fi
50+
if [ "$LLVM_ACTUAL_FINGERPRINT" != "$LLVM_GPG_FINGERPRINT" ]; then
51+
echo "ERROR: apt.llvm.org GPG key fingerprint mismatch (got $LLVM_ACTUAL_FINGERPRINT, expected $LLVM_GPG_FINGERPRINT)" >&2
52+
exit 1
53+
fi
54+
chmod 0644 /etc/apt/keyrings/apt.llvm.org.asc
55+
cat > /etc/apt/sources.list.d/apt.llvm.org.list <<EOF
56+
deb [signed-by=/etc/apt/keyrings/apt.llvm.org.asc] http://apt.llvm.org/$LLVM_CODENAME/ llvm-toolchain-$LLVM_CODENAME-$LLVM_VERSION main
57+
EOF
58+
apt-get update -y
59+
apt-get install "${APT_OPTS[@]}" "clang-$LLVM_VERSION" "lld-$LLVM_VERSION" "llvm-$LLVM_VERSION"
60+
for tool in clang clang++ lld ld.lld llvm-ar llvm-ranlib; do
61+
versioned="/usr/bin/$tool-$LLVM_VERSION"
62+
if [ ! -x "$versioned" ]; then
63+
echo "ERROR: expected $versioned after installing LLVM $LLVM_VERSION" >&2
64+
exit 1
65+
fi
66+
ln -sf "$versioned" "/usr/local/bin/$tool"
67+
done
68+
clang --version | head -n 1
3269

3370
# --- 3. users: admin (sudo) + app (no sudo) ----------------------------------
3471
log "users: admin (sudo) + app (no sudo)"

infra/provision_server.sh

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
# First-run servers accept root SSH; once provision.sh
1111
# has hardened sshd, re-run as: SSH_USER=admin ...
1212
# PROVISION_FILE default: <script-dir>/provision.sh
13+
# LLVM_VERSION default: 21
1314
#
1415
# SSH wait is indefinite — Ctrl+C to abort.
1516

@@ -25,6 +26,7 @@ NC='\033[0m'
2526

2627
SSH_USER="${SSH_USER:-root}"
2728
PROVISION_FILE="${PROVISION_FILE:-$SCRIPT_DIR/provision.sh}"
29+
LLVM_VERSION="${LLVM_VERSION:-21}"
2830

2931
err() { echo -e "${RED}error:${NC} $*" >&2; }
3032
info() { echo -e "${BOLD}$*${NC}"; }
@@ -45,6 +47,12 @@ if ! command -v ssh >/dev/null 2>&1; then
4547
err "ssh not found on PATH."
4648
exit 1
4749
fi
50+
case "$LLVM_VERSION" in
51+
''|*[!0-9]*)
52+
err "LLVM_VERSION must be a numeric LLVM major version, got '$LLVM_VERSION'"
53+
exit 2
54+
;;
55+
esac
4856

4957
SSH_OPTS=(-o StrictHostKeyChecking=accept-new -o ConnectTimeout=10 -o BatchMode=yes)
5058

@@ -60,9 +68,9 @@ done
6068
ok "sshd reachable on $SSH_USER@$IP (attempt $attempt)"
6169

6270
if [ "$SSH_USER" = "root" ]; then
63-
REMOTE_CMD="bash -s"
71+
REMOTE_CMD="env LLVM_VERSION=$LLVM_VERSION bash -s"
6472
else
65-
REMOTE_CMD="sudo bash -s"
73+
REMOTE_CMD="sudo env LLVM_VERSION=$LLVM_VERSION bash -s"
6674
fi
6775

6876
info "Running $PROVISION_FILE on $SSH_USER@$IP..."

infra/rent_baremetal.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
# SCW_TYPE default: EM-I320E-NVME
99
# PROVISION_FILE default: <repo>/infra/provision.sh
1010
# READY_TIMEOUT default: 1800 (seconds)
11+
# LLVM_VERSION default: 21
1112
#
1213
# Requires: scw, jq, ssh.
1314
# To delete the server when done: scw baremetal server delete <id> zone=<zone>
@@ -28,6 +29,7 @@ SCW_OS_ID="${SCW_OS_ID:-83640d93-a0b8-45ad-9c9f-30cae48380a4}" # Debian
2829
SCW_PROJECT_ID="${SCW_PROJECT_ID:-946cfb34-d351-48c4-8566-127e7727e15f}"
2930
PROVISION_FILE="${PROVISION_FILE:-$SCRIPT_DIR/provision.sh}"
3031
READY_TIMEOUT="${READY_TIMEOUT:-1800}"
32+
LLVM_VERSION="${LLVM_VERSION:-21}"
3133

3234
err() { echo -e "${RED}error:${NC} $*" >&2; }
3335
info() { echo -e "${BOLD}$*${NC}"; }
@@ -180,7 +182,7 @@ info "Wiping any stale known_hosts entry for $PUBLIC_IP (Scaleway recycles IPs).
180182
ssh-keygen -R "$PUBLIC_IP" >/dev/null 2>&1 || true
181183

182184
info "Handing off to provision_server.sh (Ctrl+C to skip and provision later)..."
183-
PROVISION_FILE="$PROVISION_FILE" SSH_USER=root "$SCRIPT_DIR/provision_server.sh" "$PUBLIC_IP"
185+
PROVISION_FILE="$PROVISION_FILE" SSH_USER=root LLVM_VERSION="$LLVM_VERSION" "$SCRIPT_DIR/provision_server.sh" "$PUBLIC_IP"
184186

185187
echo
186188
echo "To delete the server:"

0 commit comments

Comments
 (0)