From: Joel Rosdahl Date: Sat, 8 Nov 2025 12:28:13 +0000 (+0100) Subject: feat(msvc): Add support for caching /sourceDependencies file X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=296363700090dad459d0bfc564add9f03c653334;p=thirdparty%2Fccache.git feat(msvc): Add support for caching /sourceDependencies file --- diff --git a/src/ccache/argprocessing.cpp b/src/ccache/argprocessing.cpp index a38d342f..7c3d00b1 100644 --- a/src/ccache/argprocessing.cpp +++ b/src/ccache/argprocessing.cpp @@ -1089,6 +1089,52 @@ process_option_arg(const Context& ctx, return Statistic::none; } + const std::string_view source_dep_directives_opt = + "-sourceDependencies:directives"; + if (util::starts_with(arg, source_dep_directives_opt)) { + LOG("Compiler option {} is unsupported", args[i]); + return Statistic::unsupported_compiler_option; + } + + const std::string_view source_dep_opt = "-sourceDependencies"; + if (util::starts_with(arg, source_dep_opt)) { + // The generated file embeds absolute include paths resolved relative to the + // actual working directory even when -I uses relative paths. To avoid false + // positive cache hits across different working directories, bind the result + // key to the actual CWD. + // + // Note: A future alternative could be to instead disable direct/depend mode + // and let the preprocessor create the file instead. + LOG("Hashing current working directory since {} is used", arg); + state.hash_actual_cwd = true; + + state.add_compiler_only_arg(args[i]); + + if (arg == source_dep_opt) { + // /sourceDependencies FILE + if (i == args.size() - 1) { + LOG("Missing argument to {}", args[i]); + return Statistic::bad_compiler_arguments; + } + state.add_compiler_only_arg_no_hash(args[i + 1]); + args_info.output_sd = args[i + 1]; + ++i; + } else { + // /sourceDependenciesFILE + auto file = std::string_view(args[i]).substr(source_dep_opt.length()); + if (file == "-") { + LOG("Compiler option {} is unsupported", args[i]); + return Statistic::unsupported_compiler_option; + } + if (fs::is_directory(file)) { + LOG("{} with directory ({}) is unsupported", args[i], file); + return Statistic::unsupported_compiler_option; + } + args_info.output_sd = file; + } + return Statistic::none; + } + if (config.compiler_type() == CompilerType::gcc) { if (arg == "-fdiagnostics-color" || arg == "-fdiagnostics-color=always") { state.color_diagnostics = ColorDiagnostics::always; diff --git a/src/ccache/argsinfo.hpp b/src/ccache/argsinfo.hpp index 4b1ddb69..f591449a 100644 --- a/src/ccache/argsinfo.hpp +++ b/src/ccache/argsinfo.hpp @@ -62,6 +62,9 @@ struct ArgsInfo // Diagnostic generation information (Clang). Contains pathname if not empty. std::filesystem::path output_dia; + // Source dependencies output file (MSVC). Contains pathname if not empty. + std::filesystem::path output_sd; + // Split dwarf information (GCC 4.8 and up). Contains pathname if not empty. std::filesystem::path output_dwo; diff --git a/src/ccache/ccache.cpp b/src/ccache/ccache.cpp index 5d5e6de0..8450def1 100644 --- a/src/ccache/ccache.cpp +++ b/src/ccache/ccache.cpp @@ -1035,6 +1035,12 @@ write_result(Context& ctx, LOG("Diagnostics file {} missing", ctx.args_info.output_dia); return false; } + if (!ctx.args_info.output_sd.empty() + && !serializer.add_file(core::result::FileType::source_dependencies, + ctx.args_info.output_sd)) { + LOG("Source dependencies file {} missing", ctx.args_info.output_sd); + return false; + } if (ctx.args_info.seen_split_dwarf // Only store .dwo file if it was created by the compiler (GCC and Clang // behave differently e.g. for "-gsplit-dwarf -g1"). @@ -2862,6 +2868,9 @@ do_cache_compilation(Context& ctx) if (!ctx.args_info.output_dia.empty()) { LOG("Diagnostics file: {}", ctx.args_info.output_dia); } + if (!ctx.args_info.output_sd.empty()) { + LOG("Source dependencies file: {}", ctx.args_info.output_sd); + } if (!ctx.args_info.output_dwo.empty()) { LOG("Split dwarf file: {}", ctx.args_info.output_dwo); } diff --git a/src/ccache/core/result.cpp b/src/ccache/core/result.cpp index 41abfd37..47a174d4 100644 --- a/src/ccache/core/result.cpp +++ b/src/ccache/core/result.cpp @@ -156,6 +156,9 @@ file_type_to_string(FileType type) case FileType::ipa_clones: return ".000i.ipa-clones"; + + case FileType::source_dependencies: + return ".sourcedeps.json"; } return k_unknown_file_type; diff --git a/src/ccache/core/result.hpp b/src/ccache/core/result.hpp index 7da388c5..eb4aa464 100644 --- a/src/ccache/core/result.hpp +++ b/src/ccache/core/result.hpp @@ -93,6 +93,9 @@ enum class FileType : UnderlyingFileTypeInt { // ipa clones generated by -fdump-ipa-clones, i.e. output file but with a // .000i.ipa-clones extension. ipa_clones = 12, + + // Source dependencies file specified by MSVC /sourceDependencies. + source_dependencies = 13, }; const char* file_type_to_string(FileType type); diff --git a/src/ccache/core/resultretriever.cpp b/src/ccache/core/resultretriever.cpp index e27798d5..ab0edd18 100644 --- a/src/ccache/core/resultretriever.cpp +++ b/src/ccache/core/resultretriever.cpp @@ -201,11 +201,15 @@ ResultRetriever::get_dest_path(FileType file_type) const return m_ctx.args_info.output_ci; } break; + case FileType::ipa_clones: if (m_ctx.args_info.generating_ipa_clones) { return m_ctx.args_info.output_ipa; } break; + + case FileType::source_dependencies: + return m_ctx.args_info.output_sd; } return {};