-
Notifications
You must be signed in to change notification settings - Fork 452
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add independent flags to C or C++ files #1019
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -270,6 +270,8 @@ pub struct Build { | |
known_flag_support_status_cache: Arc<Mutex<HashMap<CompilerFlag, bool>>>, | ||
ar_flags: Vec<Arc<str>>, | ||
asm_flags: Vec<Arc<str>>, | ||
c_flags: Vec<Arc<str>>, | ||
cpp_flags: Vec<Arc<str>>, | ||
no_default_flags: bool, | ||
files: Vec<Arc<Path>>, | ||
cpp: bool, | ||
|
@@ -393,6 +395,8 @@ impl Build { | |
known_flag_support_status_cache: Arc::new(Mutex::new(HashMap::new())), | ||
ar_flags: Vec::new(), | ||
asm_flags: Vec::new(), | ||
c_flags: Vec::new(), | ||
cpp_flags: Vec::new(), | ||
no_default_flags: false, | ||
files: Vec::new(), | ||
shared_flag: None, | ||
|
@@ -569,6 +573,36 @@ impl Build { | |
self | ||
} | ||
|
||
/// Add an arbitrary flag to the invocation of the compiler for c files | ||
/// | ||
/// # Example | ||
/// | ||
/// ```no_run | ||
/// cc::Build::new() | ||
/// .file("src/foo.c") | ||
/// .c_flag("-std=c99") | ||
/// .compile("foo"); | ||
/// ``` | ||
pub fn c_flag(&mut self, flag: &str) -> &mut Build { | ||
self.c_flags.push(flag.into()); | ||
self | ||
} | ||
|
||
/// Add an arbitrary flag to the invocation of the compiler for cpp files | ||
/// | ||
/// # Example | ||
/// | ||
/// ```no_run | ||
/// cc::Build::new() | ||
/// .file("src/foo.cpp") | ||
/// .cpp_flag("-std=c++17") | ||
/// .compile("foo"); | ||
/// ``` | ||
pub fn cpp_flag(&mut self, flag: &str) -> &mut Build { | ||
self.cpp_flags.push(flag.into()); | ||
self | ||
} | ||
|
||
fn ensure_check_file(&self) -> Result<PathBuf, Error> { | ||
let out_dir = self.get_out_dir()?; | ||
let src = if self.cuda { | ||
|
@@ -653,7 +687,7 @@ impl Build { | |
compiler.push_cc_arg("-Wno-unused-command-line-argument".into()); | ||
} | ||
|
||
let mut cmd = compiler.to_command(); | ||
let mut cmd = compiler.to_command(None); | ||
let is_arm = target.contains("aarch64") || target.contains("arm"); | ||
let clang = compiler.is_like_clang(); | ||
let gnu = compiler.family == ToolFamily::Gnu; | ||
|
@@ -1614,7 +1648,7 @@ impl Build { | |
let (cmd, name) = self.msvc_macro_assembler()?; | ||
(cmd, Cow::Borrowed(Path::new(name))) | ||
} else { | ||
let mut cmd = compiler.to_command(); | ||
let mut cmd = compiler.to_command(Some(&obj.src)); | ||
for (a, b) in self.env.iter() { | ||
cmd.env(a, b); | ||
} | ||
|
@@ -1670,7 +1704,7 @@ impl Build { | |
/// This will return a result instead of panicking; see expand() for the complete description. | ||
pub fn try_expand(&self) -> Result<Vec<u8>, Error> { | ||
let compiler = self.try_get_compiler()?; | ||
let mut cmd = compiler.to_command(); | ||
let mut cmd = compiler.to_command(None); | ||
NobodyXu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
for (a, b) in self.env.iter() { | ||
cmd.env(a, b); | ||
} | ||
|
@@ -1828,6 +1862,14 @@ impl Build { | |
cmd.push_cc_arg(warnings_to_errors_flag); | ||
} | ||
|
||
for flag in self.c_flags.iter() { | ||
cmd.c_args.push((**flag).into()); | ||
} | ||
|
||
for flag in self.cpp_flags.iter() { | ||
cmd.cpp_args.push((**flag).into()); | ||
} | ||
|
||
Comment on lines
+1865
to
+1872
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you need to do this in |
||
Ok(cmd) | ||
} | ||
|
||
|
@@ -2466,7 +2508,7 @@ impl Build { | |
|
||
let out_dir = self.get_out_dir()?; | ||
let dlink = out_dir.join(lib_name.to_owned() + "_dlink.o"); | ||
let mut nvcc = self.get_compiler().to_command(); | ||
let mut nvcc = self.get_compiler().to_command(None); | ||
nvcc.arg("--device-link").arg("-o").arg(&dlink).arg(dst); | ||
run(&mut nvcc, "nvcc", &self.cargo_output)?; | ||
self.assemble_progressive(dst, &[dlink.as_path()])?; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,6 +30,8 @@ pub struct Tool { | |
pub(crate) cc_wrapper_path: Option<PathBuf>, | ||
pub(crate) cc_wrapper_args: Vec<OsString>, | ||
pub(crate) args: Vec<OsString>, | ||
pub(crate) c_args: Vec<OsString>, | ||
pub(crate) cpp_args: Vec<OsString>, | ||
pub(crate) env: Vec<(OsString, OsString)>, | ||
pub(crate) family: ToolFamily, | ||
pub(crate) cuda: bool, | ||
|
@@ -78,6 +80,8 @@ impl Tool { | |
cc_wrapper_path: None, | ||
cc_wrapper_args: Vec::new(), | ||
args: Vec::new(), | ||
c_args: Vec::new(), | ||
cpp_args: Vec::new(), | ||
env: Vec::new(), | ||
family, | ||
cuda: false, | ||
|
@@ -219,6 +223,8 @@ impl Tool { | |
cc_wrapper_path: None, | ||
cc_wrapper_args: Vec::new(), | ||
args: Vec::new(), | ||
c_args: Vec::new(), | ||
cpp_args: Vec::new(), | ||
env: Vec::new(), | ||
family, | ||
cuda, | ||
|
@@ -284,19 +290,72 @@ impl Tool { | |
} | ||
} | ||
|
||
/// Returns preferred compiler for source file. | ||
fn preferred_compiler_for_source(&self, src: Option<&PathBuf>) -> (PathBuf, &[OsString]) { | ||
let mut path = self.path.clone(); | ||
let mut extra_args: &[OsString] = &[]; | ||
if let Some(src) = src { | ||
let mut is_c = false; | ||
let mut is_cpp = false; | ||
if let Some(ext) = src.extension().and_then(|x| x.to_str()) { | ||
match ext { | ||
"c" => { | ||
is_c = true; | ||
} | ||
"cc" | "cpp" | "cxx" | "c++" => { | ||
is_cpp = true; | ||
} | ||
_ => {} | ||
} | ||
} | ||
match self.family { | ||
ToolFamily::Clang { zig_cc } if !zig_cc => { | ||
let s = path.to_string_lossy().to_string(); | ||
if is_c { | ||
path = PathBuf::from(s.replace("clang++", "clang")); | ||
extra_args = &self.c_args; | ||
} | ||
if is_cpp { | ||
if s.ends_with("clang") { | ||
path = PathBuf::from(s.replace("clang", "clang++")); | ||
} | ||
extra_args = &self.cpp_args; | ||
} | ||
} | ||
ToolFamily::Gnu => { | ||
let s = path.to_string_lossy().to_string(); | ||
if is_c { | ||
path = PathBuf::from(s.replace("g++", "gcc")); | ||
extra_args = &self.c_args; | ||
} | ||
if is_cpp { | ||
path = PathBuf::from(s.replace("gcc", "g++")); | ||
extra_args = &self.cpp_args; | ||
} | ||
} | ||
_ => {} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems that the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. MSVC has only one There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It doesn't have |
||
} | ||
} | ||
(path, extra_args) | ||
} | ||
|
||
/// Converts this compiler into a `Command` that's ready to be run. | ||
/// | ||
/// This is useful for when the compiler needs to be executed and the | ||
/// command returned will already have the initial arguments and environment | ||
/// variables configured. | ||
pub fn to_command(&self) -> Command { | ||
/// | ||
/// The `src` argument is used to determine the preferred compiler for the | ||
/// source file. If `None`, the default compiler is used. | ||
pub fn to_command(&self, src: Option<&PathBuf>) -> Command { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is breaking change, please move this to a new function. |
||
let (path, extra_args) = self.preferred_compiler_for_source(src); | ||
let mut cmd = match self.cc_wrapper_path { | ||
Some(ref cc_wrapper_path) => { | ||
let mut cmd = Command::new(cc_wrapper_path); | ||
cmd.arg(&self.path); | ||
cmd.arg(&path); | ||
cmd | ||
} | ||
None => Command::new(&self.path), | ||
None => Command::new(&path), | ||
}; | ||
cmd.args(&self.cc_wrapper_args); | ||
|
||
|
@@ -307,6 +366,8 @@ impl Tool { | |
.collect::<Vec<_>>(); | ||
cmd.args(&value); | ||
|
||
cmd.args(extra_args); | ||
|
||
for (k, v) in self.env.iter() { | ||
cmd.env(k, v); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think
cxx_flags
makes more sense.cpp
could be confused with pre-processors of C/C++ compiler.