|
84 | 84 | //! * `CC_ENABLE_DEBUG_OUTPUT` - if set, compiler command invocations and exit codes will
|
85 | 85 | //! be logged to stdout. This is useful for debugging build script issues, but can be
|
86 | 86 | //! overly verbose for normal use.
|
| 87 | +//! * `CC_SHELL_ESCAPED_FLAGS` - if set, *FLAGS will be parsed as if they were shell |
| 88 | +//! arguments, similar to `make` and `cmake`. For example, `CFLAGS='a "b c" d\ e'` will |
| 89 | +//! be parsed as `["a", "b", "c", "d", "e"]` instead of `["a", "\"b", "c\", "d\\", "e"]` |
87 | 90 | //! * `CXX...` - see [C++ Support](#c-support).
|
88 | 91 | //!
|
89 | 92 | //! Furthermore, projects using this crate may specify custom environment variables
|
@@ -224,6 +227,8 @@ use std::process::Child;
|
224 | 227 | use std::process::Command;
|
225 | 228 | use std::sync::{Arc, RwLock};
|
226 | 229 |
|
| 230 | +use shlex::Shlex; |
| 231 | + |
227 | 232 | #[cfg(feature = "parallel")]
|
228 | 233 | mod parallel;
|
229 | 234 | mod windows;
|
@@ -301,6 +306,7 @@ pub struct Build {
|
301 | 306 | apple_versions_cache: Arc<RwLock<HashMap<Box<str>, Arc<str>>>>,
|
302 | 307 | emit_rerun_if_env_changed: bool,
|
303 | 308 | cached_compiler_family: Arc<RwLock<HashMap<Box<Path>, ToolFamily>>>,
|
| 309 | + shell_escaped_flags: Option<bool>, |
304 | 310 | }
|
305 | 311 |
|
306 | 312 | /// Represents the types of errors that may occur while using cc-rs.
|
@@ -425,6 +431,7 @@ impl Build {
|
425 | 431 | apple_versions_cache: Arc::new(RwLock::new(HashMap::new())),
|
426 | 432 | emit_rerun_if_env_changed: true,
|
427 | 433 | cached_compiler_family: Arc::default(),
|
| 434 | + shell_escaped_flags: None, |
428 | 435 | }
|
429 | 436 | }
|
430 | 437 |
|
@@ -1277,6 +1284,15 @@ impl Build {
|
1277 | 1284 | self
|
1278 | 1285 | }
|
1279 | 1286 |
|
| 1287 | + /// Configure whether *FLAGS variables are parsed using `shlex`, similarly to `make` and |
| 1288 | + /// `cmake`. |
| 1289 | + /// |
| 1290 | + /// This option defaults to `false`. |
| 1291 | + pub fn shell_escaped_flags(&mut self, shell_escaped_flags: bool) -> &mut Build { |
| 1292 | + self.shell_escaped_flags = Some(shell_escaped_flags); |
| 1293 | + self |
| 1294 | + } |
| 1295 | + |
1280 | 1296 | #[doc(hidden)]
|
1281 | 1297 | pub fn __set_env<A, B>(&mut self, a: A, b: B) -> &mut Build
|
1282 | 1298 | where
|
@@ -3634,6 +3650,11 @@ impl Build {
|
3634 | 3650 | })
|
3635 | 3651 | }
|
3636 | 3652 |
|
| 3653 | + fn get_shell_escaped_flags(&self) -> bool { |
| 3654 | + self.shell_escaped_flags |
| 3655 | + .unwrap_or_else(|| self.getenv("CC_SHELL_ESCAPED_FLAGS").is_some()) |
| 3656 | + } |
| 3657 | + |
3637 | 3658 | fn get_dwarf_version(&self) -> Option<u32> {
|
3638 | 3659 | // Tentatively matches the DWARF version defaults as of rustc 1.62.
|
3639 | 3660 | let target = self.get_target().ok()?;
|
@@ -3748,12 +3769,17 @@ impl Build {
|
3748 | 3769 | }
|
3749 | 3770 |
|
3750 | 3771 | fn envflags(&self, name: &str) -> Result<Vec<String>, Error> {
|
3751 |
| - Ok(self |
3752 |
| - .getenv_with_target_prefixes(name)? |
3753 |
| - .to_string_lossy() |
3754 |
| - .split_ascii_whitespace() |
3755 |
| - .map(ToString::to_string) |
3756 |
| - .collect()) |
| 3772 | + let env_os = self.getenv_with_target_prefixes(name)?; |
| 3773 | + let env = env_os.to_string_lossy(); |
| 3774 | + |
| 3775 | + if self.get_shell_escaped_flags() { |
| 3776 | + Ok(Shlex::new(&env).collect()) |
| 3777 | + } else { |
| 3778 | + Ok(env |
| 3779 | + .split_ascii_whitespace() |
| 3780 | + .map(ToString::to_string) |
| 3781 | + .collect()) |
| 3782 | + } |
3757 | 3783 | }
|
3758 | 3784 |
|
3759 | 3785 | fn fix_env_for_apple_os(&self, cmd: &mut Command) -> Result<(), Error> {
|
|
0 commit comments