From: Joel Rosdahl Date: Wed, 8 Mar 2023 07:10:27 +0000 (+0100) Subject: feat: Support overriding MSVC /Z* options X-Git-Tag: v4.8~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d099c1804f56e7a357c8c8473cacf186da0d5d3e;p=thirdparty%2Fccache.git feat: Support overriding MSVC /Z* options 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. --- diff --git a/src/argprocessing.cpp b/src/argprocessing.cpp index 792c57f7c..bad2dadd9 100644 --- a/src/argprocessing.cpp +++ b/src/argprocessing.cpp @@ -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 -"); diff --git a/src/compopt.cpp b/src/compopt.cpp index e5415fac5..a7ec8b22c 100644 --- a/src/compopt.cpp +++ b/src/compopt.cpp @@ -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}, diff --git a/unittest/test_argprocessing.cpp b/unittest/test_argprocessing.cpp index be070d8f0..bf98b090e 100644 --- a/unittest/test_argprocessing.cpp +++ b/unittest/test_argprocessing.cpp @@ -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();