浏览代码

cmNinjaTargetGenerator: support msvc-style deps discovery for scanning

Ben Boeckel 3 年之前
父节点
当前提交
c107760417
共有 2 个文件被更改,包括 24 次插入11 次删除
  1. 3 1
      Help/dev/experimental.rst
  2. 21 10
      Source/cmNinjaTargetGenerator.cxx

+ 3 - 1
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
 The tool specified by ``CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE`` is
 expected to process the translation unit, write preprocessor dependencies
 expected to process the translation unit, write preprocessor dependencies
 to the file specified by the ``<DEP_FILE>`` placeholder, and write module
 to the file specified by the ``<DEP_FILE>`` placeholder, and write module
-dependencies to the file specified by the ``<DYNDEP_FILE>`` placeholder.
+dependencies to the file specified by the ``<DYNDEP_FILE>`` 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
 For tools which need to know the file set the source belongs to, the
 ``CMAKE_EXPERIMENTAL_CXX_MODULE_SOURCE_TYPE_FLAG_<FILE_SET_TYPE>`` flag may
 ``CMAKE_EXPERIMENTAL_CXX_MODULE_SOURCE_TYPE_FLAG_<FILE_SET_TYPE>`` flag may

+ 21 - 10
Source/cmNinjaTargetGenerator.cxx

@@ -586,6 +586,7 @@ std::string GetScanCommand(const std::string& cmakeCmd, const std::string& tdi,
 // not perform explicit preprocessing too.
 // not perform explicit preprocessing too.
 cmNinjaRule GetScanRule(
 cmNinjaRule GetScanRule(
   std::string const& ruleName, std::string const& ppFileName,
   std::string const& ruleName, std::string const& ppFileName,
+  std::string const& deptype,
   cmRulePlaceholderExpander::RuleVariables const& vars,
   cmRulePlaceholderExpander::RuleVariables const& vars,
   const std::string& responseFlag, const std::string& flags,
   const std::string& responseFlag, const std::string& flags,
   cmRulePlaceholderExpander* const rulePlaceholderExpander,
   cmRulePlaceholderExpander* const rulePlaceholderExpander,
@@ -594,8 +595,13 @@ cmNinjaRule GetScanRule(
 {
 {
   cmNinjaRule rule(ruleName);
   cmNinjaRule rule(ruleName);
   // Scanning always uses a depfile for preprocessor dependencies.
   // 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;
   cmRulePlaceholderExpander::RuleVariables scanVars;
   scanVars.CMTargetName = vars.CMTargetName;
   scanVars.CMTargetName = vars.CMTargetName;
@@ -699,6 +705,9 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
       cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
       cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
 
 
   if (needDyndep) {
   if (needDyndep) {
+    const auto& scanDepType = this->GetMakefile()->GetSafeDefinition(
+      cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_SCANDEP_DEPFILE_FORMAT"));
+
     // Rule to scan dependencies of sources that need preprocessing.
     // Rule to scan dependencies of sources that need preprocessing.
     {
     {
       std::vector<std::string> scanCommands;
       std::vector<std::string> scanCommands;
@@ -726,10 +735,10 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
                                                  "$DYNDEP_INTERMEDIATE_FILE"));
                                                  "$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 =
       scanRule.Comment =
         cmStrCat("Rule for generating ", lang, " dependencies.");
         cmStrCat("Rule for generating ", lang, " dependencies.");
@@ -757,9 +766,10 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
       scanCommands.emplace_back(
       scanCommands.emplace_back(
         GetScanCommand(cmakeCmd, tdi, lang, "$in", "$out"));
         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.
       // Write the rule for generating dependencies for the given language.
       scanRule.Comment = cmStrCat("Rule for generating ", lang,
       scanRule.Comment = cmStrCat("Rule for generating ", lang,
@@ -1249,7 +1259,8 @@ cmNinjaBuild GetScanBuildStatement(const std::string& ruleName,
     scanBuild.Variables["PREPROCESSED_OUTPUT_FILE"] = ppFileName;
     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");
   std::string const& depFileName = cmStrCat(scanBuild.Outputs.front(), ".d");
   scanBuild.Variables["DEP_FILE"] =
   scanBuild.Variables["DEP_FILE"] =
     lg->ConvertToOutputFormat(depFileName, cmOutputConverter::SHELL);
     lg->ConvertToOutputFormat(depFileName, cmOutputConverter::SHELL);