From 8d674e78449d4bcde669ee5c4a6c0809c0ee51a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20K=C3=BCmmel?= Date: Wed, 26 Sep 2012 14:38:15 +0200 Subject: Ninja: move -LIBPATH behind -link option Don' pass linker option to the compile --- Source/cmLocalGenerator.cxx | 41 ++++++++++++++++---------- Source/cmLocalGenerator.h | 7 ++++- Source/cmMakefileExecutableTargetGenerator.cxx | 12 ++++---- Source/cmMakefileLibraryTargetGenerator.cxx | 11 ++++--- Source/cmNinjaNormalTargetGenerator.cxx | 5 ++++ Source/cmake.cxx | 6 +++- 6 files changed, 55 insertions(+), 27 deletions(-) diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index d452658..2b36ad0 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -676,9 +676,13 @@ void cmLocalGenerator::AddBuildTargetRule(const char* llang, // Static Library: // Shared Module: std::string linkLibs; // should be set + std::string frameworkPath; + std::string linkPath; std::string flags; // should be set std::string linkFlags; // should be set - this->GetTargetFlags(linkLibs, flags, linkFlags, &target); + this->GetTargetFlags(linkLibs, frameworkPath, linkPath, flags, linkFlags, + &target); + linkLibs = frameworkPath + linkPath + linkLibs; cmLocalGenerator::RuleVariables vars; vars.Language = llang; vars.Objects = objs.c_str(); @@ -1450,6 +1454,8 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector& dirs, void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, std::string& flags, std::string& linkFlags, + std::string& frameworkPath, + std::string& linkPath, cmGeneratorTarget* target) { std::string buildType = @@ -1531,9 +1537,8 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, linkFlags += " "; } } - cmOStringStream linklibsStr; - this->OutputLinkLibraries(linklibsStr, *target, false); - linkLibs = linklibsStr.str(); + this->OutputLinkLibraries(linkLibs, frameworkPath, linkPath, + *target, false); } break; case cmTarget::EXECUTABLE: @@ -1557,9 +1562,8 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, return; } this->AddLanguageFlags(flags, linkLanguage, buildType.c_str()); - cmOStringStream linklibs; - this->OutputLinkLibraries(linklibs, *target, false); - linkLibs = linklibs.str(); + this->OutputLinkLibraries(linkLibs, frameworkPath, linkPath, + *target, false); if(cmSystemTools::IsOn (this->Makefile->GetDefinition("BUILD_SHARED_LIBS"))) { @@ -1651,10 +1655,13 @@ std::string cmLocalGenerator::ConvertToLinkReference(std::string const& lib) * targetLibrary should be a NULL pointer. For libraries, it should point * to the name of the library. This will not link a library against itself. */ -void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout, - cmGeneratorTarget& tgt, +void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries, + std::string& frameworkPath, + std::string& linkPath, + cmGeneratorTarget &tgt, bool relink) { + cmOStringStream fout; const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"); cmComputeLinkInformation* pcli = tgt.GetLinkInformation(config); if(!pcli) @@ -1688,9 +1695,9 @@ void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout, for(std::vector::const_iterator fdi = fwDirs.begin(); fdi != fwDirs.end(); ++fdi) { - linkLibs += "-F"; - linkLibs += this->Convert(fdi->c_str(), NONE, SHELL, false); - linkLibs += " "; + frameworkPath = " -F"; + frameworkPath += this->Convert(fdi->c_str(), NONE, SHELL, false); + frameworkPath += " "; } // Append the library search path flags. @@ -1699,10 +1706,10 @@ void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout, libDir != libDirs.end(); ++libDir) { std::string libpath = this->ConvertToOutputForExisting(libDir->c_str()); - linkLibs += libPathFlag; - linkLibs += libpath; - linkLibs += libPathTerminator; - linkLibs += " "; + linkPath += " " + libPathFlag; + linkPath += libpath; + linkPath += libPathTerminator; + linkPath += " "; } // Append the link items. @@ -1774,6 +1781,8 @@ void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout, { fout << stdLibs << " "; } + + linkLibraries = fout.str(); } diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 0916d44..51d5924 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -335,11 +335,16 @@ public: void GetTargetFlags(std::string& linkLibs, std::string& flags, std::string& linkFlags, + std::string& frameworkPath, + std::string& linkPath, cmGeneratorTarget* target); protected: ///! put all the libraries for a target on into the given stream - virtual void OutputLinkLibraries(std::ostream&, cmGeneratorTarget&, + virtual void OutputLinkLibraries(std::string& linkLibraries, + std::string& frameworkPath, + std::string& linkPath, + cmGeneratorTarget &, bool relink); // Expand rule variables in CMake of the type found in language rules diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index ca5f26a..da66656 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -318,10 +318,13 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) this->LocalGenerator->SetLinkScriptShell(useLinkScript); // Collect up flags to link in needed libraries. - cmOStringStream linklibs; - this->LocalGenerator->OutputLinkLibraries(linklibs, *this->GeneratorTarget, + std::string linkLibs; + std::string frameworkPath; + std::string linkPath; + this->LocalGenerator->OutputLinkLibraries(linkLibs, frameworkPath, linkPath, + *this->GeneratorTarget, relink); - + linkLibs = frameworkPath + linkPath + linkLibs; // Construct object file lists that may be needed to expand the // rule. std::string buildObjs; @@ -360,8 +363,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) vars.TargetVersionMajor = targetVersionMajor.c_str(); vars.TargetVersionMinor = targetVersionMinor.c_str(); - std::string linkString = linklibs.str(); - vars.LinkLibraries = linkString.c_str(); + vars.LinkLibraries = linkLibs.c_str(); vars.Flags = flags.c_str(); vars.LinkFlags = linkFlags.c_str(); // Expand placeholders in the commands. diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 368d6fc..d39e7fa 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -542,11 +542,15 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules this->LocalGenerator->SetLinkScriptShell(useLinkScript); // Collect up flags to link in needed libraries. - cmOStringStream linklibs; + std::string linkLibs; if(this->Target->GetType() != cmTarget::STATIC_LIBRARY) { + std::string frameworkPath; + std::string linkPath; this->LocalGenerator - ->OutputLinkLibraries(linklibs, *this->GeneratorTarget, relink); + ->OutputLinkLibraries(linkLibs, frameworkPath, linkPath, + *this->GeneratorTarget, relink); + linkLibs = frameworkPath + linkPath + linkLibs; } // Construct object file lists that may be needed to expand the @@ -587,8 +591,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules cmLocalGenerator::SHELL); vars.ObjectDir = objdir.c_str(); vars.Target = targetOutPathReal.c_str(); - std::string linkString = linklibs.str(); - vars.LinkLibraries = linkString.c_str(); + vars.LinkLibraries = linkLibs.c_str(); vars.ObjectsQuoted = buildObjs.c_str(); if (this->Target->HasSOName(this->ConfigName)) { diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index a13e1f0..9490658 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -420,12 +420,17 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() cmNinjaDeps explicitDeps = this->GetObjects(); cmNinjaDeps implicitDeps = this->ComputeLinkDeps(); + std::string frameworkPath; + std::string linkPath; this->GetLocalGenerator()->GetTargetFlags(vars["LINK_LIBRARIES"], vars["FLAGS"], vars["LINK_FLAGS"], + frameworkPath, + linkPath, this->GetGeneratorTarget()); this->AddModuleDefinitionFlag(vars["LINK_FLAGS"]); + vars["LINK_FLAGS"] += frameworkPath + linkPath; // Compute architecture specific link flags. Yes, these go into a different // variable for executables, probably due to a mistake made when duplicating diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 745d513..0123427 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -628,10 +628,14 @@ bool cmake::FindPackage(const std::vector& args) std::string linkLibs; + std::string frameworkPath; + std::string linkPath; std::string flags; std::string linkFlags; cmGeneratorTarget gtgt(tgt); - lg->GetTargetFlags(linkLibs, flags, linkFlags, >gt); + lg->GetTargetFlags(linkLibs, frameworkPath, linkPath, flags, linkFlags, + >gt); + linkLibs = frameworkPath + linkPath + linkLibs; printf("%s\n", linkLibs.c_str() ); -- cgit v0.12 From e31df0393973e2995f4543890df31c2b752a8ee1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20K=C3=BCmmel?= Date: Thu, 27 Sep 2012 11:45:25 +0200 Subject: Ninja: move in front of the first linker option In the response file also linker options could be passed, and because is replaced by a response file, it is necessary that no compiler option follows . --- Modules/Platform/Windows-Intel.cmake | 3 ++- Modules/Platform/Windows-MSVC.cmake | 3 ++- Modules/Platform/Windows-df.cmake | 3 ++- Source/cmNinjaNormalTargetGenerator.cxx | 36 +++++++++++++++++++++++---------- 4 files changed, 31 insertions(+), 14 deletions(-) diff --git a/Modules/Platform/Windows-Intel.cmake b/Modules/Platform/Windows-Intel.cmake index 3a30a2e..58da8c5 100644 --- a/Modules/Platform/Windows-Intel.cmake +++ b/Modules/Platform/Windows-Intel.cmake @@ -89,8 +89,9 @@ macro(__windows_compiler_intel lang) set(CMAKE_${lang}_CREATE_SHARED_LIBRARY "xilink ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} /out: /implib: /pdb: /dll ${CMAKE_END_TEMP_FILE}") set(CMAKE_${lang}_CREATE_SHARED_MODULE "${CMAKE_${lang}_CREATE_SHARED_LIBRARY}") + set(CMAKE_${lang}_COMPILER_LINKER_OPTION_FLAG_EXECUTABLE "/link") set(CMAKE_${lang}_LINK_EXECUTABLE - " ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} /Fe -link /implib: ${CMAKE_END_TEMP_FILE}") + " ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} /Fe /link /implib: ${CMAKE_END_TEMP_FILE}") set(CMAKE_${lang}_FLAGS_INIT "/DWIN32 /D_WINDOWS /W3 /Zm1000${_FLAGS_${lang}}") set(CMAKE_${lang}_FLAGS_DEBUG_INIT "/D_DEBUG /MDd /Zi /Od /RTC1") set(CMAKE_${lang}_FLAGS_MINSIZEREL_INIT "/DNDEBUG /MD /O1") diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake index cc48cfe..1f28c50 100644 --- a/Modules/Platform/Windows-MSVC.cmake +++ b/Modules/Platform/Windows-MSVC.cmake @@ -228,9 +228,10 @@ macro(__windows_compiler_msvc lang) set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE " ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO}${_COMPILE_${lang}} /FoNUL /FAs /Fa /c ${CMAKE_END_TEMP_FILE}") + set(CMAKE_${lang}_COMPILER_LINKER_OPTION_FLAG_EXECUTABLE "/link") set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_OBJECTS 1) set(CMAKE_${lang}_LINK_EXECUTABLE - "${_CMAKE_VS_LINK_EXE} ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} /Fe /Fd -link /implib: /version:. ${CMAKE_END_TEMP_FILE}") + "${_CMAKE_VS_LINK_EXE} ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} /Fe /Fd /link /implib: /version:. ${CMAKE_END_TEMP_FILE}") set(CMAKE_${lang}_FLAGS_INIT "${_PLATFORM_DEFINES}${_PLATFORM_DEFINES_${lang}} /D_WINDOWS /W3 /Zm1000${_FLAGS_${lang}}") set(CMAKE_${lang}_FLAGS_DEBUG_INIT "/D_DEBUG /MDd /Zi /Ob0 /Od ${_RTC1}") diff --git a/Modules/Platform/Windows-df.cmake b/Modules/Platform/Windows-df.cmake index 9a87be1..7e2ac9f 100644 --- a/Modules/Platform/Windows-df.cmake +++ b/Modules/Platform/Windows-df.cmake @@ -26,8 +26,9 @@ set(CMAKE_Fortran_COMPILE_OBJECT set(CMAKE_COMPILE_RESOURCE "rc /fo ") +set(CMAKE_${lang}_COMPILER_LINKER_OPTION_FLAG_EXECUTABLE "/link") set(CMAKE_Fortran_LINK_EXECUTABLE - " ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} /exe: /link ${CMAKE_END_TEMP_FILE}") + " ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} /exe: /link ${CMAKE_END_TEMP_FILE}") set(CMAKE_CREATE_WIN32_EXE /winapp) set(CMAKE_CREATE_CONSOLE_EXE ) diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 9490658..d42d7f6 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -168,11 +168,13 @@ cmNinjaNormalTargetGenerator std::string responseFlag; if (!useResponseFile) { vars.Objects = "$in"; - vars.LinkLibraries = "$LINK_LIBRARIES"; + vars.LinkLibraries = "$LINK_PATH $LINK_LIBRARIES"; } else { - // handle response file - std::string cmakeLinkVar = std::string("CMAKE_") + - this->TargetLinkLanguage + "_RESPONSE_FILE_LINK_FLAG"; + std::string cmakeVarLang = "CMAKE_"; + cmakeVarLang += this->TargetLinkLanguage; + + // build response file name + std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_LINK_FLAG"; const char * flag = GetMakefile()->GetDefinition(cmakeLinkVar.c_str()); if(flag) { responseFlag = flag; @@ -181,7 +183,14 @@ cmNinjaNormalTargetGenerator } rspfile = "$RSP_FILE"; responseFlag += rspfile; - rspcontent = "$in $LINK_LIBRARIES"; + + // build response file content + std::string linkOptionVar = cmakeVarLang; + linkOptionVar += "_COMPILER_LINKER_OPTION_FLAG_"; + linkOptionVar += cmTarget::GetTargetTypeName(targetType); + const std::string linkOption = + GetMakefile()->GetSafeDefinition(linkOptionVar.c_str()); + rspcontent = "$in " + linkOption + " $LINK_PATH $LINK_LIBRARIES"; vars.Objects = responseFlag.c_str(); vars.LinkLibraries = ""; } @@ -430,7 +439,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() this->GetGeneratorTarget()); this->AddModuleDefinitionFlag(vars["LINK_FLAGS"]); - vars["LINK_FLAGS"] += frameworkPath + linkPath; + vars["LINK_PATH"] = frameworkPath + linkPath; // Compute architecture specific link flags. Yes, these go into a different // variable for executables, probably due to a mistake made when duplicating @@ -544,15 +553,20 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() int linkRuleLength = this->GetGlobalGenerator()-> GetRuleCmdLength(this->LanguageLinkerRule()); + + int commandLineLengthLimit; + if (this->GetMakefile()->IsDefinitionSet("CMAKE_FORCE_RESPONSE_FILE")) { + commandLineLengthLimit = 1; + } else { #ifdef _WIN32 - int commandLineLengthLimit = 8000 - linkRuleLength; + commandLineLengthLimit = 8000 - linkRuleLength; #elif defined(__linux) || defined(__APPLE__) - // for instance ARG_MAX is 2096152 on Ubuntu or 262144 on Mac - int commandLineLengthLimit = ((int)sysconf(_SC_ARG_MAX)) - - linkRuleLength - 1000; + // for instance ARG_MAX is 2096152 on Ubuntu or 262144 on Mac + commandLineLengthLimit = ((int)sysconf(_SC_ARG_MAX))-linkRuleLength-1000; #else - int commandLineLengthLimit = -1; + commandLineLengthLimit = -1; #endif + } const std::string rspfile = std::string (cmake::GetCMakeFilesDirectoryPostSlash()) + -- cgit v0.12 From 1e47ccb5542954e1258affe36e0089f13618d23d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20K=C3=BCmmel?= Date: Thu, 27 Sep 2012 22:29:17 +0200 Subject: Ninja: add option to enforce usage of response files If the cmake or environment variable CMAKE_NINJA_FORCE_RESPONSE_FILE is set then a response file is used regardless the command line length. --- Source/cmNinjaNormalTargetGenerator.cxx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index d42d7f6..6c54ced 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -554,10 +554,10 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() int linkRuleLength = this->GetGlobalGenerator()-> GetRuleCmdLength(this->LanguageLinkerRule()); - int commandLineLengthLimit; - if (this->GetMakefile()->IsDefinitionSet("CMAKE_FORCE_RESPONSE_FILE")) { - commandLineLengthLimit = 1; - } else { + int commandLineLengthLimit = 1; + const char* forceRspFile = "CMAKE_NINJA_FORCE_RESPONSE_FILE"; + if (!this->GetMakefile()->IsDefinitionSet(forceRspFile) && + cmSystemTools::GetEnv(forceRspFile) == 0) { #ifdef _WIN32 commandLineLengthLimit = 8000 - linkRuleLength; #elif defined(__linux) || defined(__APPLE__) -- cgit v0.12