From c87517099abbef70b9718a3920954e9097f36bbe Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 4 Mar 2014 11:20:27 -0500 Subject: Makefile: Factor out some duplicate link libraries generation The generators for executable and library targets duplicate the logic to call the OutputLinkLibraries helper on the local generator. Factor it out into a cmMakefileTargetGenerator::CreateLinkLibs method to avoid dpulication. --- Source/cmMakefileExecutableTargetGenerator.cxx | 8 ++------ Source/cmMakefileLibraryTargetGenerator.cxx | 7 +------ Source/cmMakefileTargetGenerator.cxx | 14 ++++++++++++++ Source/cmMakefileTargetGenerator.h | 4 ++++ 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index 03fdda2..696ce94 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -325,12 +325,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) // Collect up flags to link in needed libraries. std::string linkLibs; - std::string frameworkPath; - std::string linkPath; - this->LocalGenerator->OutputLinkLibraries(linkLibs, frameworkPath, linkPath, - *this->GeneratorTarget, - relink); - linkLibs = frameworkPath + linkPath + linkLibs; + this->CreateLinkLibs(linkLibs, relink, depends); + // Construct object file lists that may be needed to expand the // rule. std::string buildObjs; diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 807aca8..2832515 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -546,12 +546,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules std::string linkLibs; if(this->Target->GetType() != cmTarget::STATIC_LIBRARY) { - std::string frameworkPath; - std::string linkPath; - this->LocalGenerator - ->OutputLinkLibraries(linkLibs, frameworkPath, linkPath, - *this->GeneratorTarget, relink); - linkLibs = frameworkPath + linkPath + linkLibs; + this->CreateLinkLibs(linkLibs, relink, depends); } // Construct object file lists that may be needed to expand the diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index e8a9fd1..e5b163b 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -1833,6 +1833,20 @@ cmMakefileTargetGenerator //---------------------------------------------------------------------------- void cmMakefileTargetGenerator +::CreateLinkLibs(std::string& linkLibs, bool relink, + std::vector& makefile_depends) +{ + std::string frameworkPath; + std::string linkPath; + this->LocalGenerator + ->OutputLinkLibraries(linkLibs, frameworkPath, linkPath, + *this->GeneratorTarget, relink); + linkLibs = frameworkPath + linkPath + linkLibs; +} + +//---------------------------------------------------------------------------- +void +cmMakefileTargetGenerator ::CreateObjectLists(bool useLinkScript, bool useArchiveRules, bool useResponseFile, std::string& buildObjs, std::vector& makefile_depends) diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index 4f8fafa..d47708d 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -163,6 +163,10 @@ protected: std::string const& options, std::vector& makefile_depends); + /** Create list of flags for link libraries. */ + void CreateLinkLibs(std::string& linkLibs, bool relink, + std::vector& makefile_depends); + /** Create lists of object files for linking and cleaning. */ void CreateObjectLists(bool useLinkScript, bool useArchiveRules, bool useResponseFile, std::string& buildObjs, -- cgit v0.12 From 02bebd60e9255b6e3eb4bbd6208b4c5cd8f5da40 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 4 Mar 2014 12:57:44 -0500 Subject: cmLocalGenerator: Add format option to ConvertToOutputForExisting Replace the hard-coded SHELL output format with an optional argument. --- Source/cmLocalGenerator.cxx | 19 +++++++++++-------- Source/cmLocalGenerator.h | 9 ++++++--- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 4266dd0..87685d5 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1228,7 +1228,8 @@ void cmLocalGenerator::InsertRuleLauncher(std::string& s, cmTarget* target, //---------------------------------------------------------------------------- std::string cmLocalGenerator::ConvertToOutputForExistingCommon(const char* remote, - std::string const& result) + std::string const& result, + OutputFormat format) { // If this is a windows shell, the result has a space, and the path // already exists, we can use a short-path to reference it without a @@ -1239,7 +1240,7 @@ cmLocalGenerator::ConvertToOutputForExistingCommon(const char* remote, std::string tmp; if(cmSystemTools::GetShortPath(remote, tmp)) { - return this->Convert(tmp.c_str(), NONE, SHELL, true); + return this->Convert(tmp.c_str(), NONE, format, true); } } @@ -1250,26 +1251,28 @@ cmLocalGenerator::ConvertToOutputForExistingCommon(const char* remote, //---------------------------------------------------------------------------- std::string cmLocalGenerator::ConvertToOutputForExisting(const char* remote, - RelativeRoot local) + RelativeRoot local, + OutputFormat format) { // Perform standard conversion. - std::string result = this->Convert(remote, local, SHELL, true); + std::string result = this->Convert(remote, local, format, true); // Consider short-path. - return this->ConvertToOutputForExistingCommon(remote, result); + return this->ConvertToOutputForExistingCommon(remote, result, format); } //---------------------------------------------------------------------------- std::string cmLocalGenerator::ConvertToOutputForExisting(RelativeRoot remote, - const char* local) + const char* local, + OutputFormat format) { // Perform standard conversion. - std::string result = this->Convert(remote, local, SHELL, true); + std::string result = this->Convert(remote, local, format, true); // Consider short-path. const char* remotePath = this->GetRelativeRootPath(remote); - return this->ConvertToOutputForExistingCommon(remotePath, result); + return this->ConvertToOutputForExistingCommon(remotePath, result, format); } //---------------------------------------------------------------------------- diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 0f7fd25..9e47120 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -198,12 +198,14 @@ public: ///! for existing files convert to output path and short path if spaces std::string ConvertToOutputForExisting(const char* remote, - RelativeRoot local = START_OUTPUT); + RelativeRoot local = START_OUTPUT, + OutputFormat format = SHELL); /** For existing path identified by RelativeRoot convert to output path and short path if spaces. */ std::string ConvertToOutputForExisting(RelativeRoot remote, - const char* local = 0); + const char* local = 0, + OutputFormat format = SHELL); virtual std::string ConvertToIncludeReference(std::string const& path); @@ -465,7 +467,8 @@ protected: bool BackwardsCompatibilityFinal; private: std::string ConvertToOutputForExistingCommon(const char* remote, - std::string const& result); + std::string const& result, + OutputFormat format); void AddSharedFlags(std::string& flags, const char* lang, bool shared); bool GetShouldUseOldFlags(bool shared, const std::string &lang) const; -- cgit v0.12 From 0c0ef9e7b7016f8ce6310c30660151b15e062a93 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 4 Mar 2014 13:04:02 -0500 Subject: cmLocalGenerator: Add format option to ConvertToIncludeReference Replace the hard-coded SHELL output format with an optional argument. --- Source/cmLocalGenerator.cxx | 5 +++-- Source/cmLocalGenerator.h | 3 ++- Source/cmLocalNinjaGenerator.cxx | 5 +++-- Source/cmLocalNinjaGenerator.h | 3 ++- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 87685d5..2090cc6 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1277,9 +1277,10 @@ cmLocalGenerator::ConvertToOutputForExisting(RelativeRoot remote, //---------------------------------------------------------------------------- std::string -cmLocalGenerator::ConvertToIncludeReference(std::string const& path) +cmLocalGenerator::ConvertToIncludeReference(std::string const& path, + OutputFormat format) { - return this->ConvertToOutputForExisting(path.c_str()); + return this->ConvertToOutputForExisting(path.c_str(), START_OUTPUT, format); } //---------------------------------------------------------------------------- diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 9e47120..986f405 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -207,7 +207,8 @@ public: const char* local = 0, OutputFormat format = SHELL); - virtual std::string ConvertToIncludeReference(std::string const& path); + virtual std::string ConvertToIncludeReference(std::string const& path, + OutputFormat format = SHELL); /** Called from command-line hook to clear dependencies. */ virtual void ClearDependencies(cmMakefile* /* mf */, diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index cd12c9d..c989cfb 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -149,9 +149,10 @@ cmLocalNinjaGenerator::ConvertToLinkReference(std::string const& lib) } std::string -cmLocalNinjaGenerator::ConvertToIncludeReference(std::string const& path) +cmLocalNinjaGenerator::ConvertToIncludeReference(std::string const& path, + OutputFormat format) { - return this->Convert(path.c_str(), HOME_OUTPUT, SHELL); + return this->Convert(path.c_str(), HOME_OUTPUT, format); } //---------------------------------------------------------------------------- diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h index ea854c6..b3d3b6b 100644 --- a/Source/cmLocalNinjaGenerator.h +++ b/Source/cmLocalNinjaGenerator.h @@ -101,7 +101,8 @@ public: protected: - virtual std::string ConvertToIncludeReference(std::string const& path); + virtual std::string ConvertToIncludeReference(std::string const& path, + OutputFormat format = SHELL); private: -- cgit v0.12 From 971653b767f2e5e81085c525c94d5e596474aa88 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 4 Mar 2014 13:06:29 -0500 Subject: cmLocalGenerator: Add format option to ConvertToLinkReference Replace the hard-coded SHELL output format with an optional argument. --- Source/cmLocalGenerator.cxx | 7 ++++--- Source/cmLocalGenerator.h | 3 ++- Source/cmLocalNinjaGenerator.cxx | 5 +++-- Source/cmLocalNinjaGenerator.h | 3 ++- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 2090cc6..1372c2a 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1759,7 +1759,8 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, } } -std::string cmLocalGenerator::ConvertToLinkReference(std::string const& lib) +std::string cmLocalGenerator::ConvertToLinkReference(std::string const& lib, + OutputFormat format) { #if defined(_WIN32) && !defined(__CYGWIN__) // Work-ardound command line parsing limitations in MSVC 6.0 and @@ -1781,14 +1782,14 @@ std::string cmLocalGenerator::ConvertToLinkReference(std::string const& lib) sp += lib.substr(pos); // Convert to an output path. - return this->Convert(sp.c_str(), NONE, SHELL); + return this->Convert(sp.c_str(), NONE, format); } } } #endif // Normal behavior. - return this->Convert(lib.c_str(), START_OUTPUT, SHELL); + return this->Convert(lib.c_str(), START_OUTPUT, format); } /** diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 986f405..2a76124 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -415,7 +415,8 @@ protected: std::string FindRelativePathTopBinary(); void SetupPathConversions(); - virtual std::string ConvertToLinkReference(std::string const& lib); + virtual std::string ConvertToLinkReference(std::string const& lib, + OutputFormat format = SHELL); /** Check whether the native build system supports the given definition. Issues a warning. */ diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index c989cfb..862823f 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -143,9 +143,10 @@ cmGlobalNinjaGenerator* cmLocalNinjaGenerator::GetGlobalNinjaGenerator() // Virtual protected methods. std::string -cmLocalNinjaGenerator::ConvertToLinkReference(std::string const& lib) +cmLocalNinjaGenerator::ConvertToLinkReference(std::string const& lib, + OutputFormat format) { - return this->Convert(lib.c_str(), HOME_OUTPUT, SHELL); + return this->Convert(lib.c_str(), HOME_OUTPUT, format); } std::string diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h index b3d3b6b..8b26806 100644 --- a/Source/cmLocalNinjaGenerator.h +++ b/Source/cmLocalNinjaGenerator.h @@ -97,7 +97,8 @@ public: void AppendCustomCommandDeps(const cmCustomCommand *cc, cmNinjaDeps &ninjaDeps); - virtual std::string ConvertToLinkReference(std::string const& lib); + virtual std::string ConvertToLinkReference(std::string const& lib, + OutputFormat format = SHELL); protected: -- cgit v0.12 From b9aa5041989a415a360e61291142e760ae7eb9e1 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 4 Mar 2014 13:12:54 -0500 Subject: cmLocalGenerator: Simplify GetIncludeFlags output formatting Use the output format argument to ConvertToIncludeReference. --- Source/cmLocalGenerator.cxx | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 1372c2a..aa64e80 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1295,6 +1295,7 @@ std::string cmLocalGenerator::GetIncludeFlags( return ""; } + OutputFormat shellFormat = forResponseFile? RESPONSE : SHELL; cmOStringStream includeFlags; std::string flagVar = "CMAKE_INCLUDE_FLAG_"; @@ -1354,10 +1355,9 @@ std::string cmLocalGenerator::GetIncludeFlags( frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir.c_str()); if(emitted.insert(frameworkDir).second) { - OutputFormat format = forResponseFile? RESPONSE : SHELL; includeFlags << fwSearchFlag << this->Convert(frameworkDir.c_str(), - START_OUTPUT, format, true) + START_OUTPUT, shellFormat, true) << " "; } continue; @@ -1376,16 +1376,8 @@ std::string cmLocalGenerator::GetIncludeFlags( } flagUsed = true; } - std::string includePath; - if(forResponseFile) - { - includePath = this->Convert(i->c_str(), START_OUTPUT, - RESPONSE, true); - } - else - { - includePath = this->ConvertToIncludeReference(*i); - } + std::string includePath = + this->ConvertToIncludeReference(*i, shellFormat); if(quotePaths && includePath.size() && includePath[0] != '\"') { includeFlags << "\""; -- cgit v0.12 From 5e8e4d0f8819052d3a69eb3cb1a4bdbc674a956c Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 4 Mar 2014 13:20:04 -0500 Subject: cmLocalGenerator: Add response file option to OutputLinkLibraries Response files require different path conversion to be threaded through construction of the link libraries flags. --- Source/cmLocalGenerator.cxx | 23 ++++++++++++++--------- Source/cmLocalGenerator.h | 3 ++- Source/cmMakefileTargetGenerator.cxx | 2 +- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index aa64e80..b86a956 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1671,7 +1671,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, } } this->OutputLinkLibraries(linkLibs, frameworkPath, linkPath, - *target, false); + *target, false, false); } break; case cmTarget::EXECUTABLE: @@ -1696,7 +1696,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, } this->AddLanguageFlags(flags, linkLanguage, buildType.c_str()); this->OutputLinkLibraries(linkLibs, frameworkPath, linkPath, - *target, false); + *target, false, false); if(cmSystemTools::IsOn (this->Makefile->GetDefinition("BUILD_SHARED_LIBS"))) { @@ -1793,8 +1793,11 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries, std::string& frameworkPath, std::string& linkPath, cmGeneratorTarget &tgt, - bool relink) + bool relink, + bool forResponseFile) { + OutputFormat shellFormat = forResponseFile? RESPONSE : SHELL; + bool escapeAllowMakeVars = !forResponseFile; cmOStringStream fout; const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"); cmComputeLinkInformation* pcli = tgt.Target->GetLinkInformation(config); @@ -1837,7 +1840,7 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries, fdi != fwDirs.end(); ++fdi) { frameworkPath += fwSearchFlag; - frameworkPath += this->Convert(fdi->c_str(), NONE, SHELL, false); + frameworkPath += this->Convert(fdi->c_str(), NONE, shellFormat, false); frameworkPath += " "; } } @@ -1847,7 +1850,9 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries, for(std::vector::const_iterator libDir = libDirs.begin(); libDir != libDirs.end(); ++libDir) { - std::string libpath = this->ConvertToOutputForExisting(libDir->c_str()); + std::string libpath = this->ConvertToOutputForExisting(libDir->c_str(), + START_OUTPUT, + shellFormat); linkPath += " " + libPathFlag; linkPath += libpath; linkPath += libPathTerminator; @@ -1865,7 +1870,7 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries, } if(li->IsPath) { - linkLibs += this->ConvertToLinkReference(li->Value); + linkLibs += this->ConvertToLinkReference(li->Value, shellFormat); } else { @@ -1890,7 +1895,7 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries, ri != runtimeDirs.end(); ++ri) { rpath += cli.GetRuntimeFlag(); - rpath += this->Convert(ri->c_str(), NONE, SHELL, false); + rpath += this->Convert(ri->c_str(), NONE, shellFormat, false); rpath += " "; } fout << rpath; @@ -1904,7 +1909,7 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries, if(!rpath.empty()) { fout << cli.GetRuntimeFlag(); - fout << this->EscapeForShell(rpath.c_str(), true); + fout << this->EscapeForShell(rpath.c_str(), escapeAllowMakeVars); fout << " "; } } @@ -1914,7 +1919,7 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries, if(!cli.GetRPathLinkFlag().empty() && !rpath_link.empty()) { fout << cli.GetRPathLinkFlag(); - fout << this->EscapeForShell(rpath_link.c_str(), true); + fout << this->EscapeForShell(rpath_link.c_str(), escapeAllowMakeVars); fout << " "; } diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 2a76124..2e05804 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -372,7 +372,8 @@ protected: std::string& frameworkPath, std::string& linkPath, cmGeneratorTarget &, - bool relink); + bool relink, + bool forResponseFile); // Expand rule variables in CMake of the type found in language rules void ExpandRuleVariables(std::string& string, diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index e5b163b..0f2b6e3 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -1840,7 +1840,7 @@ cmMakefileTargetGenerator std::string linkPath; this->LocalGenerator ->OutputLinkLibraries(linkLibs, frameworkPath, linkPath, - *this->GeneratorTarget, relink); + *this->GeneratorTarget, relink, false); linkLibs = frameworkPath + linkPath + linkLibs; } -- cgit v0.12 From 745caae6dddc9ab5c38a669adf3906f6e3484c80 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 4 Mar 2014 13:21:15 -0500 Subject: Makefile: Rename linker response file boolean to be more specific Rename local variable useResponseFile to useResponseFileForObjects when it represents CMAKE__USE_RESPONSE_FILE_FOR_OBJECTS. --- Source/cmMakefileExecutableTargetGenerator.cxx | 8 ++++---- Source/cmMakefileLibraryTargetGenerator.cxx | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index 696ce94..6754525 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -307,14 +307,14 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) } // Select whether to use a response file for objects. - bool useResponseFile = false; + bool useResponseFileForObjects = false; { std::string responseVar = "CMAKE_"; responseVar += linkLanguage; responseVar += "_USE_RESPONSE_FILE_FOR_OBJECTS"; if(this->Makefile->IsOn(responseVar.c_str())) { - useResponseFile = true; + useResponseFileForObjects = true; } } @@ -330,8 +330,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) // Construct object file lists that may be needed to expand the // rule. std::string buildObjs; - this->CreateObjectLists(useLinkScript, false, useResponseFile, - buildObjs, depends); + this->CreateObjectLists(useLinkScript, false, + useResponseFileForObjects, buildObjs, depends); cmLocalGenerator::RuleVariables vars; vars.RuleLauncher = "RULE_LAUNCH_LINK"; diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 2832515..c639f3e 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -474,14 +474,14 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules bool useLinkScript = this->GlobalGenerator->GetUseLinkScript(); // Select whether to use a response file for objects. - bool useResponseFile = false; + bool useResponseFileForObjects = false; { std::string responseVar = "CMAKE_"; responseVar += linkLanguage; responseVar += "_USE_RESPONSE_FILE_FOR_OBJECTS"; if(this->Makefile->IsOn(responseVar.c_str())) { - useResponseFile = true; + useResponseFileForObjects = true; } } @@ -528,7 +528,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules useLinkScript = true; // Archiving rules never use a response file. - useResponseFile = false; + useResponseFileForObjects = false; // Limit the length of individual object lists to less than the // 32K command line length limit on Windows. We could make this a @@ -552,8 +552,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules // Construct object file lists that may be needed to expand the // rule. std::string buildObjs; - this->CreateObjectLists(useLinkScript, useArchiveRules, useResponseFile, - buildObjs, depends); + this->CreateObjectLists(useLinkScript, useArchiveRules, + useResponseFileForObjects, buildObjs, depends); cmLocalGenerator::RuleVariables vars; vars.TargetPDB = targetOutPathPDB.c_str(); -- cgit v0.12 From 489b1c23b9a880da0012427b60cce7b6f5ddaa27 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 4 Mar 2014 13:25:42 -0500 Subject: Windows: Use response files to specify link libraries for GNU tools Work around the command-line-length limit by using an @linklibs.rsp response file to pass the flags for link libraries. This allows very long lists of libraries to be used in addition to the existing support for passing object files via response file. Suggested-by: Peter Keuschnigg --- Help/release/dev/link-libraries-response-files.rst | 5 ++++ Modules/Platform/Windows-GNU.cmake | 5 +++- Source/cmMakefileExecutableTargetGenerator.cxx | 14 ++++++++++- Source/cmMakefileLibraryTargetGenerator.cxx | 14 ++++++++++- Source/cmMakefileTargetGenerator.cxx | 28 +++++++++++++++++++++- Source/cmMakefileTargetGenerator.h | 1 + 6 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 Help/release/dev/link-libraries-response-files.rst diff --git a/Help/release/dev/link-libraries-response-files.rst b/Help/release/dev/link-libraries-response-files.rst new file mode 100644 index 0000000..cecf7f6 --- /dev/null +++ b/Help/release/dev/link-libraries-response-files.rst @@ -0,0 +1,5 @@ +link-libraries-response-files +----------------------------- + +* The Makefile generators learned to use response files with GNU tools + on Windows to pass library directories and names to the linker. diff --git a/Modules/Platform/Windows-GNU.cmake b/Modules/Platform/Windows-GNU.cmake index 2bb7a20..5c5b360 100644 --- a/Modules/Platform/Windows-GNU.cmake +++ b/Modules/Platform/Windows-GNU.cmake @@ -87,6 +87,7 @@ macro(__windows_compiler_gnu lang) set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "") set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_OBJECTS ${__WINDOWS_GNU_LD_RESPONSE}) + set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_LIBRARIES ${__WINDOWS_GNU_LD_RESPONSE}) set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_INCLUDES 1) # We prefer "@" for response files but it is not supported by gcc 3. @@ -103,7 +104,9 @@ macro(__windows_compiler_gnu lang) endif() # The GNU 3.x compilers do not support response files (only linkers). set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_INCLUDES 0) - elseif(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_OBJECTS) + # Link libraries are generated only for the front-end. + set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_LIBRARIES 0) + else() # Use "@" to pass the response file to the front-end. set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "@") endif() diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index 6754525..1802054 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -318,6 +318,18 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) } } + // 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.c_str())) + { + useResponseFileForLibs = true; + } + } + // Expand the rule variables. { // Set path conversion for link script shells. @@ -325,7 +337,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) // Collect up flags to link in needed libraries. std::string linkLibs; - this->CreateLinkLibs(linkLibs, relink, depends); + this->CreateLinkLibs(linkLibs, relink, useResponseFileForLibs, depends); // Construct object file lists that may be needed to expand the // rule. diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index c639f3e..39e00b2 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -485,6 +485,18 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules } } + // 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.c_str())) + { + useResponseFileForLibs = true; + } + } + // For static libraries there might be archiving rules. bool haveStaticLibraryRule = false; std::vector archiveCreateCommands; @@ -546,7 +558,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules std::string linkLibs; if(this->Target->GetType() != cmTarget::STATIC_LIBRARY) { - this->CreateLinkLibs(linkLibs, relink, depends); + this->CreateLinkLibs(linkLibs, relink, useResponseFileForLibs, depends); } // Construct object file lists that may be needed to expand the diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 0f2b6e3..facbcc6 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -1834,14 +1834,40 @@ cmMakefileTargetGenerator void cmMakefileTargetGenerator ::CreateLinkLibs(std::string& linkLibs, bool relink, + bool useResponseFile, std::vector& makefile_depends) { std::string frameworkPath; std::string linkPath; this->LocalGenerator ->OutputLinkLibraries(linkLibs, frameworkPath, linkPath, - *this->GeneratorTarget, relink, false); + *this->GeneratorTarget, relink, + useResponseFile); linkLibs = frameworkPath + linkPath + linkLibs; + + if(useResponseFile) + { + // Lookup the response file reference flag. + std::string responseFlagVar = "CMAKE_"; + responseFlagVar += this->Target->GetLinkerLanguage(this->ConfigName); + responseFlagVar += "_RESPONSE_FILE_LINK_FLAG"; + const char* responseFlag = + this->Makefile->GetDefinition(responseFlagVar.c_str()); + if(!responseFlag) + { + responseFlag = "@"; + } + + // Create this response file. + std::string link_rsp = + this->CreateResponseFile("linklibs.rsp", linkLibs, makefile_depends); + + // Reference the response file. + linkLibs = responseFlag; + linkLibs += this->Convert(link_rsp.c_str(), + cmLocalGenerator::NONE, + cmLocalGenerator::SHELL); + } } //---------------------------------------------------------------------------- diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index d47708d..72dc6bc 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -165,6 +165,7 @@ protected: /** Create list of flags for link libraries. */ void CreateLinkLibs(std::string& linkLibs, bool relink, + bool useResponseFile, std::vector& makefile_depends); /** Create lists of object files for linking and cleaning. */ -- cgit v0.12