summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx6
-rw-r--r--Source/cmNinjaTargetGenerator.cxx19
-rw-r--r--Source/cmSystemTools.cxx33
-rw-r--r--Source/cmSystemTools.h7
4 files changed, 60 insertions, 5 deletions
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 1a77d7ce0a..587e18a081 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/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);
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index e0b2217b78..7e29681d60 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/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);
}
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 6d620d9f0f..8978e1855c 100644
--- a/Source/cmSystemTools.cxx
+++ b/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;
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index d0902b1f9f..9de7967287 100644
--- a/Source/cmSystemTools.h
+++ b/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; }