@@ -65,12 +65,22 @@ 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
6973 - os : macos-15-intel
74+ static-target : x86_64-apple-darwin
7075 - os : ubuntu-22.04
76+ dynamic-target : x86_64-unknown-linux-gnu
77+ static-target : x86_64-unknown-linux-musl
7178 - os : ubuntu-22.04-arm
79+ dynamic-target : aarch64-unknown-linux-gnu
80+ static-target : aarch64-unknown-linux-musl
7281 llvm-from :
7382 - packages
83+ - rust-ci
7484 include :
7585 # Currently we build LLVM from source only for Linux x86_64.
7686 - toolchain :
8595
8696 env :
8797 RUST_BACKTRACE : full
88- LLVM_FEATURES : llvm-${{ matrix.toolchain.llvm }}
89- LLVM_EXCLUDE_FEATURES : llvm-link-static,no-llvm-linking
98+ # Features that have to be included for dynamic linking.
99+ LLVM_FEATURES_DYNAMIC : llvm-${{ matrix.toolchain.llvm }}
100+ # Features that have to be included for static linking.
101+ LLVM_FEATURES_STATIC : llvm-${{ matrix.toolchain.llvm }},llvm-link-static
102+ # Features that have to be excluded when running `cargo hack --feature-powerset`
103+ # and intending to link dynamically.
104+ LLVM_EXCLUDE_FEATURES_DYNAMIC : llvm-link-static,no-llvm-linking
105+ RUSTC_LLVM_INSTALL_DIR_DYNAMIC : /tmp/rustc-llvm-dynamic
106+ RUSTC_LLVM_INSTALL_DIR_STATIC : /tmp/rustc-llvm-static
90107
91108 steps :
92109 - uses : actions/checkout@v6
@@ -118,16 +135,19 @@ jobs:
118135 set -euxo pipefail
119136 echo /usr/lib/llvm-15/bin >> $GITHUB_PATH
120137
121- - name : Install LLVM (Linux, packages)
122- if : matrix.llvm-from == 'packages' && runner.os == 'Linux'
138+ - name : Add LLVM APT repository
139+ if : runner.os == 'Linux'
123140 run : |
124141 set -euxo pipefail
125142 wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc
126143 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-
128144 sudo apt update
129- sudo apt -y install llvm-${{ matrix.llvm-version }}-dev
130- echo /usr/lib/llvm-${{ matrix.llvm-version }}/bin >> $GITHUB_PATH
145+
146+ - name : Install LLVM (Linux, packages)
147+ if : matrix.llvm-from == 'packages' && runner.os == 'Linux'
148+ run : |
149+ set -euxo pipefail
150+ sudo apt -y install llvm-${{ matrix.toolchain.llvm }}-dev
131151 echo /usr/lib/llvm-${{ matrix.toolchain.llvm }}/bin >> $GITHUB_PATH
132152
133153 - name : Install LLVM (macOS, packages)
@@ -138,7 +158,39 @@ jobs:
138158 echo $(brew --prefix llvm@${{ matrix.toolchain.llvm }})/bin >> $GITHUB_PATH
139159 echo "DYLD_LIBRARY_PATH=$(brew --prefix llvm@${{ matrix.toolchain.llvm }})/lib" >> $GITHUB_ENV
140160
141- - name : Restore LLVM
161+ - name : Install LLVM from Rust CI
162+ if : matrix.llvm-from == 'rust-ci'
163+ run : |
164+ set -euxo pipefail
165+ mkdir -p $RUSTC_LLVM_INSTALL_DIR_DYNAMIC $RUSTC_LLVM_INSTALL_DIR_STATIC
166+ rustc_sha=$(cargo xtask rustc-llvm-commit --github-token "${{ secrets.GITHUB_TOKEN }}")
167+ download_llvm() {
168+ local target=$1
169+ local install_dir=$2
170+ wget -q -O - "https://ci-artifacts.rust-lang.org/rustc-builds/$rustc_sha/rust-dev-nightly-$target.tar.xz" | \
171+ tar -xJ --strip-components 2 -C $install_dir
172+ }
173+ if [[ -n "${{ matrix.platform['dynamic-target'] }}" ]]; then
174+ download_llvm \
175+ "${{ matrix.platform['dynamic-target'] }}" \
176+ ${RUSTC_LLVM_INSTALL_DIR_DYNAMIC}
177+ echo "LD_LIBRARY_PATH=${RUSTC_LLVM_INSTALL_DIR_DYNAMIC}/lib" >> $GITHUB_ENV
178+ # We start with steps that use dynamic linking. Add llvm-config
179+ # associated with dynamic target to `PATH`.
180+ echo "${RUSTC_LLVM_INSTALL_DIR_DYNAMIC}/bin" >> $GITHUB_PATH
181+ fi
182+ if [[ -n "${{ matrix.platform['static-target'] }}" ]]; then
183+ download_llvm \
184+ "${{ matrix.platform['static-target'] }}" \
185+ ${RUSTC_LLVM_INSTALL_DIR_STATIC}
186+ if [[ "${{ runner.os }}" == "Linux" ]]; then
187+ # `FileCheck` binary shipped in musl tarballs is linked dynamically
188+ # to musl, we can't execute it on Ubuntu.
189+ rm -f "${RUSTC_LLVM_INSTALL_DIR_STATIC}/bin/FileCheck"
190+ fi
191+ fi
192+
193+ - name : Restore LLVM from GitHub Actions
142194 if : matrix.llvm-from == 'source'
143195 uses : actions/cache/restore@v4
144196 with :
@@ -165,17 +217,19 @@ jobs:
165217
166218 - uses : taiki-e/install-action@cargo-hack
167219
168- - name : Check
220+ - name : Check (dynamic linking, feature powerset)
221+ if : matrix.platform.dynamic-target || matrix.llvm-from != 'rust-ci'
169222 run : |
170- cargo hack check --feature-powerset \
171- --exclude-features ${{ env.LLVM_EXCLUDE_FEATURES }},${{ matrix.toolchain.exclude-features }} \
172- --features ${{ env.LLVM_FEATURES }}
223+ cargo hack check --feature-powerset --exclude-features \
224+ ${{ env.LLVM_EXCLUDE_FEATURES_DYNAMIC }},${{ matrix.toolchain.exclude-features }} \
225+ --features ${{ env.LLVM_FEATURES_DYNAMIC }}
173226
174- - name : Build
227+ - name : Build (dynamic linking, feature powerset)
228+ if : matrix.platform.dynamic-target || matrix.llvm-from != 'rust-ci'
175229 run : |
176- cargo hack build --feature-powerset \
177- --exclude-features ${{ env.LLVM_EXCLUDE_FEATURES }},${{ matrix.toolchain.exclude-features }} \
178- --features ${{ env.LLVM_FEATURES }}
230+ cargo hack build --feature-powerset --exclude-features \
231+ ${{ env.LLVM_EXCLUDE_FEATURES_DYNAMIC }},${{ matrix.toolchain.exclude-features }} \
232+ --features ${{ env.LLVM_FEATURES_DYNAMIC }}
179233
180234 # Toolchains provided by rustup include standard library artifacts
181235 # only for Tier 1 targets, which do not include BPF targets.
@@ -185,11 +239,13 @@ jobs:
185239 # running compiler tests.
186240 #
187241 # `RUSTC_BOOTSTRAP` is needed to use `rustc-build-sysroot` on stable Rust.
188- - name : Test (sysroot built on demand)
242+ - name : Test (sysroot built on demand, dynamic linking)
243+ if : matrix.platform.dynamic-target || matrix.llvm-from != 'rust-ci'
189244 run : |
190245 RUSTC_BOOTSTRAP=1 cargo hack test --feature-powerset \
191- --exclude-features ${{ env.LLVM_EXCLUDE_FEATURES }},${{ matrix.toolchain.exclude-features }} \
192- --features ${{ env.LLVM_FEATURES }}
246+ --exclude-features \
247+ ${{ env.LLVM_EXCLUDE_FEATURES_DYNAMIC }},${{ matrix.toolchain.exclude-features }} \
248+ --features ${{ env.LLVM_FEATURES_DYNAMIC }}
193249
194250 # To make things easier for package maintainers, the step of building a
195251 # custom sysroot can be skipped by setting the `BPFEL_SYSROOT_DIR`
@@ -200,7 +256,7 @@ jobs:
200256 #
201257 # `RUSTC_BOOTSTRAP` is needed to make `xtask build-std` work on stable
202258 # Rust.
203- - name : Test (prebuilt BPF standard library)
259+ - name : Build BPF standard library
204260 run : |
205261 set -euxo pipefail
206262
@@ -211,9 +267,13 @@ jobs:
211267 --sysroot-dir "$BPFEL_SYSROOT_DIR" \
212268 --target bpfel-unknown-none
213269
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 }}
270+ - name : Test (prebuilt BPF standard libary, dynamic linking)
271+ if : matrix.platform.dynamic-target || matrix.llvm-from != 'rust-ci'
272+ run : |
273+ BPFEL_SYSROOT_DIR="${{ github.workspace }}/bpf-sysroot" \
274+ cargo hack test --feature-powerset --exclude-features \
275+ ${{ env.LLVM_EXCLUDE_FEATURES_DYNAMIC }},${{ matrix.toolchain.exclude-features }} \
276+ --features ${{ env.LLVM_FEATURES_DYNAMIC }}
217277
218278 - uses : actions/checkout@v6
219279 if : runner.os == 'Linux' && matrix.toolchain.rust == 'nightly'
@@ -224,13 +284,70 @@ jobs:
224284
225285 - name : Install
226286 if : runner.os == 'Linux' && matrix.toolchain.rust == 'nightly'
227- run : cargo install --path . --no-default-features --features ${{ env.LLVM_FEATURES }}
287+ run : |
288+ cargo install --path . --no-default-features --features \
289+ ${{ env.LLVM_FEATURES_DYNAMIC }}
228290
229291 - name : Run aya integration tests
230292 if : runner.os == 'Linux' && matrix.toolchain.rust == 'nightly'
231293 working-directory : aya
232294 run : cargo xtask integration-test local
233295
296+ - name : Prepare for static linking (LLVM from Rust CI)
297+ if : matrix.llvm-from == 'rust-ci'
298+ run : |
299+ echo "${RUSTC_LLVM_INSTALL_DIR_STATIC}/bin" >> $GITHUB_PATH
300+
301+ - name : Install static libraries (macOS)
302+ if : runner.os == 'macOS'
303+ # macOS does not provide any static libraries. Homebrew does provide
304+ # them, but in custom paths that the system-wide clang is not aware of.
305+ # Point build.rs to them by setting environment variables.
306+ #
307+ # We install llvm package only for libc++.
308+ #
309+ # libLLVM from homebrew requires zstd.
310+ run : |
311+ brew install llvm zlib
312+ echo "CXXSTDLIB_PATH=$(brew --prefix llvm)/lib/c++" >> $GITHUB_ENV
313+ echo "ZLIB_PATH=$(brew --prefix zlib)/lib" >> $GITHUB_ENV
314+ if [[ "${{ matrix.llvm-from }}" == "packages" ]]; then
315+ brew install zstd
316+ echo "LIBZSTD_PATH=$(brew --prefix zstd)/lib" >> $GITHUB_ENV
317+ fi
318+
319+ - name : Point to correct stdc++ (Linux)
320+ if : runner.os == 'Linux'
321+ # There are multiple versions of stdc++ static libraries on Ubuntu,
322+ # each of them in versioned subdirectory inside /usr/lib/gcc. Pick one
323+ # for clarity.
324+ run : |
325+ echo "CXXSTDLIB_PATH=/usr/lib/gcc/x86_64-linux-gnu/12"
326+
327+ - name : Check (static linking, single feature set)
328+ # Static linking in combination with `cargo hack --feature-powerset`
329+ # (multiple builds) increases the disk usage massively. Therefore we
330+ # perform all static builds with only one fixed feature set.
331+ run : |
332+ cargo check --no-default-features --features \
333+ ${{ env.LLVM_FEATURES_STATIC }}
334+
335+ - name : Build (static linking, single feature set)
336+ run : |
337+ cargo build --no-default-features --features \
338+ ${{ env.LLVM_FEATURES_STATIC }}
339+
340+ - name : Test (sysroot built on demand, static linking)
341+ run : |
342+ RUSTC_BOOTSTRAP=1 cargo test --no-default-features --features \
343+ ${{ env.LLVM_FEATURES_STATIC }}
344+
345+ - name : Test (prebuilt BPF standard library, static linking)
346+ run : |
347+ BPFEL_SYSROOT_DIR="${{ github.workspace }}/bpf-sysroot" \
348+ cargo test --no-default-features --features \
349+ ${{ env.LLVM_FEATURES_STATIC }}
350+
234351 - name : Report disk usage
235352 if : ${{ always() }}
236353 uses : ./.github/actions/report-disk-usage
0 commit comments