[cmake-commits] king committed cmComputeLinkInformation.cxx 1.10 1.11 cmComputeLinkInformation.h 1.6 1.7 cmGlobalXCodeGenerator.cxx 1.182 1.183 cmInstallTargetGenerator.cxx 1.53 1.54 cmInstallTargetGenerator.h 1.21 1.22 cmLocalGenerator.cxx 1.261 1.262 cmLocalGenerator.h 1.100 1.101 cmLocalVisualStudio6Generator.cxx 1.139 1.140 cmLocalVisualStudio7Generator.cxx 1.214 1.215 cmTarget.cxx 1.183 1.184 cmTarget.h 1.99 1.100

cmake-commits at cmake.org cmake-commits at cmake.org
Tue Jan 29 15:07:35 EST 2008


Update of /cvsroot/CMake/CMake/Source
In directory public:/mounts/ram/cvs-serv17496/Source

Modified Files:
	cmComputeLinkInformation.cxx cmComputeLinkInformation.h 
	cmGlobalXCodeGenerator.cxx cmInstallTargetGenerator.cxx 
	cmInstallTargetGenerator.h cmLocalGenerator.cxx 
	cmLocalGenerator.h cmLocalVisualStudio6Generator.cxx 
	cmLocalVisualStudio7Generator.cxx cmTarget.cxx cmTarget.h 
Log Message:
ENH: Add cmTarget::GetLinkInformation method to allow several places in the generators to share link information while only computing it once per configuration for a target.  Use it to simplify the chrpath feature.


Index: cmLocalVisualStudio7Generator.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmLocalVisualStudio7Generator.cxx,v
retrieving revision 1.214
retrieving revision 1.215
diff -u -d -r1.214 -r1.215
--- cmLocalVisualStudio7Generator.cxx	22 Jan 2008 14:13:03 -0000	1.214
+++ cmLocalVisualStudio7Generator.cxx	29 Jan 2008 20:07:33 -0000	1.215
@@ -762,11 +762,12 @@
                            targetNameImport, targetNamePDB, configName);
 
     // Compute the link library and directory information.
-    cmComputeLinkInformation cli(&target, configName);
-    if(!cli.Compute())
+    cmComputeLinkInformation* pcli = target.GetLinkInformation(configName);
+    if(!pcli)
       {
       return;
       }
+    cmComputeLinkInformation& cli = *pcli;
     const char* linkLanguage = cli.GetLinkLanguage();
 
     // Compute the variable name to lookup standard libraries for this
@@ -831,11 +832,12 @@
                               targetNameImport, targetNamePDB, configName);
 
     // Compute the link library and directory information.
-    cmComputeLinkInformation cli(&target, configName);
-    if(!cli.Compute())
+    cmComputeLinkInformation* pcli = target.GetLinkInformation(configName);
+    if(!pcli)
       {
       return;
       }
+    cmComputeLinkInformation& cli = *pcli;
     const char* linkLanguage = cli.GetLinkLanguage();
 
     // Compute the variable name to lookup standard libraries for this

Index: cmLocalGenerator.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmLocalGenerator.h,v
retrieving revision 1.100
retrieving revision 1.101
diff -u -d -r1.100 -r1.101
--- cmLocalGenerator.h	23 Jan 2008 18:03:03 -0000	1.100
+++ cmLocalGenerator.h	29 Jan 2008 20:07:33 -0000	1.101
@@ -248,13 +248,6 @@
    */
   virtual std::string GetTargetDirectory(cmTarget const& target) const;
 
-  ///! Determine the arguments for the linker call, used also by 
-  /// cmInstallTargetGenerator
-  bool GetLinkerArgs(std::string& rpath, std::string& linkLibs,
-                     cmTarget& tgt, bool relink, unsigned int minRpathSize);
-  
-  bool IsChrpathAvailable(const cmTarget& target);
-
   /**
    * Get the level of backwards compatibility requested by the project
    * in this directory.  This is the value of the CMake variable

Index: cmLocalGenerator.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmLocalGenerator.cxx,v
retrieving revision 1.261
retrieving revision 1.262
diff -u -d -r1.261 -r1.262
--- cmLocalGenerator.cxx	28 Jan 2008 13:38:35 -0000	1.261
+++ cmLocalGenerator.cxx	29 Jan 2008 20:07:33 -0000	1.262
@@ -1483,70 +1483,33 @@
   return this->Convert(lib.c_str(), START_OUTPUT, SHELL);
 }
 
-bool cmLocalGenerator::GetLinkerArgs(std::string& rpath, 
-                                     std::string& linkLibs,
-                                     cmTarget& tgt,
-                                     bool relink,
-                                     unsigned int minRpathSize)
+/**
+ * Output the linking rules on a command line.  For executables,
+ * 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,
+                                           cmTarget& tgt,
+                                           bool relink)
 {
-  rpath = "";
-  // collect all the flags needed for linking libraries
-  linkLibs = "";
-
   const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE");
-
-  cmComputeLinkInformation cli(&tgt, config);
-  if(!cli.Compute())
-    {
-    return false;
-    }
-
-  const char* linkLanguage = cli.GetLinkLanguage();
-
-  // Embed runtime search paths if possible and if required.
-  bool outputRuntime = !this->Makefile->IsOn("CMAKE_SKIP_RPATH");
-
-  // Lookup rpath specification flags.
-  std::string runtimeFlag;
-  std::string runtimeSep;
-  if(tgt.GetType() != cmTarget::STATIC_LIBRARY)
+  cmComputeLinkInformation* pcli = tgt.GetLinkInformation(config);
+  if(!pcli)
     {
-    std::string runTimeFlagVar = "CMAKE_";
-    if(tgt.GetType() == cmTarget::EXECUTABLE)
-      {
-      runTimeFlagVar += "EXECUTABLE";
-      }
-    else
-      {
-      runTimeFlagVar += "SHARED_LIBRARY";
-      }
-    runTimeFlagVar += "_RUNTIME_";
-    runTimeFlagVar += linkLanguage;
-    runTimeFlagVar += "_FLAG";
-    std::string runTimeFlagSepVar = runTimeFlagVar + "_SEP";
-    runtimeFlag = this->Makefile->GetSafeDefinition(runTimeFlagVar.c_str());
-    runtimeSep = this->Makefile->GetSafeDefinition(runTimeFlagSepVar.c_str());
+    return;
     }
-  // concatenate all paths or no?
-  bool runtimeConcatenate = !runtimeSep.empty();
+  cmComputeLinkInformation& cli = *pcli;
 
-  const char* runtimeAlways =
-    this->Makefile->GetDefinition("CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH");
+  // Collect library linking flags command line options.
+  std::string linkLibs;
 
-  // Turn off rpath support if no flag is available to specify it.
-  if(runtimeFlag.empty())
-    {
-    outputRuntime = false;
-    runtimeAlways = 0;
-    }
+  const char* linkLanguage = cli.GetLinkLanguage();
 
   std::string libPathFlag = 
     this->Makefile->GetRequiredDefinition("CMAKE_LIBRARY_PATH_FLAG");
   std::string libPathTerminator = 
     this->Makefile->GetSafeDefinition("CMAKE_LIBRARY_PATH_TERMINATOR");
-  std::string libLinkFlag = 
-    this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FLAG");
-  
+
   // Flags to link an executable to shared libraries.
   std::string linkFlagsVar = "CMAKE_SHARED_LIBRARY_LINK_";
   linkFlagsVar += linkLanguage;
@@ -1595,146 +1558,55 @@
     linkLibs += " ";
     }
 
-  // Select whether to generate an rpath for the install tree or the
-  // build tree.
-  bool linking_for_install =
-    relink || tgt.GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH");
-  bool use_install_rpath =
-    outputRuntime && tgt.HaveInstallTreeRPATH() && linking_for_install;
-  bool use_build_rpath =
-    outputRuntime && tgt.HaveBuildTreeRPATH() && !linking_for_install;
-  bool use_link_rpath =
-    outputRuntime && linking_for_install &&
-    tgt.GetPropertyAsBool("INSTALL_RPATH_USE_LINK_PATH");
+  // Write the library flags to the build rule.
+  fout << linkLibs;
 
-  // Construct the RPATH.
+  // Get the RPATH entries.
   std::vector<std::string> runtimeDirs;
-  if(use_install_rpath)
-    {
-    const char* install_rpath = tgt.GetProperty("INSTALL_RPATH");
-    cmSystemTools::ExpandListArgument(install_rpath, runtimeDirs);
-    }
-  if(use_build_rpath || use_link_rpath)
+  cli.GetRPath(runtimeDirs, relink);
+
+  // Check what kind of rpath flags to use.
+  if(cli.GetRuntimeSep().empty())
     {
-    std::vector<std::string> const& rdirs = cli.GetRuntimeSearchPath();
-    for(std::vector<std::string>::const_iterator ri = rdirs.begin();
-        ri != rdirs.end(); ++ri)
+    // Each rpath entry gets its own option ("-R a -R b -R c")
+    std::string rpath;
+    for(std::vector<std::string>::iterator ri = runtimeDirs.begin();
+        ri != runtimeDirs.end(); ++ri)
       {
-      // Put this directory in the rpath if using build-tree rpath
-      // support or if using the link path as an rpath.
-      if(use_build_rpath)
-        {
-        runtimeDirs.push_back(*ri);
-        }
-      else if(use_link_rpath)
-        {
-        // Do not add any path inside the source or build tree.
-        const char* topSourceDir = this->Makefile->GetHomeDirectory();
-        const char* topBinaryDir = this->Makefile->GetHomeOutputDirectory();
-        if(!cmSystemTools::ComparePath(ri->c_str(), topSourceDir) &&
-           !cmSystemTools::ComparePath(ri->c_str(), topBinaryDir) &&
-           !cmSystemTools::IsSubDirectory(ri->c_str(), topSourceDir) &&
-           !cmSystemTools::IsSubDirectory(ri->c_str(), topBinaryDir))
-          {
-          runtimeDirs.push_back(*ri);
-          }
-        }
+      rpath += cli.GetRuntimeFlag();
+      rpath += this->Convert(ri->c_str(), FULL, SHELL, false);
+      rpath += " ";
       }
+    fout << rpath;
     }
-  if(runtimeAlways)
-    {
-    // Add runtime paths required by the platform to always be
-    // present.  This is done even when skipping rpath support.
-    cmSystemTools::ExpandListArgument(runtimeAlways, runtimeDirs);
-    }
-
-  // Convert the runtime directory names for use in the build file.
-  for(std::vector<std::string>::iterator ri = runtimeDirs.begin();
-      ri != runtimeDirs.end(); ++ri)
+  else
     {
-    *ri = this->Convert(ri->c_str(), FULL, SHELL, false);
-    }
+    // All rpath entries are combined ("-Wl,-rpath,a:b:c").
+    std::string rpath = cli.GetRPathString(relink);
 
-  if(!runtimeDirs.empty())
-    {
-    // For the runtime search directories, do a "-Wl,-rpath,a:b:c" or
-    // a "-R a -R b -R c" type link line
-    rpath += runtimeFlag;
-    std::vector<std::string>::iterator itr = runtimeDirs.begin();
-    rpath += *itr;
-    ++itr;
-    for( ; itr != runtimeDirs.end(); ++itr )
+    // If not relinking, make sure the rpath string is long enough to
+    // support a subsequent chrpath on installation.
+    if(!relink)
       {
-      if(runtimeConcatenate)
-        {
-        rpath += runtimeSep;
-        rpath += *itr;
-        }
-      else
+      std::string::size_type minLength = cli.GetChrpathString().size();
+      while(rpath.size() < minLength)
         {
-        rpath += " ";
-        rpath += runtimeFlag;
-        rpath += *itr;
+        rpath += cli.GetRuntimeSep();
         }
       }
-    }
 
-  while (rpath.size() < minRpathSize)
-    {
-    if (rpath.size()==0)
+    // Store the rpath option in the stream.
+    if(!rpath.empty())
       {
-      rpath += runtimeFlag;
+      fout << cli.GetRuntimeFlag();
+      fout << this->EscapeForShell(rpath.c_str(), true);
+      fout << " ";
       }
-
-    rpath += runtimeSep;
     }
-  return true;
-}
-
-/**
- * Output the linking rules on a command line.  For executables,
- * 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,
-                                           cmTarget& tgt,
-                                           bool relink)
-{
-  std::string rpath;
-  std::string linkLibs;
-  unsigned int minBuildRpathSize = 0;
-  
-  if ((relink==false) 
-    && this->Makefile->IsOn("CMAKE_USE_CHRPATH") 
-    && (tgt.IsChrpathAvailable()))
-    {
-    std::string installRpath;
-    std::string dummy;
-    this->GetLinkerArgs(installRpath, dummy, tgt, true, 0);
-    minBuildRpathSize = static_cast<unsigned int>(installRpath.size());
-    }
-
-  if (!this->GetLinkerArgs(rpath, linkLibs, tgt, relink, minBuildRpathSize))
-    {
-    return;
-    }
-
-  const char* linkLanguage = 
-    tgt.GetLinkerLanguage(this->GetGlobalGenerator());
-  if(!linkLanguage)
-    {
-    cmSystemTools::
-      Error("CMake can not determine linker language for target:",
-            tgt.GetName());
-    return;
-    }
-
-  fout << linkLibs;
-  fout << rpath << " ";
 
   // Add standard libraries for this language.
   std::string standardLibsVar = "CMAKE_";
-  standardLibsVar += linkLanguage;
+  standardLibsVar += cli.GetLinkLanguage();
   standardLibsVar += "_STANDARD_LIBRARIES";
   if(const char* stdLibs =
      this->Makefile->GetDefinition(standardLibsVar.c_str()))

Index: cmGlobalXCodeGenerator.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmGlobalXCodeGenerator.cxx,v
retrieving revision 1.182
retrieving revision 1.183
diff -u -d -r1.182 -r1.183
--- cmGlobalXCodeGenerator.cxx	28 Jan 2008 18:05:58 -0000	1.182
+++ cmGlobalXCodeGenerator.cxx	29 Jan 2008 20:07:33 -0000	1.183
@@ -2105,11 +2105,12 @@
       }
 
     // Compute the link library and directory information.
-    cmComputeLinkInformation cli(cmtarget, configName);
-    if(!cli.Compute())
+    cmComputeLinkInformation* pcli = cmtarget->GetLinkInformation(configName);
+    if(!pcli)
       {
       continue;
       }
+    cmComputeLinkInformation& cli = *pcli;
 
     // Add dependencies directly on library files.
     {

Index: cmInstallTargetGenerator.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmInstallTargetGenerator.h,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- cmInstallTargetGenerator.h	28 Jan 2008 13:38:35 -0000	1.21
+++ cmInstallTargetGenerator.h	29 Jan 2008 20:07:33 -0000	1.22
@@ -58,6 +58,7 @@
                                const char* config,
                                const std::string& toDestDirPath);
   void AddChrpathPatchRule(std::ostream& os, Indent const& indent,
+                           const char* config,
                            std::string const& toDestDirPath);
   
   void AddStripRule(std::ostream& os, Indent const& indent,

Index: cmComputeLinkInformation.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmComputeLinkInformation.cxx,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- cmComputeLinkInformation.cxx	28 Jan 2008 18:05:58 -0000	1.10
+++ cmComputeLinkInformation.cxx	29 Jan 2008 20:07:33 -0000	1.11
@@ -168,6 +168,12 @@
   // Get the language used for linking this target.
   this->LinkLanguage =
     this->Target->GetLinkerLanguage(this->GlobalGenerator);
+  if(!this->LinkLanguage)
+    {
+    // The Compute method will do nothing, so skip the rest of the
+    // initialization.
+    return;
+    }
 
   // Check whether we should use an import library for linking a target.
   this->UseImportLibrary =
@@ -194,6 +200,31 @@
   this->LibLinkSuffix =
     this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX");
 
+  // Get options needed to specify RPATHs.
+  this->RuntimeUseChrpath = false;
+  if(this->Target->GetType() != cmTarget::STATIC_LIBRARY)
+    {
+    std::string rtVar = "CMAKE_";
+    if(this->Target->GetType() == cmTarget::EXECUTABLE)
+      {
+      rtVar += "EXECUTABLE";
+      }
+    else
+      {
+      rtVar += "SHARED_LIBRARY";
+      }
+    rtVar += "_RUNTIME_";
+    rtVar += this->LinkLanguage;
+    rtVar += "_FLAG";
+    std::string rtSepVar = rtVar + "_SEP";
+    this->RuntimeFlag = this->Makefile->GetSafeDefinition(rtVar.c_str());
+    this->RuntimeSep = this->Makefile->GetSafeDefinition(rtSepVar.c_str());
+    this->RuntimeAlways =
+      (this->Makefile->
+       GetSafeDefinition("CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH"));
+    this->RuntimeUseChrpath = this->Target->IsChrpathUsed();
+    }
+
   // Get link type information.
   this->ComputeLinkTypeInfo();
 
@@ -1227,3 +1258,105 @@
     }
   cmSystemTools::Message(e.str().c_str());
 }
+
+//----------------------------------------------------------------------------
+void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
+                                        bool for_install)
+{
+  // Select whether to generate runtime search directories.
+  bool outputRuntime =
+    !this->Makefile->IsOn("CMAKE_SKIP_RPATH") && !this->RuntimeFlag.empty();
+
+  // Select whether to generate an rpath for the install tree or the
+  // build tree.
+  bool linking_for_install =
+    (for_install ||
+     this->Target->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"));
+  bool use_install_rpath =
+    (outputRuntime && this->Target->HaveInstallTreeRPATH() &&
+     linking_for_install);
+  bool use_build_rpath =
+    (outputRuntime && this->Target->HaveBuildTreeRPATH() &&
+     !linking_for_install);
+  bool use_link_rpath =
+    outputRuntime && linking_for_install &&
+    this->Target->GetPropertyAsBool("INSTALL_RPATH_USE_LINK_PATH");
+
+  // Construct the RPATH.
+  if(use_install_rpath)
+    {
+    const char* install_rpath = this->Target->GetProperty("INSTALL_RPATH");
+    cmSystemTools::ExpandListArgument(install_rpath, runtimeDirs);
+    }
+  if(use_build_rpath || use_link_rpath)
+    {
+    std::vector<std::string> const& rdirs = this->GetRuntimeSearchPath();
+    for(std::vector<std::string>::const_iterator ri = rdirs.begin();
+        ri != rdirs.end(); ++ri)
+      {
+      // Put this directory in the rpath if using build-tree rpath
+      // support or if using the link path as an rpath.
+      if(use_build_rpath)
+        {
+        runtimeDirs.push_back(*ri);
+        }
+      else if(use_link_rpath)
+        {
+        // Do not add any path inside the source or build tree.
+        const char* topSourceDir = this->Makefile->GetHomeDirectory();
+        const char* topBinaryDir = this->Makefile->GetHomeOutputDirectory();
+        if(!cmSystemTools::ComparePath(ri->c_str(), topSourceDir) &&
+           !cmSystemTools::ComparePath(ri->c_str(), topBinaryDir) &&
+           !cmSystemTools::IsSubDirectory(ri->c_str(), topSourceDir) &&
+           !cmSystemTools::IsSubDirectory(ri->c_str(), topBinaryDir))
+          {
+          runtimeDirs.push_back(*ri);
+          }
+        }
+      }
+    }
+
+  // Add runtime paths required by the platform to always be
+  // present.  This is done even when skipping rpath support.
+  cmSystemTools::ExpandListArgument(this->RuntimeAlways.c_str(), runtimeDirs);
+}
+
+//----------------------------------------------------------------------------
+std::string cmComputeLinkInformation::GetRPathString(bool for_install)
+{
+  // Get the directories to use.
+  std::vector<std::string> runtimeDirs;
+  this->GetRPath(runtimeDirs, for_install);
+
+  // Concatenate the paths.
+  std::string rpath;
+  const char* sep = "";
+  for(std::vector<std::string>::const_iterator ri = runtimeDirs.begin();
+      ri != runtimeDirs.end(); ++ri)
+    {
+    // Separate from previous path.
+    rpath += sep;
+    sep = this->GetRuntimeSep().c_str();
+
+    // Add this path.
+    rpath += *ri;
+    }
+  return rpath;
+}
+
+//----------------------------------------------------------------------------
+std::string cmComputeLinkInformation::GetChrpathString()
+{
+  if(!this->RuntimeUseChrpath)
+    {
+    return "";
+    }
+
+  return this->GetRPathString(true);
+}
+
+//----------------------------------------------------------------------------
+std::string cmComputeLinkInformation::GetChrpathTool()
+{
+  return this->Makefile->GetSafeDefinition("CMAKE_CHRPATH");
+}

Index: cmComputeLinkInformation.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmComputeLinkInformation.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- cmComputeLinkInformation.h	27 Jan 2008 18:42:49 -0000	1.6
+++ cmComputeLinkInformation.h	29 Jan 2008 20:07:33 -0000	1.7
@@ -50,6 +50,12 @@
   std::vector<std::string> const& GetFrameworkPaths();
   const char* GetLinkLanguage() const { return this->LinkLanguage; }
   std::vector<std::string> const& GetRuntimeSearchPath();
+  std::string const& GetRuntimeFlag() const { return this->RuntimeFlag; }
+  std::string const& GetRuntimeSep() const { return this->RuntimeSep; }
+  void GetRPath(std::vector<std::string>& runtimeDirs, bool for_install);
+  std::string GetRPathString(bool for_install);
+  std::string GetChrpathString();
+  std::string GetChrpathTool();
 private:
   void AddItem(std::string const& item, cmTarget* tgt);
 
@@ -76,6 +82,10 @@
   std::string LibLinkFlag;
   std::string LibLinkFileFlag;
   std::string LibLinkSuffix;
+  std::string RuntimeFlag;
+  std::string RuntimeSep;
+  std::string RuntimeAlways;
+  bool RuntimeUseChrpath;
 
   // Link type adjustment.
   void ComputeLinkTypeInfo();

Index: cmLocalVisualStudio6Generator.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmLocalVisualStudio6Generator.cxx,v
retrieving revision 1.139
retrieving revision 1.140
diff -u -d -r1.139 -r1.140
--- cmLocalVisualStudio6Generator.cxx	28 Jan 2008 13:38:35 -0000	1.139
+++ cmLocalVisualStudio6Generator.cxx	29 Jan 2008 20:07:33 -0000	1.140
@@ -1570,11 +1570,12 @@
                      std::string& options)
 {
   // Compute the link information for this configuration.
-  cmComputeLinkInformation cli(&target, configName);
-  if(!cli.Compute())
+  cmComputeLinkInformation* pcli = target.GetLinkInformation(configName);
+  if(!pcli)
     {
     return;
     }
+  cmComputeLinkInformation& cli = *pcli;
   typedef cmComputeLinkInformation::ItemVector ItemVector;
   ItemVector const& linkLibs = cli.GetItems();
   std::vector<std::string> const& linkDirs = cli.GetDirectories();

Index: cmTarget.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmTarget.h,v
retrieving revision 1.99
retrieving revision 1.100
diff -u -d -r1.99 -r1.100
--- cmTarget.h	28 Jan 2008 19:46:16 -0000	1.99
+++ cmTarget.h	29 Jan 2008 20:07:33 -0000	1.100
@@ -24,6 +24,7 @@
 class cmMakefile;
 class cmSourceFile;
 class cmGlobalGenerator;
+class cmComputeLinkInformation;
 
 /** \class cmTarget
  * \brief Represent a library or executable target loaded from a makefile.
@@ -35,6 +36,7 @@
 {
 public:
   cmTarget();
+  ~cmTarget();
   enum TargetType { EXECUTABLE, STATIC_LIBRARY,
                     SHARED_LIBRARY, MODULE_LIBRARY, UTILITY, GLOBAL_TARGET,
                     INSTALL_FILES, INSTALL_PROGRAMS, INSTALL_DIRECTORY};
@@ -289,13 +291,15 @@
 
   bool HaveBuildTreeRPATH();
   bool HaveInstallTreeRPATH();
-  
-  /// return true if chrpath might work for this target
-  bool IsChrpathAvailable();
+
+  /** Return true if chrpath might work for this target */
+  bool IsChrpathUsed();
 
   std::string GetInstallNameDirForBuildTree(const char* config);
   std::string GetInstallNameDirForInstallTree(const char* config);
 
+  cmComputeLinkInformation* GetLinkInformation(const char* config);
+
   // Get the properties
   cmPropertyMap &GetProperties() { return this->Properties; };
 
@@ -462,6 +466,8 @@
   ImportInfo const* GetImportInfo(const char* config);
   void ComputeImportInfo(std::string const& desired_config, ImportInfo& info);
 
+  std::map<cmStdString, cmComputeLinkInformation*> LinkInformation;
+
   // The cmMakefile instance that owns this target.  This should
   // always be set.
   cmMakefile* Makefile;

Index: cmInstallTargetGenerator.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmInstallTargetGenerator.cxx,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -d -r1.53 -r1.54
--- cmInstallTargetGenerator.cxx	28 Jan 2008 19:46:16 -0000	1.53
+++ cmInstallTargetGenerator.cxx	29 Jan 2008 20:07:33 -0000	1.54
@@ -16,6 +16,7 @@
 =========================================================================*/
 #include "cmInstallTargetGenerator.h"
 
+#include "cmComputeLinkInformation.h"
 #include "cmGlobalGenerator.h"
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
@@ -283,7 +284,7 @@
 
   os << indent << "IF(EXISTS \"" << toDestDirPath << "\")\n";
   this->AddInstallNamePatchRule(os, indent.Next(), config, toDestDirPath);
