Skip to content

Commit a022c11

Browse files
committed
BINDGEN_EXTRA_CLANG_ARGS handling in webgpu-shim/build.rs
1 parent 81e4d04 commit a022c11

1 file changed

Lines changed: 64 additions & 1 deletion

File tree

‎webgpu-shim/build.rs‎

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const WEBGPU_H_SHA256_SUM: &str =
1010
fn main() {
1111
println!("cargo:rerun-if-changed=wgpu.h");
1212
println!("cargo:rerun-if-changed=dep/webgpu-headers/webgpu.h");
13+
println!("cargo:rerun-if-env-changed=BINDGEN_EXTRA_CLANG_ARGS");
1314

1415
let webgpu_h_download_dir = download_webgpu_header();
1516

@@ -49,7 +50,69 @@ fn main() {
4950
.size_t_is_usize(true)
5051
.ignore_functions()
5152
.layout_tests(true)
52-
.clang_macro_fallback();
53+
.clang_macro_fallback()
54+
// bindgen's automatic include-path detection shells out to a `clang`
55+
// binary and appends its reported system include paths as redundant
56+
// `-isystem` flags on top of what libclang already resolves via
57+
// LIBCLANG_PATH. For cross-compiled (Android) targets those duplicate
58+
// paths corrupt stdint.h/stddef.h parsing (e.g. "unknown type name
59+
// 'uint32_t'"/'size_t'"), so rely solely on the explicit --sysroot/
60+
// --target flags below instead.
61+
.detect_include_paths(false);
62+
63+
// Add extra clang arguments for cross-compilation (e.g., Android)
64+
// Try common Android targets first since TARGET in build scripts is the host
65+
let possible_targets = [
66+
"aarch64_linux_android",
67+
"aarch64-linux-android",
68+
"armv7_linux_androideabi",
69+
"armv7-linux-androideabi",
70+
"i686_linux_android",
71+
"i686-linux-android",
72+
"x86_64_linux_android",
73+
"x86_64-linux-android",
74+
];
75+
76+
let mut found = false;
77+
for target in possible_targets.iter() {
78+
let clang_args_env = format!("BINDGEN_EXTRA_CLANG_ARGS_{}", target);
79+
println!("cargo:rerun-if-env-changed={}", clang_args_env);
80+
if let Ok(extra_args) = env::var(&clang_args_env) {
81+
for arg in extra_args.split_whitespace() {
82+
builder = builder.clang_arg(arg);
83+
}
84+
found = true;
85+
break;
86+
}
87+
}
88+
89+
// Fall back to generic BINDGEN_EXTRA_CLANG_ARGS
90+
if !found {
91+
println!("cargo:rerun-if-env-changed=BINDGEN_EXTRA_CLANG_ARGS");
92+
if let Ok(extra_args) = env::var("BINDGEN_EXTRA_CLANG_ARGS") {
93+
for arg in extra_args.split_whitespace() {
94+
builder = builder.clang_arg(arg);
95+
}
96+
}
97+
}
98+
99+
// When cross-compiling, libclang's own resource-dir auto-detection
100+
// (relied on for stdint.h/stddef.h builtins) has proven unreliable
101+
// depending on which build unit (host vs. target) this build script runs
102+
// as. Since LIBCLANG_PATH points at the toolchain's libclang, derive its
103+
// sibling `clang/<version>` resource directory explicitly instead of
104+
// trusting auto-detection.
105+
println!("cargo:rerun-if-env-changed=LIBCLANG_PATH");
106+
if found {
107+
if let Ok(libclang_path) = env::var("LIBCLANG_PATH") {
108+
let clang_dir = PathBuf::from(&libclang_path).join("clang");
109+
if let Ok(entries) = fs::read_dir(&clang_dir) {
110+
if let Some(version_dir) = entries.filter_map(|e| e.ok()).map(|e| e.path()).find(|p| p.is_dir()) {
111+
builder = builder.clang_arg(format!("-resource-dir={}", version_dir.display()));
112+
}
113+
}
114+
}
115+
}
53116

54117
for (old_name, new_name) in types_to_rename {
55118
let line = format!("pub type {old_name} = *const crate::{new_name};");

0 commit comments

Comments
 (0)