Skip to content

Commit

Permalink
Merge pull request #1543 from emilio/include-path
Browse files Browse the repository at this point in the history
options: Add an option to opt-out of include path detection.
  • Loading branch information
emilio authored Mar 26, 2019
2 parents b59419a + 09c299b commit 002cb29
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 50 deletions.
108 changes: 58 additions & 50 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1135,6 +1135,12 @@ impl Builder {
self
}

/// Whether to detect include paths using clang_sys.
pub fn detect_include_paths(mut self, doit: bool) -> Self {
self.options.detect_include_paths = doit;
self
}

/// Prepend the enum name to constant or bitfield variants.
pub fn prepend_enum_name(mut self, doit: bool) -> Self {
self.options.prepend_enum_name = doit;
Expand Down Expand Up @@ -1504,6 +1510,9 @@ struct BindgenOptions {
/// [1]: https://github.com/rust-lang-nursery/rust-bindgen/issues/528
enable_mangling: bool,

/// Whether to detect include paths using clang_sys.
detect_include_paths: bool,

/// Whether to prepend the enum name to bitfield or constant variants.
prepend_enum_name: bool,

Expand Down Expand Up @@ -1638,6 +1647,7 @@ impl Default for BindgenOptions {
objc_extern_crate: false,
block_extern_crate: false,
enable_mangling: true,
detect_include_paths: true,
prepend_enum_name: true,
time_phases: false,
record_matches: true,
Expand Down Expand Up @@ -1689,69 +1699,67 @@ impl Bindings {

options.build();

// Filter out include paths and similar stuff, so we don't incorrectly
// promote them to `-isystem`.
let clang_args_for_clang_sys = {
let mut last_was_include_prefix = false;
options.clang_args.iter().filter(|arg| {
if last_was_include_prefix {
last_was_include_prefix = false;
return false;
}
fn detect_include_paths(options: &mut BindgenOptions) {
if !options.detect_include_paths {
return;
}

let arg = &**arg;
// Filter out include paths and similar stuff, so we don't incorrectly
// promote them to `-isystem`.
let clang_args_for_clang_sys = {
let mut last_was_include_prefix = false;
options.clang_args.iter().filter(|arg| {
if last_was_include_prefix {
last_was_include_prefix = false;
return false;
}

// https://clang.llvm.org/docs/ClangCommandLineReference.html
// -isystem and -isystem-after are harmless.
if arg == "-I" || arg == "--include-directory" {
last_was_include_prefix = true;
return false;
}
let arg = &**arg;

if arg.starts_with("-I") || arg.starts_with("--include-directory=") {
return false;
}
// https://clang.llvm.org/docs/ClangCommandLineReference.html
// -isystem and -isystem-after are harmless.
if arg == "-I" || arg == "--include-directory" {
last_was_include_prefix = true;
return false;
}

true
}).cloned().collect::<Vec<_>>()
};
if arg.starts_with("-I") || arg.starts_with("--include-directory=") {
return false;
}

true
}).cloned().collect::<Vec<_>>()
};

debug!("Trying to find clang with flags: {:?}", clang_args_for_clang_sys);
debug!("Trying to find clang with flags: {:?}", clang_args_for_clang_sys);

let clang = match clang_sys::support::Clang::find(None, &clang_args_for_clang_sys) {
None => return,
Some(clang) => clang,
};

// TODO: Make this path fixup configurable?
if let Some(clang) = clang_sys::support::Clang::find(
None,
&clang_args_for_clang_sys,
) {
debug!("Found clang: {:?}", clang);

// If --target is specified, assume caller knows what they're doing
// and don't mess with include paths for them
let has_target_arg = options
.clang_args
.iter()
.rposition(|arg| arg.starts_with("--target"))
.is_some();
if !has_target_arg {
// Whether we are working with C or C++ inputs.
let is_cpp = args_are_cpp(&options.clang_args);
let search_paths = if is_cpp {
clang.cpp_search_paths
} else {
clang.c_search_paths
};

if let Some(search_paths) = search_paths {
for path in search_paths.into_iter() {
if let Ok(path) = path.into_os_string().into_string() {
options.clang_args.push("-isystem".to_owned());
options.clang_args.push(path);
}
// Whether we are working with C or C++ inputs.
let is_cpp = args_are_cpp(&options.clang_args);
let search_paths = if is_cpp {
clang.cpp_search_paths
} else {
clang.c_search_paths
};

if let Some(search_paths) = search_paths {
for path in search_paths.into_iter() {
if let Ok(path) = path.into_os_string().into_string() {
options.clang_args.push("-isystem".to_owned());
options.clang_args.push(path);
}
}
}
}

detect_include_paths(&mut options);

#[cfg(unix)]
fn can_read(perms: &std::fs::Permissions) -> bool {
use std::os::unix::fs::PermissionsExt;
Expand Down
7 changes: 7 additions & 0 deletions src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@ where
Arg::with_name("no-prepend-enum-name")
.long("no-prepend-enum-name")
.help("Do not prepend the enum name to bitfield or constant variants."),
Arg::with_name("no-include-path-detection")
.long("no-include-path-detection")
.help("Do not try to detect default include paths"),
Arg::with_name("unstable-rust")
.long("unstable-rust")
.help("Generate unstable Rust code (deprecated; use --rust-target instead).")
Expand Down Expand Up @@ -447,6 +450,10 @@ where
builder = builder.prepend_enum_name(false);
}

if matches.is_present("no-include-path-detection") {
builder = builder.detect_include_paths(false);
}

if matches.is_present("time-phases") {
builder = builder.time_phases(true);
}
Expand Down

0 comments on commit 002cb29

Please sign in to comment.