diff options
author | Emilio Cobos Álvarez <me@emiliocobos.me> | 2016-07-03 20:26:13 -0700 |
---|---|---|
committer | Emilio Cobos Álvarez <me@emiliocobos.me> | 2016-07-04 21:02:01 -0700 |
commit | 44c3b185ecf66a10c729cde695c4472fb70ae184 (patch) | |
tree | 35c1f85923deba8e28f1a25add4f0ddc2c03d2be | |
parent | 2396141a0df110a8e341927f66eb73d647db2a82 (diff) |
bindgen: use clang-sys for the include path.
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | src/bin/bindgen.rs | 13 | ||||
-rw-r--r-- | src/lib.rs | 74 |
3 files changed, 13 insertions, 76 deletions
@@ -15,6 +15,8 @@ clippy = { version = "*", optional = true } log = "0.3.*" libc = "0.2.*" syntex_syntax = "0.32" +# TODO: Use clang-sys for our low-level bindings once llvm 3.9 is stable. +clang-sys = "0.7.2" [features] static = [] diff --git a/src/bin/bindgen.rs b/src/bin/bindgen.rs index fd0a7ffe..228c5f95 100644 --- a/src/bin/bindgen.rs +++ b/src/bin/bindgen.rs @@ -4,6 +4,7 @@ extern crate bindgen; #[macro_use] extern crate log; +extern crate clang_sys; use bindgen::{Bindings, BindgenOptions, LinkType, Logger}; use std::io; @@ -214,12 +215,14 @@ pub fn main() { let mut bind_args: Vec<_> = env::args().collect(); let bin = bind_args.remove(0); - match bindgen::get_include_dir() { - Some(path) => { - bind_args.push("-I".to_owned()); - bind_args.push(path); + if let Some(clang) = clang_sys::support::Clang::find(None) { + // TODO: distinguish C and C++ paths? C++'s should be enough, I guess. + for path in clang.cpp_search_paths.into_iter() { + if let Ok(path) = path.into_os_string().into_string() { + bind_args.push("-isystem".to_owned()); + bind_args.push(path); + } } - None => (), } match parse_args(&bind_args) { @@ -7,6 +7,7 @@ #![cfg_attr(feature = "clippy", plugin(clippy))] extern crate syntex_syntax as syntax; +extern crate clang_sys; extern crate libc; #[macro_use] extern crate log; @@ -15,8 +16,7 @@ use std::collections::HashSet; use std::default::Default; use std::io::{Write, self}; use std::fs::OpenOptions; -use std::path::{Path, self}; -use std::{env, fs}; +use std::path::Path; use syntax::ast; use syntax::codemap::{DUMMY_SP, Span}; @@ -332,8 +332,7 @@ fn builtin_names() -> HashSet<String> { } #[test] -fn builder_state() -{ +fn builder_state() { let logger = DummyLogger; let mut build = builder(); { @@ -345,70 +344,3 @@ fn builder_state() assert!(build.options.clang_args.binary_search(&"example.h".to_owned()).is_ok()); assert!(build.options.links.binary_search(&("m".to_owned(), LinkType::Static)).is_ok()); } - -// Get the first directory in PATH that contains a file named "clang". -fn get_clang_dir() -> Option<path::PathBuf>{ - if let Some(paths) = env::var_os("PATH") { - for mut path in env::split_paths(&paths) { - path.push("clang"); - if let Ok(real_path) = fs::canonicalize(&path) { - if fs::metadata(&real_path).iter().any(|m| m.is_file()) && - real_path - .file_name() - .and_then(|f| f.to_str()) - .iter() - .any(|&f| f.starts_with("clang")) { - if let Some(dir) = real_path.parent() { - return Some(dir.to_path_buf()) - } - } - } - } - } - None -} - -// Try to find the directory that contains clang's bundled headers. Clang itself does something -// very similar: it takes the parent directory of the current executable, appends -// "../lib/clang/<VERSIONSTRING>/include". We have two problems emulating this behaviour: -// * We don't have a very good way of finding the clang executable, but can fake this by -// searching $PATH and take one directory that contains "clang". -// * We don't have access to <VERSIONSTRING>. There is clang_getClangVersion(), but it returns -// a human-readable description string which is not guaranteed to be stable and a pain to parse. -// We work around that by just taking the first directory in ../lib/clang and hope it's the -// current version. -// TODO: test if this works on Windows at all. -#[doc(hidden)] -pub fn get_include_dir() -> Option<String> { - match get_clang_dir() { - Some(mut p) => { - p.push(".."); - p.push("lib"); - p.push("clang"); - - let dir_iter = match fs::read_dir(p) { - Ok(dir_iter) => dir_iter, - _ => return None - }; - for dir in dir_iter { - match dir { - Ok(dir) => { - // Let's take the first dir. In my case, there's only one directory - // there anyway. - let mut p = dir.path(); - p.push("include"); - match p.into_os_string().into_string() { - Ok(s) => return Some(s), - // We found the directory, but can't access it as it contains - // invalid unicode. - _ => return None, - } - } - _ => return None, - } - } - None - } - None => None, - } -} |