summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <me@emiliocobos.me>2016-07-03 20:26:13 -0700
committerEmilio Cobos Álvarez <me@emiliocobos.me>2016-07-04 21:02:01 -0700
commit44c3b185ecf66a10c729cde695c4472fb70ae184 (patch)
tree35c1f85923deba8e28f1a25add4f0ddc2c03d2be
parent2396141a0df110a8e341927f66eb73d647db2a82 (diff)
bindgen: use clang-sys for the include path.
-rw-r--r--Cargo.toml2
-rw-r--r--src/bin/bindgen.rs13
-rw-r--r--src/lib.rs74
3 files changed, 13 insertions, 76 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 0261c19d..ef725331 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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) {
diff --git a/src/lib.rs b/src/lib.rs
index 24876cc9..a72e9584 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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,
- }
-}