diff options
-rw-r--r-- | Modules/Platform/Windows-GNU.cmake | 4 | ||||
-rw-r--r-- | Source/cmGlobalNinjaGenerator.cxx | 20 | ||||
-rw-r--r-- | Source/cmGlobalNinjaGenerator.h | 14 | ||||
-rw-r--r-- | Source/cmNinjaNormalTargetGenerator.cxx | 40 |
4 files changed, 54 insertions, 24 deletions
diff --git a/Modules/Platform/Windows-GNU.cmake b/Modules/Platform/Windows-GNU.cmake index 1a2ee5e..4a37eca 100644 --- a/Modules/Platform/Windows-GNU.cmake +++ b/Modules/Platform/Windows-GNU.cmake @@ -115,7 +115,9 @@ macro(__windows_compiler_gnu lang) list(APPEND CMAKE_${lang}_ABI_FILES "Platform/Windows-GNU-${lang}-ABI") # Support very long lists of object files. - if("${CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG}" STREQUAL "@") + # TODO: check for which gcc versions this is still needed, not needed for gcc >= 4.4. + # Ninja generator doesn't support this work around. + if("${CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG}" STREQUAL "@" AND NOT CMAKE_GENERATOR MATCHES "Ninja") foreach(rule CREATE_SHARED_MODULE CREATE_SHARED_LIBRARY LINK_EXECUTABLE) # The gcc/collect2/ld toolchain does not use response files # internally so we cannot pass long object lists. Instead pass diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 9829d19..07cc75f 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -217,6 +217,7 @@ void cmGlobalNinjaGenerator::AddCustomCommandRule() "Rule for running custom commands.", /*depfile*/ "", /*rspfile*/ "", + /*rspcontent*/ "", /*restat*/ true); } @@ -258,6 +259,7 @@ void cmGlobalNinjaGenerator::WriteRule(std::ostream& os, const std::string& comment, const std::string& depfile, const std::string& rspfile, + const std::string& rspcontent, bool restat, bool generator) { @@ -304,10 +306,15 @@ void cmGlobalNinjaGenerator::WriteRule(std::ostream& os, if(!rspfile.empty()) { - cmGlobalNinjaGenerator::Indent(os, 1); - os << "rspfile = " << rspfile << "\n"; - cmGlobalNinjaGenerator::Indent(os, 1); - os << "rspfile_content = $in" << "\n"; + if (rspcontent.empty()) + { + cmSystemTools::Error("No rspfile_content given!", comment.c_str()); + return; + } + cmGlobalNinjaGenerator::Indent(os, 1); + os << "rspfile = " << rspfile << "\n"; + cmGlobalNinjaGenerator::Indent(os, 1); + os << "rspfile_content = " << rspcontent << "\n"; } if(restat) @@ -538,6 +545,7 @@ void cmGlobalNinjaGenerator::AddRule(const std::string& name, const std::string& comment, const std::string& depfile, const std::string& rspfile, + const std::string& rspcontent, bool restat, bool generator) { @@ -555,6 +563,7 @@ void cmGlobalNinjaGenerator::AddRule(const std::string& name, comment, depfile, rspfile, + rspcontent, restat, generator); @@ -911,6 +920,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) "Rule for re-running cmake.", /*depfile=*/ "", /*rspfile=*/ "", + /*rspcontent*/ "", /*restat=*/ false, /*generator=*/ true); @@ -960,6 +970,7 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os) "Rule for cleaning all built files.", /*depfile=*/ "", /*rspfile=*/ "", + /*rspcontent*/ "", /*restat=*/ false, /*generator=*/ false); WriteBuild(os, @@ -981,6 +992,7 @@ void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os) "Rule for printing all primary targets available.", /*depfile=*/ "", /*rspfile=*/ "", + /*rspcontent*/ "", /*restat=*/ false, /*generator=*/ false); WriteBuild(os, diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index e5f8099..ff4f85d 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -114,11 +114,12 @@ public: const std::string& name, const std::string& command, const std::string& description, - const std::string& comment = "", - const std::string& depfile = "", - const std::string& rspfile = "" , - bool restat = false, - bool generator = false); + const std::string& comment, + const std::string& depfile, + const std::string& rspfile, + const std::string& rspcontent, + bool restat, + bool generator); /** * Write a variable named @a name to @a os with value @a value and an @@ -231,9 +232,10 @@ public: void AddRule(const std::string& name, const std::string& command, const std::string& description, - const std::string& comment = "", + const std::string& comment, const std::string& depfile = "", const std::string& rspfile = "", + const std::string& rspcontent = "", bool restat = false, bool generator = false); diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 0cf90aa..be7739e 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -18,6 +18,12 @@ #include "cmMakefile.h" #include <assert.h> +#include <algorithm> + +#ifndef _WIN32 +#include <unistd.h> +#endif + cmNinjaNormalTargetGenerator:: cmNinjaNormalTargetGenerator(cmTarget* target) @@ -75,10 +81,8 @@ void cmNinjaNormalTargetGenerator::Generate() } else { - this->WriteLinkRule(false); -#ifdef _WIN32 // TODO response file support only Linux - this->WriteLinkRule(true); -#endif + this->WriteLinkRule(false); // write rule without rspfile support + this->WriteLinkRule(true); // write rule with rspfile support this->WriteLinkStatement(); } } @@ -140,6 +144,7 @@ cmNinjaNormalTargetGenerator // Select whether to use a response file for objects. std::string rspfile; + std::string rspcontent; if (!this->GetGlobalGenerator()->HasRule(ruleName)) { cmLocalGenerator::RuleVariables vars; @@ -150,6 +155,7 @@ cmNinjaNormalTargetGenerator std::string responseFlag; if (!useResponseFile) { vars.Objects = "$in"; + vars.LinkLibraries = "$LINK_LIBRARIES"; } else { // handle response file std::string cmakeLinkVar = std::string("CMAKE_") + @@ -162,7 +168,9 @@ cmNinjaNormalTargetGenerator } rspfile = "$out.rsp"; responseFlag += rspfile; + rspcontent = "$in $LINK_LIBRARIES"; vars.Objects = responseFlag.c_str(); + vars.LinkLibraries = ""; } vars.ObjectDir = "$OBJECT_DIR"; @@ -189,7 +197,6 @@ cmNinjaNormalTargetGenerator vars.TargetVersionMajor = targetVersionMajor.c_str(); vars.TargetVersionMinor = targetVersionMinor.c_str(); - vars.LinkLibraries = "$LINK_LIBRARIES"; vars.Flags = "$FLAGS"; vars.LinkFlags = "$LINK_FLAGS"; @@ -227,7 +234,8 @@ cmNinjaNormalTargetGenerator description.str(), comment.str(), /*depfile*/ "", - rspfile); + rspfile, + rspcontent); } if (this->TargetNameOut != this->TargetNameReal) { @@ -365,8 +373,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() outputs.push_back(targetOutputReal); // Compute specific libraries to link with. - cmNinjaDeps explicitDeps = this->GetObjects(), - implicitDeps = this->ComputeLinkDeps(); + cmNinjaDeps explicitDeps = this->GetObjects(); + cmNinjaDeps implicitDeps = this->ComputeLinkDeps(); this->GetLocalGenerator()->GetTargetFlags(vars["LINK_LIBRARIES"], vars["FLAGS"], @@ -432,6 +440,9 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() path = GetTarget()->GetSupportDirectory(); vars["OBJECT_DIR"] = ConvertToNinjaPath(path.c_str()); EnsureDirectoryExists(path); + // ar.exe can't handle backslashes in rsp files (implictly used by gcc) + std::string& linkLibraries = vars["LINK_LIBRARIES"]; + std::replace(linkLibraries.begin(), linkLibraries.end(), '\\', '/'); } std::vector<cmCustomCommand> *cmdLists[3] = { @@ -478,12 +489,15 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() symlinkVars["POST_BUILD"] = postBuildCmdLine; } - int cmdLineLimit; -#ifdef _WIN32 - cmdLineLimit = 8000 - this->GetGlobalGenerator()-> + int linkRuleLength = this->GetGlobalGenerator()-> GetRuleCmdLength(this->LanguageLinkerRule()); +#ifdef _WIN32 + int commandLineLengthLimit = 8000 - linkRuleLength; +#elif defined(__linux) || defined(__APPLE__) + // for instance ARG_MAX is 2096152 on Ubuntu or 262144 on Mac + int commandLineLengthLimit = sysconf(_SC_ARG_MAX) - linkRuleLength - 1000; #else - cmdLineLimit = -1; // TODO + int commandLineLengthLimit = -1; #endif // Write the build statement for this target. @@ -495,7 +509,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() implicitDeps, emptyDeps, vars, - cmdLineLimit); + commandLineLengthLimit); if (targetOutput != targetOutputReal) { if (targetType == cmTarget::EXECUTABLE) { |