From c107760417d5941202713fbaaa3e25e62d1dd12e Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Wed, 20 Apr 2022 12:32:16 -0400 Subject: cmNinjaTargetGenerator: support msvc-style deps discovery for scanning --- Help/dev/experimental.rst | 4 +++- Source/cmNinjaTargetGenerator.cxx | 31 +++++++++++++++++++++---------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/Help/dev/experimental.rst b/Help/dev/experimental.rst index 2943c7c..7638d22 100644 --- a/Help/dev/experimental.rst +++ b/Help/dev/experimental.rst @@ -36,7 +36,9 @@ For example, add code like the following to a test project: The tool specified by ``CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE`` is expected to process the translation unit, write preprocessor dependencies to the file specified by the ```` placeholder, and write module -dependencies to the file specified by the ```` placeholder. +dependencies to the file specified by the ```` placeholder. The +``CMAKE_EXPERIMENTAL_CXX_SCANDEP_DEPFILE_FORMAT`` file may be set to ``msvc`` +for scandep rules which use ``msvc``-style dependency reporting. For tools which need to know the file set the source belongs to, the ``CMAKE_EXPERIMENTAL_CXX_MODULE_SOURCE_TYPE_FLAG_`` flag may diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index fa058d2..3fac7f5 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -586,6 +586,7 @@ std::string GetScanCommand(const std::string& cmakeCmd, const std::string& tdi, // not perform explicit preprocessing too. cmNinjaRule GetScanRule( std::string const& ruleName, std::string const& ppFileName, + std::string const& deptype, cmRulePlaceholderExpander::RuleVariables const& vars, const std::string& responseFlag, const std::string& flags, cmRulePlaceholderExpander* const rulePlaceholderExpander, @@ -594,8 +595,13 @@ cmNinjaRule GetScanRule( { cmNinjaRule rule(ruleName); // Scanning always uses a depfile for preprocessor dependencies. - rule.DepType = ""; // no deps= for multiple outputs - rule.DepFile = "$DEP_FILE"; + if (deptype == "msvc"_s) { + rule.DepType = deptype; + rule.DepFile = ""; + } else { + rule.DepType = ""; // no deps= for multiple outputs + rule.DepFile = "$DEP_FILE"; + } cmRulePlaceholderExpander::RuleVariables scanVars; scanVars.CMTargetName = vars.CMTargetName; @@ -699,6 +705,9 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL); if (needDyndep) { + const auto& scanDepType = this->GetMakefile()->GetSafeDefinition( + cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_SCANDEP_DEPFILE_FORMAT")); + // Rule to scan dependencies of sources that need preprocessing. { std::vector scanCommands; @@ -726,10 +735,10 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, "$DYNDEP_INTERMEDIATE_FILE")); } - auto scanRule = - GetScanRule(scanRuleName, ppFileName, vars, responseFlag, flags, - rulePlaceholderExpander.get(), this->GetLocalGenerator(), - std::move(scanCommands), config); + auto scanRule = GetScanRule( + scanRuleName, ppFileName, scanDepType, vars, responseFlag, flags, + rulePlaceholderExpander.get(), this->GetLocalGenerator(), + std::move(scanCommands), config); scanRule.Comment = cmStrCat("Rule for generating ", lang, " dependencies."); @@ -757,9 +766,10 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, scanCommands.emplace_back( GetScanCommand(cmakeCmd, tdi, lang, "$in", "$out")); - auto scanRule = GetScanRule( - scanRuleName, "", vars, "", flags, rulePlaceholderExpander.get(), - this->GetLocalGenerator(), std::move(scanCommands), config); + auto scanRule = + GetScanRule(scanRuleName, "", scanDepType, vars, "", flags, + rulePlaceholderExpander.get(), this->GetLocalGenerator(), + std::move(scanCommands), config); // Write the rule for generating dependencies for the given language. scanRule.Comment = cmStrCat("Rule for generating ", lang, @@ -1249,7 +1259,8 @@ cmNinjaBuild GetScanBuildStatement(const std::string& ruleName, scanBuild.Variables["PREPROCESSED_OUTPUT_FILE"] = ppFileName; } - // Scanning always uses a depfile for preprocessor dependencies. + // Scanning always provides a depfile for preprocessor dependencies. This + // variable is unused in `msvc`-deptype scanners. std::string const& depFileName = cmStrCat(scanBuild.Outputs.front(), ".d"); scanBuild.Variables["DEP_FILE"] = lg->ConvertToOutputFormat(depFileName, cmOutputConverter::SHELL); -- cgit v0.12