Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

options: Add an option to opt-out of include path detection. #1543

Merged
merged 1 commit into from
Mar 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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