summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2008-02-27 22:10:45 (GMT)
committerBrad King <brad.king@kitware.com>2008-02-27 22:10:45 (GMT)
commitdfe2ea6406d3ab22f1a4193906611fb67fd3ab6e (patch)
treee00166515d5fe978ef5fe0dd15852790145951e0
parent4c137bad6b663ff342064c293a49fecf03498207 (diff)
downloadCMake-dfe2ea6406d3ab22f1a4193906611fb67fd3ab6e.zip
CMake-dfe2ea6406d3ab22f1a4193906611fb67fd3ab6e.tar.gz
CMake-dfe2ea6406d3ab22f1a4193906611fb67fd3ab6e.tar.bz2
ENH: Handle large object file lists on some platforms
- Use a response file when enabled by CMAKE_<LANG>_USE_RESPONSE_FILE_FOR_OBJECTS - Enable for C and CXX with cl (MSVC) - Enable for Fortran with ifort (Intel Fortran)
-rw-r--r--Modules/Platform/Windows-ifort.cmake6
-rw-r--r--Modules/Platform/cl.cmake9
-rw-r--r--Source/cmDocumentVariables.cxx2
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx25
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx28
-rw-r--r--Source/cmMakefileTargetGenerator.cxx24
-rw-r--r--Source/cmMakefileTargetGenerator.h7
7 files changed, 93 insertions, 8 deletions
diff --git a/Modules/Platform/Windows-ifort.cmake b/Modules/Platform/Windows-ifort.cmake
index 7ea5581..295fa3e 100644
--- a/Modules/Platform/Windows-ifort.cmake
+++ b/Modules/Platform/Windows-ifort.cmake
@@ -9,8 +9,10 @@ ENDIF(CMAKE_VERBOSE_MAKEFILE)
SET(CMAKE_Fortran_MODDIR_FLAG "-module:")
+SET(CMAKE_Fortran_USE_RESPONSE_FILE_FOR_OBJECTS 1)
+
SET(CMAKE_Fortran_CREATE_SHARED_LIBRARY
- "link ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} /out:<TARGET> /dll <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
+ "link ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /dll <LINK_FLAGS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
SET(CMAKE_Fortran_CREATE_SHARED_MODULE ${CMAKE_Fortran_CREATE_SHARED_LIBRARY})
@@ -24,7 +26,7 @@ SET(CMAKE_Fortran_COMPILE_OBJECT
SET(CMAKE_COMPILE_RESOURCE "rc <FLAGS> /fo<OBJECT> <SOURCE>")
SET(CMAKE_Fortran_LINK_EXECUTABLE
- "<CMAKE_Fortran_COMPILER> ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} <FLAGS> <OBJECTS> /Fe<TARGET> -link <CMAKE_Fortran_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
+ "<CMAKE_Fortran_COMPILER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} <FLAGS> /Fe<TARGET> -link <CMAKE_Fortran_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
SET(CMAKE_CREATE_WIN32_EXE /subsystem:windows)
SET(CMAKE_CREATE_CONSOLE_EXE /subsystem:console)
diff --git a/Modules/Platform/cl.cmake b/Modules/Platform/cl.cmake
index 6afb73f..c0f014b 100644
--- a/Modules/Platform/cl.cmake
+++ b/Modules/Platform/cl.cmake
@@ -17,7 +17,7 @@ ELSE(CMAKE_VERBOSE_MAKEFILE)
ENDIF(CMAKE_VERBOSE_MAKEFILE)
# create a shared C++ library
SET(CMAKE_CXX_CREATE_SHARED_LIBRARY
- "<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /dll /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
+ "<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /dll /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <LINK_FLAGS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
SET(CMAKE_CXX_CREATE_SHARED_MODULE ${CMAKE_CXX_CREATE_SHARED_LIBRARY})
# create a C shared library
@@ -40,12 +40,13 @@ SET(CMAKE_CXX_COMPILE_OBJECT
SET(CMAKE_C_COMPILE_OBJECT
"<CMAKE_C_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO} <FLAGS> <DEFINES> /Fo<OBJECT> /Fd<TARGET_PDB> -c <SOURCE>${CMAKE_END_TEMP_FILE}")
-
+SET(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1)
SET(CMAKE_C_LINK_EXECUTABLE
- "<CMAKE_C_COMPILER> ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} <FLAGS> <OBJECTS> /Fe<TARGET> /Fd<TARGET_PDB> -link /implib:<TARGET_IMPLIB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
+ "<CMAKE_C_COMPILER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} <FLAGS> /Fe<TARGET> /Fd<TARGET_PDB> -link /implib:<TARGET_IMPLIB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
+SET(CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS 1)
SET(CMAKE_CXX_LINK_EXECUTABLE
- "<CMAKE_CXX_COMPILER> ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} <FLAGS> <OBJECTS> /Fe<TARGET> /Fd<TARGET_PDB> -link /implib:<TARGET_IMPLIB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
+ "<CMAKE_CXX_COMPILER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} <FLAGS> /Fe<TARGET> /Fd<TARGET_PDB> -link /implib:<TARGET_IMPLIB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
SET(CMAKE_C_CREATE_PREPROCESSED_SOURCE
"<CMAKE_C_COMPILER> > <PREPROCESSED_SOURCE> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO} <FLAGS> <DEFINES> -E <SOURCE>${CMAKE_END_TEMP_FILE}")
diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx
index 4466a0f..0a54849 100644
--- a/Source/cmDocumentVariables.cxx
+++ b/Source/cmDocumentVariables.cxx
@@ -1059,6 +1059,8 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_<LANG>_STANDARD_LIBRARIES_INIT",
cmProperty::VARIABLE,0,0);
+ cm->DefineProperty("CMAKE_<LANG>_USE_RESPONSE_FILE_FOR_OBJECTS",
+ cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_EXECUTABLE_SUFFIX_<LANG>",
cmProperty::VARIABLE,0,0);
cm->DefineProperty("CMAKE_EXE_LINK_DYNAMIC_<LANG>_FLAGS",
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 9e8d42d..1715fe9 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -328,6 +328,18 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
}
}
+ // Select whether to use a response file for objects.
+ bool useResponseFile = false;
+ {
+ std::string responseVar = "CMAKE_";
+ responseVar += linkLanguage;
+ responseVar += "_USE_RESPONSE_FILE_FOR_OBJECTS";
+ if(this->Makefile->IsOn(responseVar.c_str()))
+ {
+ useResponseFile = true;
+ }
+ }
+
// Expand the rule variables.
{
// Set path conversion for link script shells.
@@ -343,7 +355,18 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
std::string variableNameExternal;
this->WriteObjectsVariable(variableName, variableNameExternal);
std::string buildObjs;
- if(useLinkScript)
+ if(useResponseFile)
+ {
+ std::string objects;
+ this->WriteObjectsString(objects);
+ std::string objects_rsp =
+ this->CreateResponseFile("objects.rsp", objects, depends);
+ buildObjs = "@";
+ buildObjs += this->Convert(objects_rsp.c_str(),
+ cmLocalGenerator::NONE,
+ cmLocalGenerator::SHELL);
+ }
+ else if(useLinkScript)
{
this->WriteObjectsString(buildObjs);
}
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index dd4c9eb..1c7f108 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -567,6 +567,18 @@ 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 useResponseFile = false;
+ {
+ std::string responseVar = "CMAKE_";
+ responseVar += linkLanguage;
+ responseVar += "_USE_RESPONSE_FILE_FOR_OBJECTS";
+ if(this->Makefile->IsOn(responseVar.c_str()))
+ {
+ useResponseFile = true;
+ }
+ }
+
// For static libraries there might be archiving rules.
std::vector<std::string> archiveCreateCommands;
std::vector<std::string> archiveAppendCommands;
@@ -605,6 +617,9 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
// Archiving rules are always run with a link script.
useLinkScript = true;
+ // Archiving rules never use a response file.
+ useResponseFile = false;
+
// Limit the length of individual object lists to less than the
// 32K command line length limit on Windows. We could make this a
// platform file variable but this should work everywhere.
@@ -631,7 +646,18 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
std::string variableNameExternal;
this->WriteObjectsVariable(variableName, variableNameExternal);
std::string buildObjs;
- if(useLinkScript)
+ if(useResponseFile)
+ {
+ std::string objects;
+ this->WriteObjectsString(objects);
+ std::string objects_rsp =
+ this->CreateResponseFile("objects.rsp", objects, depends);
+ buildObjs = "@";
+ buildObjs += this->Convert(objects_rsp.c_str(),
+ cmLocalGenerator::NONE,
+ cmLocalGenerator::SHELL);
+ }
+ else if(useLinkScript)
{
if(!useArchiveRules)
{
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index f268ddf..b15410b 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -1584,6 +1584,30 @@ cmMakefileTargetGenerator
}
//----------------------------------------------------------------------------
+std::string
+cmMakefileTargetGenerator
+::CreateResponseFile(const char* name, std::string const& options,
+ std::vector<std::string>& makefile_depends)
+{
+ // Create the response file.
+ std::string responseFileNameFull = this->TargetBuildDirectoryFull;
+ responseFileNameFull += "/";
+ responseFileNameFull += name;
+ cmGeneratedFileStream responseStream(responseFileNameFull.c_str());
+ responseStream << options << "\n";
+
+ // Add a dependency so the target will rebuild when the set of
+ // objects changes.
+ makefile_depends.push_back(responseFileNameFull);
+
+ // Construct the name to be used on the command line.
+ std::string responseFileName = this->TargetBuildDirectory;
+ responseFileName += "/";
+ responseFileName += name;
+ return responseFileName;
+}
+
+//----------------------------------------------------------------------------
const char* cmMakefileTargetGenerator::GetFortranModuleDirectory()
{
// Compute the module directory.
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index 1039f3d..3a6ec0d 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -137,6 +137,13 @@ protected:
std::vector<std::string>& makefile_commands,
std::vector<std::string>& makefile_depends);
+ /** Create a response file with the given set of options. Returns
+ the relative path from the target build working directory to the
+ response file name. */
+ std::string CreateResponseFile(const char* name,
+ std::string const& options,
+ std::vector<std::string>& makefile_depends);
+
virtual void CloseFileStreams();
void RemoveForbiddenFlags(const char* flagVar, const char* linkLang,
std::string& linkFlags);