summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2016-07-21 15:27:31 (GMT)
committerCMake Topic Stage <kwrobot@kitware.com>2016-07-21 15:27:31 (GMT)
commitdbc0ec1648b493b237efd704bec38c757b6da5a5 (patch)
tree33a000928b0abfb6e7f06cbbf073403bb21c2d2d /Source
parent850764fc701ce9e1190d5bb20af97ec511763f0b (diff)
parentc7a7c655f0433c7ca4ea6ec5ce78b7f17cbf5140 (diff)
downloadCMake-dbc0ec1648b493b237efd704bec38c757b6da5a5.zip
CMake-dbc0ec1648b493b237efd704bec38c757b6da5a5.tar.gz
CMake-dbc0ec1648b493b237efd704bec38c757b6da5a5.tar.bz2
Merge topic 'makefile-response-files'
c7a7c655 Makefile: Avoid link line object list lengths nearing system limits 34ba5c53 Makefile: Factor out response file checks into common helper
Diffstat (limited to 'Source')
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx25
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx25
-rw-r--r--Source/cmMakefileTargetGenerator.cxx71
-rw-r--r--Source/cmMakefileTargetGenerator.h3
4 files changed, 82 insertions, 42 deletions
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 8730ccd..3b8bf5a 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -277,27 +277,10 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
}
}
- // Select whether to use a response file for objects.
- bool useResponseFileForObjects = false;
- {
- std::string responseVar = "CMAKE_";
- responseVar += linkLanguage;
- responseVar += "_USE_RESPONSE_FILE_FOR_OBJECTS";
- if (this->Makefile->IsOn(responseVar)) {
- useResponseFileForObjects = true;
- }
- }
-
- // Select whether to use a response file for libraries.
- bool useResponseFileForLibs = false;
- {
- std::string responseVar = "CMAKE_";
- responseVar += linkLanguage;
- responseVar += "_USE_RESPONSE_FILE_FOR_LIBRARIES";
- if (this->Makefile->IsOn(responseVar)) {
- useResponseFileForLibs = true;
- }
- }
+ bool useResponseFileForObjects =
+ this->CheckUseResponseFileForObjects(linkLanguage);
+ bool const useResponseFileForLibs =
+ this->CheckUseResponseFileForLibraries(linkLanguage);
// Expand the rule variables.
{
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 7de2db0..68f8ff1 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -429,27 +429,10 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
// Determine whether a link script will be used.
bool useLinkScript = this->GlobalGenerator->GetUseLinkScript();
- // Select whether to use a response file for objects.
- bool useResponseFileForObjects = false;
- {
- std::string responseVar = "CMAKE_";
- responseVar += linkLanguage;
- responseVar += "_USE_RESPONSE_FILE_FOR_OBJECTS";
- if (this->Makefile->IsOn(responseVar)) {
- useResponseFileForObjects = true;
- }
- }
-
- // Select whether to use a response file for libraries.
- bool useResponseFileForLibs = false;
- {
- std::string responseVar = "CMAKE_";
- responseVar += linkLanguage;
- responseVar += "_USE_RESPONSE_FILE_FOR_LIBRARIES";
- if (this->Makefile->IsOn(responseVar)) {
- useResponseFileForLibs = true;
- }
- }
+ bool useResponseFileForObjects =
+ this->CheckUseResponseFileForObjects(linkLanguage);
+ bool const useResponseFileForLibs =
+ this->CheckUseResponseFileForLibraries(linkLanguage);
// For static libraries there might be archiving rules.
bool haveStaticLibraryRule = false;
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 00b1219..e12fc09 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -31,6 +31,10 @@
#include <ctype.h>
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+
cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmGeneratorTarget* target)
: cmCommonTargetGenerator(target)
, OSXBundleGenerator(CM_NULLPTR)
@@ -1447,6 +1451,73 @@ void cmMakefileTargetGenerator::CreateLinkScript(
makefile_depends.push_back(linkScriptName);
}
+static size_t calculateCommandLineLengthLimit()
+{
+#if defined(_SC_ARG_MAX)
+ return ((size_t)sysconf(_SC_ARG_MAX)) - 1000;
+#else
+ return 0;
+#endif
+}
+
+bool cmMakefileTargetGenerator::CheckUseResponseFileForObjects(
+ std::string const& l) const
+{
+ // Check for an explicit setting one way or the other.
+ std::string const responseVar =
+ "CMAKE_" + l + "_USE_RESPONSE_FILE_FOR_OBJECTS";
+ if (const char* val = this->Makefile->GetDefinition(responseVar)) {
+ if (*val) {
+ return cmSystemTools::IsOn(val);
+ }
+ }
+
+ // Check for a system limit.
+ if (size_t const limit = calculateCommandLineLengthLimit()) {
+ // Compute the total length of our list of object files with room
+ // for argument separation and quoting. This does not convert paths
+ // relative to START_OUTPUT like the final list will be, so the actual
+ // list will likely be much shorter than this. However, in the worst
+ // case all objects will remain as absolute paths.
+ size_t length = 0;
+ for (std::vector<std::string>::const_iterator i = this->Objects.begin();
+ i != this->Objects.end(); ++i) {
+ length += i->size() + 3;
+ }
+ for (std::vector<std::string>::const_iterator i =
+ this->ExternalObjects.begin();
+ i != this->ExternalObjects.end(); ++i) {
+ length += i->size() + 3;
+ }
+
+ // We need to guarantee room for both objects and libraries, so
+ // if the objects take up more than half then use a response file
+ // for them.
+ if (length > (limit / 2)) {
+ return true;
+ }
+ }
+
+ // We do not need a response file for objects.
+ return false;
+}
+
+bool cmMakefileTargetGenerator::CheckUseResponseFileForLibraries(
+ std::string const& l) const
+{
+ // Check for an explicit setting one way or the other.
+ std::string const responseVar =
+ "CMAKE_" + l + "_USE_RESPONSE_FILE_FOR_LIBRARIES";
+ if (const char* val = this->Makefile->GetDefinition(responseVar)) {
+ if (*val) {
+ return cmSystemTools::IsOn(val);
+ }
+ }
+
+ // We do not need a response file for libraries.
+ return false;
+}
+
std::string cmMakefileTargetGenerator::CreateResponseFile(
const char* name, std::string const& options,
std::vector<std::string>& makefile_depends)
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index 4284549..29b8887 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -151,6 +151,9 @@ protected:
std::string CreateResponseFile(const char* name, std::string const& options,
std::vector<std::string>& makefile_depends);
+ bool CheckUseResponseFileForObjects(std::string const& l) const;
+ bool CheckUseResponseFileForLibraries(std::string const& l) const;
+
/** Create list of flags for link libraries. */
void CreateLinkLibs(std::string& linkLibs, bool relink, bool useResponseFile,
std::vector<std::string>& makefile_depends,