From 2aadef2c5a07a59658c0cc3da4a90b153293f543 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Thu, 27 Feb 2020 17:47:34 +0900 Subject: [PATCH] Support both -arg and /arg with msvc/clang-cl without altering paths 34c6f9a added support for /arg flags by replacing the initial slash with a -, and falling back to normal argument parsing. Unfortunately, when running clang-cl on a non-Windows system, that means absolute paths get garbled, and that can lead to bad argument parsing with separate arguments (e.g. -I /absolute/path). We change the arguments definition for MSVC to include both styles, by hacking up a macro that generates two lists, one with - arguments, and one with / arguments. Merging the two lists at build time doesn't seem possible without going full procedural macro. Fixes #669 --- src/compiler/msvc.rs | 73 +++++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 35 deletions(-) diff --git a/src/compiler/msvc.rs b/src/compiler/msvc.rs index 1d5233b1e..330285646 100644 --- a/src/compiler/msvc.rs +++ b/src/compiler/msvc.rs @@ -227,29 +227,43 @@ ArgData! { use self::ArgData::*; -counted_array!(static ARGS: [ArgInfo; _] = [ - take_arg!("-D", OsString, Concatenated, PreprocessorArgument), - take_arg!("-FA", OsString, Concatenated, TooHard), - take_arg!("-FI", PathBuf, CanBeSeparated, PreprocessorArgumentPath), - take_arg!("-FR", PathBuf, Concatenated, TooHardPath), - take_arg!("-Fa", PathBuf, Concatenated, TooHardPath), - take_arg!("-Fd", PathBuf, Concatenated, ProgramDatabase), - take_arg!("-Fe", PathBuf, Concatenated, TooHardPath), - take_arg!("-Fi", PathBuf, Concatenated, TooHardPath), - take_arg!("-Fm", PathBuf, Concatenated, TooHardPath), - take_arg!("-Fo", PathBuf, Concatenated, Output), - take_arg!("-Fp", PathBuf, Concatenated, TooHardPath), - take_arg!("-Fr", PathBuf, Concatenated, TooHardPath), - flag!("-Fx", TooHardFlag), - take_arg!("-I", PathBuf, CanBeSeparated, PreprocessorArgumentPath), - take_arg!("-U", OsString, Concatenated, PreprocessorArgument), - take_arg!("-Xclang", OsString, Separated, XClang), - flag!("-Zi", DebugInfo), - flag!("-c", DoCompilation), - take_arg!("-deps", PathBuf, Concatenated, DepFile), - flag!("-fsyntax-only", TooHardFlag), - take_arg!("-o", PathBuf, Separated, Output), // Deprecated but valid - flag!("-showIncludes", ShowIncludes), +macro_rules! msvc_args { + (static ARGS: [$t:ty; _] = [$($macro:ident ! ($($v:tt)*),)*]) => { + counted_array!(static ARGS: [$t; _] = [$(msvc_args!(@one "-", $macro!($($v)*)),)*]); + counted_array!(static SLASH_ARGS: [$t; _] = [$(msvc_args!(@one "/", $macro!($($v)*)),)*]); + }; + (@one $prefix:expr, msvc_take_arg!($s:expr, $($t:tt)*)) => { + take_arg!(concat!($prefix, $s), $($t)+) + }; + (@one $prefix:expr, msvc_flag!($s:expr, $($t:tt)+)) => { + flag!(concat!($prefix, $s), $($t)+) + }; + (@one $prefix:expr, $other:expr) => { $other }; +} + +msvc_args!(static ARGS: [ArgInfo; _] = [ + msvc_take_arg!("D", OsString, Concatenated, PreprocessorArgument), + msvc_take_arg!("FA", OsString, Concatenated, TooHard), + msvc_take_arg!("FI", PathBuf, CanBeSeparated, PreprocessorArgumentPath), + msvc_take_arg!("FR", PathBuf, Concatenated, TooHardPath), + msvc_take_arg!("Fa", PathBuf, Concatenated, TooHardPath), + msvc_take_arg!("Fd", PathBuf, Concatenated, ProgramDatabase), + msvc_take_arg!("Fe", PathBuf, Concatenated, TooHardPath), + msvc_take_arg!("Fi", PathBuf, Concatenated, TooHardPath), + msvc_take_arg!("Fm", PathBuf, Concatenated, TooHardPath), + msvc_take_arg!("Fo", PathBuf, Concatenated, Output), + msvc_take_arg!("Fp", PathBuf, Concatenated, TooHardPath), + msvc_take_arg!("Fr", PathBuf, Concatenated, TooHardPath), + msvc_flag!("Fx", TooHardFlag), + msvc_take_arg!("I", PathBuf, CanBeSeparated, PreprocessorArgumentPath), + msvc_take_arg!("U", OsString, Concatenated, PreprocessorArgument), + msvc_take_arg!("Xclang", OsString, Separated, XClang), + msvc_flag!("Zi", DebugInfo), + msvc_flag!("c", DoCompilation), + msvc_take_arg!("deps", PathBuf, Concatenated, DepFile), + msvc_flag!("fsyntax-only", TooHardFlag), + msvc_take_arg!("o", PathBuf, Separated, Output), // Deprecated but valid + msvc_flag!("showIncludes", ShowIncludes), take_arg!("@", PathBuf, Concatenated, TooHardPath), ]); @@ -270,18 +284,7 @@ pub fn parse_arguments( let mut show_includes = false; let mut xclangs: Vec = vec![]; - // First convert all `/foo` arguments to `-foo` to accept both styles - let it = arguments.iter().map(|i| { - if let Some(arg) = i.split_prefix("/") { - let mut dash = OsString::from("-"); - dash.push(&arg); - dash - } else { - i.clone() - } - }); - - for arg in ArgsIter::new(it, &ARGS[..]) { + for arg in ArgsIter::new(arguments.iter().cloned(), (&ARGS[..], &SLASH_ARGS[..])) { let arg = try_or_cannot_cache!(arg, "argument parse"); match arg.get_data() { Some(TooHardFlag) | Some(TooHard(_)) | Some(TooHardPath(_)) => {