clang wrapper skeleton

This commit is contained in:
Andrea Fioraldi 2021-03-23 12:17:28 +01:00
parent 009c35dbf9
commit 19133f5827

View File

@ -1,9 +1,133 @@
pub mod runtime; use std::{string::String, vec::Vec};
#[derive(Debug)]
pub enum Error {
InvalidArguments(String),
Unknown(String),
}
/// Wrap a compiler hijacking its arguments
pub trait CompilerWrapper {
/// Set the wrapper arguments parsing a command line set of arguments
fn from_args<'a>(&'a mut self, args: Vec<String>) -> Result<&'a mut Self, Error>;
/// Add a compiler argument
fn add_arg<'a>(&'a mut self, arg: String) -> Result<&'a mut Self, Error>;
/// Run the compiler
fn compile(&mut self) -> Result<(), Error>;
}
/// Wrap Clang
pub struct ClangWrapper {
optimize: bool,
wrapped_cc: String,
wrapped_cxx: String,
name: String,
is_cpp: bool,
linking: bool,
x_set: bool,
bit_mode: u32,
args: Vec<String>,
}
impl CompilerWrapper for ClangWrapper {
fn from_args<'a>(&'a mut self, args: Vec<String>) -> Result<&'a mut Self, Error> {
let mut new_args = vec![];
if args.len() < 1 {
return Err(Error::InvalidArguments(
"The number of arguments cannot be 0".into(),
));
}
self.name = args[0].clone();
// Detect C++ compiler looking at the wrapper name
self.is_cpp = self.name.ends_with("++");
if self.is_cpp {
new_args.push(self.wrapped_cxx.clone());
} else {
new_args.push(self.wrapped_cc.clone());
}
// Sancov flag
// new_args.push("-fsanitize-coverage=trace-pc-guard".into());
let mut linking = true;
// Detect stray -v calls from ./configure scripts.
if args.len() == 1 && args[1] == "-v" {
linking = false;
}
for arg in &args[1..] {
match arg.as_str() {
"-x" => self.x_set = true,
"-m32" => self.bit_mode = 32,
"-m64" => self.bit_mode = 64,
"-c" | "-S" | "-E" => linking = false,
"-shared" => linking = false, // TODO dynamic list?
"-Wl,-z,defs" | "-Wl,--no-undefined" => continue,
_ => (),
};
new_args.push(arg.clone());
}
self.linking = linking;
if self.optimize {
new_args.push("-g".into());
new_args.push("-O3".into());
new_args.push("-funroll-loops".into());
}
// Fuzzing define common among tools
new_args.push("-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION=1".into());
self.args = new_args;
Ok(self)
}
fn add_arg<'a>(&'a mut self, arg: String) -> Result<&'a mut Self, Error> {
self.args.push(arg);
Ok(self)
}
fn compile(&mut self) -> Result<(), Error> {
if self.linking {
if self.x_set {
self.args.push("-x".into());
self.args.push("none".into());
}
}
Ok(())
}
}
impl ClangWrapper {
pub fn new(wrapped_cc: &str, wrapped_cxx: &str) -> Self {
Self {
optimize: true,
wrapped_cc: wrapped_cc.into(),
wrapped_cxx: wrapped_cxx.into(),
name: "".into(),
is_cpp: false,
linking: false,
x_set: false,
bit_mode: 0,
args: vec![],
}
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
#[test] #[test]
fn it_works() { fn test_clang_version() {
assert_eq!(2 + 2, 4); ClangWrapper::new("clang", "clang++")
.from_args(vec!["my-clang", "-v"])
.unwrap()
.compile()
.unwrap();
} }
} }