Skip to content

Commit 7e4a8aa

Browse files
committed
Fix LLVM CI libclang setup
1 parent 15f7262 commit 7e4a8aa

7 files changed

Lines changed: 84 additions & 16 deletions

File tree

.github/workflows/python-release.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ jobs:
214214
PATH=${{ matrix.gcc_path_prefix }}$HOME/.cargo/bin:$HOME/.pecos/deps/llvm-21.1/bin:$HOME/.pecos/deps/cmake-${{ env.PECOS_CMAKE_VERSION }}/bin:/usr/local/cuda-12.6/bin:$PATH
215215
LD_LIBRARY_PATH=${{ matrix.gcc_ld_path }}$HOME/.pecos/deps/llvm-21.1/lib:$LD_LIBRARY_PATH
216216
LLVM_SYS_211_PREFIX=$HOME/.pecos/deps/llvm-21.1
217+
LIBCLANG_PATH=$HOME/.pecos/deps/llvm-21.1/lib
217218
CMAKE=$HOME/.pecos/deps/cmake-${{ env.PECOS_CMAKE_VERSION }}/bin/cmake
218219
CUDA_PATH=/usr/local/cuda-12.6
219220
MATURIN_PEP517_ARGS="--locked --features=extension-module,mwpf"
@@ -249,6 +250,7 @@ jobs:
249250
CIBW_ENVIRONMENT_MACOS: >
250251
PATH=$HOME/.cargo/bin:$HOME/.pecos/deps/llvm-21.1/bin:$HOME/.pecos/deps/cmake-${{ env.PECOS_CMAKE_VERSION }}/CMake.app/Contents/bin:$PATH
251252
LLVM_SYS_211_PREFIX=$HOME/.pecos/deps/llvm-21.1
253+
LIBCLANG_PATH=$HOME/.pecos/deps/llvm-21.1/lib
252254
CMAKE=$HOME/.pecos/deps/cmake-${{ env.PECOS_CMAKE_VERSION }}/CMake.app/Contents/bin/cmake
253255
MACOSX_DEPLOYMENT_TARGET=13.2
254256
SDKROOT=$(xcrun --show-sdk-path)
@@ -274,12 +276,13 @@ jobs:
274276
CIBW_ENVIRONMENT_WINDOWS: >
275277
PATH="C:\\Users\\runneradmin\\.pecos\\deps\\llvm-21.1\\bin;C:\\Users\\runneradmin\\.pecos\\deps\\cmake-${{ env.PECOS_CMAKE_VERSION }}\\bin;$PATH"
276278
LLVM_SYS_211_PREFIX="C:\\Users\\runneradmin\\.pecos\\deps\\llvm-21.1"
279+
LIBCLANG_PATH="C:\\Users\\runneradmin\\.pecos\\deps\\llvm-21.1\\bin"
277280
CMAKE="C:\\Users\\runneradmin\\.pecos\\deps\\cmake-${{ env.PECOS_CMAKE_VERSION }}\\bin\\cmake.exe"
278281
MATURIN_PEP517_ARGS="--locked --features=extension-module,mwpf"
279282
CIBW_BEFORE_ALL_WINDOWS: >
280283
echo "=== Installing LLVM 21.1 development archive ===" &&
281284
rustup update &&
282-
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\ci\install-llvm-21-windows.ps1 -InstallDir "C:\Users\runneradmin\.pecos\deps\llvm-21.1" -Version ${{ env.LLVM_RELEASE_VERSION }} &&
285+
powershell.exe -NoProfile -ExecutionPolicy Bypass -File scripts\ci\install-llvm-21-windows.ps1 -InstallDir "C:\Users\runneradmin\.pecos\deps\llvm-21.1" -Version ${{ env.LLVM_RELEASE_VERSION }} &&
283286
cargo run --locked --release -p pecos-cli -- llvm configure "C:\Users\runneradmin\.pecos\deps\llvm-21.1" &&
284287
cargo run --locked --release -p pecos-cli -- install cmake --force &&
285288
echo "=== Checking LLVM installation ===" &&
@@ -317,6 +320,7 @@ jobs:
317320
PATH=$HOME/.cargo/bin:$HOME/.pecos/deps/llvm-21.1/bin:$PATH
318321
LD_LIBRARY_PATH=$HOME/.pecos/deps/llvm-21.1/lib:$LD_LIBRARY_PATH
319322
LLVM_SYS_211_PREFIX=$HOME/.pecos/deps/llvm-21.1
323+
LIBCLANG_PATH=$HOME/.pecos/deps/llvm-21.1/lib
320324
CIBW_BEFORE_ALL_LINUX: |
321325
bash scripts/ci/ensure-rust.sh stable minimal
322326
export PATH=$HOME/.cargo/bin:$PATH
@@ -329,6 +333,7 @@ jobs:
329333
CIBW_ENVIRONMENT_MACOS: >
330334
PATH=$HOME/.cargo/bin:$HOME/.pecos/deps/llvm-21.1/bin:$PATH
331335
LLVM_SYS_211_PREFIX=$HOME/.pecos/deps/llvm-21.1
336+
LIBCLANG_PATH=$HOME/.pecos/deps/llvm-21.1/lib
332337
MACOSX_DEPLOYMENT_TARGET=13.2
333338
SDKROOT=$(xcrun --show-sdk-path)
334339
CIBW_BEFORE_ALL_MACOS: |
@@ -354,9 +359,10 @@ jobs:
354359
CIBW_ENVIRONMENT_WINDOWS: >
355360
PATH="C:\\Users\\runneradmin\\.pecos\\deps\\llvm-21.1\\bin;$PATH"
356361
LLVM_SYS_211_PREFIX="C:\\Users\\runneradmin\\.pecos\\deps\\llvm-21.1"
362+
LIBCLANG_PATH="C:\\Users\\runneradmin\\.pecos\\deps\\llvm-21.1\\bin"
357363
CIBW_BEFORE_ALL_WINDOWS: >
358364
rustup update &&
359-
if not exist "C:\Users\runneradmin\.pecos\deps\llvm-21.1\bin\llvm-config.exe" (powershell -NoProfile -ExecutionPolicy Bypass -File scripts\ci\install-llvm-21-windows.ps1 -InstallDir "C:\Users\runneradmin\.pecos\deps\llvm-21.1" -Version ${{ env.LLVM_RELEASE_VERSION }}) else (echo LLVM already installed from pecos-rslib build) &&
365+
if not exist "C:\Users\runneradmin\.pecos\deps\llvm-21.1\bin\llvm-config.exe" (powershell.exe -NoProfile -ExecutionPolicy Bypass -File scripts\ci\install-llvm-21-windows.ps1 -InstallDir "C:\Users\runneradmin\.pecos\deps\llvm-21.1" -Version ${{ env.LLVM_RELEASE_VERSION }}) else (echo LLVM already installed from pecos-rslib build) &&
360366
cargo run --locked --release -p pecos-cli -- llvm configure "C:\Users\runneradmin\.pecos\deps\llvm-21.1"
361367
CIBW_BEFORE_BUILD_WINDOWS: >
362368
pip install delvewheel &&

