Skip to content

Commit

Permalink
Fix bugs in --clang-macro-fallback
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jbaublitz committed Jan 10, 2025
1 parent 59a43e1 commit 69c3649
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 53 deletions.
4 changes: 0 additions & 4 deletions bindgen/clang.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Index>,
tu: TranslationUnit,
Expand All @@ -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<str>],
) -> Option<Self> {
Expand All @@ -1954,7 +1952,6 @@ impl FallbackTranslationUnit {
)?;
Some(FallbackTranslationUnit {
file_path: file,
header_path,
pch_path,
tu: f_translation_unit,
idx: f_index,
Expand Down Expand Up @@ -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);
}
}
Expand Down
76 changes: 27 additions & 49 deletions bindgen/ir/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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("") {
Expand All @@ -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,
Expand All @@ -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()
Expand Down
1 change: 1 addition & 0 deletions bindgen/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ impl Builder {
}

// Transform input headers to arguments on the clang command line.
self.options.fallback_clang_args = self.options.clang_args.clone();
self.options.clang_args.extend(
self.options.input_headers
[..self.options.input_headers.len().saturating_sub(1)]
Expand Down
5 changes: 5 additions & 0 deletions bindgen/options/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Box<str>> {
methods: {},
as_args: ignore,
},
/// Tuples of unsaved file contents of the form (name, contents).
input_header_contents: Vec<(Box<str>, Box<str>)> {
methods: {
Expand Down

0 comments on commit 69c3649

Please sign in to comment.