diff options
author | Brad King <brad.king@kitware.com> | 2008-02-27 22:10:45 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2008-02-27 22:10:45 (GMT) |
commit | dfe2ea6406d3ab22f1a4193906611fb67fd3ab6e (patch) | |
tree | e00166515d5fe978ef5fe0dd15852790145951e0 | |
parent | 4c137bad6b663ff342064c293a49fecf03498207 (diff) | |
download | CMake-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.cmake | 6 | ||||
-rw-r--r-- | Modules/Platform/cl.cmake | 9 | ||||
-rw-r--r-- | Source/cmDocumentVariables.cxx | 2 | ||||
-rw-r--r-- | Source/cmMakefileExecutableTargetGenerator.cxx | 25 | ||||
-rw-r--r-- | Source/cmMakefileLibraryTargetGenerator.cxx | 28 | ||||
-rw-r--r-- | Source/cmMakefileTargetGenerator.cxx | 24 | ||||
-rw-r--r-- | Source/cmMakefileTargetGenerator.h | 7 |
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); |