mirror of
https://github.com/topjohnwu/cxx.git
synced 2024-11-24 04:20:02 +00:00
Add flag to inject additional #include lines
This commit is contained in:
parent
2d40845a49
commit
33d3029780
@ -33,6 +33,10 @@ struct Opt {
|
||||
/// Emit header with declarations only
|
||||
#[structopt(long)]
|
||||
header: bool,
|
||||
|
||||
/// Any additional headers to #include
|
||||
#[structopt(short, long)]
|
||||
include: Vec<String>,
|
||||
}
|
||||
|
||||
fn write(content: impl AsRef<[u8]>) {
|
||||
@ -42,9 +46,13 @@ fn write(content: impl AsRef<[u8]>) {
|
||||
fn main() {
|
||||
let opt = Opt::from_args();
|
||||
|
||||
let gen = gen::Opt {
|
||||
include: opt.include,
|
||||
};
|
||||
|
||||
match (opt.input, opt.header) {
|
||||
(Some(input), true) => write(gen::do_generate_header(&input)),
|
||||
(Some(input), false) => write(gen::do_generate_bridge(&input)),
|
||||
(Some(input), true) => write(gen::do_generate_header(&input, gen)),
|
||||
(Some(input), false) => write(gen::do_generate_bridge(&input, gen)),
|
||||
(None, true) => write(include::HEADER),
|
||||
(None, false) => unreachable!(), // enforced by required_unless
|
||||
}
|
||||
|
@ -49,6 +49,12 @@ impl Includes {
|
||||
}
|
||||
}
|
||||
|
||||
impl Extend<String> for Includes {
|
||||
fn extend<I: IntoIterator<Item = String>>(&mut self, iter: I) {
|
||||
self.custom.extend(iter);
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Includes {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
for include in &self.custom {
|
||||
|
18
gen/mod.rs
18
gen/mod.rs
@ -36,17 +36,23 @@ struct Input {
|
||||
module: Vec<Item>,
|
||||
}
|
||||
|
||||
pub(super) fn do_generate_bridge(path: &Path) -> OutFile {
|
||||
#[derive(Default)]
|
||||
pub(super) struct Opt {
|
||||
/// Any additional headers to #include
|
||||
pub include: Vec<String>,
|
||||
}
|
||||
|
||||
pub(super) fn do_generate_bridge(path: &Path, opt: Opt) -> OutFile {
|
||||
let header = false;
|
||||
generate(path, header)
|
||||
generate(path, opt, header)
|
||||
}
|
||||
|
||||
pub(super) fn do_generate_header(path: &Path) -> OutFile {
|
||||
pub(super) fn do_generate_header(path: &Path, opt: Opt) -> OutFile {
|
||||
let header = true;
|
||||
generate(path, header)
|
||||
generate(path, opt, header)
|
||||
}
|
||||
|
||||
fn generate(path: &Path, header: bool) -> OutFile {
|
||||
fn generate(path: &Path, opt: Opt, header: bool) -> OutFile {
|
||||
let source = match fs::read_to_string(path) {
|
||||
Ok(source) => source,
|
||||
Err(err) => format_err(path, "", Error::Io(err)),
|
||||
@ -57,7 +63,7 @@ fn generate(path: &Path, header: bool) -> OutFile {
|
||||
let apis = syntax::parse_items(bridge.module)?;
|
||||
let types = Types::collect(&apis)?;
|
||||
check::typecheck(&apis, &types)?;
|
||||
let out = write::gen(bridge.namespace, &apis, &types, header);
|
||||
let out = write::gen(bridge.namespace, &apis, &types, opt, header);
|
||||
Ok(out)
|
||||
})() {
|
||||
Ok(out) => out,
|
||||
|
11
gen/write.rs
11
gen/write.rs
@ -1,10 +1,16 @@
|
||||
use crate::gen::include;
|
||||
use crate::gen::out::OutFile;
|
||||
use crate::gen::{include, Opt};
|
||||
use crate::syntax::atom::Atom::{self, *};
|
||||
use crate::syntax::{Api, ExternFn, Struct, Type, Types, Var};
|
||||
use proc_macro2::Ident;
|
||||
|
||||
pub(super) fn gen(namespace: Vec<String>, apis: &[Api], types: &Types, header: bool) -> OutFile {
|
||||
pub(super) fn gen(
|
||||
namespace: Vec<String>,
|
||||
apis: &[Api],
|
||||
types: &Types,
|
||||
opt: Opt,
|
||||
header: bool,
|
||||
) -> OutFile {
|
||||
let mut out_file = OutFile::new(namespace.clone(), header);
|
||||
let out = &mut out_file;
|
||||
|
||||
@ -12,6 +18,7 @@ pub(super) fn gen(namespace: Vec<String>, apis: &[Api], types: &Types, header: b
|
||||
writeln!(out, "#pragma once");
|
||||
}
|
||||
|
||||
out.include.extend(opt.include);
|
||||
for api in apis {
|
||||
if let Api::Include(include) = api {
|
||||
out.include.insert(include.value());
|
||||
|
@ -383,6 +383,7 @@ pub mod private {
|
||||
}
|
||||
|
||||
use crate::error::Result;
|
||||
use crate::gen::Opt;
|
||||
use anyhow::anyhow;
|
||||
use std::fs;
|
||||
use std::io::{self, Write};
|
||||
@ -465,13 +466,13 @@ impl Build {
|
||||
}
|
||||
|
||||
fn try_generate_bridge(rust_source_file: &Path) -> Result<cc::Build> {
|
||||
let header = gen::do_generate_header(rust_source_file);
|
||||
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);
|
||||
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)?;
|
||||
let mut build = paths::cc_build();
|
||||
|
Loading…
Reference in New Issue
Block a user