#![allow(
clippy::inherent_to_string,
clippy::needless_doctest_main,
clippy::new_without_default,
clippy::toplevel_ref_arg
)]
mod error;
mod gen;
mod paths;
mod syntax;
use crate::error::Result;
use crate::gen::Opt;
use anyhow::anyhow;
use std::fs;
use std::io::{self, Write};
use std::iter;
use std::path::Path;
use std::process;
#[must_use]
pub fn bridge(rust_source_file: impl AsRef<Path>) -> cc::Build {
bridges(iter::once(rust_source_file))
}
pub fn bridges(rust_source_files: impl IntoIterator<Item = impl AsRef<Path>>) -> cc::Build {
let mut build = paths::cc_build();
build.cpp(true);
build.cpp_link_stdlib(None);
for path in rust_source_files {
if let Err(err) = try_generate_bridge(&mut build, path.as_ref()) {
let _ = writeln!(io::stderr(), "\n\ncxxbridge error: {:?}\n\n", anyhow!(err));
process::exit(1);
}
}
build
}
fn try_generate_bridge(build: &mut cc::Build, rust_source_file: &Path) -> Result<()> {
let header = gen::do_generate_header(rust_source_file, Opt::default());
let header_path = paths::out_with_extension(rust_source_file, ".h")?;
fs::create_dir_all(header_path.parent().unwrap())?;
fs::write(&header_path, header)?;
paths::symlink_header(&header_path, rust_source_file);
let bridge = gen::do_generate_bridge(rust_source_file, Opt::default());
let bridge_path = paths::out_with_extension(rust_source_file, ".cc")?;
fs::write(&bridge_path, bridge)?;
build.file(&bridge_path);
let ref cxx_h = paths::include_dir()?.join("rust").join("cxx.h");
let _ = fs::create_dir_all(cxx_h.parent().unwrap());
let _ = fs::remove_file(cxx_h);
let _ = fs::write(cxx_h, gen::include::HEADER);
Ok(())
}