Skip to content

Commit 802561e

Browse files
glandiumemilio
authored andcommitted
Add --target to the clang args earlier
Because the --target was passed after the include path detection, in cases of cross-compilation, the include path detection would add paths relevant to the host (e.g. /usr/include/x86_64_linux-gnu on x86_64 linux while targeting something else), possibly breaking things along the way.
1 parent d55b063 commit 802561e

File tree

2 files changed

+57
-66
lines changed

2 files changed

+57
-66
lines changed

src/ir/context.rs

+1-66
Original file line numberDiff line numberDiff line change
@@ -507,46 +507,12 @@ impl<'ctx> WhitelistedItemsTraversal<'ctx> {
507507
}
508508
}
509509

510-
const HOST_TARGET: &'static str =
511-
include_str!(concat!(env!("OUT_DIR"), "/host-target.txt"));
512-
513-
/// Returns the effective target, and whether it was explicitly specified on the
514-
/// clang flags.
515-
fn find_effective_target(clang_args: &[String]) -> (String, bool) {
516-
use std::env;
517-
518-
let mut args = clang_args.iter();
519-
while let Some(opt) = args.next() {
520-
if opt.starts_with("--target=") {
521-
let mut split = opt.split('=');
522-
split.next();
523-
return (split.next().unwrap().to_owned(), true);
524-
}
525-
526-
if opt == "-target" {
527-
if let Some(target) = args.next() {
528-
return (target.clone(), true);
529-
}
530-
}
531-
}
532-
533-
// If we're running from a build script, try to find the cargo target.
534-
if let Ok(t) = env::var("TARGET") {
535-
return (t, false);
536-
}
537-
538-
(HOST_TARGET.to_owned(), false)
539-
}
540-
541510
impl BindgenContext {
542511
/// Construct the context for the given `options`.
543512
pub(crate) fn new(options: BindgenOptions) -> Self {
544513
// TODO(emilio): Use the CXTargetInfo here when available.
545514
//
546515
// see: https://reviews.llvm.org/D32389
547-
let (effective_target, explicit_target) =
548-
find_effective_target(&options.clang_args);
549-
550516
let index = clang::Index::new(false, true);
551517

552518
let parse_options =
@@ -555,26 +521,11 @@ impl BindgenContext {
555521
let translation_unit = {
556522
let _t =
557523
Timer::new("translation_unit").with_output(options.time_phases);
558-
// NOTE: The effective_target == HOST_TARGET check wouldn't be sound
559-
// normally in some cases if we were to call a binary (if you have a
560-
// 32-bit clang and are building on a 64-bit system for example).
561-
// But since we rely on opening libclang.so, it has to be the same
562-
// architecture and thus the check is fine.
563-
let clang_args = if explicit_target ||
564-
effective_target == HOST_TARGET
565-
{
566-
Cow::Borrowed(&options.clang_args)
567-
} else {
568-
let mut args = Vec::with_capacity(options.clang_args.len() + 1);
569-
args.push(format!("--target={}", effective_target));
570-
args.extend_from_slice(&options.clang_args);
571-
Cow::Owned(args)
572-
};
573524

574525
clang::TranslationUnit::parse(
575526
&index,
576527
"",
577-
&clang_args,
528+
&options.clang_args,
578529
&options.input_unsaved_files,
579530
parse_options,
580531
).expect("libclang error; possible causes include:
@@ -587,22 +538,6 @@ If you encounter an error missing from this list, please file an issue or a PR!"
587538
};
588539

589540
let target_info = clang::TargetInfo::new(&translation_unit);
590-
591-
#[cfg(debug_assertions)]
592-
{
593-
if let Some(ref ti) = target_info {
594-
if effective_target == HOST_TARGET {
595-
assert_eq!(
596-
ti.pointer_width / 8,
597-
mem::size_of::<*mut ()>(),
598-
"{:?} {:?}",
599-
effective_target,
600-
HOST_TARGET
601-
);
602-
}
603-
}
604-
}
605-
606541
let root_module = Self::build_root_module(ItemId(0));
607542
let root_module_id = root_module.id().as_module_id_unchecked();
608543

src/lib.rs

+56
Original file line numberDiff line numberDiff line change
@@ -1914,6 +1914,35 @@ pub struct Bindings {
19141914
module: proc_macro2::TokenStream,
19151915
}
19161916

1917+
pub(crate) const HOST_TARGET: &'static str =
1918+
include_str!(concat!(env!("OUT_DIR"), "/host-target.txt"));
1919+
1920+
/// Returns the effective target, and whether it was explicitly specified on the
1921+
/// clang flags.
1922+
fn find_effective_target(clang_args: &[String]) -> (String, bool) {
1923+
let mut args = clang_args.iter();
1924+
while let Some(opt) = args.next() {
1925+
if opt.starts_with("--target=") {
1926+
let mut split = opt.split('=');
1927+
split.next();
1928+
return (split.next().unwrap().to_owned(), true);
1929+
}
1930+
1931+
if opt == "-target" {
1932+
if let Some(target) = args.next() {
1933+
return (target.clone(), true);
1934+
}
1935+
}
1936+
}
1937+
1938+
// If we're running from a build script, try to find the cargo target.
1939+
if let Ok(t) = env::var("TARGET") {
1940+
return (t, false);
1941+
}
1942+
1943+
(HOST_TARGET.to_owned(), false)
1944+
}
1945+
19171946
impl Bindings {
19181947
/// Generate bindings for the given options.
19191948
pub(crate) fn generate(
@@ -1931,6 +1960,20 @@ impl Bindings {
19311960

19321961
options.build();
19331962

1963+
let (effective_target, explicit_target) =
1964+
find_effective_target(&options.clang_args);
1965+
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) {
1972+
options
1973+
.clang_args
1974+
.insert(0, format!("--target={}", effective_target));
1975+
};
1976+
19341977
fn detect_include_paths(options: &mut BindgenOptions) {
19351978
if !options.detect_include_paths {
19361979
return;
@@ -2045,6 +2088,19 @@ impl Bindings {
20452088
let time_phases = options.time_phases;
20462089
let mut context = BindgenContext::new(options);
20472090

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+
}
2102+
}
2103+
20482104
{
20492105
let _t = time::Timer::new("parse").with_output(time_phases);
20502106
parse(&mut context)?;

0 commit comments

Comments
 (0)