Skip to content

Commit af4a15e

Browse files
committed
use another way
1 parent bc026f5 commit af4a15e

1 file changed

Lines changed: 33 additions & 28 deletions

File tree

Modules/cpython-sys/build.rs

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ fn main() {
1010
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
1111
let builddir = env::var("PYTHON_BUILD_DIR").ok();
1212
emit_rerun_instructions(builddir.as_deref());
13-
prefer_newest_libclang();
1413
if gil_disabled(srcdir, builddir.as_deref()) {
1514
println!("cargo:rustc-cfg=py_gil_disabled");
1615
}
@@ -41,38 +40,32 @@ fn emit_rerun_instructions(builddir: Option<&str>) {
4140
}
4241
}
4342

44-
/// When LIBCLANG_PATH is not already set, scan /usr/lib/llvm-*/lib for the
45-
/// newest available libclang and point bindgen at it. Ubuntu 24.04 ships
46-
/// libclang-18 by default, which has broken headers (stdatomic.h, mmintrin.h).
47-
/// CI jobs that install a newer LLVM (e.g. clang-20) also get a working
48-
/// libclang in /usr/lib/llvm-20/lib -- we just need to tell bindgen about it.
49-
fn prefer_newest_libclang() {
50-
if env::var_os("LIBCLANG_PATH").is_some() {
51-
return;
52-
}
43+
/// Find the newest clang resource directory on the system.
44+
///
45+
/// Ubuntu 24.04 ships libclang-18 whose built-in headers (stdatomic.h,
46+
/// mmintrin.h) are broken. CI jobs install a newer clang (e.g. clang-20)
47+
/// whose resource directory at /usr/lib/llvm-20/lib/clang/20 has working
48+
/// headers. We pass -resource-dir to bindgen's clang so it picks up those
49+
/// headers instead of the broken libclang-18 ones.
50+
fn newest_clang_resource_dir() -> Option<PathBuf> {
5351
let base = Path::new("/usr/lib");
5452
let mut best: Option<(u32, PathBuf)> = None;
55-
if let Ok(entries) = std::fs::read_dir(base) {
56-
for entry in entries.flatten() {
57-
let name = entry.file_name();
58-
let name = name.to_string_lossy();
59-
if let Some(ver_str) = name.strip_prefix("llvm-") {
60-
if let Ok(ver) = ver_str.parse::<u32>() {
61-
let lib_dir = entry.path().join("lib");
62-
if lib_dir.is_dir() {
63-
if best.as_ref().map_or(true, |(v, _)| ver > *v) {
64-
best = Some((ver, lib_dir));
65-
}
66-
}
67-
}
53+
for entry in std::fs::read_dir(base).ok()?.flatten() {
54+
let name = entry.file_name();
55+
let name = name.to_string_lossy();
56+
if let Some(ver_str) = name.strip_prefix("llvm-")
57+
&& let Ok(ver) = ver_str.parse::<u32>()
58+
{
59+
// Resource dir: /usr/lib/llvm-<N>/lib/clang/<N>
60+
let resource_dir = entry.path().join("lib").join("clang").join(ver_str);
61+
if resource_dir.join("include").is_dir()
62+
&& best.as_ref().map_or(true, |(v, _)| ver > *v)
63+
{
64+
best = Some((ver, resource_dir));
6865
}
6966
}
7067
}
71-
if let Some((ver, lib_dir)) = best {
72-
eprintln!("cpython-sys: using libclang from llvm-{ver}");
73-
// SAFETY: build scripts are single-threaded.
74-
unsafe { env::set_var("LIBCLANG_PATH", &lib_dir) };
75-
}
68+
best.map(|(_, p)| p)
7669
}
7770

7871
fn gil_disabled(srcdir: &Path, builddir: Option<&str>) -> bool {
@@ -98,6 +91,18 @@ fn generate_c_api_bindings(srcdir: &Path, builddir: Option<&str>, out_path: &Pat
9891
// Suppress all clang warnings (deprecation warnings, etc.)
9992
builder = builder.clang_arg("-w");
10093

94+
// Use the newest clang resource directory available on the system.
95+
// Bindgen links against whatever libclang it finds (often an older
96+
// system version), but the built-in headers in that version may be
97+
// broken (e.g. libclang-18 on Ubuntu 24.04 has broken stdatomic.h
98+
// and mmintrin.h). Overriding -resource-dir makes clang use a
99+
// newer set of built-in headers without changing which libclang.so
100+
// is loaded.
101+
if let Some(resource_dir) = newest_clang_resource_dir() {
102+
eprintln!("cpython-sys: using clang resource dir {}", resource_dir.display());
103+
builder = builder.clang_arg(format!("-resource-dir={}", resource_dir.display()));
104+
}
105+
101106
// Tell clang the correct target triple for cross-compilation when we have
102107
// an LLVM-specific triple. Otherwise let bindgen translate Cargo's TARGET
103108
// itself (e.g. aarch64-apple-ios-sim -> arm64-apple-ios-simulator).

0 commit comments

Comments
 (0)