Forráskód Böngészése

Merge topic 'ninja-dyndep-response-file'

594d3d6f Ninja: support response file for cmake_ninja_depends on Windows

Acked-by: Kitware Robot <[email protected]>
Merge-request: !722
Brad King 8 éve
szülő
commit
74672e2ffa

+ 5 - 1
Source/cmGlobalNinjaGenerator.cxx

@@ -1842,10 +1842,14 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
 int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
                              std::vector<std::string>::const_iterator argEnd)
 {
+  std::vector<std::string> arg_full =
+    cmSystemTools::HandleResponseFile(argBeg, argEnd);
+
   std::string arg_dd;
   std::string arg_tdi;
   std::vector<std::string> arg_ddis;
-  for (std::vector<std::string>::const_iterator a = argBeg; a != argEnd; ++a) {
+  for (std::vector<std::string>::const_iterator a = arg_full.begin();
+       a != arg_full.end(); ++a) {
     std::string const& arg = *a;
     if (cmHasLiteralPrefix(arg, "--tdi=")) {
       arg_tdi = arg.substr(6);

+ 15 - 4
Source/cmNinjaTargetGenerator.cxx

@@ -557,13 +557,26 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
     // Write the rule for ninja dyndep file generation.
     std::vector<std::string> ddCmds;
 
+#ifdef _WIN32
+    // Windows command line length is limited -> use response file for dyndep
+    // rules
+    std::string ddRspFile = "$out.rsp";
+    std::string ddRspContent = "$in";
+    std::string ddInput = "@" + ddRspFile;
+#else
+    std::string ddRspFile;
+    std::string ddRspContent;
+    std::string ddInput = "$in";
+#endif
+
     // Run CMake dependency scanner on preprocessed output.
     std::string const cmake = this->GetLocalGenerator()->ConvertToOutputFormat(
       cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
     ddCmds.push_back(cmake + " -E cmake_ninja_dyndep"
                              " --tdi=" +
                      tdi + " --dd=$out"
-                           " $in");
+                           " " +
+                     ddInput);
 
     std::string const ddCmdLine =
       this->GetLocalGenerator()->BuildCommandLine(ddCmds);
@@ -575,9 +588,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
     this->GetGlobalGenerator()->AddRule(
       this->LanguageDyndepRule(lang), ddCmdLine, ddDesc.str(), ddComment.str(),
       /*depfile*/ "",
-      /*deps*/ "",
-      /*rspfile*/ "",
-      /*rspcontent*/ "",
+      /*deps*/ "", ddRspFile, ddRspContent,
       /*restat*/ "",
       /*generator*/ false);
   }

+ 33 - 0
Source/cmSystemTools.cxx

@@ -505,6 +505,39 @@ void cmSystemTools::ParseUnixCommandLine(const char* command,
   argv.Store(args);
 }
 
+std::vector<std::string> cmSystemTools::HandleResponseFile(
+  std::vector<std::string>::const_iterator argBeg,
+  std::vector<std::string>::const_iterator argEnd)
+{
+  std::vector<std::string> arg_full;
+  for (std::vector<std::string>::const_iterator a = argBeg; a != argEnd; ++a) {
+    std::string const& arg = *a;
+    if (cmHasLiteralPrefix(arg, "@")) {
+      cmsys::ifstream responseFile(arg.substr(1).c_str(), std::ios::in);
+      if (!responseFile) {
+        std::string error = "failed to open for reading (";
+        error += cmSystemTools::GetLastSystemError();
+        error += "):\n  ";
+        error += arg.substr(1);
+        cmSystemTools::Error(error.c_str());
+      } else {
+        std::string line;
+        cmSystemTools::GetLineFromStream(responseFile, line);
+        std::vector<std::string> args2;
+#ifdef _WIN32
+        cmSystemTools::ParseWindowsCommandLine(line.c_str(), args2);
+#else
+        cmSystemTools::ParseUnixCommandLine(line.c_str(), args2);
+#endif
+        arg_full.insert(arg_full.end(), args2.begin(), args2.end());
+      }
+    } else {
+      arg_full.push_back(arg);
+    }
+  }
+  return arg_full;
+}
+
 std::vector<std::string> cmSystemTools::ParseArguments(const char* command)
 {
   std::vector<std::string> args;

+ 7 - 0
Source/cmSystemTools.h

@@ -253,6 +253,13 @@ public:
   static void ParseUnixCommandLine(const char* command,
                                    std::vector<std::string>& args);
 
+  /**
+   * Handle response file in an argument list and return a new argument list
+   * **/
+  static std::vector<std::string> HandleResponseFile(
+    std::vector<std::string>::const_iterator argBeg,
+    std::vector<std::string>::const_iterator argEnd);
+
   static size_t CalculateCommandLineLengthLimit();
 
   static void EnableMessages() { s_DisableMessages = false; }