Skip to content

Commit 76920aa

Browse files
committed
Fix bugs in --clang-macro-fallback
This commit resolves a bug where -include was not respected and a bug where -MMD was passed to the fallback translation unit which would cause the dependency file to be overwritten with useless information about temporary files.
1 parent 1be53c6 commit 76920aa

File tree

4 files changed

+44
-53
lines changed

4 files changed

+44
-53
lines changed

bindgen/clang.rs

-4
Original file line numberDiff line numberDiff line change
@@ -1914,7 +1914,6 @@ impl Drop for TranslationUnit {
19141914
/// Translation unit used for macro fallback parsing
19151915
pub(crate) struct FallbackTranslationUnit {
19161916
file_path: String,
1917-
header_path: String,
19181917
pch_path: String,
19191918
idx: Box<Index>,
19201919
tu: TranslationUnit,
@@ -1930,7 +1929,6 @@ impl FallbackTranslationUnit {
19301929
/// Create a new fallback translation unit
19311930
pub(crate) fn new(
19321931
file: String,
1933-
header_path: String,
19341932
pch_path: String,
19351933
c_args: &[Box<str>],
19361934
) -> Option<Self> {
@@ -1952,7 +1950,6 @@ impl FallbackTranslationUnit {
19521950
)?;
19531951
Some(FallbackTranslationUnit {
19541952
file_path: file,
1955-
header_path,
19561953
pch_path,
19571954
tu: f_translation_unit,
19581955
idx: f_index,
@@ -1991,7 +1988,6 @@ impl FallbackTranslationUnit {
19911988
impl Drop for FallbackTranslationUnit {
19921989
fn drop(&mut self) {
19931990
let _ = std::fs::remove_file(&self.file_path);
1994-
let _ = std::fs::remove_file(&self.header_path);
19951991
let _ = std::fs::remove_file(&self.pch_path);
19961992
}
19971993
}

bindgen/ir/context.rs

+27-49
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ use quote::ToTokens;
2929
use std::borrow::Cow;
3030
use std::cell::{Cell, RefCell};
3131
use std::collections::{BTreeSet, HashMap as StdHashMap};
32-
use std::fs::OpenOptions;
33-
use std::io::Write;
3432
use std::mem;
3533
use std::path::Path;
3634

@@ -2054,8 +2052,11 @@ If you encounter an error missing from this list, please file an issue or a PR!"
20542052

20552053
let mut header_names_to_compile = Vec::new();
20562054
let mut header_paths = Vec::new();
2057-
let mut header_contents = String::new();
2058-
for input_header in &self.options.input_headers {
2055+
let mut header_includes = Vec::new();
2056+
let single_header = self.options().input_headers.last().cloned()?;
2057+
for input_header in &self.options.input_headers
2058+
[..self.options.input_headers.len() - 1]
2059+
{
20592060
let path = Path::new(input_header.as_ref());
20602061
if let Some(header_path) = path.parent() {
20612062
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!"
20672068
header_paths.push(".");
20682069
}
20692070
let header_name = path.file_name()?.to_str()?;
2071+
header_includes.push(header_name.to_string());
20702072
header_names_to_compile
20712073
.push(header_name.split(".h").next()?.to_string());
2072-
header_contents +=
2073-
format!("\n#include <{header_name}>").as_str();
20742074
}
2075-
let header_to_precompile = format!(
2075+
let pch = format!(
20762076
"{}/{}",
20772077
match self.options().clang_macro_fallback_build_dir {
20782078
Some(ref path) => path.as_os_str().to_str()?,
20792079
None => ".",
20802080
},
2081-
header_names_to_compile.join("-") + "-precompile.h"
2081+
header_names_to_compile.join("-") + "-precompile.h.pch"
20822082
);
2083-
let pch = header_to_precompile.clone() + ".pch";
2084-
2085-
let mut header_to_precompile_file = OpenOptions::new()
2086-
.create(true)
2087-
.truncate(true)
2088-
.write(true)
2089-
.open(&header_to_precompile)
2090-
.ok()?;
2091-
header_to_precompile_file
2092-
.write_all(header_contents.as_bytes())
2093-
.ok()?;
2094-
2095-
let mut c_args = Vec::new();
2083+
2084+
let mut c_args = self.options.fallback_clang_args.clone();
20962085
c_args.push("-x".to_string().into_boxed_str());
20972086
c_args.push("c-header".to_string().into_boxed_str());
20982087
for header_path in header_paths {
20992088
c_args.push(format!("-I{header_path}").into_boxed_str());
21002089
}
2101-
c_args.extend(
2102-
self.options
2103-
.clang_args
2104-
.iter()
2105-
.filter(|next| {
2106-
!self.options.input_headers.contains(next) &&
2107-
next.as_ref() != "-include"
2108-
})
2109-
.cloned(),
2110-
);
2090+
for header_include in header_includes {
2091+
c_args.push("-include".to_string().into_boxed_str());
2092+
c_args.push(header_include.into_boxed_str());
2093+
}
21112094
let mut tu = clang::TranslationUnit::parse(
21122095
&index,
2113-
&header_to_precompile,
2096+
&single_header,
21142097
&c_args,
21152098
&[],
21162099
clang_sys::CXTranslationUnit_ForSerialization,
@@ -2121,23 +2104,18 @@ If you encounter an error missing from this list, please file an issue or a PR!"
21212104
"-include-pch".to_string().into_boxed_str(),
21222105
pch.clone().into_boxed_str(),
21232106
];
2124-
c_args.extend(
2125-
self.options
2126-
.clang_args
2127-
.clone()
2128-
.iter()
2129-
.filter(|next| {
2130-
!self.options.input_headers.contains(next) &&
2131-
next.as_ref() != "-include"
2132-
})
2133-
.cloned(),
2134-
);
2135-
self.fallback_tu = Some(clang::FallbackTranslationUnit::new(
2136-
file,
2137-
header_to_precompile,
2138-
pch,
2139-
&c_args,
2140-
)?);
2107+
let mut skip_next = false;
2108+
for arg in self.options.fallback_clang_args.iter() {
2109+
if arg.as_ref() == "-include" {
2110+
skip_next = true;
2111+
} else if skip_next {
2112+
skip_next = false;
2113+
} else {
2114+
c_args.push(arg.clone())
2115+
}
2116+
}
2117+
self.fallback_tu =
2118+
Some(clang::FallbackTranslationUnit::new(file, pch, &c_args)?);
21412119
}
21422120

21432121
self.fallback_tu.as_mut()

bindgen/lib.rs

+12
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,18 @@ impl Builder {
348348
}
349349

350350
// Transform input headers to arguments on the clang command line.
351+
self.options.fallback_clang_args = self
352+
.options
353+
.clang_args
354+
.iter()
355+
.filter(|arg| {
356+
!arg.starts_with("-MMD") &&
357+
!arg.starts_with("-MD") &&
358+
!arg.starts_with("--write-user-dependencies") &&
359+
!arg.starts_with("--user-dependencies")
360+
})
361+
.cloned()
362+
.collect::<Vec<_>>();
351363
self.options.clang_args.extend(
352364
self.options.input_headers
353365
[..self.options.input_headers.len().saturating_sub(1)]

bindgen/options/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -1234,6 +1234,11 @@ options! {
12341234
// This field is handled specially inside the macro.
12351235
as_args: ignore,
12361236
},
1237+
/// The set of arguments to be passed straight through to Clang for the macro fallback code.
1238+
fallback_clang_args: Vec<Box<str>> {
1239+
methods: {},
1240+
as_args: ignore,
1241+
},
12371242
/// Tuples of unsaved file contents of the form (name, contents).
12381243
input_header_contents: Vec<(Box<str>, Box<str>)> {
12391244
methods: {

0 commit comments

Comments
 (0)