]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
feat: Support overriding MSVC /Z* options
authorJoel Rosdahl <joel@rosdahl.net>
Wed, 8 Mar 2023 07:10:27 +0000 (08:10 +0100)
committerJoel Rosdahl <joel@rosdahl.net>
Wed, 8 Mar 2023 09:07:12 +0000 (10:07 +0100)
MSVC options /Zi and /ZI are too hard since they produce separate PDB
files. /Z7 is OK, but if the command line contains /Zi or /ZI followed
by /Z7, MSVC will use the latter (with a warning) but ccache will still
consider the command line too hard.

This commit makes ccache understand that only the last /Z* option will
be used and thus accepts the command line if the last /Z* option is /Z7.

Closes #1239.

src/argprocessing.cpp
src/compopt.cpp
unittest/test_argprocessing.cpp

index 792c57f7c6dbd2d5afc0637e336bdb374df035de..bad2dadd991bfc3da98f9efc08b540f2d42b675a 100644 (file)
@@ -71,8 +71,9 @@ struct ArgumentProcessingState
   bool found_md_or_mmd_opt = false;
   bool found_Wa_a_opt = false;
 
-  std::string explicit_language;    // As specified with -x.
-  std::string input_charset_option; // -finput-charset=...
+  std::string explicit_language;       // As specified with -x.
+  std::string input_charset_option;    // -finput-charset=...
+  std::string last_seen_msvc_z_option; // /Z7, /Zi or /ZI
 
   // Is the dependency file set via -Wp,-M[M]D,target or -MFtarget?
   OutputDepOrigin output_dep_origin = OutputDepOrigin::none;
@@ -607,6 +608,12 @@ process_option_arg(const Context& ctx,
     return Statistic::none;
   }
 
+  if (config.is_compiler_group_msvc() && util::starts_with(arg, "-Z")) {
+    state.last_seen_msvc_z_option = args[i];
+    state.common_args.push_back(args[i]);
+    return Statistic::none;
+  }
+
   // These options require special handling, because they behave differently
   // with gcc -E, when the output file is not specified.
   if ((arg == "-MD" || arg == "-MMD") && !config.is_compiler_group_msvc()) {
@@ -1160,6 +1167,13 @@ process_args(Context& ctx)
     return Statistic::unsupported_compiler_option;
   }
 
+  if (!state.last_seen_msvc_z_option.empty()
+      && state.last_seen_msvc_z_option.substr(2) != "7") {
+    // /Zi and /ZI are unsupported, but /Z7 is fine.
+    LOG("Compiler option {} is unsupported", state.last_seen_msvc_z_option);
+    return Statistic::unsupported_compiler_option;
+  }
+
   // Don't try to second guess the compiler's heuristics for stdout handling.
   if (args_info.output_obj == "-") {
     LOG_RAW("Output file is -");
index e5415fac514aae4dfe13227c9af5b0141bc340d9..a7ec8b22c54cec3391f2c5fdf1f3d1c08f0393e8 100644 (file)
@@ -96,8 +96,6 @@ const CompOpt compopts[] = {
   {"-Xpreprocessor", AFFECTS_CPP | TOO_HARD_DIRECT | TAKES_ARG},
   {"-Yc", TAKES_ARG | TOO_HARD},                                    // msvc
   {"-Yu", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH}, // msvc
-  {"-ZI", TOO_HARD},                                                // msvc
-  {"-Zi", TOO_HARD},                                                // msvc
   {"-all_load", AFFECTS_COMP},
   {"-analyze", TOO_HARD}, // Clang
   {"-arch", TAKES_ARG},
index be070d8f05b968cf2e68196ea50de78e33cbd489..bf98b090e0ab28f17189f8328ee3a51e61268870 100644 (file)
@@ -699,4 +699,51 @@ TEST_CASE("MSVC options"
   CHECK(result.compiler_args.to_string() == "cl.exe /foobar -c");
 }
 
+TEST_CASE("MSVC debug information format options")
+{
+  TestContext test_context;
+  Context ctx;
+  ctx.config.set_compiler_type(CompilerType::msvc);
+  util::write_file("foo.c", "");
+
+  SUBCASE("Only /Z7")
+  {
+    ctx.orig_args = Args::from_string("cl.exe /c foo.c /Z7");
+    const ProcessArgsResult result = process_args(ctx);
+    REQUIRE(!result.error);
+    CHECK(result.preprocessor_args.to_string() == "cl.exe /Z7");
+    CHECK(result.compiler_args.to_string() == "cl.exe /Z7 -c");
+  }
+
+  SUBCASE("Only /Zi")
+  {
+    ctx.orig_args = Args::from_string("cl.exe /c foo.c /Zi");
+    const ProcessArgsResult result = process_args(ctx);
+    CHECK(result.error == Statistic::unsupported_compiler_option);
+  }
+
+  SUBCASE("Only /ZI")
+  {
+    ctx.orig_args = Args::from_string("cl.exe /c foo.c /ZI");
+    const ProcessArgsResult result = process_args(ctx);
+    CHECK(result.error == Statistic::unsupported_compiler_option);
+  }
+
+  SUBCASE("/Z7 + /Zi")
+  {
+    ctx.orig_args = Args::from_string("cl.exe /Z7 /c foo.c /Zi");
+    const ProcessArgsResult result = process_args(ctx);
+    CHECK(result.error == Statistic::unsupported_compiler_option);
+  }
+
+  SUBCASE("/Zi + /Z7")
+  {
+    ctx.orig_args = Args::from_string("cl.exe /Zi /c foo.c /Z7");
+    const ProcessArgsResult result = process_args(ctx);
+    REQUIRE(!result.error);
+    CHECK(result.preprocessor_args.to_string() == "cl.exe /Zi /Z7");
+    CHECK(result.compiler_args.to_string() == "cl.exe /Zi /Z7 -c");
+  }
+}
+
 TEST_SUITE_END();