diff --git a/src/bin/bindgen.rs b/src/bin/bindgen.rs index c66a3744..4c884448 100755 --- a/src/bin/bindgen.rs +++ b/src/bin/bindgen.rs @@ -8,7 +8,7 @@ extern crate log; extern crate clang_sys; extern crate rustc_serialize; -use bindgen::{BindgenOptions, Bindings, LinkType, clang_version}; +use bindgen::{BindgenOptions, Bindings, LinkType, ClangVersion, clang_version}; use std::default::Default; use std::env; use std::fs; @@ -217,15 +217,26 @@ pub fn main() { let mut bind_args: Vec<_> = env::args().collect(); - let clang_version = clang_version(); - - if cfg!(feature = "llvm_stable") { - assert_eq!(clang_version, "3.8.0"); - } else { - assert_eq!(clang_version, "3.9.0"); - } - - debug!("Using Clang Version: {}", clang_version); + match clang_version() { + None => { + error!("Could not retrieve Clang version...") + }, + Some(v) => { + if cfg!(feature = "llvm_stable") { + if (v.major,v.minor) != (3,8) { + error!("Got Clang {}.{}, expected 3.8", v.major, v.minor) + } else { + info!("Using: {}", v.full) + } + } else { + if (v.major, v.minor) != (3,9) { + error!("Got Clang {}.{}, expected 3.9", v.major, v.minor) + } else { + info!("Using: {}", v.full) + } + } + } + }; if let Some(clang) = clang_sys::support::Clang::find(None) { let has_clang_args = diff --git a/src/clang.rs b/src/clang.rs index a8e4fdf2..437c3f15 100755 --- a/src/clang.rs +++ b/src/clang.rs @@ -1427,6 +1427,7 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> Enum_CXVisitorResult { CXChildVisit_Continue } +/// Try to extract the clang version to a string pub fn extract_clang_version() -> Option { let s: String = unsafe { clang_getClangVersion().into() }; diff --git a/src/lib.rs b/src/lib.rs index 5124c417..c3e9203b 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -449,14 +449,33 @@ fn parse(context: &mut BindgenContext) { "How did this happen?"); } -/// Get the version number (e.g. 3.9.0) of Clang in String form -pub fn clang_version() -> String { - clang::extract_clang_version() - .expect("Could not retrieve Clang version!") - .split(' ') - .nth(2) - .expect("Could not parse Clang version!") - .to_string() +/// Extracted Clang version data +#[derive(Debug)] +pub struct ClangVersion { + /// major semvar + pub major: u32, + /// minor semvar + pub minor: u32, + /// full version string + pub full: String, +} + +/// Get the major and the minor semvar numbers of Clang's version +pub fn clang_version() -> Option { + let raw_v: String = match clang::extract_clang_version() { + None => return None, + Some(v) => v, + }; + let split_v: Vec<&str> = match raw_v.split_whitespace().nth(2) { + None => return None, + Some(v) => v.split_terminator('.').collect(), + }; + let maybe_major = split_v[0].parse::(); + let maybe_minor = split_v[1].parse::(); + match (maybe_major,maybe_minor) { + (Ok(major),Ok(minor)) => Some(ClangVersion { major: major, minor: minor, full: raw_v.clone() }), + _ => None, + } }