.github/workflows/python-test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ jobs:
140140
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
141141
with:
142142
path: ~/.pecos/deps/llvm-21.1
143-
key: llvm-${{ env.LLVM_RELEASE_VERSION }}-${{ runner.os }}-${{ runner.arch }}-v2
143+
key: llvm-${{ env.LLVM_RELEASE_VERSION }}-${{ runner.os }}-${{ runner.arch }}-v3
144144

145145
# `just ci-env` is the first cargo invocation. Its `_msvc-bootstrap`
146146
# prerequisite writes the MSVC linker + LIB/INCLUDE into

.github/workflows/rust-test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ jobs:
9191
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
9292
with:
9393
path: ~/.pecos/deps/llvm-21.1
94-
key: llvm-${{ env.LLVM_RELEASE_VERSION }}-${{ runner.os }}-${{ runner.arch }}-v2
94+
key: llvm-${{ env.LLVM_RELEASE_VERSION }}-${{ runner.os }}-${{ runner.arch }}-v3
9595

9696
- name: Ensure LLVM ${{ env.LLVM_VERSION }}
9797
run: just ci-env
@@ -232,7 +232,7 @@ jobs:
232232
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
233233
with:
234234
path: ~/.pecos/deps/llvm-21.1
235-
key: llvm-${{ env.LLVM_RELEASE_VERSION }}-${{ runner.os }}-${{ runner.arch }}-v2
235+
key: llvm-${{ env.LLVM_RELEASE_VERSION }}-${{ runner.os }}-${{ runner.arch }}-v3
236236

