Browse Source

Merge topic 'ninja-LIBPATH'

1e47ccb Ninja: add option to enforce usage of response files
e31df03 Ninja: move <OBJECTS> in front of the first linker option
8d674e7 Ninja: move -LIBPATH behind -link option
Brad King 13 years ago
parent
commit
47e50423bf

+ 2 - 1
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:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /dll  <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES> ${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_${lang}_COMPILER> ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} <FLAGS> <OBJECTS> /Fe<TARGET> -link /implib:<TARGET_IMPLIB> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
+    "<CMAKE_${lang}_COMPILER> ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} <FLAGS> /Fe<TARGET> <OBJECTS> /link /implib:<TARGET_IMPLIB> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${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")

+ 2 - 1
Modules/Platform/Windows-MSVC.cmake

@@ -228,9 +228,10 @@ macro(__windows_compiler_msvc lang)
   set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE
     "<CMAKE_${lang}_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO}${_COMPILE_${lang}} <FLAGS> <DEFINES> /FoNUL /FAs /Fa<ASSEMBLY_SOURCE> /c <SOURCE>${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_${lang}_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_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
+    "${_CMAKE_VS_LINK_EXE}<CMAKE_${lang}_COMPILER> ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} <FLAGS> /Fe<TARGET> /Fd<TARGET_PDB> <OBJECTS> /link /implib:<TARGET_IMPLIB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${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}")

+ 2 - 1
Modules/Platform/Windows-df.cmake

@@ -26,8 +26,9 @@ set(CMAKE_Fortran_COMPILE_OBJECT
 
 set(CMAKE_COMPILE_RESOURCE "rc <FLAGS> /fo<OBJECT> <SOURCE>")
 
+set(CMAKE_${lang}_COMPILER_LINKER_OPTION_FLAG_EXECUTABLE "/link")
 set(CMAKE_Fortran_LINK_EXECUTABLE
-    "<CMAKE_Fortran_COMPILER> ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} <FLAGS> <OBJECTS> /exe:<TARGET> /link <CMAKE_Fortran_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
+    "<CMAKE_Fortran_COMPILER> ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} <FLAGS> /exe:<TARGET> <OBJECTS> /link <CMAKE_Fortran_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
 
 set(CMAKE_CREATE_WIN32_EXE /winapp)
 set(CMAKE_CREATE_CONSOLE_EXE )

+ 25 - 16
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();
@@ -1453,6 +1457,8 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs,
 void cmLocalGenerator::GetTargetFlags(std::string& linkLibs,
                                  std::string& flags,
                                  std::string& linkFlags,
+                                 std::string& frameworkPath,
+                                 std::string& linkPath,
                                  cmGeneratorTarget* target)
 {
   std::string buildType =
@@ -1534,9 +1540,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:
@@ -1560,9 +1565,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")))
         {
@@ -1654,10 +1658,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)
@@ -1691,9 +1698,9 @@ void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout,
   for(std::vector<std::string>::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.
@@ -1702,10 +1709,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.
@@ -1777,6 +1784,8 @@ void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout,
     {
     fout << stdLibs << " ";
     }
+
+  linkLibraries = fout.str();
 }
 
 

+ 6 - 1
Source/cmLocalGenerator.h

@@ -340,11 +340,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

+ 7 - 5
Source/cmMakefileExecutableTargetGenerator.cxx

@@ -323,10 +323,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;
@@ -365,8 +368,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.

+ 7 - 4
Source/cmMakefileLibraryTargetGenerator.cxx

@@ -546,11 +546,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
@@ -591,8 +595,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))
     {

+ 29 - 10
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 = "";
     }
@@ -420,12 +429,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_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
@@ -539,15 +553,20 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
 
   int linkRuleLength = this->GetGlobalGenerator()->
                                  GetRuleCmdLength(this->LanguageLinkerRule());
+
+  int commandLineLengthLimit = 1;
+  const char* forceRspFile = "CMAKE_NINJA_FORCE_RESPONSE_FILE";
+  if (!this->GetMakefile()->IsDefinitionSet(forceRspFile) &&
+      cmSystemTools::GetEnv(forceRspFile) == 0) {
 #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()) +

+ 5 - 1
Source/cmake.cxx

@@ -628,10 +628,14 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
 
 
     std::string linkLibs;
+    std::string frameworkPath;
+    std::string linkPath;
     std::string flags;
     std::string linkFlags;
     cmGeneratorTarget gtgt(tgt);
-    lg->GetTargetFlags(linkLibs, flags, linkFlags, &gtgt);
+    lg->GetTargetFlags(linkLibs, frameworkPath, linkPath, flags, linkFlags,
+                       &gtgt);
+    linkLibs = frameworkPath + linkPath + linkLibs;
 
     printf("%s\n", linkLibs.c_str() );