Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bugs in --clang-macro-fallback #3072

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
7 changes: 7 additions & 0 deletions bindgen/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<Vec<_>>();
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
Loading