Skip to content

Commit 9a7ca27

Browse files
authored
Merge pull request #23 from ParaToolsInc/llvm-20
Bump default toolchain to LLVM 20
2 parents 8213a87 + 91e75e3 commit 9a7ca27

10 files changed

Lines changed: 457 additions & 13 deletions

File tree

.claude/skills/build/SKILL.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,7 @@ Build the project Docker images:
2323
4. If $ARGUMENTS contains "devtools" or "all":
2424
- Build devtools: `docker buildx build --builder salt-8cpu -f Dockerfile.devtools -t salt-dev-tools --load .`
2525
5. Report build success/failure and image sizes via `docker images | grep salt-dev`
26+
6. If $ARGUMENTS contains "intel" or "ifx":
27+
- `docker run -it --name salt-ifx salt-dev-tools install-intel-ifx.sh --trust-intel-repo`
28+
- **Reset CMD** (docker commit inherits the running command): `docker commit --change='CMD ["/bin/bash"]' salt-ifx salt-dev-tools:intel-<version>`
29+
- `docker rm salt-ifx`

.dockerignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Dockerfile.devtools
44
**/.DS_Store
55
/.github/
66
*.md
7+
!claude-user-CLAUDE.md
78
LICENSE
89
/patches/README.md
910
/patches/LICENSE

