diff --git a/bindgen/clang.rs b/bindgen/clang.rs index 66558bc8cc..9828c8ba03 100644 --- a/bindgen/clang.rs +++ b/bindgen/clang.rs @@ -1916,7 +1916,6 @@ impl Drop for TranslationUnit { /// Translation unit used for macro fallback parsing pub(crate) struct FallbackTranslationUnit { file_path: String, - header_path: String, pch_path: String, idx: Box, tu: TranslationUnit, @@ -1932,7 +1931,6 @@ impl FallbackTranslationUnit { /// Create a new fallback translation unit pub(crate) fn new( file: String, - header_path: String, pch_path: String, c_args: &[Box], ) -> Option { @@ -1954,7 +1952,6 @@ impl FallbackTranslationUnit { )?; Some(FallbackTranslationUnit { file_path: file, - header_path, pch_path, tu: f_translation_unit, idx: f_index, @@ -1993,7 +1990,6 @@ impl FallbackTranslationUnit { impl Drop for FallbackTranslationUnit { fn drop(&mut self) { let _ = std::fs::remove_file(&self.file_path); - let _ = std::fs::remove_file(&self.header_path); let _ = std::fs::remove_file(&self.pch_path); } } diff --git a/bindgen/ir/context.rs b/bindgen/ir/context.rs index 098dd25e59..229959d9c1 100644 --- a/bindgen/ir/context.rs +++ b/bindgen/ir/context.rs @@ -29,8 +29,6 @@ use quote::ToTokens; use std::borrow::Cow; use std::cell::{Cell, RefCell}; use std::collections::{BTreeSet, HashMap as StdHashMap}; -use std::fs::OpenOptions; -use std::io::Write; use std::mem; use std::path::Path; @@ -2054,8 +2052,11 @@ If you encounter an error missing from this list, please file an issue or a PR!" let mut header_names_to_compile = Vec::new(); let mut header_paths = Vec::new(); - let mut header_contents = String::new(); - for input_header in &self.options.input_headers { + let mut header_includes = Vec::new(); + let single_header = self.options().input_headers.last().cloned()?; + for input_header in &self.options.input_headers + [..self.options.input_headers.len() - 1] + { let path = Path::new(input_header.as_ref()); if let Some(header_path) = path.parent() { if header_path == Path::new("") { @@ -2067,50 +2068,32 @@ If you encounter an error missing from this list, please file an issue or a PR!" header_paths.push("."); } let header_name = path.file_name()?.to_str()?; + header_includes.push(header_name.to_string()); header_names_to_compile .push(header_name.split(".h").next()?.to_string()); - header_contents += - format!("\n#include <{header_name}>").as_str(); } - let header_to_precompile = format!( + let pch = format!( "{}/{}", match self.options().clang_macro_fallback_build_dir { Some(ref path) => path.as_os_str().to_str()?, None => ".", }, - header_names_to_compile.join("-") + "-precompile.h" + header_names_to_compile.join("-") + "-precompile.h.pch" ); - let pch = header_to_precompile.clone() + ".pch"; - - let mut header_to_precompile_file = OpenOptions::new() - .create(true) - .truncate(true) - .write(true) - .open(&header_to_precompile) - .ok()?; - header_to_precompile_file - .write_all(header_contents.as_bytes()) - .ok()?; - - let mut c_args = Vec::new(); + + let mut c_args = self.options.fallback_clang_args.clone(); c_args.push("-x".to_string().into_boxed_str()); c_args.push("c-header".to_string().into_boxed_str()); for header_path in header_paths { c_args.push(format!("-I{header_path}").into_boxed_str()); } - c_args.extend( - self.options - .clang_args - .iter() - .filter(|next| { - !self.options.input_headers.contains(next) && - next.as_ref() != "-include" - }) - .cloned(), - ); + for header_include in header_includes { + c_args.push("-include".to_string().into_boxed_str()); + c_args.push(header_include.into_boxed_str()); + } let mut tu = clang::TranslationUnit::parse( &index, - &header_to_precompile, + &single_header, &c_args, &[], clang_sys::CXTranslationUnit_ForSerialization, @@ -2121,23 +2104,18 @@ If you encounter an error missing from this list, please file an issue or a PR!" "-include-pch".to_string().into_boxed_str(), pch.clone().into_boxed_str(), ]; - c_args.extend( - self.options - .clang_args - .clone() - .iter() - .filter(|next| { - !self.options.input_headers.contains(next) && - next.as_ref() != "-include" - }) - .cloned(), - ); - self.fallback_tu = Some(clang::FallbackTranslationUnit::new( - file, - header_to_precompile, - pch, - &c_args, - )?); + let mut skip_next = false; + for arg in self.options.fallback_clang_args.iter() { + if arg.as_ref() == "-include" { + skip_next = true; + } else if skip_next { + skip_next = false; + } else { + c_args.push(arg.clone()) + } + } + self.fallback_tu = + Some(clang::FallbackTranslationUnit::new(file, pch, &c_args)?); } self.fallback_tu.as_mut() diff --git a/bindgen/lib.rs b/bindgen/lib.rs index 9e22e37ce6..f34448e0bc 100644 --- a/bindgen/lib.rs +++ b/bindgen/lib.rs @@ -348,6 +348,13 @@ impl Builder { } // Transform input headers to arguments on the clang command line. + self.options.fallback_clang_args = self + .options + .clang_args + .iter() + .filter(|arg| !arg.contains("-MMD") && !arg.contains("-MD")) + .cloned() + .collect::>(); self.options.clang_args.extend( self.options.input_headers [..self.options.input_headers.len().saturating_sub(1)] diff --git a/bindgen/options/mod.rs b/bindgen/options/mod.rs index 6bf652d4e1..9d1d195980 100644 --- a/bindgen/options/mod.rs +++ b/bindgen/options/mod.rs @@ -1234,6 +1234,11 @@ options! { // This field is handled specially inside the macro. as_args: ignore, }, + /// The set of arguments to be passed straight through to Clang for the macro fallback code. + fallback_clang_args: Vec> { + methods: {}, + as_args: ignore, + }, /// Tuples of unsaved file contents of the form (name, contents). input_header_contents: Vec<(Box, Box)> { methods: {