Skip to content

Put the bootstrapped LLVM bin dir on PATH - #23

Merged
alii merged 1 commit into
masterfrom
llvm-bin-on-path
Sep 16, 2026
Merged

alii merged 1 commit into
masterfrom
llvm-bin-on-path

Conversation

@alii

@alii alii commented Sep 16, 2026

Copy link
Copy Markdown
Member

Problem. bootstrap.sh installs LLVM N and adds /usr/lib/llvm-N/bin to PATH via shell profiles, which Docker RUN/exec shells never read, and its unversioned /usr/bin/llvm-symbolizer symlink is only created on Ubuntu. On this Debian image the tools resolve only as clang-N, llvm-symbolizer-N, etc. Derived images that symlinked a hardcoded llvm-symbolizer-21 broke today when main moved to LLVM 23 (oven-sh/bun#42851).

Fix. After bootstrap, link /usr/lib/llvm-current to the newest installed llvm-N and put its bin on PATH with ENV. Unversioned clang, ld.lld, llvm-symbolizer then work in :base, :prebuilt, :heavy and anything built from them, and follow future LLVM bumps without editing this file. The step fails the build if no llvm-N with a clang is present.

Not built locally; the next daily run (or a manual dispatch) is its first build.

bootstrap.sh installs LLVM N and adds /usr/lib/llvm-N/bin to PATH through
shell profiles, which Docker RUN and exec shells never read; its unversioned
/usr/bin/llvm-symbolizer symlink is created only on Ubuntu (install_gcc).
On this Debian image the tools therefore resolve only as clang-N,
llvm-symbolizer-N and so on, and downstream images have been symlinking a
hardcoded version, which broke when main moved from LLVM 21 to 23.

Link /usr/lib/llvm-current to the newest installed llvm-N after bootstrap
and put its bin on PATH with ENV, so unversioned names work in every
derived image and follow future LLVM bumps with no edit here.
@alii
alii merged commit 88381bd into master Sep 16, 2026
1 check passed

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — small, self-contained Dockerfile addition that fails the build loudly rather than silently if its assumptions don't hold.

What was reviewed:

  • No-match case for the unquoted llvm-[0-9]* glob: ls prints nothing to stdout, llvm_dir is empty, and test -x /bin/clang fails the step, so the build errors as intended.
  • PATH prepend shadowing: the LLVM bin dir carries clang/lld/llvm-* names but no gcc/g++/ld, so the later g++ -std=c++20 check and rustup/cargo steps are unaffected.
  • set -eu and sort -V under dash/coreutils in debian:trixie-slim — both supported; llvm-current is excluded from the glob so the symlink can't select itself on rebuilds.
Extended reasoning...

Overview

The PR adds one 15-line block to /home/claude/bun-development-docker-image/Dockerfile between the scripts/bootstrap.sh step and the Rust toolchain install: a RUN that resolves the newest /usr/lib/llvm-N directory, asserts it contains an executable clang, symlinks it to /usr/lib/llvm-current, runs llvm-symbolizer --version as a smoke test, and an ENV PATH that prepends /usr/lib/llvm-current/bin. The code matches the PR description. Dockerfile.heavy builds FROM ${BASE_IMAGE} so it inherits the ENV as claimed; Dockerfile.webkit is a separate Ubuntu-based image with its own hardcoded LLVM 21 symlinks and is untouched.

Security risks

None. The step reads only local filesystem paths under /usr/lib, creates a symlink there as root during image build, and adds a directory to PATH. No network access, no secrets, no user input. The prepended PATH entry only contains LLVM binaries, so it does not hijack gcc, g++, ld, cc, or anything the rustup/cargo steps rely on.

Level of scrutiny

Low-to-moderate: it is a build-recipe change whose worst-case failure mode is a failed image build, not a silently wrong artifact. I walked through the shell semantics that the change hinges on: under dash with set -eu, a non-matching glob is passed literally to ls, which writes to stderr and exits non-zero, but the pipeline's status is tail's (0), so set -e does not fire there — instead llvm_dir is empty and test -x "/bin/clang" fails, which is the intended loud failure. sort -V and ls -d are coreutils; ln -sfn correctly replaces an existing symlink on rebuild; the glob llvm-[0-9]* cannot match llvm-current. The one theoretical edge — a Debian libllvmNN package creating a bare /usr/lib/llvm-NN newer than the version bootstrap.sh pins — would also fail the test -x check rather than pick a wrong toolchain, and nothing in the current apt install list pulls such a package.

Other factors

The author notes it has not been built locally; the next scheduled or manual build is the first real exercise, and any breakage would be an immediate build failure visible in CI rather than a latent runtime issue. There are no CODEOWNERS/ANTOWNERS files, no CLAUDE.md conventions, no other reviewers, and the style (comment block above RUN, ; \ continuations, ENV for path changes) matches the rest of the file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant