Browse Source

cmLinkLineComputer: Extract from cmLocalGenerator

CMake has several classes which have too many responsibilities.
cmLocalGenerator is one of them.  Start to extract the link line
computation.  Create generator-specific implementations of the interface
to account for generator-specific behavior.

Unfortunately MSVC60 has different behavior to everything else and CMake
still generates makefiles for it.  Isolate it with MSVC60-specific
names.
Stephen Kelly 9 years ago
parent
commit
5b361fdda0

+ 6 - 0
Source/CMakeLists.txt

@@ -300,6 +300,8 @@ set(SRCS
   cmInstallDirectoryGenerator.cxx
   cmInstallDirectoryGenerator.cxx
   cmLinkedTree.h
   cmLinkedTree.h
   cmLinkItem.h
   cmLinkItem.h
+  cmLinkLineComputer.cxx
+  cmLinkLineComputer.h
   cmListFileCache.cxx
   cmListFileCache.cxx
   cmListFileCache.h
   cmListFileCache.h
   cmListFileLexer.c
   cmListFileLexer.c
@@ -318,6 +320,8 @@ set(SRCS
   cmMakefileUtilityTargetGenerator.cxx
   cmMakefileUtilityTargetGenerator.cxx
   cmMessenger.cxx
   cmMessenger.cxx
   cmMessenger.h
   cmMessenger.h
+  cmMSVC60LinkLineComputer.cxx
+  cmMSVC60LinkLineComputer.h
   cmOSXBundleGenerator.cxx
   cmOSXBundleGenerator.cxx
   cmOSXBundleGenerator.h
   cmOSXBundleGenerator.h
   cmOutputConverter.cxx
   cmOutputConverter.cxx
@@ -545,6 +549,8 @@ set(SRCS ${SRCS}
   cmNinjaNormalTargetGenerator.h
   cmNinjaNormalTargetGenerator.h
   cmNinjaUtilityTargetGenerator.cxx
   cmNinjaUtilityTargetGenerator.cxx
   cmNinjaUtilityTargetGenerator.h
   cmNinjaUtilityTargetGenerator.h
+  cmNinjaLinkLineComputer.cxx
+  cmNinjaLinkLineComputer.h
   )
   )
 
 
 # Temporary variable for tools targets
 # Temporary variable for tools targets

+ 4 - 2
Source/cmCommonTargetGenerator.cxx

@@ -12,6 +12,7 @@
 #include "cmComputeLinkInformation.h"
 #include "cmComputeLinkInformation.h"
 #include "cmGeneratorTarget.h"
 #include "cmGeneratorTarget.h"
 #include "cmGlobalCommonGenerator.h"
 #include "cmGlobalCommonGenerator.h"
+#include "cmLinkLineComputer.h"
 #include "cmLocalCommonGenerator.h"
 #include "cmLocalCommonGenerator.h"
 #include "cmLocalGenerator.h"
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
 #include "cmMakefile.h"
@@ -59,7 +60,8 @@ void cmCommonTargetGenerator::AddFeatureFlags(std::string& flags,
   }
   }
 }
 }
 
 
