@@ -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,39 @@ 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_DYNAMIC $RUSTC_LLVM_INSTALL_DIR_STATIC
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 \
185+ "${{ matrix.platform['dynamic-target'] }}" \
186+ ${RUSTC_LLVM_INSTALL_DIR_DYNAMIC}
187+ echo "LD_LIBRARY_PATH=${RUSTC_LLVM_INSTALL_DIR_DYNAMIC}/lib" >> $GITHUB_ENV
188+ # We start with steps that use dynamic linking. Add llvm-config
189+ # associated with dynamic target to `PATH`.
190+ echo "${RUSTC_LLVM_INSTALL_DIR_DYNAMIC}/bin" >> $GITHUB_PATH
191+ fi
192+ if [[ -n "${{ matrix.platform['static-target'] }}" ]]; then
193+ download_llvm \
194+ "${{ matrix.platform['static-target'] }}" \
195+ ${RUSTC_LLVM_INSTALL_DIR_STATIC}
196+ if [[ "${{ runner.os }}" == "Linux" ]]; then
197+ # `FileCheck` binary shipped in musl tarballs is linked dynamically
198+ # to musl, we can't execute it on Ubuntu.
199+ rm -f "${RUSTC_LLVM_INSTALL_DIR_STATIC}/bin/FileCheck"
200+ fi
201+ fi
202+
203+ - name : Restore LLVM from GitHub Actions
142204 if : matrix.llvm-from == 'source'
143205 uses : actions/cache/restore@v4
144206 with :
@@ -165,17 +227,19 @@ jobs:
165227
166228 - uses : taiki-e/install-action@cargo-hack
167229
168- - name : Check
230+ - name : Check (dynamic linking, feature powerset)
231+ if : matrix.platform.dynamic-target || matrix.llvm-from != 'rust-ci'
169232 run : |
170- cargo hack check --feature-powerset \
171- --exclude-features ${{ env.LLVM_EXCLUDE_FEATURES }},${{ matrix.toolchain.exclude-features }} \
172- --features ${{ env.LLVM_FEATURES }}
233+ cargo hack check --feature-powerset --exclude-features \
234+ ${{ env.LLVM_EXCLUDE_FEATURES_DYNAMIC }},${{ matrix.toolchain.exclude-features }},${{ matrix.platform .exclude-features }} \
235+ --features ${{ env.LLVM_FEATURES_DYNAMIC }}
173236
174- - name : Build
237+ - name : Build (dynamic linking, feature powerset)
238+ if : matrix.platform.dynamic-target || matrix.llvm-from != 'rust-ci'
175239 run : |
176- cargo hack build --feature-powerset \
177- --exclude-features ${{ env.LLVM_EXCLUDE_FEATURES }},${{ matrix.toolchain.exclude-features }} \
178- --features ${{ env.LLVM_FEATURES }}
240+ cargo hack build --feature-powerset --exclude-features \
241+ ${{ env.LLVM_EXCLUDE_FEATURES_DYNAMIC }},${{ matrix.toolchain.exclude-features }},${{ matrix.platform .exclude-features }} \
242+ --features ${{ env.LLVM_FEATURES_DYNAMIC }}
179243
180244 # Toolchains provided by rustup include standard library artifacts
181245 # only for Tier 1 targets, which do not include BPF targets.
@@ -185,11 +249,13 @@ jobs:
185249 # running compiler tests.
186250 #
187251 # `RUSTC_BOOTSTRAP` is needed to use `rustc-build-sysroot` on stable Rust.
188- - name : Test (sysroot built on demand)
252+ - name : Test (sysroot built on demand, dynamic linking)
253+ if : matrix.platform.dynamic-target || matrix.llvm-from != 'rust-ci'
189254 run : |
190255 RUSTC_BOOTSTRAP=1 cargo hack test --feature-powerset \
191- --exclude-features ${{ env.LLVM_EXCLUDE_FEATURES }},${{ matrix.toolchain.exclude-features }} \
192- --features ${{ env.LLVM_FEATURES }}
256+ --exclude-features \
257+ ${{ env.LLVM_EXCLUDE_FEATURES_DYNAMIC }},${{ matrix.toolchain.exclude-features }},${{ matrix.platform.exclude-features }} \
258+ --features ${{ env.LLVM_FEATURES_DYNAMIC }}
193259
194260 # To make things easier for package maintainers, the step of building a
195261 # custom sysroot can be skipped by setting the `BPFEL_SYSROOT_DIR`
@@ -200,7 +266,7 @@ jobs:
200266 #
201267 # `RUSTC_BOOTSTRAP` is needed to make `xtask build-std` work on stable
202268 # Rust.
203- - name : Test (prebuilt BPF standard library)
269+ - name : Build BPF standard library
204270 run : |
205271 set -euxo pipefail
206272
@@ -211,9 +277,36 @@ jobs:
211277 --sysroot-dir "$BPFEL_SYSROOT_DIR" \
212278 --target bpfel-unknown-none
213279
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 }}
280+ - name : Test (prebuilt BPF standard libary, dynamic linking)
281+ if : matrix.platform.dynamic-target || matrix.llvm-from != 'rust-ci'
282+ run : |
283+ BPFEL_SYSROOT_DIR="${{ github.workspace }}/bpf-sysroot" \
284+ cargo hack test --feature-powerset --exclude-features \
285+ ${{ env.LLVM_EXCLUDE_FEATURES_DYNAMIC }},${{ matrix.toolchain.exclude-features }},${{ matrix.platform.exclude-features }} \
286+ --features ${{ env.LLVM_FEATURES_DYNAMIC }}
287+
288+ - name : Prepare for static linking (LLVM from Rust CI)
289+ if : matrix.llvm-from == 'rust-ci'
290+ run : |
291+ echo "${RUSTC_LLVM_INSTALL_DIR_STATIC}/bin" >> $GITHUB_PATH
292+
293+ - name : Install static libraries (macOS)
294+ if : runner.os == 'macOS'
295+ # macOS does not provide any static libraries. Homebrew does provide
296+ # them, but in custom paths that the system-wide clang is not aware of.
297+ # Point build.rs to them by setting environment variables.
298+ #
299+ # We install llvm package only for libc++.
300+ #
301+ # libLLVM from homebrew requires zstd.
302+ run : |
303+ brew install llvm zlib
304+ echo "CXXSTDLIB_PATH=$(brew --prefix llvm)/lib/c++" >> $GITHUB_ENV
305+ echo "ZLIB_PATH=$(brew --prefix zlib)/lib" >> $GITHUB_ENV
306+ if [[ "${{ matrix.llvm-from }}" == "packages" ]]; then
307+ brew install zstd
308+ echo "LIBZSTD_PATH=$(brew --prefix zstd)/lib" >> $GITHUB_ENV
309+ fi
217310
218311 - uses : actions/checkout@v6
219312 if : runner.os == 'Linux' && matrix.toolchain.rust == 'nightly'
@@ -224,13 +317,39 @@ jobs:
224317
225318 - name : Install
226319 if : runner.os == 'Linux' && matrix.toolchain.rust == 'nightly'
227- run : cargo install --path . --no-default-features --features ${{ env.LLVM_FEATURES }}
320+ run : |
321+ cargo install --path . --no-default-features --features \
322+ ${{ env.LLVM_FEATURES_STATIC }}
228323
229324 - name : Run aya integration tests
230325 if : runner.os == 'Linux' && matrix.toolchain.rust == 'nightly'
231326 working-directory : aya
232327 run : cargo xtask integration-test local
233328
329+ - name : Check (static linking, single feature set)
330+ # Static linking in combination with `cargo hack --feature-powerset`
331+ # (multiple builds) increases the disk usage massively. Therefore we
332+ # perform all static builds with only one fixed feature set.
333+ run : |
334+ cargo check --no-default-features --features \
335+ ${{ env.LLVM_FEATURES_STATIC }},${{ matrix.platform.llvm-features-static }}
336+
337+ - name : Build (static linking, single feature set)
338+ run : |
339+ cargo build --no-default-features --features \
340+ ${{ env.LLVM_FEATURES_STATIC }},${{ matrix.platform.llvm-features-static }}
341+
342+ - name : Test (sysroot built on demand, static linking)
343+ run : |
344+ RUSTC_BOOTSTRAP=1 cargo test --no-default-features --features \
345+ ${{ env.LLVM_FEATURES_STATIC }},${{ matrix.platform.llvm-features-static }}
346+
347+ - name : Test (prebuilt BPF standard library, static linking)
348+ run : |
349+ BPFEL_SYSROOT_DIR="${{ github.workspace }}/bpf-sysroot" \
350+ cargo test --no-default-features --features \
351+ ${{ env.LLVM_FEATURES_STATIC }},${{ matrix.platform.llvm-features-static }}
352+
234353 - name : Report disk usage
235354 if : ${{ always() }}
236355 uses : ./.github/actions/report-disk-usage
0 commit comments