diff --git a/src/lib.rs b/src/lib.rs index 05030ce2a..2fe30b98c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -108,6 +108,7 @@ pub struct Build { cpp_set_stdlib: Option>, cuda: bool, cudart: Option>, + std: Option>, target: Option>, host: Option>, out_dir: Option>, @@ -314,6 +315,7 @@ impl Build { cpp_set_stdlib: None, cuda: false, cudart: None, + std: None, target: None, host: None, out_dir: None, @@ -708,6 +710,37 @@ impl Build { self } + /// Specify the C or C++ language standard version. + /// + /// These values are common to modern versions of GCC, Clang and MSVC: + /// - `c11` for ISO/IEC 9899:2011 + /// - `c17` for ISO/IEC 9899:2018 + /// - `c++14` for ISO/IEC 14882:2014 + /// - `c++17` for ISO/IEC 14882:2017 + /// - `c++20` for ISO/IEC 14882:2020 + /// + /// Other values have less broad support, e.g. MSVC does not support `c++11` + /// (`c++14` is the minimum), `c89` (omit the flag instead) or `c99`. + /// + /// For compiling C++ code, you should also set `.cpp(true)`. + /// + /// The default is that no standard flag is passed to the compiler, so the + /// language version will be the compiler's default. + /// + /// # Example + /// + /// ```no_run + /// cc::Build::new() + /// .file("src/modern.cpp") + /// .cpp(true) + /// .std("c++17") + /// .compile("modern"); + /// ``` + pub fn std(&mut self, std: &str) -> &mut Build { + self.std = Some(std.into()); + self + } + /// Set warnings into errors flag. /// /// Disabled by default. @@ -1613,6 +1646,14 @@ impl Build { println!("Info: default compiler flags are disabled"); } + if let Some(ref std) = self.std { + let separator = match cmd.family { + ToolFamily::Msvc { .. } => ':', + ToolFamily::Gnu | ToolFamily::Clang => '=', + }; + cmd.push_cc_arg(format!("-std{}{}", separator, std).into()); + } + if let Ok(flags) = self.envflags(if self.cpp { "CXXFLAGS" } else { "CFLAGS" }) { for arg in flags { cmd.push_cc_arg(arg.into()); diff --git a/tests/test.rs b/tests/test.rs index 161abd8ab..7f1ddb218 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -366,6 +366,14 @@ fn gnu_no_dash_dash() { test.cmd(0).must_not_have("--"); } +#[test] +fn gnu_std_c() { + let test = Test::gnu(); + test.gcc().file("foo.c").std("c11").compile("foo"); + + test.cmd(0).must_have("-std=c11"); +} + #[test] fn msvc_smoke() { reset_env(); @@ -443,6 +451,14 @@ fn msvc_no_dash_dash() { test.cmd(0).must_not_have("--"); } +#[test] +fn msvc_std_c() { + let test = Test::msvc(); + test.gcc().file("foo.c").std("c11").compile("foo"); + + test.cmd(0).must_have("-std:c11"); +} + // Disable this test with the parallel feature because the execution // order is not deterministic. #[cfg(not(feature = "parallel"))]