[cmake-commits] king committed cmComputeLinkInformation.cxx 1.20 1.21 cmOrderDirectories.cxx 1.1 1.2 cmSystemTools.cxx 1.361 1.362 cmSystemTools.h 1.147 1.148

cmake-commits at cmake.org cmake-commits at cmake.org
Thu Feb 21 13:58:43 EST 2008


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

Modified Files:
	cmComputeLinkInformation.cxx cmOrderDirectories.cxx 
	cmSystemTools.cxx cmSystemTools.h 
Log Message:
ENH: Improve linking to third-party shared libraries on soname platforms

  - Reduce false positives in cases of unknown soname
  - Make library extension regular expressions match only at end of string
  - When linking to libraries in implicit dirs convert to the -l option
    only if the file name is one that can be found by the linker
    (ex. /usr/lib/libfoo.so.1 should be linked by full path)
  - Add cmSystemTools::GuessLibrarySOName to guess the soname of a
    library based on presence of a symlink
  - In cmComputeLinkInformation try to guess an soname before assuming
    that a third-party library is built without an soname
  - In cmOrderDirectories guess the soname of shared libraries in cases
    it is otherwise unknown


Index: cmSystemTools.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmSystemTools.h,v
retrieving revision 1.147
retrieving revision 1.148
diff -u -d -r1.147 -r1.148
--- cmSystemTools.h	24 Jan 2008 19:41:18 -0000	1.147
+++ cmSystemTools.h	21 Feb 2008 18:58:41 -0000	1.148
@@ -377,6 +377,10 @@
                                 bool newLine, bool enabled);
 #endif
 
+  /** Try to guess the soname of a shared library.  */
+  static bool GuessLibrarySOName(std::string const& fullPath,
+                                 std::string& soname);
+
 private:
   static bool s_ForceUnixPaths;
   static bool s_RunCommandHideConsole;

Index: cmComputeLinkInformation.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmComputeLinkInformation.cxx,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- cmComputeLinkInformation.cxx	21 Feb 2008 16:41:11 -0000	1.20
+++ cmComputeLinkInformation.cxx	21 Feb 2008 18:58:40 -0000	1.21
@@ -27,6 +27,8 @@
 
 #include <ctype.h>
 
+//#define CM_COMPUTE_LINK_INFO_DEBUG
+
 /*
 Notes about linking on various platforms:
 
@@ -905,7 +907,7 @@
     }
 
   // Finish the list.
-  libext += ").*";
+  libext += ")$";
   return libext;
 }
 
@@ -1070,6 +1072,13 @@
     return false;
     }
 
+  // Only apply the policy below if the library file is one that can
+  // be found by the linker.
+  if(!this->ExtractAnyLibraryName.find(item))
+    {
+    return false;
+    }
+
   // Many system linkers support multiple architectures by
   // automatically selecting the implicit linker search path for the
   // current architecture.  If the library appears in an implicit link
@@ -1262,13 +1271,19 @@
 {
   // This platform will use the path to a library as its soname if the
   // library is given via path and was not built with an soname.  If
-  // this is a shared library that might be the case.  TODO: Check if
-  // the lib is a symlink to detect that it actually has an soname.
+  // this is a shared library that might be the case.
   std::string file = cmSystemTools::GetFilenameName(item);
   if(this->ExtractSharedLibraryName.find(file))
     {
-    this->AddSharedLibNoSOName(item);
-    return true;
+    // If we can guess the soname fairly reliably then assume the
+    // library has one.  Otherwise assume the library has no builtin
+    // soname.
+    std::string soname;
+    if(!cmSystemTools::GuessLibrarySOName(item, soname))
+      {
+      this->AddSharedLibNoSOName(item);
+      return true;
+      }
     }
   return false;
 }

Index: cmSystemTools.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmSystemTools.cxx,v
retrieving revision 1.361
retrieving revision 1.362
diff -u -d -r1.361 -r1.362
--- cmSystemTools.cxx	25 Jan 2008 13:11:04 -0000	1.361
+++ cmSystemTools.cxx	21 Feb 2008 18:58:40 -0000	1.362
@@ -2150,3 +2150,34 @@
     }
 }
 #endif
+
+//----------------------------------------------------------------------------
+bool cmSystemTools::GuessLibrarySOName(std::string const& fullPath,
+                                       std::string& soname)
+{
+  // If the file is not a symlink we have no guess for its soname.
+  if(!cmSystemTools::FileIsSymlink(fullPath.c_str()))
+    {
+    return false;
+    }
+  if(!cmSystemTools::ReadSymlink(fullPath.c_str(), soname))
+    {
+    return false;
+    }
+
+  // If the symlink has a path component we have no guess for the soname.
+  if(!cmSystemTools::GetFilenamePath(soname).empty())
+    {
+    return false;
+    }
+
+  // If the symlink points at an extended version of the same name
+  // assume it is the soname.
+  std::string name = cmSystemTools::GetFilenameName(fullPath);
+  if(soname.length() > name.length() &&
+     soname.substr(0, name.length()) == name)
+    {
+    return true;
+    }
+  return false;
+}

Index: cmOrderDirectories.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmOrderDirectories.cxx,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- cmOrderDirectories.cxx	21 Feb 2008 16:41:11 -0000	1.1
+++ cmOrderDirectories.cxx	21 Feb 2008 18:58:40 -0000	1.2
@@ -119,6 +119,15 @@
                                      const char* soname):
     cmOrderDirectoriesConstraint(od, file), SOName(soname? soname : "")
     {
+    if(this->SOName.empty())
+      {
+      // Try to guess the soname.
+      std::string soguess;
+      if(cmSystemTools::GuessLibrarySOName(file, soguess))
+        {
+        this->SOName = soguess;
+        }
+      }
     }
 
   virtual void Report(std::ostream& e)
@@ -164,7 +173,6 @@
     // Get the set of files that might conflict.  Since we do not
     // know the soname just look at all files that start with the
     // file name.  Usually the soname starts with the library name.
-    // TODO: Check if the library is a symlink and guess the soname.
     std::string base = this->FileName;
     std::set<cmStdString>::const_iterator first = files.lower_bound(base);
     ++base[base.size()-1];



More information about the Cmake-commits mailing list