mirror of
https://github.com/openharmony/third_party_rust_cc-rs.git
synced 2026-07-01 06:41:52 -04:00
Add a method to macro-expand source files
This commit is contained in:
@@ -1,2 +1,4 @@
|
||||
target
|
||||
Cargo.lock
|
||||
.idea
|
||||
*.iml
|
||||
|
||||
@@ -81,4 +81,10 @@ fn main() {
|
||||
.cargo_metadata(false)
|
||||
.file("src/opt_linkage.c")
|
||||
.compile("libOptLinkage.a");
|
||||
|
||||
let out = gcc::Config::new()
|
||||
.file("src/expand.c")
|
||||
.expand();
|
||||
let out = String::from_utf8(out).unwrap();
|
||||
assert!(out.contains("hello world"));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
#define HELLO hello
|
||||
#define WORLD world
|
||||
|
||||
HELLO WORLD
|
||||
+48
-11
@@ -52,10 +52,10 @@ extern crate rayon;
|
||||
use std::env;
|
||||
use std::ffi::{OsString, OsStr};
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use std::path::{PathBuf, Path};
|
||||
use std::process::{Command, Stdio};
|
||||
use std::io::{BufReader, BufRead, Write};
|
||||
use std::io::{self, BufReader, BufRead, Read, Write};
|
||||
use std::thread;
|
||||
|
||||
#[cfg(windows)]
|
||||
mod registry;
|
||||
@@ -131,6 +131,15 @@ impl ToolFamily {
|
||||
ToolFamily::Clang => "-I",
|
||||
}
|
||||
}
|
||||
|
||||
/// What the flag to request macro-expanded source output looks like
|
||||
fn expand_flag(&self) -> &'static str {
|
||||
match *self {
|
||||
ToolFamily::Msvc => "/E",
|
||||
ToolFamily::Gnu |
|
||||
ToolFamily::Clang => "-E",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Compile a library from the given set of input C files.
|
||||
@@ -473,6 +482,29 @@ impl Config {
|
||||
run(&mut cmd, &name);
|
||||
}
|
||||
|
||||
/// Run the compiler, returning the macro-expanded version of the input files.
|
||||
///
|
||||
/// This is only relevant for C and C++ files.
|
||||
pub fn expand(&self) -> Vec<u8> {
|
||||
let compiler = self.get_compiler();
|
||||
let mut cmd = compiler.to_command();
|
||||
for &(ref a, ref b) in self.env.iter() {
|
||||
cmd.env(a, b);
|
||||
}
|
||||
cmd.arg(compiler.family.expand_flag());
|
||||
for file in self.files.iter() {
|
||||
cmd.arg(file);
|
||||
}
|
||||
|
||||
let name = compiler.path
|
||||
.file_name()
|
||||
.unwrap()
|
||||
.to_string_lossy()
|
||||
.into_owned();
|
||||
|
||||
run(&mut cmd, &name)
|
||||
}
|
||||
|
||||
/// Get the compiler that's in use for this configuration.
|
||||
///
|
||||
/// This function will return a `Tool` which represents the culmination
|
||||
@@ -1044,23 +1076,27 @@ impl Tool {
|
||||
}
|
||||
}
|
||||
|
||||
fn run(cmd: &mut Command, program: &str) {
|
||||
fn run(cmd: &mut Command, program: &str) -> Vec<u8> {
|
||||
println!("running: {:?}", cmd);
|
||||
// Capture the standard error coming from these programs, and write it out
|
||||
// with cargo:warning= prefixes. Note that this is a bit wonky to avoid
|
||||
// requiring the output to be UTF-8, we instead just ship bytes from one
|
||||
// location to another.
|
||||
let spawn_result = match cmd.stderr(Stdio::piped()).spawn() {
|
||||
let (spawn_result, stdout) = match cmd.stdout(Stdio::piped()).stderr(Stdio::piped()).spawn() {
|
||||
Ok(mut child) => {
|
||||
let stderr = BufReader::new(child.stderr.take().unwrap());
|
||||
for line in stderr.split(b'\n').filter_map(|l| l.ok()) {
|
||||
print!("cargo:warning=");
|
||||
std::io::stdout().write_all(&line).unwrap();
|
||||
println!("");
|
||||
}
|
||||
child.wait()
|
||||
thread::spawn(move || {
|
||||
for line in stderr.split(b'\n').filter_map(|l| l.ok()) {
|
||||
print!("cargo:warning=");
|
||||
std::io::stdout().write_all(&line).unwrap();
|
||||
println!("");
|
||||
}
|
||||
});
|
||||
let mut stdout = vec![];
|
||||
child.stdout.take().unwrap().read_to_end(&mut stdout).unwrap();
|
||||
(child.wait(), stdout)
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
Err(e) => (Err(e), vec![]),
|
||||
};
|
||||
let status = match spawn_result {
|
||||
Ok(status) => status,
|
||||
@@ -1083,6 +1119,7 @@ fn run(cmd: &mut Command, program: &str) {
|
||||
if !status.success() {
|
||||
fail(&format!("command did not execute successfully, got: {}", status));
|
||||
}
|
||||
stdout
|
||||
}
|
||||
|
||||
fn fail(s: &str) -> ! {
|
||||
|
||||
Reference in New Issue
Block a user