Skip to content

Commit 50cf047

Browse files
committed
fix: support header_contents in macro fallback
1 parent 2048231 commit 50cf047

4 files changed

Lines changed: 87 additions & 10 deletions

File tree

bindgen-tests/tests/tests.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,37 @@ fn test_macro_fallback_non_system_dir() {
617617
}
618618
}
619619

620+
#[test]
621+
fn test_macro_fallback_header_contents() {
622+
if let Some((9, _)) = clang_version().parsed {
623+
return;
624+
}
625+
626+
let tmpdir = tempfile::tempdir().unwrap();
627+
let actual = builder()
628+
.disable_header_comment()
629+
.header_contents(
630+
"test.h",
631+
"#define UINT32_C(c) c ## U\n\
632+
#define SIMPLE 42\n\
633+
#define COMPOUND UINT32_C(69)\n",
634+
)
635+
.clang_macro_fallback()
636+
.clang_macro_fallback_build_dir(tmpdir.path())
637+
.clang_arg("--target=x86_64-unknown-linux")
638+
.generate()
639+
.unwrap()
640+
.to_string();
641+
642+
let actual = format_code(actual).unwrap();
643+
let expected = format_code(
644+
"pub const SIMPLE: u32 = 42;\npub const COMPOUND: u32 = 69;\n",
645+
)
646+
.unwrap();
647+
648+
assert_eq!(expected, actual);
649+
}
650+
620651
#[test]
621652
// Doesn't support executing sh file on Windows.
622653
// We may want to implement it in Rust so that we support all systems.

bindgen/clang.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1915,6 +1915,7 @@ impl Drop for TranslationUnit {
19151915
pub(crate) struct FallbackTranslationUnit {
19161916
file_path: String,
19171917
pch_path: String,
1918+
materialized_headers: Vec<String>,
19181919
idx: Box<Index>,
19191920
tu: TranslationUnit,
19201921
}
@@ -1931,6 +1932,7 @@ impl FallbackTranslationUnit {
19311932
file: String,
19321933
pch_path: String,
19331934
c_args: &[Box<str>],
1935+
materialized_headers: Vec<String>,
19341936
) -> Option<Self> {
19351937
// Create empty file
19361938
OpenOptions::new()
@@ -1951,6 +1953,7 @@ impl FallbackTranslationUnit {
19511953
Some(FallbackTranslationUnit {
19521954
file_path: file,
19531955
pch_path,
1956+
materialized_headers,
19541957
tu: f_translation_unit,
19551958
idx: f_index,
19561959
})
@@ -1989,6 +1992,9 @@ impl Drop for FallbackTranslationUnit {
19891992
fn drop(&mut self) {
19901993
let _ = std::fs::remove_file(&self.file_path);
19911994
let _ = std::fs::remove_file(&self.pch_path);
1995+
for path in &self.materialized_headers {
1996+
let _ = std::fs::remove_file(path);
1997+
}
19921998
}
19931999
}
19942000

bindgen/ir/context.rs

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2055,11 +2055,46 @@ If you encounter an error missing from this list, please file an issue or a PR!"
20552055

20562056
let index = clang::Index::new(false, false);
20572057

2058+
let build_dir =
2059+
match self.options().clang_macro_fallback_build_dir {
2060+
Some(ref path) => path.as_os_str().to_str()?,
2061+
None => ".",
2062+
};
2063+
let materialized_headers: Vec<String> = self
2064+
.options()
2065+
.input_header_contents
2066+
.iter()
2067+
.enumerate()
2068+
.map(|(index, (_, contents))| {
2069+
let path =
2070+
format!("{build_dir}/.macro_eval_header_{index}.h");
2071+
std::fs::write(&path, contents.as_ref()).unwrap_or_else(
2072+
|error| {
2073+
panic!(
2074+
"failed to materialize header_contents() for \
2075+
clang_macro_fallback at {path}: {error}"
2076+
)
2077+
},
2078+
);
2079+
path
2080+
})
2081+
.collect();
2082+
2083+
let effective_headers: Vec<Box<str>> = self
2084+
.options()
2085+
.input_headers
2086+
.iter()
2087+
.cloned()
2088+
.chain(materialized_headers.iter().map(|path| {
2089+
path.as_str().into()
2090+
}))
2091+
.collect();
2092+
20582093
let mut header_names_to_compile = Vec::new();
20592094
let mut header_paths = Vec::new();
20602095
let mut header_includes = Vec::new();
20612096
let [input_headers @ .., single_header] =
2062-
&self.options().input_headers[..]
2097+
&effective_headers[..]
20632098
else {
20642099
return None;
20652100
};
@@ -2121,8 +2156,12 @@ If you encounter an error missing from this list, please file an issue or a PR!"
21212156
c_args.push(arg.clone());
21222157
}
21232158
}
2124-
self.fallback_tu =
2125-
Some(clang::FallbackTranslationUnit::new(file, pch, &c_args)?);
2159+
self.fallback_tu = Some(clang::FallbackTranslationUnit::new(
2160+
file,
2161+
pch,
2162+
&c_args,
2163+
materialized_headers,
2164+
)?);
21262165
}
21272166

21282167
self.fallback_tu.as_mut()

bindgen/lib.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -361,13 +361,14 @@ impl Builder {
361361
.flat_map(|header| ["-include".into(), header.clone()]),
362362
);
363363

364-
let input_unsaved_files =
365-
std::mem::take(&mut self.options.input_header_contents)
366-
.into_iter()
367-
.map(|(name, contents)| {
368-
clang::UnsavedFile::new(name.as_ref(), contents.as_ref())
369-
})
370-
.collect::<Vec<_>>();
364+
let input_unsaved_files = self
365+
.options
366+
.input_header_contents
367+
.iter()
368+
.map(|(name, contents)| {
369+
clang::UnsavedFile::new(name.as_ref(), contents.as_ref())
370+
})
371+
.collect::<Vec<_>>();
371372

372373
Bindings::generate(self.options, &input_unsaved_files)
373374
}

0 commit comments

Comments
 (0)