[cmake-commits] alex committed cmInstallTargetGenerator.cxx 1.47 1.48 cmInstallTargetGenerator.h 1.18 1.19 cmLocalGenerator.cxx 1.241 1.242 cmLocalGenerator.h 1.86 1.87 cmTarget.cxx 1.168 1.169 cmTarget.h 1.92 1.93

cmake-commits at cmake.org cmake-commits at cmake.org
Tue Dec 18 17:50:29 EST 2007


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

Modified Files:
	cmInstallTargetGenerator.cxx cmInstallTargetGenerator.h 
	cmLocalGenerator.cxx cmLocalGenerator.h cmTarget.cxx 
	cmTarget.h 
Log Message:
ENH: add support for chrpath, so the RPATH in ELF files can be changed when
installing without having to link the target again -> can save a lot of time

chrpath is handled very similar to install_name_tool on the mac. If the
RPATH in the build tree file is to short, it is padded using the separator
character. 
This is currently disabled by default, it can be enabled using the option
CMAKE_USE_CHRPATH. There are additional checks whether it is safe to enable
it. I will rework them and use FILE(READ) instead to detect whether the
binaries are actually ELF files.

chrpath is available here 
http://www.tux.org/pub/X-Windows/ftp.hungry.com/chrpath/
or kde svn (since a few days): http://websvn.kde.org/trunk/kdesupport/chrpath/

Alex


Index: cmLocalGenerator.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmLocalGenerator.cxx,v
retrieving revision 1.241
retrieving revision 1.242
diff -u -d -r1.241 -r1.242
--- cmLocalGenerator.cxx	26 Nov 2007 22:57:39 -0000	1.241
+++ cmLocalGenerator.cxx	18 Dec 2007 22:50:27 -0000	1.242
@@ -1479,7 +1479,8 @@
 bool cmLocalGenerator::GetLinkerArgs(std::string& rpath, 
                                      std::string& linkLibs,
                                      cmTarget& tgt,
-                                     bool relink)
+                                     bool relink,
+                                     int minRpathSize)
 {
   rpath = "";
   // collect all the flags needed for linking libraries
@@ -1656,6 +1657,18 @@
         }
       }
     }
+
+  if (rpath.size()<minRpathSize)
+    {
+    if (rpath.size()==0)
+      {
+      rpath += runtimeFlag;
+      }
+    while (rpath.size() < minRpathSize)
+      {
+      rpath += runtimeSep;
+      }
+    }
   return true;
 }
 
@@ -1670,7 +1683,19 @@
 {
   std::string rpath;
   std::string linkLibs;
-  if (!this->GetLinkerArgs(rpath, linkLibs, tgt, relink))
+  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=installRpath.size();
+    }
+
+  if (!this->GetLinkerArgs(rpath, linkLibs, tgt, relink, minBuildRpathSize))
     {
     return;
     }

Index: cmLocalGenerator.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmLocalGenerator.h,v
retrieving revision 1.86
retrieving revision 1.87
diff -u -d -r1.86 -r1.87
--- cmLocalGenerator.h	26 Nov 2007 22:57:39 -0000	1.86
+++ cmLocalGenerator.h	18 Dec 2007 22:50:27 -0000	1.87
@@ -242,6 +242,13 @@
    */
   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, int minRpathSize);
+  
+  bool IsChrpathAvailable(const cmTarget& target);
+
 protected:
 
   /** Construct a comment for a custom command.  */
@@ -258,10 +265,6 @@
   ///! put all the libraries for a target on into the given stream
   virtual void OutputLinkLibraries(std::ostream&, cmTarget&, bool relink);
   
-  ///! Determine the arguments for the linker call
-  bool GetLinkerArgs(std::string& rpath, std::string& linkLibs,
-                     cmTarget& tgt, bool relink);
-
   // Expand rule variables in CMake of the type found in language rules
   void ExpandRuleVariables(std::string& string,
                            const RuleVariables& replaceValues);

Index: cmInstallTargetGenerator.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmInstallTargetGenerator.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- cmInstallTargetGenerator.h	24 Aug 2007 17:30:40 -0000	1.18
+++ cmInstallTargetGenerator.h	18 Dec 2007 22:50:27 -0000	1.19
@@ -54,6 +54,9 @@
   void AddInstallNamePatchRule(std::ostream& os, Indent const& indent,
                                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,
                     cmTarget::TargetType type,
                     const std::string& toDestDirPath);

Index: cmTarget.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmTarget.h,v
retrieving revision 1.92
retrieving revision 1.93
diff -u -d -r1.92 -r1.93
--- cmTarget.h	10 Oct 2007 15:06:14 -0000	1.92
+++ cmTarget.h	18 Dec 2007 22:50:27 -0000	1.93
@@ -277,6 +277,9 @@
 
   bool HaveBuildTreeRPATH();
   bool HaveInstallTreeRPATH();
+  
+  /// return true if chrpath might work for this target
+  bool IsChrpathAvailable();
 
   std::string GetInstallNameDirForBuildTree(const char* config);
   std::string GetInstallNameDirForInstallTree(const char* config);

Index: cmInstallTargetGenerator.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmInstallTargetGenerator.cxx,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -d -r1.47 -r1.48
--- cmInstallTargetGenerator.cxx	10 Oct 2007 15:06:14 -0000	1.47
+++ cmInstallTargetGenerator.cxx	18 Dec 2007 22:50:27 -0000	1.48
@@ -305,6 +305,7 @@
 
   os << indent << "IF(EXISTS \"" << toDestDirPath << "\")\n";
   this->AddInstallNamePatchRule(os, indent.Next(), config, 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";
@@ -506,6 +507,60 @@
 
 //----------------------------------------------------------------------------
 void
+cmInstallTargetGenerator
+::AddChrpathPatchRule(std::ostream& os, Indent const& indent,
+                          const char* config, std::string const& toDestDirPath)
+{
+  if(this->ImportLibrary ||
+     !(this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
+       this->Target->GetType() == cmTarget::MODULE_LIBRARY ||
+       this->Target->GetType() == cmTarget::EXECUTABLE))
+    {
+    return;
+    }
+
+  if((this->Target->GetMakefile()->IsOn("CMAKE_USE_CHRPATH")==false)
+      || (this->Target->IsChrpathAvailable()==false))
+    {
+    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)
+    {
+    return;
+    }
+
+  std::string runTimeFlagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
+  runTimeFlagVar += linkLanguage;
+  runTimeFlagVar += "_FLAG";
+
+  std::string runtimeFlag = 
+        this->Target->GetMakefile()->GetSafeDefinition(runTimeFlagVar.c_str());
+
+  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());
+    }
+
+  // Write a rule to run chrpath to set the install-tree RPATH
+  os << indent << "EXECUTE_PROCESS(COMMAND \"" << chrpathTool;
+  os << "\" -r \"" << newRpath << "\" \"" << toDestDirPath << "\")\n";
+}
+
+//----------------------------------------------------------------------------
+void
 cmInstallTargetGenerator::AddStripRule(std::ostream& os,
                                        Indent const& indent,
                                        cmTarget::TargetType type,

Index: cmTarget.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmTarget.cxx,v
retrieving revision 1.168
retrieving revision 1.169
diff -u -d -r1.168 -r1.169
--- cmTarget.cxx	17 Dec 2007 15:12:22 -0000	1.168
+++ cmTarget.cxx	18 Dec 2007 22:50:27 -0000	1.169
@@ -2242,6 +2242,12 @@
     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"))
     {
@@ -2518,3 +2524,42 @@
       }
     }
 }
+
+bool cmTarget::IsChrpathAvailable()
+{
+  //only return true if the flag is "-Wl,rpath," amd 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 runTimeFlagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
+  runTimeFlagVar += linkLanguage;
+  runTimeFlagVar += "_FLAG";
+  std::string runTimeFlagSepVar = runTimeFlagVar + "_SEP";
+
+  std::string runtimeSep = 
+                  this->Makefile->GetSafeDefinition(runTimeFlagSepVar.c_str());
+
+  if (runtimeSep.size()<=0)
+    {
+    return 0;
+    }
+
+  std::string runtimeFlag = 
+                     this->Makefile->GetSafeDefinition(runTimeFlagVar.c_str());
+
+  if (runtimeFlag!="-Wl,-rpath,")
+    {
+    return false;
+    }
+
+  return true;
+}



More information about the Cmake-commits mailing list