-  this->AddChrpathPatchRule(os, indent.Next(), toDestDirPath);
+  this->AddChrpathPatchRule(os, indent.Next(), config, toDestDirPath);
   this->AddRanlibRule(os, indent.Next(), type, toDestDirPath);
   this->AddStripRule(os, indent.Next(), type, toDestDirPath);
   os << indent << "ENDIF(EXISTS \"" << toDestDirPath << "\")\n";
@@ -487,7 +488,7 @@
 void
 cmInstallTargetGenerator
 ::AddChrpathPatchRule(std::ostream& os, Indent const& indent,
-                      std::string const& toDestDirPath)
+                      const char* config, std::string const& toDestDirPath)
 {
   if(this->ImportLibrary ||
      !(this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
@@ -497,40 +498,24 @@
     return;
     }
 
-  if((this->Target->GetMakefile()->IsOn("CMAKE_USE_CHRPATH")==false)
-      || (this->Target->IsChrpathAvailable()==false))
+  if(!this->Target->IsChrpathUsed())
     {
     return;
     }
 
-  // Fix the RPATH in installed ELF binaries using chrpath.
-  std::string chrpathTool =
-    this->Target->GetMakefile()->GetSafeDefinition("CMAKE_CHRPATH");
-
-  std::string installRpath;
-  std::string dummy;
-  this->Target->GetMakefile()->GetLocalGenerator()->GetLinkerArgs(
-                                  installRpath, dummy, *this->Target, true, 0);
-
-  const char* linkLanguage = this->Target->GetLinkerLanguage(this->Target->
-                     GetMakefile()->GetLocalGenerator()->GetGlobalGenerator());
-  if (linkLanguage==0)
+  // Get the link information for this target.
+  // It can provide the RPATH.
+  cmComputeLinkInformation* cli = this->Target->GetLinkInformation(config);
+  if(!cli)
     {
     return;
     }
 
-  std::string runTimeFlagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
-  runTimeFlagVar += linkLanguage;
-  runTimeFlagVar += "_FLAG";
-
-  std::string runtimeFlag = 
-        this->Target->GetMakefile()->GetSafeDefinition(runTimeFlagVar.c_str());
+  // Get the install RPATH from the link information.
+  std::string newRpath = cli->GetChrpathString();
 
-  const char* newRpath=installRpath.c_str();
-  if (strstr(installRpath.c_str(), runtimeFlag.c_str())==installRpath.c_str())
-    {
-    newRpath = installRpath.c_str()+strlen(runtimeFlag.c_str());
-    }
+  // Fix the RPATH in installed ELF binaries using chrpath.
+  std::string chrpathTool = cli->GetChrpathTool();
 
   // Write a rule to run chrpath to set the install-tree RPATH
   os << indent << "EXECUTE_PROCESS(COMMAND \"" << chrpathTool;

Index: cmTarget.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmTarget.cxx,v
retrieving revision 1.183
retrieving revision 1.184
diff -u -d -r1.183 -r1.184
--- cmTarget.cxx	28 Jan 2008 20:12:12 -0000	1.183
+++ cmTarget.cxx	29 Jan 2008 20:07:33 -0000	1.184
@@ -20,6 +20,7 @@
 #include "cmSourceFile.h"
 #include "cmLocalGenerator.h"
 #include "cmGlobalGenerator.h"
+#include "cmComputeLinkInformation.h"
 #include <map>
 #include <set>
 #include <queue>
@@ -41,6 +42,17 @@
 }
 
 //----------------------------------------------------------------------------
+cmTarget::~cmTarget()
+{
+  for(std::map<cmStdString, cmComputeLinkInformation*>::iterator
+        i = this->LinkInformation.begin();
+      i != this->LinkInformation.end(); ++i)
+    {
+    delete i->second;
+    }
+}
+
+//----------------------------------------------------------------------------
 void cmTarget::DefineProperties(cmake *cm)
 {
   cm->DefineProperty
@@ -2531,12 +2543,6 @@
     return false;
     }
 
-  if(this->Makefile->IsOn("CMAKE_USE_CHRPATH") 
-     && (this->IsChrpathAvailable()))
-    {
-    return false;
-    }
-
   // If skipping all rpaths completely then no relinking is needed.
   if(this->Makefile->IsOn("CMAKE_SKIP_RPATH"))
     {
@@ -2549,6 +2555,12 @@
     return false;
     }
 
+  // If chrpath is going to be used no relinking is needed.
+  if(this->IsChrpathUsed())
+    {
+    return false;
+    }
+
   // Check for rpath support on this platform.
   if(const char* ll = this->GetLinkerLanguage(
        this->Makefile->GetLocalGenerator()->GetGlobalGenerator()))
@@ -2809,35 +2821,28 @@
     }
 }
 
