Skip to content

Commit bde9266

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 59a43e1 commit bde9266

File tree

6 files changed

+38
-53
lines changed

6 files changed

+38
-53
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
#include <one_header.h>
3+
#include <another_header.h>

bindgen/clang.rs

-4
Original file line numberDiff line numberDiff line change
@@ -1916,7 +1916,6 @@ impl Drop for TranslationUnit {
19161916
/// Translation unit used for macro fallback parsing
19171917
pub(crate) struct FallbackTranslationUnit {
19181918
file_path: String,
1919-
header_path: String,
19201919
pch_path: String,
19211920
idx: Box<Index>,
19221921
tu: TranslationUnit,
@@ -1932,7 +1931,6 @@ impl FallbackTranslationUnit {
19321931
/// Create a new fallback translation unit
19331932
pub(crate) fn new(
19341933
file: String,
1935-
header_path: String,
19361934
pch_path: String,
19371935
c_args: &[Box<str>],
19381936
) -> Option<Self> {
@@ -1954,7 +1952,6 @@ impl FallbackTranslationUnit {
19541952
)?;
19551953
Some(FallbackTranslationUnit {
19561954
file_path: file,
1957-
header_path,
19581955
pch_path,
19591956
tu: f_translation_unit,
19601957
idx: f_index,
@@ -1993,7 +1990,6 @@ impl FallbackTranslationUnit {
19931990
impl Drop for FallbackTranslationUnit {
19941991
fn drop(&mut self) {
19951992
let _ = std::fs::remove_file(&self.file_path);
1996-
let _ = std::fs::remove_file(&self.header_path);
19971993
let _ = std::fs::remove_file(&self.pch_path);
19981994
}
19991995
}

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

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

350350
// Transform input headers to arguments on the clang command line.
351+
self.options.fallback_clang_args = self.options.clang_args.clone();
351352
self.options.clang_args.extend(
352353
self.options.input_headers
353354
[..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: {

file.d

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.macro_eval.o: /home/jbaublitz/bindgen-test/testheader.h \
2+
/usr/include/libcryptsetup.h .macro_eval.c

0 commit comments

Comments
 (0)