run_make_support/external_deps/c_cxx_compiler/cc.rs
1use std::path::Path;
2
3use crate::command::Command;
4use crate::{env_var, is_msvc};
5
6/// Construct a new platform-specific C compiler invocation.
7///
8/// WARNING: This means that what flags are accepted by the underlying C compiler is
9/// platform- AND compiler-specific. Consult the relevant docs for `gcc`, `clang` and `mvsc`.
10#[track_caller]
11pub fn cc() -> Cc {
12 Cc::new()
13}
14
15/// Construct a new platform-specific CXX compiler invocation.
16/// CXX_DEFAULT_FLAGS is passed from compiletest.
17#[track_caller]
18pub fn cxx() -> Cc {
19 Cc::new_cxx()
20}
21
22/// A platform-specific C compiler invocation builder. The specific C compiler used is
23/// passed down from compiletest.
24#[derive(Debug)]
25#[must_use]
26pub struct Cc {
27 cmd: Command,
28}
29
30crate::macros::impl_common_helpers!(Cc);
31
32impl Cc {
33 /// Construct a new platform-specific C compiler invocation.
34 ///
35 /// WARNING: This means that what flags are accepted by the underlying C compile is
36 /// platform- AND compiler-specific. Consult the relevant docs for `gcc`, `clang` and `mvsc`.
37 #[track_caller]
38 pub fn new() -> Self {
39 let compiler = env_var("CC");
40
41 let mut cmd = Command::new(compiler);
42
43 let default_cflags = env_var("CC_DEFAULT_FLAGS");
44 for flag in default_cflags.split(char::is_whitespace) {
45 cmd.arg(flag);
46 }
47
48 Self { cmd }
49 }
50
51 /// Construct a new platform-specific CXX compiler invocation.
52 /// CXX_DEFAULT_FLAGS is passed from compiletest.
53 #[track_caller]
54 pub fn new_cxx() -> Self {
55 let compiler = env_var("CXX");
56
57 let mut cmd = Command::new(compiler);
58
59 let default_cflags = env_var("CXX_DEFAULT_FLAGS");
60 for flag in default_cflags.split(char::is_whitespace) {
61 cmd.arg(flag);
62 }
63
64 Self { cmd }
65 }
66
67 /// Specify path of the input file.
68 pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
69 self.cmd.arg(path.as_ref());
70 self
71 }
72
73 /// Adds directories to the list that the linker searches for libraries.
74 /// Equivalent to `-L`.
75 pub fn library_search_path<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
76 self.cmd.arg("-L");
77 self.cmd.arg(path.as_ref());
78 self
79 }
80
81 /// Specify `-o` or `-Fe`/`-Fo` depending on platform/compiler.
82 pub fn out_exe(&mut self, name: &str) -> &mut Self {
83 let mut path = std::path::PathBuf::from(name);
84
85 if is_msvc() {
86 path.set_extension("exe");
87 let fe_path = path.clone();
88 path.set_extension("");
89 path.set_extension("obj");
90 let fo_path = path;
91 self.cmd.arg(format!("-Fe:{}", fe_path.to_str().unwrap()));
92 self.cmd.arg(format!("-Fo:{}", fo_path.to_str().unwrap()));
93 } else {
94 self.cmd.arg("-o");
95 self.cmd.arg(name);
96 }
97
98 self
99 }
100
101 /// Specify path of the output binary.
102 pub fn output<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
103 self.cmd.arg("-o");
104 self.cmd.arg(path.as_ref());
105 self
106 }
107
108 /// Optimize the output.
109 /// Equivalent to `-O3` for GNU-compatible linkers or `-O2` for MSVC linkers.
110 pub fn optimize(&mut self) -> &mut Self {
111 if is_msvc() {
112 self.cmd.arg("-O2");
113 } else {
114 self.cmd.arg("-O3");
115 }
116 self
117 }
118}