Skip to content

Commit f4d0b7c

Browse files
committed
lib: Fix inferred target when clang target differs from rust target.
Fixes #1211.
1 parent 6653d0c commit f4d0b7c

File tree

1 file changed

+36
-20
lines changed

1 file changed

+36
-20
lines changed

src/lib.rs

+36-20
Original file line numberDiff line numberDiff line change
@@ -1917,6 +1917,17 @@ pub struct Bindings {
19171917
pub(crate) const HOST_TARGET: &'static str =
19181918
include_str!(concat!(env!("OUT_DIR"), "/host-target.txt"));
19191919

1920+
// Some architecture triplets are different between rust and libclang, see #1211
1921+
// and duplicates.
1922+
fn rust_to_clang_target(rust_target: &str) -> String {
1923+
if rust_target.starts_with("aarch64-apple-") {
1924+
let mut clang_target = "arm64-apple-".to_owned();
1925+
clang_target.push_str(&rust_target["aarch64-apple-".len()..]);
1926+
return clang_target;
1927+
}
1928+
rust_target.to_owned()
1929+
}
1930+
19201931
/// Returns the effective target, and whether it was explicitly specified on the
19211932
/// clang flags.
19221933
fn find_effective_target(clang_args: &[String]) -> (String, bool) {
@@ -1937,10 +1948,10 @@ fn find_effective_target(clang_args: &[String]) -> (String, bool) {
19371948

19381949
// If we're running from a build script, try to find the cargo target.
19391950
if let Ok(t) = env::var("TARGET") {
1940-
return (t, false);
1951+
return (rust_to_clang_target(&t), false);
19411952
}
19421953

1943-
(HOST_TARGET.to_owned(), false)
1954+
(rust_to_clang_target(HOST_TARGET), false)
19441955
}
19451956

19461957
impl Bindings {
@@ -1963,12 +1974,15 @@ impl Bindings {
19631974
let (effective_target, explicit_target) =
19641975
find_effective_target(&options.clang_args);
19651976

1966-
// NOTE: The effective_target == HOST_TARGET check wouldn't be sound
1967-
// normally in some cases if we were to call a binary (if you have a
1968-
// 32-bit clang and are building on a 64-bit system for example).
1969-
// But since we rely on opening libclang.so, it has to be the same
1970-
// architecture and thus the check is fine.
1971-
if !(explicit_target || effective_target == HOST_TARGET) {
1977+
let is_host_build =
1978+
rust_to_clang_target(HOST_TARGET) == effective_target;
1979+
1980+
// NOTE: The is_host_build check wouldn't be sound normally in some
1981+
// cases if we were to call a binary (if you have a 32-bit clang and are
1982+
// building on a 64-bit system for example). But since we rely on
1983+
// opening libclang.so, it has to be the same architecture and thus the
1984+
// check is fine.
1985+
if !explicit_target && !is_host_build {
19721986
options
19731987
.clang_args
19741988
.insert(0, format!("--target={}", effective_target));
@@ -2088,17 +2102,14 @@ impl Bindings {
20882102
let time_phases = options.time_phases;
20892103
let mut context = BindgenContext::new(options);
20902104

2091-
#[cfg(debug_assertions)]
2092-
{
2093-
if effective_target == HOST_TARGET {
2094-
assert_eq!(
2095-
context.target_pointer_size(),
2096-
std::mem::size_of::<*mut ()>(),
2097-
"{:?} {:?}",
2098-
effective_target,
2099-
HOST_TARGET
2100-
);
2101-
}
2105+
if is_host_build {
2106+
debug_assert_eq!(
2107+
context.target_pointer_size(),
2108+
std::mem::size_of::<*mut ()>(),
2109+
"{:?} {:?}",
2110+
effective_target,
2111+
HOST_TARGET
2112+
);
21022113
}
21032114

21042115
{
@@ -2109,7 +2120,7 @@ impl Bindings {
21092120
let (items, options) = codegen::codegen(context);
21102121

21112122
Ok(Bindings {
2112-
options: options,
2123+
options,
21132124
module: quote! {
21142125
#( #items )*
21152126
},
@@ -2444,3 +2455,8 @@ fn commandline_flag_unit_test_function() {
24442455
.iter()
24452456
.all(|ref x| command_line_flags.contains(x),));
24462457
}
2458+
2459+
#[test]
2460+
fn test_rust_to_clang_target() {
2461+
assert_eq!(rust_to_clang_target("aarch64-apple-ios"), "arm64-apple-ios");
2462+
}

0 commit comments

Comments
 (0)