-void cmCommonTargetGenerator::AddModuleDefinitionFlag(std::string& flags)
+void cmCommonTargetGenerator::AddModuleDefinitionFlag(
+  cmLinkLineComputer* linkLineComputer, std::string& flags)
 {
 {
   if (!this->ModuleDefinitionFile) {
   if (!this->ModuleDefinitionFile) {
     return;
     return;
@@ -76,7 +78,7 @@ void cmCommonTargetGenerator::AddModuleDefinitionFlag(std::string& flags)
   // vs6's "cl -link" pass it to the linker.
   // vs6's "cl -link" pass it to the linker.
   std::string flag = defFileFlag;
   std::string flag = defFileFlag;
   flag += this->LocalGenerator->ConvertToOutputFormat(
   flag += this->LocalGenerator->ConvertToOutputFormat(
-    this->LocalGenerator->ConvertToLinkReference(
+    linkLineComputer->ConvertToLinkReference(
       this->ModuleDefinitionFile->GetFullPath()),
       this->ModuleDefinitionFile->GetFullPath()),
     cmOutputConverter::SHELL);
     cmOutputConverter::SHELL);
   this->LocalGenerator->AppendFlags(flags, flag);
   this->LocalGenerator->AppendFlags(flags, flag);

+ 3 - 1
Source/cmCommonTargetGenerator.h

@@ -16,6 +16,7 @@ class cmGlobalCommonGenerator;
 class cmLocalCommonGenerator;
 class cmLocalCommonGenerator;
 class cmMakefile;
 class cmMakefile;
 class cmSourceFile;
 class cmSourceFile;
+class cmLinkLineComputer;
 
 
 /** \class cmCommonTargetGenerator
 /** \class cmCommonTargetGenerator
  * \brief Common infrastructure for Makefile and Ninja per-target generators
  * \brief Common infrastructure for Makefile and Ninja per-target generators
@@ -37,7 +38,8 @@ protected:
   bool GetFeatureAsBool(const std::string& feature);
   bool GetFeatureAsBool(const std::string& feature);
 
 
   // Helper to add flag for windows .def file.
   // Helper to add flag for windows .def file.
-  void AddModuleDefinitionFlag(std::string& flags);
+  void AddModuleDefinitionFlag(cmLinkLineComputer* linkLineComputer,
+                               std::string& flags);
 
 
   cmGeneratorTarget* GeneratorTarget;
   cmGeneratorTarget* GeneratorTarget;
   cmMakefile* Makefile;
   cmMakefile* Makefile;

+ 7 - 2
Source/cmGhsMultiTargetGenerator.cxx

@@ -5,6 +5,7 @@
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratorTarget.h"
 #include "cmGeneratorTarget.h"
 #include "cmGlobalGhsMultiGenerator.h"
 #include "cmGlobalGhsMultiGenerator.h"
+#include "cmLinkLineComputer.h"
 #include "cmLocalGhsMultiGenerator.h"
 #include "cmLocalGhsMultiGenerator.h"
 #include "cmMakefile.h"
 #include "cmMakefile.h"
 #include "cmSourceFile.h"
 #include "cmSourceFile.h"
@@ -362,9 +363,13 @@ void cmGhsMultiTargetGenerator::WriteTargetLinkLibraries(
       this->GeneratorTarget->GetCreateRuleVariable(language, config);
       this->GeneratorTarget->GetCreateRuleVariable(language, config);
     bool useWatcomQuote =
     bool useWatcomQuote =
       this->Makefile->IsOn(createRule + "_USE_WATCOM_QUOTE");
       this->Makefile->IsOn(createRule + "_USE_WATCOM_QUOTE");
+    CM_AUTO_PTR<cmLinkLineComputer> linkLineComputer(
+      this->GetGlobalGenerator()->CreateLinkLineComputer(
+        this->LocalGenerator->GetStateSnapshot().GetDirectory()));
+
     this->LocalGenerator->GetTargetFlags(
     this->LocalGenerator->GetTargetFlags(
-      config, linkLibraries, flags, linkFlags, frameworkPath, linkPath,
-      this->GeneratorTarget, useWatcomQuote);
+      linkLineComputer.get(), config, linkLibraries, flags, linkFlags,
+      frameworkPath, linkPath, this->GeneratorTarget, useWatcomQuote);
     linkFlags = cmSystemTools::TrimWhitespace(linkFlags);
     linkFlags = cmSystemTools::TrimWhitespace(linkFlags);
 
 
     if (!linkPath.empty()) {
     if (!linkPath.empty()) {

+ 14 - 0
Source/cmGlobalGenerator.cxx

@@ -20,7 +20,9 @@
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorTarget.h"
 #include "cmGeneratorTarget.h"
 #include "cmInstallGenerator.h"
 #include "cmInstallGenerator.h"
+#include "cmLinkLineComputer.h"
 #include "cmLocalGenerator.h"
 #include "cmLocalGenerator.h"
+#include "cmMSVC60LinkLineComputer.h"
 #include "cmMakefile.h"
 #include "cmMakefile.h"
 #include "cmOutputConverter.h"
 #include "cmOutputConverter.h"
 #include "cmPolicies.h"
 #include "cmPolicies.h"
@@ -1412,6 +1414,18 @@ cmGlobalGenerator::CreateQtAutoGeneratorsTargets()
   return autogenTargets;
   return autogenTargets;
 }
 }
 
 
+cmLinkLineComputer* cmGlobalGenerator::CreateLinkLineComputer(
+  cmState::Directory stateDir) const
+{
+  return new cmLinkLineComputer(stateDir);
+}
+
+cmLinkLineComputer* cmGlobalGenerator::CreateMSVC60LinkLineComputer(
+  cmState::Directory stateDir) const
+{
+  return new cmMSVC60LinkLineComputer(stateDir);
+}
+
 void cmGlobalGenerator::FinalizeTargetCompileInfo()
 void cmGlobalGenerator::FinalizeTargetCompileInfo()
 {
 {
   std::vector<std::string> const langs =
   std::vector<std::string> const langs =

+ 7 - 0
Source/cmGlobalGenerator.h

@@ -34,6 +34,7 @@ class cmExportBuildFileGenerator;
 class cmExternalMakefileProjectGenerator;
 class cmExternalMakefileProjectGenerator;
 class cmGeneratorTarget;
 class cmGeneratorTarget;
 class cmLocalGenerator;
 class cmLocalGenerator;
+class cmLinkLineComputer;
 class cmMakefile;
 class cmMakefile;
 class cmake;
 class cmake;
 
 
@@ -105,6 +106,12 @@ public:
    */
    */
   virtual void Generate();
   virtual void Generate();
 
 
+  virtual cmLinkLineComputer* CreateLinkLineComputer(
+    cmState::Directory stateDir) const;
+
+  cmLinkLineComputer* CreateMSVC60LinkLineComputer(
+    cmState::Directory stateDir) const;
+
   /**
   /**
    * Set/Get and Clear the enabled languages.
    * Set/Get and Clear the enabled languages.
    */
    */

+ 8 - 0
Source/cmGlobalNinjaGenerator.cxx

@@ -11,6 +11,7 @@
 #include "cmLocalGenerator.h"
 #include "cmLocalGenerator.h"
 #include "cmLocalNinjaGenerator.h"
 #include "cmLocalNinjaGenerator.h"
 #include "cmMakefile.h"
 #include "cmMakefile.h"
+#include "cmNinjaLinkLineComputer.h"
 #include "cmOutputConverter.h"
 #include "cmOutputConverter.h"
 #include "cmState.h"
 #include "cmState.h"
 #include "cmSystemTools.h"
 #include "cmSystemTools.h"
@@ -64,6 +65,13 @@ void cmGlobalNinjaGenerator::WriteComment(std::ostream& os,
   os << "# " << comment.substr(lpos) << "\n\n";
   os << "# " << comment.substr(lpos) << "\n\n";
 }
 }
 
 
+cmLinkLineComputer* cmGlobalNinjaGenerator::CreateLinkLineComputer(
+  cmState::Directory /* stateDir */) const
+{
+  return new cmNinjaLinkLineComputer(
+    this->LocalGenerators[0]->GetStateSnapshot().GetDirectory(), this);
+}
+
 std::string cmGlobalNinjaGenerator::EncodeRuleName(std::string const& name)
 std::string cmGlobalNinjaGenerator::EncodeRuleName(std::string const& name)
 {
 {
   // Ninja rule names must match "[a-zA-Z0-9_.-]+".  Use ".xx" to encode
   // Ninja rule names must match "[a-zA-Z0-9_.-]+".  Use ".xx" to encode

+ 3 - 0
Source/cmGlobalNinjaGenerator.h

@@ -70,6 +70,9 @@ public:
   std::string EncodePath(const std::string& path);
   std::string EncodePath(const std::string& path);
   static std::string EncodeDepfileSpace(const std::string& path);
   static std::string EncodeDepfileSpace(const std::string& path);
 
 
+  cmLinkLineComputer* CreateLinkLineComputer(cmState::Directory stateDir) const
+    CM_OVERRIDE;
+
   /**
   /**
    * Write the given @a comment to the output stream @a os. It
    * Write the given @a comment to the output stream @a os. It
    * handles new line character properly.
    * handles new line character properly.

+ 27 - 0
Source/cmLinkLineComputer.cxx

@@ -0,0 +1,27 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+
+#include "cmLinkLineComputer.h"
+#include "cmOutputConverter.h"
+
+cmLinkLineComputer::cmLinkLineComputer(cmState::Directory stateDir)
+  : StateDir(stateDir)
+{
+}
+
+cmLinkLineComputer::~cmLinkLineComputer()
+{
+}
+
+std::string cmLinkLineComputer::ConvertToLinkReference(
+  std::string const& lib) const
+{
+  std::string relLib = lib;
+
+  if (cmOutputConverter::ContainedInDirectory(
+        this->StateDir.GetCurrentBinary(), lib, this->StateDir)) {
+    relLib = cmOutputConverter::ForceToRelativePath(
+      this->StateDir.GetCurrentBinary(), lib);
+  }
+  return relLib;
+}

+ 21 - 0
Source/cmLinkLineComputer.h

@@ -0,0 +1,21 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+
+#ifndef cmLinkLineComputer_h
+#define cmLinkLineComputer_h
+
+#include "cmState.h"
+
+class cmLinkLineComputer
+{
+public:
+  cmLinkLineComputer(cmState::Directory stateDir);
+  virtual ~cmLinkLineComputer();
+
+  virtual std::string ConvertToLinkReference(std::string const& input) const;
+
+private:
+  cmState::Directory StateDir;
+};
+
+#endif

+ 16 - 48
Source/cmLocalGenerator.cxx

@@ -12,6 +12,7 @@
 #include "cmInstallGenerator.h"
 #include "cmInstallGenerator.h"
 #include "cmInstallScriptGenerator.h"
 #include "cmInstallScriptGenerator.h"
 #include "cmInstallTargetGenerator.h"
 #include "cmInstallTargetGenerator.h"
+#include "cmLinkLineComputer.h"
 #include "cmMakefile.h"
 #include "cmMakefile.h"
 #include "cmSourceFile.h"
 #include "cmSourceFile.h"
 #include "cmSystemTools.h"
 #include "cmSystemTools.h"
@@ -1148,9 +1149,10 @@ void cmLocalGenerator::GetStaticLibraryFlags(std::string& flags,
 }
 }
 
 
 void cmLocalGenerator::GetTargetFlags(
 void cmLocalGenerator::GetTargetFlags(
-  const std::string& config, std::string& linkLibs, std::string& flags,
-  std::string& linkFlags, std::string& frameworkPath, std::string& linkPath,
-  cmGeneratorTarget* target, bool useWatcomQuote)
+  cmLinkLineComputer* linkLineComputer, const std::string& config,
+  std::string& linkLibs, std::string& flags, std::string& linkFlags,
+  std::string& frameworkPath, std::string& linkPath, cmGeneratorTarget* target,
+  bool useWatcomQuote)
 {
 {
   const std::string buildType = cmSystemTools::UpperCase(config);
   const std::string buildType = cmSystemTools::UpperCase(config);
   const char* libraryLinkVariable =
   const char* libraryLinkVariable =
@@ -1203,8 +1205,9 @@ void cmLocalGenerator::GetTargetFlags(
           linkFlags += " ";
           linkFlags += " ";
         }
         }
       }
       }
-      this->OutputLinkLibraries(linkLibs, frameworkPath, linkPath, *target,
-                                false, false, useWatcomQuote);
+      this->OutputLinkLibraries(linkLineComputer, linkLibs, frameworkPath,
+                                linkPath, *target, false, false,
+                                useWatcomQuote);
     } break;
     } break;
     case cmState::EXECUTABLE: {
     case cmState::EXECUTABLE: {
       linkFlags += this->Makefile->GetSafeDefinition("CMAKE_EXE_LINKER_FLAGS");
       linkFlags += this->Makefile->GetSafeDefinition("CMAKE_EXE_LINKER_FLAGS");
@@ -1223,8 +1226,9 @@ void cmLocalGenerator::GetTargetFlags(
         return;
         return;
       }
       }
       this->AddLanguageFlags(flags, linkLanguage, buildType);
       this->AddLanguageFlags(flags, linkLanguage, buildType);
-      this->OutputLinkLibraries(linkLibs, frameworkPath, linkPath, *target,
-                                false, false, useWatcomQuote);
+      this->OutputLinkLibraries(linkLineComputer, linkLibs, frameworkPath,
+                                linkPath, *target, false, false,
+                                useWatcomQuote);
       if (cmSystemTools::IsOn(
       if (cmSystemTools::IsOn(
             this->Makefile->GetDefinition("BUILD_SHARED_LIBS"))) {
             this->Makefile->GetDefinition("BUILD_SHARED_LIBS"))) {
         std::string sFlagVar = std::string("CMAKE_SHARED_BUILD_") +
         std::string sFlagVar = std::string("CMAKE_SHARED_BUILD_") +
@@ -1383,51 +1387,15 @@ std::string cmLocalGenerator::GetTargetFortranFlags(
   return std::string();
   return std::string();
 }
 }
 
 
-std::string cmLocalGenerator::ConvertToLinkReference(std::string const& lib)
-{
-#if defined(_WIN32) && !defined(__CYGWIN__)
-  // Work-ardound command line parsing limitations in MSVC 6.0
-  if (this->Makefile->IsOn("MSVC60")) {
-    // Search for the last space.
-    std::string::size_type pos = lib.rfind(' ');
-    if (pos != lib.npos) {
-      // Find the slash after the last space, if any.
-      pos = lib.find('/', pos);
-
-      // Convert the portion of the path with a space to a short path.
-      std::string sp;
-      if (cmSystemTools::GetShortPath(lib.substr(0, pos).c_str(), sp)) {
-        // Append the rest of the path with no space.
-        sp += lib.substr(pos);
-
-        return sp;
-      }
-    }
-  }
-#endif
-
-  // Normal behavior.
-  std::string relLib = lib;
-  cmState::Directory stateDir = this->GetStateSnapshot().GetDirectory();
-  if (cmOutputConverter::ContainedInDirectory(
-        stateDir.GetCurrentBinary(), lib, stateDir)) {
-    relLib = cmOutputConverter::ForceToRelativePath(
-      stateDir.GetCurrentBinary(), lib);
-  }
-  return relLib;
-}
-
 /**
 /**
  * Output the linking rules on a command line.  For executables,
  * Output the linking rules on a command line.  For executables,
  * targetLibrary should be a NULL pointer.  For libraries, it should point
  * 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.
  * to the name of the library.  This will not link a library against itself.
  */
  */
-void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries,
-                                           std::string& frameworkPath,
-                                           std::string& linkPath,
-                                           cmGeneratorTarget& tgt, bool relink,
-                                           bool forResponseFile,
-                                           bool useWatcomQuote)
+void cmLocalGenerator::OutputLinkLibraries(
+  cmLinkLineComputer* linkLineComputer, std::string& linkLibraries,
+  std::string& frameworkPath, std::string& linkPath, cmGeneratorTarget& tgt,
+  bool relink, bool forResponseFile, bool useWatcomQuote)
 {
 {
   OutputFormat shellFormat =
   OutputFormat shellFormat =
     (forResponseFile) ? RESPONSE : ((useWatcomQuote) ? WATCOMQUOTE : SHELL);
     (forResponseFile) ? RESPONSE : ((useWatcomQuote) ? WATCOMQUOTE : SHELL);
@@ -1486,7 +1454,7 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries,
     }
     }
     if (li->IsPath) {
     if (li->IsPath) {
       linkLibs += this->ConvertToOutputFormat(
       linkLibs += this->ConvertToOutputFormat(
-        this->ConvertToLinkReference(li->Value), shellFormat);
+        linkLineComputer->ConvertToLinkReference(li->Value), shellFormat);
     } else {
     } else {
       linkLibs += li->Value;
       linkLibs += li->Value;
     }
     }

+ 5 - 4
Source/cmLocalGenerator.h

@@ -24,6 +24,7 @@ class cmGeneratorTarget;
 class cmGlobalGenerator;
 class cmGlobalGenerator;
 class cmMakefile;
 class cmMakefile;
 class cmSourceFile;
 class cmSourceFile;
+class cmLinkLineComputer;
 
 
 /** \class cmLocalGenerator
 /** \class cmLocalGenerator
  * \brief Create required build files for a directory.
  * \brief Create required build files for a directory.
@@ -312,7 +313,8 @@ public:
 
 
   /** Fill out these strings for the given target.  Libraries to link,
   /** Fill out these strings for the given target.  Libraries to link,
    *  flags, and linkflags. */
    *  flags, and linkflags. */
-  void GetTargetFlags(const std::string& config, std::string& linkLibs,
+  void GetTargetFlags(cmLinkLineComputer* linkLineComputer,
+                      const std::string& config, std::string& linkLibs,
                       std::string& flags, std::string& linkFlags,
                       std::string& flags, std::string& linkFlags,
                       std::string& frameworkPath, std::string& linkPath,
                       std::string& frameworkPath, std::string& linkPath,
                       cmGeneratorTarget* target, bool useWatcomQuote);
                       cmGeneratorTarget* target, bool useWatcomQuote);
@@ -345,7 +347,8 @@ public:
 
 
 protected:
 protected:
   ///! put all the libraries for a target on into the given stream
   ///! put all the libraries for a target on into the given stream
-  void OutputLinkLibraries(std::string& linkLibraries,
+  void OutputLinkLibraries(cmLinkLineComputer* linkLineComputer,
+                           std::string& linkLibraries,
                            std::string& frameworkPath, std::string& linkPath,
                            std::string& frameworkPath, std::string& linkPath,
                            cmGeneratorTarget&, bool relink,
                            cmGeneratorTarget&, bool relink,
                            bool forResponseFile, bool useWatcomQuote);
                            bool forResponseFile, bool useWatcomQuote);
@@ -370,8 +373,6 @@ protected:
   std::string& CreateSafeUniqueObjectFileName(const std::string& sin,
   std::string& CreateSafeUniqueObjectFileName(const std::string& sin,
                                               std::string const& dir_max);
                                               std::string const& dir_max);
 
 
-  virtual std::string ConvertToLinkReference(std::string const& lib);
-
   /** Check whether the native build system supports the given
   /** Check whether the native build system supports the given
       definition.  Issues a warning.  */
       definition.  Issues a warning.  */
   virtual bool CheckDefinition(std::string const& define) const;
   virtual bool CheckDefinition(std::string const& define) const;

+ 0 - 6
Source/cmLocalNinjaGenerator.cxx

@@ -120,12 +120,6 @@ cmGlobalNinjaGenerator* cmLocalNinjaGenerator::GetGlobalNinjaGenerator()
 
 
 // Virtual protected methods.
 // Virtual protected methods.
 
 
-std::string cmLocalNinjaGenerator::ConvertToLinkReference(
-  std::string const& lib)
-{
-  return this->GetGlobalNinjaGenerator()->ConvertToNinjaPath(lib);
-}
-
 std::string cmLocalNinjaGenerator::ConvertToIncludeReference(
 std::string cmLocalNinjaGenerator::ConvertToIncludeReference(
   std::string const& path, cmOutputConverter::OutputFormat format,
   std::string const& path, cmOutputConverter::OutputFormat format,
   bool forceFullPaths)
   bool forceFullPaths)

+ 0 - 2
Source/cmLocalNinjaGenerator.h

@@ -76,8 +76,6 @@ public:
   void AppendCustomCommandDeps(cmCustomCommandGenerator const& ccg,
   void AppendCustomCommandDeps(cmCustomCommandGenerator const& ccg,
                                cmNinjaDeps& ninjaDeps);
                                cmNinjaDeps& ninjaDeps);
 
 
-  std::string ConvertToLinkReference(std::string const& lib) CM_OVERRIDE;
-
   void ComputeObjectFilenames(
   void ComputeObjectFilenames(
     std::map<cmSourceFile const*, std::string>& mapping,
     std::map<cmSourceFile const*, std::string>& mapping,
     cmGeneratorTarget const* gt = CM_NULLPTR) CM_OVERRIDE;
     cmGeneratorTarget const* gt = CM_NULLPTR) CM_OVERRIDE;

+ 35 - 0
Source/cmMSVC60LinkLineComputer.cxx

@@ -0,0 +1,35 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+
+#include "cmMSVC60LinkLineComputer.h"
+
+#include "cmSystemTools.h"
+
+cmMSVC60LinkLineComputer::cmMSVC60LinkLineComputer(cmState::Directory stateDir)
+  : cmLinkLineComputer(stateDir)
+{
+}
+
+std::string cmMSVC60LinkLineComputer::ConvertToLinkReference(
+  std::string const& lib) const
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+  // Work-ardound command line parsing limitations in MSVC 6.0
+  // Search for the last space.
+  std::string::size_type pos = lib.rfind(' ');
+  if (pos != lib.npos) {
+    // Find the slash after the last space, if any.
+    pos = lib.find('/', pos);
+
+    // Convert the portion of the path with a space to a short path.
+    std::string sp;
+    if (cmSystemTools::GetShortPath(lib.substr(0, pos).c_str(), sp)) {
+      // Append the rest of the path with no space.
+      sp += lib.substr(pos);
+      return sp;
+    }
+  }
+#endif
+
+  return cmLinkLineComputer::ConvertToLinkReference(lib);
+}

+ 18 - 0
Source/cmMSVC60LinkLineComputer.h

@@ -0,0 +1,18 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+
+#ifndef cmMSVC60LinkLineComputer_h
+#define cmMSVC60LinkLineComputer_h
+
+#include "cmLinkLineComputer.h"
+
+class cmMSVC60LinkLineComputer : public cmLinkLineComputer
+{
+public:
+  cmMSVC60LinkLineComputer(cmState::Directory stateDir);
+
+  std::string ConvertToLinkReference(std::string const& input) const
+    CM_OVERRIDE;
+};
+
+#endif

+ 8 - 1
Source/cmMakefileExecutableTargetGenerator.cxx

@@ -5,6 +5,7 @@
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratorTarget.h"
 #include "cmGeneratorTarget.h"
 #include "cmGlobalUnixMakefileGenerator3.h"
 #include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmLinkLineComputer.h"
 #include "cmLocalGenerator.h"
 #include "cmLocalGenerator.h"
 #include "cmLocalUnixMakefileGenerator3.h"
 #include "cmLocalUnixMakefileGenerator3.h"
 #include "cmMakefile.h"
 #include "cmMakefile.h"
@@ -215,7 +216,13 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
   this->LocalGenerator->AppendFlags(
   this->LocalGenerator->AppendFlags(
     linkFlags, this->GeneratorTarget->GetProperty(linkFlagsConfig));
     linkFlags, this->GeneratorTarget->GetProperty(linkFlagsConfig));
 
 
-  this->AddModuleDefinitionFlag(linkFlags);
+  {
+    CM_AUTO_PTR<cmLinkLineComputer> linkLineComputer(
+      this->CreateLinkLineComputer(
+        this->LocalGenerator->GetStateSnapshot().GetDirectory()));
+
+    this->AddModuleDefinitionFlag(linkLineComputer.get(), linkFlags);
+  }
 
 
   // Construct a list of files associated with this executable that
   // Construct a list of files associated with this executable that
   // may need to be cleaned.
   // may need to be cleaned.

+ 13 - 2
Source/cmMakefileLibraryTargetGenerator.cxx

@@ -5,6 +5,7 @@
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratorTarget.h"
 #include "cmGeneratorTarget.h"
 #include "cmGlobalUnixMakefileGenerator3.h"
 #include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmLinkLineComputer.h"
 #include "cmLocalGenerator.h"
 #include "cmLocalGenerator.h"
 #include "cmLocalUnixMakefileGenerator3.h"
 #include "cmLocalUnixMakefileGenerator3.h"
 #include "cmMakefile.h"
 #include "cmMakefile.h"
@@ -159,7 +160,12 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
 
 
   this->LocalGenerator->AddConfigVariableFlags(
   this->LocalGenerator->AddConfigVariableFlags(
     extraFlags, "CMAKE_SHARED_LINKER_FLAGS", this->ConfigName);
     extraFlags, "CMAKE_SHARED_LINKER_FLAGS", this->ConfigName);
-  this->AddModuleDefinitionFlag(extraFlags);
+
+  CM_AUTO_PTR<cmLinkLineComputer> linkLineComputer(
+    this->CreateLinkLineComputer(
+      this->LocalGenerator->GetStateSnapshot().GetDirectory()));
+
+  this->AddModuleDefinitionFlag(linkLineComputer.get(), extraFlags);
 
 
   if (this->GeneratorTarget->GetProperty("LINK_WHAT_YOU_USE")) {
   if (this->GeneratorTarget->GetProperty("LINK_WHAT_YOU_USE")) {
     this->LocalGenerator->AppendFlags(extraFlags, " -Wl,--no-as-needed");
     this->LocalGenerator->AppendFlags(extraFlags, " -Wl,--no-as-needed");
@@ -184,7 +190,12 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
     extraFlags, this->GeneratorTarget->GetProperty(linkFlagsConfig));
     extraFlags, this->GeneratorTarget->GetProperty(linkFlagsConfig));
   this->LocalGenerator->AddConfigVariableFlags(
   this->LocalGenerator->AddConfigVariableFlags(
     extraFlags, "CMAKE_MODULE_LINKER_FLAGS", this->ConfigName);
     extraFlags, "CMAKE_MODULE_LINKER_FLAGS", this->ConfigName);
-  this->AddModuleDefinitionFlag(extraFlags);
+
+  CM_AUTO_PTR<cmLinkLineComputer> linkLineComputer(
+    this->CreateLinkLineComputer(
+      this->LocalGenerator->GetStateSnapshot().GetDirectory()));
+
+  this->AddModuleDefinitionFlag(linkLineComputer.get(), extraFlags);
 
 
   this->WriteLibraryRules(linkRuleVar, extraFlags, relink);
   this->WriteLibraryRules(linkRuleVar, extraFlags, relink);
 }
 }

+ 18 - 3
Source/cmMakefileTargetGenerator.cxx

@@ -10,6 +10,7 @@
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorTarget.h"
 #include "cmGeneratorTarget.h"
 #include "cmGlobalUnixMakefileGenerator3.h"
 #include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmLinkLineComputer.h"
 #include "cmLocalGenerator.h"
 #include "cmLocalGenerator.h"
 #include "cmLocalUnixMakefileGenerator3.h"
 #include "cmLocalUnixMakefileGenerator3.h"
 #include "cmMakefile.h"
 #include "cmMakefile.h"
@@ -1588,15 +1589,29 @@ std::string cmMakefileTargetGenerator::CreateResponseFile(
   return responseFileName;
   return responseFileName;
 }
 }
 
 
