@@ -65,12 +65,32 @@ jobs:
6565 llvm : 21
6666 exclude-features : llvm-20,rust-llvm-20
6767 platform :
68+ # Rust CI ships only one flavor of libLLVM, dynamic or static, per
69+ # target. Linux GNU targets come with dynamic ones. Apple and Linux
70+ # musl targets come with static ones.
6871 - os : macos-latest
72+ static-target : aarch64-apple-darwin
73+ # Rust does not provide a dynamic libLLVM library on macOS,
74+ # therefore we exclude `default` and `rust-llvm-*`.
75+ # macOS does not provide static libc++ and zlib and the ones
76+ # provided by homebrew might be ABI-incompatible, therefore we
77+ # exclude `llvm-deps-link-static`.
78+ exclude-features : default,llvm-deps-link-static,rust-llvm-19,rust-llvm-20,rust-llvm-21
6979 - os : macos-15-intel
80+ static-target : x86_64-apple-darwin
81+ exclude-features : default,llvm-deps-link-static,rust-llvm-19,rust-llvm-20,rust-llvm-21
7082 - os : ubuntu-22.04
83+ dynamic-target : x86_64-unknown-linux-gnu
84+ static-target : x86_64-unknown-linux-musl
85+ # Link dependencies like libc++, zlib, zstd statically on Linux.
86+ llvm-features-static : llvm-deps-link-static
7187 - os : ubuntu-22.04-arm
88+ dynamic-target : aarch64-unknown-linux-gnu
89+ static-target : aarch64-unknown-linux-musl
90+ llvm-features-static : llvm-deps-link-static
7291 llvm-from :
7392 - packages
93+ - rust-ci
7494 include :
7595 # Currently we build LLVM from source only for Linux x86_64.
7696 - toolchain :
@@ -85,8 +105,15 @@ jobs:
85105
86106 env :
87107 RUST_BACKTRACE : full
88- LLVM_FEATURES : llvm-${{ matrix.toolchain.llvm }}
89- LLVM_EXCLUDE_FEATURES : llvm-deps-link-static,llvm-link-static,no-llvm-linking
108+ # Features that have to be included for dynamic linking.
109+ LLVM_FEATURES_DYNAMIC : llvm-${{ matrix.toolchain.llvm }}
110+ # Features that have to be included for static linking.
111+ LLVM_FEATURES_STATIC : llvm-${{ matrix.toolchain.llvm }},llvm-link-static
112+ # Features that have to be excluded when running `cargo hack --feature-powerset`
113+ # and intending to link dynamically.
114+ LLVM_EXCLUDE_FEATURES_DYNAMIC : llvm-deps-link-static,llvm-link-static,no-llvm-linking
115+ RUSTC_LLVM_INSTALL_DIR_DYNAMIC : /tmp/rustc-llvm-dynamic
116+ RUSTC_LLVM_INSTALL_DIR_STATIC : /tmp/rustc-llvm-static
90117
91118 steps :
92119 - uses : actions/checkout@v6
@@ -118,16 +145,19 @@ jobs:
118145 set -euxo pipefail
119146 echo /usr/lib/llvm-15/bin >> $GITHUB_PATH
120147
121- - name : Install LLVM (Linux, packages)
122- if : matrix.llvm-from == 'packages' && runner.os == 'Linux'
148+ - name : Add LLVM APT repository
149+ if : runner.os == 'Linux'
123150 run : |
124151 set -euxo pipefail
125152 wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc
126153 echo -e deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-${{ matrix.toolchain.llvm }} main | sudo tee /etc/apt/sources.list.d/llvm.list
127-
128154 sudo apt update
129- sudo apt -y install llvm-${{ matrix.llvm-version }}-dev
130- echo /usr/lib/llvm-${{ matrix.llvm-version }}/bin >> $GITHUB_PATH
155+
156+ - name : Install LLVM (Linux, packages)
157+ if : matrix.llvm-from == 'packages' && runner.os == 'Linux'
158+ run : |
159+ set -euxo pipefail
160+ sudo apt -y install llvm-${{ matrix.toolchain.llvm }}-dev
131161 echo /usr/lib/llvm-${{ matrix.toolchain.llvm }}/bin >> $GITHUB_PATH
132162
133163 - name : Install LLVM (macOS, packages)
@@ -138,7 +168,35 @@ jobs:
138168 echo $(brew --prefix llvm@${{ matrix.toolchain.llvm }})/bin >> $GITHUB_PATH
139169 echo "DYLD_LIBRARY_PATH=$(brew --prefix llvm@${{ matrix.toolchain.llvm }})/lib" >> $GITHUB_ENV
140170
141- - name : Restore LLVM
171+ - name : Install LLVM from Rust CI
172+ if : matrix.llvm-from == 'rust-ci'
173+ run : |
174+ set -euxo pipefail
175+ mkdir -p $RUSTC_LLVM_INSTALL_DIR
176+ rustc_sha=$(cargo xtask rustc-llvm-commit --github-token "${{ secrets.GITHUB_TOKEN }}")
177+ download_llvm() {
178+ local target=$1
179+ local install_dir=$2
180+ wget -q -O - "https://ci-artifacts.rust-lang.org/rustc-builds/$rustc_sha/rust-dev-nightly-$target.tar.xz" | \
181+ tar -xJ --strip-components 2 -C $install_dir
182+ }
183+ if [[ -n "${{ matrix.platform['dynamic-target'] }}" ]]; then
184+ download_llvm "${{ matrix.platform['dynamic-target'] }}"
185+ echo "LD_LIBRARY_PATH=${RUSTC_LLVM_INSTALL_DIR_DYNAMIC}/lib" >> $GITHUB_ENV
186+ # Add the dynamic libraries to `PATH` by default. All steps expected
187+ # to link statically should overwrite `PATH` on their own.
188+ echo "${RUSTC_LLVM_INSTALL_DIR_DYNAMIC}/bin" >> $GITHUB_PATH
189+ fi
190+ if [[ -n "${{ matrix.platform['static-target'] }}" ]]; then
191+ download_llvm "${{ matrix.platform['static-target'] }}"
192+ if [[ "${{ runner.os }}" == "Linux" ]]; then
193+ # `FileCheck` binary shipped in musl tarballs is linked dynamically
194+ # to musl, we can't execute it on Ubuntu.
195+ rm -f "${RUSTC_LLVM_INSTALL_DIR_STATIC}/bin/FileCheck"
196+ fi
197+ fi
198+
199+ - name : Restore LLVM from GitHub Actions
142200 if : matrix.llvm-from == 'source'
143201 uses : actions/cache/restore@v4
144202 with :
@@ -165,17 +223,17 @@ jobs:
165223
166224 - uses : taiki-e/install-action@cargo-hack
167225
168- - name : Check
226+ - name : Check (dynamic linking, feature powerset)
169227 run : |
170- cargo hack check --feature-powerset \
171- --exclude-features ${{ env.LLVM_EXCLUDE_FEATURES }},${{ matrix.toolchain.exclude-features }} \
172- --features ${{ env.LLVM_FEATURES }}
228+ cargo hack check --feature-powerset --exclude-features \
229+ ${{ env.LLVM_EXCLUDE_FEATURES_DYNAMIC }},${{ matrix.toolchain.exclude-features }},${{ matrix.platform .exclude-features }} \
230+ --features ${{ env.LLVM_FEATURES_DYNAMIC }}
173231
174- - name : Build
232+ - name : Build (dynamic linking, feature powerset)
175233 run : |
176- cargo hack build --feature-powerset \
177- --exclude-features ${{ env.LLVM_EXCLUDE_FEATURES }},${{ matrix.toolchain.exclude-features }} \
178- --features ${{ env.LLVM_FEATURES }}
234+ cargo hack build --feature-powerset --exclude-features \
235+ ${{ env.LLVM_EXCLUDE_FEATURES_DYNAMIC }},${{ matrix.toolchain.exclude-features }},${{ matrix.platform .exclude-features }} \
236+ --features ${{ env.LLVM_FEATURES_DYNAMIC }}
179237
180238 # Toolchains provided by rustup include standard library artifacts
181239 # only for Tier 1 targets, which do not include BPF targets.
@@ -185,11 +243,12 @@ jobs:
185243 # running compiler tests.
186244 #
187245 # `RUSTC_BOOTSTRAP` is needed to use `rustc-build-sysroot` on stable Rust.
188- - name : Test (sysroot built on demand)
246+ - name : Test (sysroot built on demand, dynamic linking )
189247 run : |
190248 RUSTC_BOOTSTRAP=1 cargo hack test --feature-powerset \
191- --exclude-features ${{ env.LLVM_EXCLUDE_FEATURES }},${{ matrix.toolchain.exclude-features }} \
192- --features ${{ env.LLVM_FEATURES }}
249+ --exclude-features \
250+ ${{ env.LLVM_EXCLUDE_FEATURES_DYNAMIC }},${{ matrix.toolchain.exclude-features }},${{ matrix.platform.exclude-features }} \
251+ --features ${{ env.LLVM_FEATURES_DYNAMIC }}
193252
194253 # To make things easier for package maintainers, the step of building a
195254 # custom sysroot can be skipped by setting the `BPFEL_SYSROOT_DIR`
@@ -200,7 +259,7 @@ jobs:
200259 #
201260 # `RUSTC_BOOTSTRAP` is needed to make `xtask build-std` work on stable
202261 # Rust.
203- - name : Test (prebuilt BPF standard library)
262+ - name : Build BPF standard library
204263 run : |
205264 set -euxo pipefail
206265
@@ -211,9 +270,12 @@ jobs:
211270 --sysroot-dir "$BPFEL_SYSROOT_DIR" \
212271 --target bpfel-unknown-none
213272
214- BPFEL_SYSROOT_DIR="$BPFEL_SYSROOT_DIR" cargo hack test --feature-powerset \
215- --exclude-features ${{ env.LLVM_EXCLUDE_FEATURES }},${{ matrix.toolchain.exclude-features }} \
216- --features ${{ env.LLVM_FEATURES }}
273+ - name : Test (prebuilt BPF standard libary, dynamic linking)
274+ run : |
275+ BPFEL_SYSROOT_DIR="${{ github.workspace }}/bpf-sysroot" \
276+ cargo hack test --feature-powerset --exclude-features \
277+ ${{ env.LLVM_EXCLUDE_FEATURES_DYNAMIC }},${{ matrix.toolchain.exclude-features }},${{ matrix.platform.exclude-features }} \
278+ --features ${{ env.LLVM_FEATURES_DYNAMIC }}
217279
218280 - uses : actions/checkout@v6
219281 if : runner.os == 'Linux' && matrix.toolchain.rust == 'nightly'
@@ -224,13 +286,53 @@ jobs:
224286
225287 - name : Install
226288 if : runner.os == 'Linux' && matrix.toolchain.rust == 'nightly'
227- run : cargo install --path . --no-default-features --features ${{ env.LLVM_FEATURES }}
289+ run : |
290+ cargo install --path . --no-default-features --features \
291+ ${{ env.LLVM_FEATURES_DYNAMIC }}
228292
229293 - name : Run aya integration tests
230294 if : runner.os == 'Linux' && matrix.toolchain.rust == 'nightly'
231295 working-directory : aya
232296 run : cargo xtask integration-test local
233297
298+ - name : Prepare for static linking (macOS)
299+ if : runner.os == 'macOS'
300+ # macOS does not provide any static libraries. Homebrew does provide
301+ # them, but in custom paths that the system-wide clang is not aware of.
302+ # Point build.rs to them by setting environment variables.
303+ run : |
304+ echo "CXXSTDLIB_PATH=$(brew --prefix llvm@17)/lib/c++" >> $GITHUB_ENV
305+ echo "ZLIB_PATH=$(brew --prefix zlib)/lib" >> $GITHUB_ENV
306+
307+ - name : Prepare for static linking (LLVM from Rust CI)
308+ if : matrix.llvm-from == 'rust-ci'
309+ run : |
310+ echo "${RUSTC_LLVM_INSTALL_DIR_STATIC}/bin" >> $GITHUB_PATH
311+
312+ - name : Check (static linking, single feature set)
313+ # Static linking in combination with `cargo hack --feature-powerset`
314+ # (multiple builds) increases the disk usage massively. Therefore we
315+ # perform all static builds with only one fixed feature set.
316+ run : |
317+ cargo check --no-default-features --features \
318+ ${{ env.LLVM_FEATURES_STATIC }},${{ matrix.platform.llvm-features-static }}
319+
320+ - name : Build (static linking, single feature set)
321+ run : |
322+ cargo build --no-default-features --features \
323+ ${{ env.LLVM_FEATURES_STATIC }},${{ matrix.platform.llvm-features-static }}
324+
325+ - name : Test (sysroot built on demand, static linking)
326+ run : |
327+ RUSTC_BOOTSTRAP=1 cargo test --no-default-features --features \
328+ ${{ env.LLVM_FEATURES_STATIC }},${{ matrix.platform.llvm-features-static }}
329+
330+ - name : Test (prebuilt BPF standard library, static linking)
331+ run : |
332+ BPFEL_SYSROOT_DIR="${{ github.workspace }}/bpf-sysroot" \
333+ cargo test --no-default-features --features \
334+ ${{ env.LLVM_FEATURES_STATIC }},${{ matrix.platform.llvm-features-static }}
335+
234336 - name : Report disk usage
235337 if : ${{ always() }}
236338 uses : ./.github/actions/report-disk-usage
0 commit comments