From: Orgad Shaneh Date: Sun, 16 Jan 2022 17:51:55 +0000 (+0200) Subject: feat: Support MSVC /Yu option (compiling with PCH) (#991) X-Git-Tag: v4.6~46 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=13fcafe31a5d53f138922441d6929f8447fb0c73;p=thirdparty%2Fccache.git feat: Support MSVC /Yu option (compiling with PCH) (#991) Co-authored-by: Luboš Luňák --- diff --git a/src/argprocessing.cpp b/src/argprocessing.cpp index a83dc597b..fa788c7ea 100644 --- a/src/argprocessing.cpp +++ b/src/argprocessing.cpp @@ -50,6 +50,8 @@ struct ArgumentProcessingState bool found_S_opt = false; bool found_pch = false; bool found_fpch_preprocess = false; + bool found_Yu = false; + bool found_valid_Fp = false; ColorDiagnostics color_diagnostics = ColorDiagnostics::automatic; bool found_directives_only = false; bool found_rewrite_includes = false; @@ -110,16 +112,43 @@ detect_pch(const std::string& option, const std::string& arg, std::string& included_pch_file, bool is_cc1_option, - bool* found_pch) + ArgumentProcessingState& state) { - ASSERT(found_pch); - // Try to be smart about detecting precompiled headers. // If the option is an option for Clang (is_cc1_option), don't accept // anything just because it has a corresponding precompiled header, // because Clang doesn't behave that way either. std::string pch_file; - if (option == "-include-pch" || option == "-include-pth") { + if (option == "-Yu") { + state.found_Yu = true; + if (state.found_valid_Fp) { // Use file set by -Fp. + LOG("Detected use of precompiled header: {}", included_pch_file); + pch_file = included_pch_file; + } else { + std::string file = Util::change_extension(arg, ".pch"); + if (Stat::stat(file)) { + LOG("Detected use of precompiled header: {}", file); + pch_file = file; + } + } + } else if (option == "-Fp") { + std::string file = arg; + if (Util::get_extension(file).empty()) { + file += ".pch"; + } + if (Stat::stat(file)) { + state.found_valid_Fp = true; + if (!state.found_Yu) { + LOG("Precompiled header file specified: {}", file); + included_pch_file = file; // remember file + return true; // -Fp does not turn on PCH + } + LOG("Detected use of precompiled header: {}", file); + pch_file = file; + included_pch_file.clear(); // reset pch file set from /Yu + // continue and set as if the file was passed to -Yu + } + } else if (option == "-include-pch" || option == "-include-pth") { if (Stat::stat(arg)) { LOG("Detected use of precompiled header: {}", arg); pch_file = arg; @@ -142,7 +171,7 @@ detect_pch(const std::string& option, return false; } included_pch_file = pch_file; - *found_pch = true; + state.found_pch = true; } return true; } @@ -869,7 +898,7 @@ process_arg(const Context& ctx, args[i + next], args_info.included_pch_file, next == 2, - &state.found_pch)) { + state)) { return Statistic::bad_compiler_arguments; } @@ -886,13 +915,28 @@ process_arg(const Context& ctx, return nullopt; } - // Same as above but options with concatenated argument beginning with a - // slash. + // Same as above but options with concatenated path argument beginning with a + // slash or select few that do not require a slash. + // FIXME: None of them really need a slash, the path may be relative, this + // should check prefix. if (args[i][0] == '-') { size_t slash_pos = args[i].find('/'); + if (args[i].size() > 3 + && (util::starts_with(args[i], "-Yu") + || util::starts_with(args[i], "-Fp"))) { + slash_pos = 3; + } if (slash_pos != std::string::npos) { std::string option = args[i].substr(0, slash_pos); if (compopt_takes_concat_arg(option) && compopt_takes_path(option)) { + if (!detect_pch(option, + args[i].substr(slash_pos), + args_info.included_pch_file, + false, + state)) { + return Statistic::bad_compiler_arguments; + } + auto relpath = Util::make_relative_path(ctx, string_view(args[i]).substr(slash_pos)); std::string new_option = option + relpath; @@ -1237,7 +1281,7 @@ process_args(Context& ctx) if (!state.input_charset_option.empty()) { state.cpp_args.push_back(state.input_charset_option); } - if (state.found_pch) { + if (state.found_pch && ctx.config.compiler_type() != CompilerType::cl) { state.cpp_args.push_back("-fpch-preprocess"); } if (!state.explicit_language.empty()) { diff --git a/src/compopt.cpp b/src/compopt.cpp index 732b5a4d4..68a863c91 100644 --- a/src/compopt.cpp +++ b/src/compopt.cpp @@ -76,6 +76,7 @@ const CompOpt compopts[] = { {"-F", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH}, {"-FI", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH}, // msvc {"-FU", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH}, // msvc + {"-Fp", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH}, // msvc {"-G", TAKES_ARG}, {"-I", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH}, {"-L", TAKES_ARG}, @@ -95,9 +96,10 @@ const CompOpt compopts[] = { {"-Xclang", TAKES_ARG}, {"-Xlinker", TAKES_ARG | TAKES_CONCAT_ARG | AFFECTS_COMP}, {"-Xpreprocessor", AFFECTS_CPP | TOO_HARD_DIRECT | TAKES_ARG}, - {"-Yc", TAKES_ARG | TOO_HARD}, // msvc - {"-ZI", TOO_HARD}, // msvc - {"-Zi", TOO_HARD}, // msvc + {"-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},