237237
- name: Bootstrap MSVC for the Cargo build path (Windows)
238238
if: runner.os == 'Windows'

.github/workflows/test-docs-examples.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ jobs:
7575
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
7676
with:
7777
path: ~/.pecos/deps/llvm-21.1
78-
key: llvm-${{ env.LLVM_RELEASE_VERSION }}-${{ runner.os }}-${{ runner.arch }}-v2
78+
key: llvm-${{ env.LLVM_RELEASE_VERSION }}-${{ runner.os }}-${{ runner.arch }}-v3
7979

8080
- name: Ensure LLVM ${{ env.LLVM_VERSION }}
8181
run: just ci-env

crates/pecos-cli/src/cli/env_cmd.rs

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@
2626
use std::collections::BTreeMap;
2727
use std::ffi::OsString;
2828
use std::fmt::Write;
29+
use std::fs;
2930
use std::fs::OpenOptions;
3031
use std::io::Write as IoWrite;
31-
use std::path::Path;
32+
use std::path::{Path, PathBuf};
3233

3334
use pecos_build::Result;
3435
use pecos_build::errors::Error;
@@ -59,11 +60,16 @@ pub fn collect_env() -> BTreeMap<String, String> {
5960
}
6061
}
6162

62-
if pecos_build::llvm::get_llvm_shared_mode(&llvm_path)
63-
.is_ok_and(|mode| mode.trim().eq_ignore_ascii_case("shared"))
64-
&& let Ok(libdir) = pecos_build::llvm::get_llvm_libdir(&llvm_path)
65-
{
66-
add_llvm_runtime_library_path(&mut env, &libdir);
63+
if let Ok(libdir) = pecos_build::llvm::get_llvm_libdir(&llvm_path) {
64+
if pecos_build::llvm::get_llvm_shared_mode(&llvm_path)
65+
.is_ok_and(|mode| mode.trim().eq_ignore_ascii_case("shared"))
66+
{
67+
add_llvm_runtime_library_path(&mut env, &libdir);
68+
}
69+
70+
if let Some(libclang_dir) = find_libclang_dir(&llvm_path, &libdir) {
71+
env.insert("LIBCLANG_PATH".into(), libclang_dir.display().to_string());
72+
}
6773
}
6874
}
6975

@@ -161,6 +167,42 @@ fn prepend_path_env(env: &mut BTreeMap<String, String>, key: &str, first: &Path)
161167
}
162168
}
163169

