| #[derive(Clone)] |
| pub struct CompilationCommandBuilder { |
| compiler: String, |
| target: Option<String>, |
| cxx_toolchain_dir: Option<String>, |
| arch_flags: Vec<String>, |
| optimization: String, |
| include_paths: Vec<String>, |
| project_root: Option<String>, |
| output: String, |
| input: String, |
| linker: Option<String>, |
| extra_flags: Vec<String>, |
| } |
| |
| impl CompilationCommandBuilder { |
| pub fn new() -> Self { |
| Self { |
| compiler: String::new(), |
| target: None, |
| cxx_toolchain_dir: None, |
| arch_flags: Vec::new(), |
| optimization: "2".to_string(), |
| include_paths: Vec::new(), |
| project_root: None, |
| output: String::new(), |
| input: String::new(), |
| linker: None, |
| extra_flags: Vec::new(), |
| } |
| } |
| |
| pub fn set_compiler(mut self, compiler: &str) -> Self { |
| self.compiler = compiler.to_string(); |
| self |
| } |
| |
| pub fn set_target(mut self, target: &str) -> Self { |
| self.target = Some(target.to_string()); |
| self |
| } |
| |
| pub fn set_cxx_toolchain_dir(mut self, path: Option<&str>) -> Self { |
| self.cxx_toolchain_dir = path.map(|p| p.to_string()); |
| self |
| } |
| |
| pub fn add_arch_flags(mut self, flags: Vec<&str>) -> Self { |
| let mut new_arch_flags = flags.into_iter().map(|v| v.to_string()).collect(); |
| self.arch_flags.append(&mut new_arch_flags); |
| |
| self |
| } |
| |
| pub fn set_opt_level(mut self, optimization: &str) -> Self { |
| self.optimization = optimization.to_string(); |
| self |
| } |
| |
| /// Sets a list of include paths for compilation. |
| /// The paths that are passed must be relative to the |
| /// "cxx_toolchain_dir" directory path. |
| pub fn set_include_paths(mut self, paths: Vec<&str>) -> Self { |
| self.include_paths = paths.into_iter().map(|path| path.to_string()).collect(); |
| self |
| } |
| |
| /// Sets the root path of all the generated test files. |
| pub fn set_project_root(mut self, path: &str) -> Self { |
| self.project_root = Some(path.to_string()); |
| self |
| } |
| |
| /// The name of the output executable, without any suffixes |
| pub fn set_output_name(mut self, path: &str) -> Self { |
| self.output = path.to_string(); |
| self |
| } |
| |
| /// The name of the input C file, without any suffixes |
| pub fn set_input_name(mut self, path: &str) -> Self { |
| self.input = path.to_string(); |
| self |
| } |
| |
| pub fn set_linker(mut self, linker: String) -> Self { |
| self.linker = Some(linker); |
| self |
| } |
| |
| pub fn add_extra_flags(mut self, flags: Vec<&str>) -> Self { |
| let mut flags: Vec<String> = flags.into_iter().map(|f| f.to_string()).collect(); |
| self.extra_flags.append(&mut flags); |
| self |
| } |
| |
| pub fn add_extra_flag(self, flag: &str) -> Self { |
| self.add_extra_flags(vec![flag]) |
| } |
| } |
| |
| impl CompilationCommandBuilder { |
| pub fn make_string(self) -> String { |
| let arch_flags = self.arch_flags.join("+"); |
| let flags = std::env::var("CPPFLAGS").unwrap_or("".into()); |
| let project_root = self.project_root.unwrap_or_default(); |
| let project_root_str = project_root.as_str(); |
| let mut output = self.output.clone(); |
| if self.linker.is_some() { |
| output += ".o" |
| }; |
| let mut command = format!( |
| "{} {flags} -march={arch_flags} \ |
| -O{} \ |
| -o {project_root}/{} \ |
| {project_root}/{}.cpp", |
| self.compiler, self.optimization, output, self.input, |
| ); |
| |
| command = command + " " + self.extra_flags.join(" ").as_str(); |
| |
| if let Some(target) = &self.target { |
| command = command + " --target=" + target; |
| } |
| |
| if let (Some(linker), Some(cxx_toolchain_dir)) = (&self.linker, &self.cxx_toolchain_dir) { |
| let include_args = self |
| .include_paths |
| .iter() |
| .map(|path| "--include-directory=".to_string() + cxx_toolchain_dir + path) |
| .collect::<Vec<_>>() |
| .join(" "); |
| |
| command = command |
| + " -c " |
| + include_args.as_str() |
| + " && " |
| + linker |
| + " " |
| + project_root_str |
| + "/" |
| + &output |
| + " -o " |
| + project_root_str |
| + "/" |
| + &self.output |
| + " && rm " |
| + project_root_str |
| + "/" |
| + &output; |
| } |
| command |
| } |
| } |