.github/workflows/CI.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ jobs:
4848
- 'build-llvm.sh'
4949
- 'docker-entrypoint.sh'
5050
- 'install-intel-ifx.sh'
51+
- 'claude-statusline.sh'
52+
- 'claude-user-CLAUDE.md'
5153
- 'patches'
5254
- 'patches/**'
5355
- '.dockerignore'

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
.claude/worktrees/**
22
.claude/settings.local.json
3+
last-claude-session.txt
4+
*.tgz

CLAUDE.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,52 @@ git clone --recursive git@github.com:ParaToolsInc/salt-dev.git # patches/ submod
2323
- PDT checksum (`2fc9e86...`) pinned in `Dockerfile` -- update if upstream changes `pdt_lite.tgz`
2424
- LLVM build: 150-200 min cold, ~4 min with ccache; `ARG PHASED_BUILD=true` enables OOM-aware phased build
2525
- Intel IFX APT repo has signature verification issues on Debian 13+ (sqv rejects Intel's OpenPGP format); `install-intel-ifx.sh` detects and prompts for `[trusted=yes]`
26+
- `docker commit` captures the running command as the new `CMD`. After committing a container that ran `install-intel-ifx.sh`, reset `CMD` with: `docker commit --change='CMD ["/bin/bash"]' <container> <image:tag>`
27+
28+
## Working Style
29+
30+
Behavioral guidelines (adapted from [andrej-karpathy-skills](https://github.com/forrestchang/andrej-karpathy-skills/blob/main/CLAUDE.md)) to reduce common LLM coding mistakes. These bias toward caution over speed; use judgment for trivial tasks.
31+
32+
### Think Before Coding
33+
34+
Don't assume. Don't hide confusion. Surface tradeoffs.
35+
36+
- State assumptions explicitly. If uncertain, ask.
37+
- If multiple interpretations exist, present them -- don't pick silently.
38+
- If a simpler approach exists, say so. Push back when warranted.
39+
- If something is unclear, stop. Name what's confusing. Ask.
40+
41+
### Simplicity First
42+
43+
Minimum code that solves the problem. Nothing speculative.
44+
45+
- No features beyond what was asked.
46+
- No abstractions for single-use code.
47+
- No "flexibility" or "configurability" that wasn't requested.
48+
- No error handling for impossible scenarios.
49+
- If you write 200 lines and it could be 50, rewrite it.
50+
51+
Test: "Would a senior engineer say this is overcomplicated?" If yes, simplify.
52+
53+
### Surgical Changes
54+
55+
Touch only what you must. Clean up only your own mess.
56+
57+
- Don't "improve" adjacent code, comments, or formatting.
58+
- Don't refactor things that aren't broken.
59+
- Match existing style, even if you'd do it differently.
60+
- If you notice unrelated dead code, mention it -- don't delete it.
61+
- Remove imports/variables/functions that YOUR changes made unused.
62+
- Don't remove pre-existing dead code unless asked.
63+
64+
Every changed line should trace directly to the user's request.
65+
66+
### Goal-Driven Execution
67+
68+
Define success criteria. Loop until verified.
69+
70+
- "Add validation" -> "Write tests for invalid inputs, then make them pass"
71+
- "Fix the bug" -> "Write a test that reproduces it, then make it pass"
72+
- "Refactor X" -> "Ensure tests pass before and after"
73+
74+
For multi-step tasks, state a brief plan with verification per step. Strong success criteria let you loop independently; weak criteria ("make it work") require constant clarification.

Dockerfile

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,15 +107,23 @@ set -euo pipefail
107107
ccache -s
108108

109109
# Configure the build
110+
# LLVM >= 20: openmp moved from PROJECTS to RUNTIMES (hard error in LLVM 21)
111+
if [ "${LLVM_VER}" -ge 20 ]; then
112+
LLVM_PROJECTS="flang;clang;clang-tools-extra;mlir"
113+
LLVM_RUNTIMES="compiler-rt;openmp"
114+
else
115+
LLVM_PROJECTS="flang;clang;clang-tools-extra;mlir;openmp"
116+
LLVM_RUNTIMES="compiler-rt"
117+
fi
110118
CMAKE_EXTRA_ARGS=()
111119
if uname -a | grep x86 ; then CMAKE_EXTRA_ARGS+=("-DLLVM_TARGETS_TO_BUILD=X86"); fi
112120
cmake -GNinja \
113121
-DCMAKE_INSTALL_PREFIX=/tmp/llvm \
114122
-DCMAKE_MAKE_PROGRAM=/usr/local/bin/ninja \
115123
-DCMAKE_BUILD_TYPE=Release \
116124
-DLLVM_CCACHE_BUILD=On \
117-
-DLLVM_ENABLE_PROJECTS="flang;clang;clang-tools-extra;mlir;openmp" \
118-
-DLLVM_ENABLE_RUNTIMES="compiler-rt" \
125+
-DLLVM_ENABLE_PROJECTS="$LLVM_PROJECTS" \
126+
-DLLVM_ENABLE_RUNTIMES="$LLVM_RUNTIMES" \
119127
"${CMAKE_EXTRA_ARGS[@]}" \
120128
-S /llvm-project/llvm -B /llvm-project/llvm/build
121129

@@ -131,7 +139,6 @@ set -euo pipefail
131139
install-clang-resource-headers
132140
install-mlir-headers install-mlir-libraries install-mlir-cmake-exports
133141
install-openmp-resource-headers
134-
install-compiler-rt
135142
)
136143

137144
# LLVM >= 20 renamed the 'flang-new' binary to 'flang' and its install target accordingly
@@ -144,6 +151,13 @@ set -euo pipefail
144151
install-FortranParser install-FortranRuntime install-FortranSemantics
145152
)
146153

154+
# Use install-runtimes (aggregate target) because individual runtime install
155+
# targets (e.g. install-omp) aren't forwarded from the ExternalProject sub-build.
156+
# Runs after flang so the openmp cmake detects flang and builds Fortran modules.
157+
RUNTIME_TARGETS=(
158+
install-runtimes
159+
)
160+
147161
ccache -s
148162

149163
if ${PHASED_BUILD:-true}; then
@@ -178,10 +192,14 @@ set -euo pipefail
178192
# Phase 3: Flang targets at full parallelism (OOM .o files pre-built)
179193
echo "--- Phase 3: Flang targets (parallel, OOM files pre-built) ---"
180194
build-llvm.sh "${BUILD_LLVM_ARGS[@]}" "${FLANG_TARGETS[@]}"
195+
196+
# Phase 4: Runtime targets (parallel, requires clang+flang for Fortran modules)
197+
echo "--- Phase 4: Runtime targets (parallel) ---"
198+
build-llvm.sh "${BUILD_LLVM_ARGS[@]}" "${RUNTIME_TARGETS[@]}"
181199
else
182200
# Single pass: all targets at once (use PHASED_BUILD=false to select)
183201
build-llvm.sh "${BUILD_LLVM_ARGS[@]}" \
184-
"${NON_FLANG_TARGETS[@]}" "${FLANG_TARGETS[@]}"
202+
"${NON_FLANG_TARGETS[@]}" "${FLANG_TARGETS[@]}" "${RUNTIME_TARGETS[@]}"
185203
fi
186204

187205
rm -rf /llvm-project/llvm
@@ -262,6 +280,12 @@ COPY --from=builder /usr/local/bin/ninja /usr/local/bin/
262280
# Copy build results of stage 1 to /usr/local.
263281
COPY --from=builder /tmp/llvm/ /usr/
264282

283+
# Register LLVM per-target runtime dir with the dynamic linker.
284+
# LLVM normalizes all triples to include the vendor (x86_64-unknown-linux-gnu),
285+
# which differs from Debian's multiarch path (x86_64-linux-gnu).
286+
# hadolint ignore=SC2046
287+
RUN echo /usr/lib/$(clang -dumpmachine) > /etc/ld.so.conf.d/llvm-runtimes.conf && ldconfig
288+
265289
# Setup ccache
266290
ENV CCACHE_DIR=/home/salt/ccache
267291

Dockerfile.devtools

Lines changed: 82 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,19 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
4242
set -euo pipefail
4343
apt-get update
4444
apt-get install -y --no-install-recommends \
45+
bat \
46+
bubblewrap \
4547
emacs-nox \
48+
gdb \
4649
gh \
47-
nodejs npm \
48-
ripgrep \
49-
silversearcher-ag \
5050
htop \
51-
gdb \
5251
jq \
52+
nodejs npm \
5353
python3 \
54-
bat \
54+
ripgrep \
55+
shellcheck \
56+
silversearcher-ag \
57+
socat \
5558
sudo \
5659
valgrind
5760
# Symlink batcat to bat for convenience (Debian name conflict)
@@ -61,20 +64,91 @@ set -euo pipefail
6164
rm -rf /var/lib/apt/lists/*
6265
EOC
6366

64-
# Install Claude Code globally via npm
65-
# Intentionally unpinned: always install latest Claude Code
67+
# Install Claude Code sandbox runtime globally via npm, then do a
68+
# native per-user install of Claude Code for the salt user.
69+
# Intentionally unpinned: always install latest versions
6670
# hadolint ignore=DL3016
67-
RUN npm install -g @anthropic-ai/claude-code
71+
RUN npm install -g @anthropic-ai/claude-code @anthropic-ai/sandbox-runtime
72+
USER salt
73+
RUN claude install
74+
USER root
75+
RUN npm uninstall -g @anthropic-ai/claude-code
76+
77+
# Install caveman skill (https://github.com/JuliusBrussee/caveman)
78+
# Pinned to v1.6.0 commit for supply-chain integrity (no curl|bash).
79+
# Default mode "full" written to ~/.claude/.caveman-active so statusline shows badge
80+
# from first launch and caveman-activate.js sees existing state on session start.
81+
ARG CAVEMAN_REF=c2ed24b3e5d412cd0c25197b2bc9af587621fd99
82+
USER salt
83+
# hadolint ignore=DL3003
84+
RUN <<EOC
85+
#!/usr/bin/env bash
86+
set -euo pipefail
87+
# Pre-seed settings.json so install.sh's backup step has a file to back up
88+
mkdir -p ~/.claude
89+
[ -f ~/.claude/settings.json ] || echo '{}' > ~/.claude/settings.json
90+
git clone https://github.com/JuliusBrussee/caveman /tmp/caveman
91+
cd /tmp/caveman
92+
git checkout "${CAVEMAN_REF}"
93+
bash hooks/install.sh
94+
rm -rf /tmp/caveman
95+
echo "full" > ~/.claude/.caveman-active
96+
# Merge statusLine + attribution into settings.json caveman just wrote.
97+
# statusLine references our portable statusline script; attribution disables
98+
# co-author lines in commits/PRs (project policy).
99+
jq '.statusLine = {"type":"command","command":"bash ~/.claude/statusline-command.sh"} | .attribution = {"commit":"","pr":""}' \
100+
~/.claude/settings.json > /tmp/settings.json
101+
mv /tmp/settings.json ~/.claude/settings.json
102+
EOC
103+
104+
USER root
105+
106+
# Install multithreaded FPM (Fortran Package Manager)
107+
# install.sh bootstraps fpm from source: downloads a single-file bootstrap,
108+
# compiles it, then uses it to build the real fpm from the repo with OpenMP.
109+
# Intentionally unpinned: always install latest FPM from main branch.
110+
# hadolint ignore=DL3003
111+
RUN <<EOC
112+
#!/usr/bin/env bash
113+
set -euo pipefail
114+
git clone --depth 1 https://github.com/fortran-lang/fpm /tmp/fpm
115+
cd /tmp/fpm
116+
FC=gfortran FFLAGS="-O3 -fopenmp" ./install.sh --prefix=/usr/local
117+
rm -rf /tmp/fpm
118+
EOC
119+
120+
# Install actionlint (GitHub Actions workflow linter)
121+
# https://github.com/rhysd/actionlint/releases
122+
ARG ACTIONLINT_VERSION=1.7.11
123+
ARG ACTIONLINT_SHA256=900919a84f2229bac68ca9cd4103ea297abc35e9689ebb842c6e34a3d1b01b0a
124+
RUN <<EOC
125+
#!/usr/bin/env bash
126+
set -euo pipefail
127+
curl -fsSL "https://github.com/rhysd/actionlint/releases/download/v${ACTIONLINT_VERSION}/actionlint_${ACTIONLINT_VERSION}_linux_amd64.tar.gz" \
128+
-o /tmp/actionlint.tar.gz
129+
echo "${ACTIONLINT_SHA256} /tmp/actionlint.tar.gz" | sha256sum -c -
130+
tar -xzf /tmp/actionlint.tar.gz -C /usr/local/bin actionlint
131+
chmod +x /usr/local/bin/actionlint
132+
rm /tmp/actionlint.tar.gz
133+
EOC
68134

69135
# Copy Intel IFX installer script (run manually when needed)
70136
COPY install-intel-ifx.sh /usr/local/bin/install-intel-ifx.sh
71137
RUN chmod +x /usr/local/bin/install-intel-ifx.sh
72138

139+
# Copy Claude Code statusline script (installed into ~/.claude/ by entrypoint)
140+
COPY claude-statusline.sh /usr/local/share/claude/statusline-command.sh
141+
142+
# Copy user-level CLAUDE.md (installed into ~/.claude/ by entrypoint)
143+
COPY claude-user-CLAUDE.md /usr/local/share/claude/CLAUDE.md
144+
73145
# Copy entrypoint script
74146
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
75147
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
76148

77149
# Switch to salt user for runtime
150+
# Explicit HOME survives --user overrides (Docker defaults HOME=/ for unknown UIDs)
151+
ENV HOME=/home/salt
78152
USER salt
79153
WORKDIR /home/salt/src
80154

0 commit comments

Comments
 (0)