170+
fn find_libclang_dir(llvm_path: &Path, libdir: &Path) -> Option<PathBuf> {
171+
let mut candidates = vec![libdir.to_path_buf()];
172+
if cfg!(windows) {
173+
candidates.insert(0, llvm_path.join("bin"));
174+
}
175+
176+
candidates
177+
.into_iter()
178+
.find(|candidate| contains_libclang(candidate))
179+
}
180+
181+
fn contains_libclang(dir: &Path) -> bool {
182+
let Ok(entries) = fs::read_dir(dir) else {
183+
return false;
184+
};
185+
186+
entries
187+
.filter_map(std::result::Result::ok)
188+
.any(|entry| entry.file_name().to_str().is_some_and(is_libclang_filename))
189+
}
190+
191+
fn is_libclang_filename(name: &str) -> bool {
192+
if cfg!(windows) {
193+
return name.eq_ignore_ascii_case("libclang.dll");
194+
}
195+
196+
if cfg!(target_os = "macos") {
197+
return name == "libclang.dylib"
198+
|| (name.starts_with("libclang.") && name.ends_with(".dylib"));
199+
}
200+
201+
name == "libclang.so"
202+
|| name.starts_with("libclang.so.")
203+
|| name.starts_with("libclang-") && name.contains(".so")
204+
}
205+
164206
/// Print environment in shell-eval format: `export KEY="VALUE"`
165207
pub fn print_shell(env: &BTreeMap<String, String>) {
166208
for (key, value) in env {

scripts/ci/install-llvm-21-conda-linux.sh

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,17 @@ esac
2222

2323
llvm_is_valid() {
2424
local llvm_config="$1"
25+
local llvm_dir
26+
27+
llvm_dir="$(dirname "$(dirname "$llvm_config")")"
2528

2629
[ -x "$llvm_config" ] || return 1
2730
"$llvm_config" --version | grep -q '^21\.1' || return 1
2831
[ "$("$llvm_config" --shared-mode)" = "shared" ] || return 1
2932
"$llvm_config" --libnames --link-shared | grep -q 'libLLVM-21\.so'
33+
find "$llvm_dir/lib" -maxdepth 1 \
34+
\( -name 'libclang.so' -o -name 'libclang-*.so' -o -name 'libclang.so.*' -o -name 'libclang-*.so.*' \) \
35+
| grep -q .
3036
}
3137

3238
LLVM_CONFIG="$INSTALL_DIR/bin/llvm-config"
@@ -61,17 +67,22 @@ MAMBA_ROOT_PREFIX="$MAMBA_ROOT_PREFIX" "$MAMBA_BIN" create \
6167
-p "$INSTALL_DIR" \
6268
--override-channels \
6369
-c conda-forge \
64-
"llvmdev=${LLVM_RELEASE_VERSION}"
70+
"llvmdev=${LLVM_RELEASE_VERSION}" \
71+
"libclang=${LLVM_RELEASE_VERSION}"
6572

6673
if ! llvm_is_valid "$LLVM_CONFIG"; then
67-
echo "conda-forge LLVM install did not provide shared LLVM ${LLVM_RELEASE_VERSION}" >&2
74+
echo "conda-forge LLVM install did not provide shared LLVM and libclang ${LLVM_RELEASE_VERSION}" >&2
6875
"$LLVM_CONFIG" --version >&2 || true
6976
"$LLVM_CONFIG" --shared-mode >&2 || true
7077
"$LLVM_CONFIG" --libnames --link-shared >&2 || true
78+
find "$INSTALL_DIR/lib" -maxdepth 1 -name 'libclang*' -print >&2 || true
7179
exit 1
7280
fi
7381

7482
"$LLVM_CONFIG" --version
7583
"$LLVM_CONFIG" --shared-mode
7684
"$LLVM_CONFIG" --libnames --link-shared
77-
echo "Installed shared LLVM ${LLVM_RELEASE_VERSION} to $INSTALL_DIR"
85+
find "$INSTALL_DIR/lib" -maxdepth 1 \
86+
\( -name 'libclang.so' -o -name 'libclang-*.so' -o -name 'libclang.so.*' -o -name 'libclang-*.so.*' \) \
87+
-print
88+
echo "Installed shared LLVM and libclang ${LLVM_RELEASE_VERSION} to $INSTALL_DIR"

scripts/ci/install-llvm-21-windows.ps1

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,16 @@ try {
6868
throw "SHA256 mismatch for $Asset. Expected $ExpectedSha256, got $ActualSha256"
6969
}
7070

71-
tar -xf $Archive -C $ExtractDir --strip-components=1
71+
$Tar = Join-Path $env:SystemRoot "System32\tar.exe"
72+
if (-not (Test-Path $Tar)) {
73+
$Tar = "tar.exe"
74+
}
75+
76+
Write-Host "Extracting LLVM archive with $Tar"
77+
& $Tar -xf $Archive -C $ExtractDir --strip-components=1
78+
if ($LASTEXITCODE -ne 0) {
79+
throw "tar failed with exit code $LASTEXITCODE"
80+
}
7281

7382
if (Test-Path $InstallDir) {
7483
Remove-Item -Recurse -Force $InstallDir

0 commit comments

Comments
 (0)