-bool cmTarget::IsChrpathAvailable()
+//----------------------------------------------------------------------------
+bool cmTarget::IsChrpathUsed()
 {
-  //only return true if chrpath has been found (happens only if the executable 
-  // format is ELF) and if the separator is not empty
-  if (this->Makefile->IsSet("CMAKE_CHRPATH")==false)
-    {
-    return false;
-    }
-
-  const char* linkLanguage = this->GetLinkerLanguage(this->Makefile->
-                                    GetLocalGenerator()->GetGlobalGenerator());
-  if (linkLanguage==0)
-    {
-    return false;
-    }
-
-  std::string runTimeFlagSepVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
-  runTimeFlagSepVar += linkLanguage;
-  runTimeFlagSepVar += "_FLAG_SEP";
-
-  std::string runtimeSep = 
-                  this->Makefile->GetSafeDefinition(runTimeFlagSepVar.c_str());
-
-  if (runtimeSep.size()<=0)
+  // Enable use of "chrpath" if it is available, the user has turned
+  // on the feature, and the rpath flag uses a separator.
+  if(const char* ll = this->GetLinkerLanguage(
+       this->Makefile->GetLocalGenerator()->GetGlobalGenerator()))
     {
-    return 0;
+    std::string sepVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
+    sepVar += ll;
+    sepVar += "_FLAG_SEP";
+    const char* sep = this->Makefile->GetDefinition(sepVar.c_str());
+    if(sep && *sep)
+      {
+      if(this->Makefile->IsSet("CMAKE_CHRPATH") &&
+         this->Makefile->IsOn("CMAKE_USE_CHRPATH"))
+        {
+        return true;
+        }
+      }
     }
-
-  return true;
+  return false;
 }
 
 //----------------------------------------------------------------------------
@@ -3044,3 +3049,29 @@
     return 0;
     }
 }
+
+//----------------------------------------------------------------------------
+cmComputeLinkInformation*
+cmTarget::GetLinkInformation(const char* config)
+{
+  // Lookup any existing information for this configuration.
+  std::map<cmStdString, cmComputeLinkInformation*>::iterator
+    i = this->LinkInformation.find(config?config:"");
+  if(i == this->LinkInformation.end())
+    {
+    // Compute information for this configuration.
+    cmComputeLinkInformation* info =
+      new cmComputeLinkInformation(this, config);
+    if(!info || !info->Compute())
+      {
+      delete info;
+      info = 0;
+      }
+
+    // Store the information for this configuration.
+    std::map<cmStdString, cmComputeLinkInformation*>::value_type
+      entry(config?config:"", info);
+    i = this->LinkInformation.insert(entry).first;
+    }
+  return i->second;
+}



More information about the Cmake-commits mailing list