+cmLinkLineComputer* cmMakefileTargetGenerator::CreateLinkLineComputer(
+  cmState::Directory stateDir)
+{
+  if (this->Makefile->IsOn("MSVC60")) {
+    return this->GlobalGenerator->CreateMSVC60LinkLineComputer(stateDir);
+  }
+  return this->GlobalGenerator->CreateLinkLineComputer(stateDir);
+}
+
 void cmMakefileTargetGenerator::CreateLinkLibs(
 void cmMakefileTargetGenerator::CreateLinkLibs(
   std::string& linkLibs, bool relink, bool useResponseFile,
   std::string& linkLibs, bool relink, bool useResponseFile,
   std::vector<std::string>& makefile_depends, bool useWatcomQuote)
   std::vector<std::string>& makefile_depends, bool useWatcomQuote)
 {
 {
   std::string frameworkPath;
   std::string frameworkPath;
   std::string linkPath;
   std::string linkPath;
-  this->LocalGenerator->OutputLinkLibraries(linkLibs, frameworkPath, linkPath,
-                                            *this->GeneratorTarget, relink,
-                                            useResponseFile, useWatcomQuote);
+
+  CM_AUTO_PTR<cmLinkLineComputer> linkLineComputer(
+    this->CreateLinkLineComputer(
+      this->LocalGenerator->GetStateSnapshot().GetDirectory()));
+
+  this->LocalGenerator->OutputLinkLibraries(
+    linkLineComputer.get(), linkLibs, frameworkPath, linkPath,
+    *this->GeneratorTarget, relink, useResponseFile, useWatcomQuote);
   linkLibs = frameworkPath + linkPath + linkLibs;
   linkLibs = frameworkPath + linkPath + linkLibs;
 
 
   if (useResponseFile && linkLibs.find_first_not_of(' ') != linkLibs.npos) {
   if (useResponseFile && linkLibs.find_first_not_of(' ') != linkLibs.npos) {

+ 2 - 0
Source/cmMakefileTargetGenerator.h

@@ -139,6 +139,8 @@ protected:
                         std::vector<std::string>& makefile_commands,
                         std::vector<std::string>& makefile_commands,
                         std::vector<std::string>& makefile_depends);
                         std::vector<std::string>& makefile_depends);
 
 
+  cmLinkLineComputer* CreateLinkLineComputer(cmState::Directory stateDir);
+
   /** Create a response file with the given set of options.  Returns
   /** Create a response file with the given set of options.  Returns
       the relative path from the target build working directory to the
       the relative path from the target build working directory to the
       response file name.  */
       response file name.  */

+ 18 - 0
Source/cmNinjaLinkLineComputer.cxx

@@ -0,0 +1,18 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+
+#include "cmNinjaLinkLineComputer.h"
+#include "cmGlobalNinjaGenerator.h"
+
+cmNinjaLinkLineComputer::cmNinjaLinkLineComputer(
+  cmState::Directory stateDir, cmGlobalNinjaGenerator const* gg)
+  : cmLinkLineComputer(stateDir)
+  , GG(gg)
+{
+}
+
+std::string cmNinjaLinkLineComputer::ConvertToLinkReference(
+  std::string const& lib) const
+{
+  return GG->ConvertToNinjaPath(lib);
+}

+ 25 - 0
Source/cmNinjaLinkLineComputer.h

@@ -0,0 +1,25 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+
+#ifndef cmNinjaLinkLineComputer_h
+#define cmNinjaLinkLineComputer_h
+
+#include "cmLinkLineComputer.h"
+#include "cmState.h"
+
+class cmGlobalNinjaGenerator;
+
+class cmNinjaLinkLineComputer : public cmLinkLineComputer
+{
+public:
+  cmNinjaLinkLineComputer(cmState::Directory stateDir,
+                          cmGlobalNinjaGenerator const* gg);
+
+  std::string ConvertToLinkReference(std::string const& input) const
+    CM_OVERRIDE;
+
+private:
+  cmGlobalNinjaGenerator const* GG;
+};
+
+#endif

+ 10 - 4
Source/cmNinjaNormalTargetGenerator.cxx

@@ -8,6 +8,7 @@
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratorTarget.h"
 #include "cmGeneratorTarget.h"
 #include "cmGlobalNinjaGenerator.h"
 #include "cmGlobalNinjaGenerator.h"
+#include "cmLinkLineComputer.h"
 #include "cmLocalGenerator.h"
 #include "cmLocalGenerator.h"
 #include "cmLocalNinjaGenerator.h"
 #include "cmLocalNinjaGenerator.h"
 #include "cmMakefile.h"
 #include "cmMakefile.h"
@@ -470,9 +471,14 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
   vars["TARGET_FILE"] =
   vars["TARGET_FILE"] =
     localGen.ConvertToOutputFormat(targetOutputReal, cmOutputConverter::SHELL);
     localGen.ConvertToOutputFormat(targetOutputReal, cmOutputConverter::SHELL);
 
 
-  localGen.GetTargetFlags(this->GetConfigName(), vars["LINK_LIBRARIES"],
-                          vars["FLAGS"], vars["LINK_FLAGS"], frameworkPath,
-                          linkPath, &genTarget, useWatcomQuote);
+  CM_AUTO_PTR<cmLinkLineComputer> linkLineComputer(
+    this->GetGlobalGenerator()->CreateLinkLineComputer(
+      localGen.GetStateSnapshot().GetDirectory()));
+
+  localGen.GetTargetFlags(linkLineComputer.get(), this->GetConfigName(),
+                          vars["LINK_LIBRARIES"], vars["FLAGS"],
+                          vars["LINK_FLAGS"], frameworkPath, linkPath,
+                          &genTarget, useWatcomQuote);
   if (this->GetMakefile()->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS") &&
   if (this->GetMakefile()->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS") &&
       (gt.GetType() == cmState::SHARED_LIBRARY ||
       (gt.GetType() == cmState::SHARED_LIBRARY ||
        gt.IsExecutableWithExports())) {
        gt.IsExecutableWithExports())) {
@@ -497,7 +503,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
 
 
   this->addPoolNinjaVariable("JOB_POOL_LINK", &gt, vars);
   this->addPoolNinjaVariable("JOB_POOL_LINK", &gt, vars);
 
 
-  this->AddModuleDefinitionFlag(vars["LINK_FLAGS"]);
+  this->AddModuleDefinitionFlag(linkLineComputer.get(), vars["LINK_FLAGS"]);
   vars["LINK_FLAGS"] =
   vars["LINK_FLAGS"] =
     cmGlobalNinjaGenerator::EncodeLiteral(vars["LINK_FLAGS"]);
     cmGlobalNinjaGenerator::EncodeLiteral(vars["LINK_FLAGS"]);
 
 

+ 7 - 2
Source/cmServerProtocol.cxx

@@ -7,6 +7,7 @@
 #include "cmFileMonitor.h"
 #include "cmFileMonitor.h"
 #include "cmGeneratorTarget.h"
 #include "cmGeneratorTarget.h"
 #include "cmGlobalGenerator.h"
 #include "cmGlobalGenerator.h"
+#include "cmLinkLineComputer.h"
 #include "cmListFileCache.h"
 #include "cmListFileCache.h"
 #include "cmLocalGenerator.h"
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
 #include "cmMakefile.h"
@@ -728,8 +729,12 @@ static Json::Value DumpTarget(cmGeneratorTarget* target,
     std::string linkLanguageFlags;
     std::string linkLanguageFlags;
     std::string frameworkPath;
     std::string frameworkPath;
     std::string linkPath;
     std::string linkPath;
-    lg->GetTargetFlags(config, linkLibs, linkLanguageFlags, linkFlags,
-                       frameworkPath, linkPath, target, false);
+    CM_AUTO_PTR<cmLinkLineComputer> linkLineComputer(
+      lg->GetGlobalGenerator()->CreateLinkLineComputer(
+        lg->GetStateSnapshot().GetDirectory()));
+    lg->GetTargetFlags(linkLineComputer.get(), config, linkLibs,
+                       linkLanguageFlags, linkFlags, frameworkPath, linkPath,
+                       target, false);
 
 
     linkLibs = cmSystemTools::TrimWhitespace(linkLibs);
     linkLibs = cmSystemTools::TrimWhitespace(linkLibs);
     linkFlags = cmSystemTools::TrimWhitespace(linkFlags);
     linkFlags = cmSystemTools::TrimWhitespace(linkFlags);

+ 5 - 2
Source/cmake.cxx

@@ -12,6 +12,7 @@
 #include "cmGeneratorTarget.h"
 #include "cmGeneratorTarget.h"
 #include "cmGlobalGenerator.h"
 #include "cmGlobalGenerator.h"
 #include "cmGlobalGeneratorFactory.h"
 #include "cmGlobalGeneratorFactory.h"
+#include "cmLinkLineComputer.h"
 #include "cmLocalGenerator.h"
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
 #include "cmMakefile.h"
 #include "cmMessenger.h"
 #include "cmMessenger.h"
@@ -582,8 +583,10 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
     gg->CreateGenerationObjects();
     gg->CreateGenerationObjects();
     cmGeneratorTarget* gtgt = gg->FindGeneratorTarget(tgt->GetName());
     cmGeneratorTarget* gtgt = gg->FindGeneratorTarget(tgt->GetName());
     cmLocalGenerator* lg = gtgt->GetLocalGenerator();
     cmLocalGenerator* lg = gtgt->GetLocalGenerator();
-    lg->GetTargetFlags(buildType, linkLibs, flags, linkFlags, frameworkPath,
-                       linkPath, gtgt, false);
+    CM_AUTO_PTR<cmLinkLineComputer> linkLineComputer(
+      gg->CreateLinkLineComputer(lg->GetStateSnapshot().GetDirectory()));
+    lg->GetTargetFlags(linkLineComputer.get(), buildType, linkLibs, flags,
+                       linkFlags, frameworkPath, linkPath, gtgt, false);
     linkLibs = frameworkPath + linkPath + linkLibs;
     linkLibs = frameworkPath + linkPath + linkLibs;
 
 
     printf("%s\n", linkLibs.c_str());
     printf("%s\n", linkLibs.c_str());

+ 2 - 0
bootstrap

@@ -297,6 +297,8 @@ CMAKE_CXX_SOURCES="\
   cmFileTimeComparison \
   cmFileTimeComparison \
   cmGlobalUnixMakefileGenerator3 \
   cmGlobalUnixMakefileGenerator3 \
   cmLocalUnixMakefileGenerator3 \
   cmLocalUnixMakefileGenerator3 \
+  cmLinkLineComputer \
+  cmMSVC60LinkLineComputer \
   cmMakefileExecutableTargetGenerator \
   cmMakefileExecutableTargetGenerator \
   cmMakefileLibraryTargetGenerator \
   cmMakefileLibraryTargetGenerator \
   cmMakefileTargetGenerator \
   cmMakefileTargetGenerator \