Browse Source

cmTransformDepfile: Add support for MSBuild AdditionalInputs format

Brad King 4 years ago
parent
commit
7291f31254

+ 6 - 0
Source/cmCustomCommandGenerator.cxx

@@ -230,6 +230,9 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(
       case cmDepfileFormat::MakeDepfile:
         argv.emplace_back("makedepfile");
         break;
+      case cmDepfileFormat::MSBuildAdditionalInputs:
+        argv.emplace_back("MSBuildAdditionalInputs");
+        break;
     }
     argv.push_back(this->LG->GetSourceDirectory());
     argv.push_back(this->LG->GetCurrentSourceDirectory());
@@ -437,6 +440,9 @@ std::string cmCustomCommandGenerator::GetInternalDepfileName(
     case cmDepfileFormat::MakeDepfile:
       extension = ".d";
       break;
+    case cmDepfileFormat::MSBuildAdditionalInputs:
+      extension = ".AdditionalInputs";
+      break;
   }
   return cmStrCat(this->LG->GetBinaryDirectory(), "/CMakeFiles/d/",
                   hash.HashString(depfile), extension);

+ 31 - 0
Source/cmTransformDepfile.cxx

@@ -2,7 +2,9 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmTransformDepfile.h"
 
+#include <algorithm>
 #include <functional>
+#include <memory>
 #include <string>
 #include <type_traits>
 #include <utility>
@@ -78,6 +80,32 @@ void WriteDepfile(cmDepfileFormat format, cmsys::ofstream& fout,
     }
   }
 }
+
+void WriteMSBuildAdditionalInputs(cmsys::ofstream& fout,
+                                  cmLocalGenerator const& lg,
+                                  cmGccDepfileContent const& content)
+{
+  if (content.empty()) {
+    return;
+  }
+
+  // Write a UTF-8 BOM so MSBuild knows the encoding when reading the file.
+  static const char utf8bom[] = { char(0xEF), char(0xBB), char(0xBF) };
+  fout.write(utf8bom, sizeof(utf8bom));
+
+  // Write the format expected by MSBuild CustomBuild AdditionalInputs.
+  const char* sep = "";
+  for (std::string path : content.front().paths) {
+    if (!cmSystemTools::FileIsFullPath(path)) {
+      path =
+        cmSystemTools::CollapseFullPath(path, lg.GetCurrentBinaryDirectory());
+    }
+    std::replace(path.begin(), path.end(), '/', '\\');
+    fout << sep << path;
+    sep = ";";
+  }
+  fout << "\n";
+}
 }
 
 bool cmTransformDepfile(cmDepfileFormat format, const cmLocalGenerator& lg,
@@ -103,6 +131,9 @@ bool cmTransformDepfile(cmDepfileFormat format, const cmLocalGenerator& lg,
     case cmDepfileFormat::MakeDepfile:
       WriteDepfile(format, fout, lg, content);
       break;
+    case cmDepfileFormat::MSBuildAdditionalInputs:
+      WriteMSBuildAdditionalInputs(fout, lg, content);
+      break;
   }
   return true;
 }

+ 2 - 1
Source/cmTransformDepfile.h

@@ -7,7 +7,8 @@
 enum class cmDepfileFormat
 {
   GccDepfile,
-  MakeDepfile
+  MakeDepfile,
+  MSBuildAdditionalInputs,
 };
 
 class cmLocalGenerator;

+ 2 - 0
Source/cmcmd.cxx

@@ -1531,6 +1531,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
         format = cmDepfileFormat::GccDepfile;
       } else if (args[3] == "makedepfile") {
         format = cmDepfileFormat::MakeDepfile;
+      } else if (args[3] == "MSBuildAdditionalInputs") {
+        format = cmDepfileFormat::MSBuildAdditionalInputs;
       } else {
         return 1;
       }