浏览代码

ENH: Teach find_library to find OpenBSD-style libs

OpenBSD shared libraries use a ".so.<major>.<minor>" extension and do
not have a symlink with just a ".so" extension.  Its "ld" is capable of
finding the library with the best version.  This change adds support for
finding such libraries.  See issue #3470.
Brad King 17 年之前
父节点
当前提交
434a99bbeb
共有 3 个文件被更改,包括 38 次插入2 次删除
  1. 1 0
      Modules/Platform/OpenBSD.cmake
  2. 30 2
      Source/cmFindLibraryCommand.cxx
  3. 7 0
      Source/cmake.cxx

+ 1 - 0
Modules/Platform/OpenBSD.cmake

@@ -1,2 +1,3 @@
 SET(CMAKE_DL_LIBS "")
+SET_PROPERTY(GLOBAL PROPERTY FIND_LIBRARY_USE_OPENBSD_VERSIONING 1)
 INCLUDE(Platform/UnixPaths)

+ 30 - 2
Source/cmFindLibraryCommand.cxx

@@ -249,6 +249,11 @@ struct cmFindLibraryHelper
   size_type BestPrefix;
   size_type BestSuffix;
 
+  // Support for OpenBSD shared library naming: lib<name>.so.<major>.<minor>
+  bool OpenBSD;
+  unsigned int BestMajor;
+  unsigned int BestMinor;
+
   // Current name under consideration.
   cmsys::RegularExpression NameRegex;
   bool TryRawName;
@@ -290,11 +295,18 @@ cmFindLibraryHelper::cmFindLibraryHelper(cmMakefile* mf):
   this->RegexFromList(this->PrefixRegexStr, this->Prefixes);
   this->RegexFromList(this->SuffixRegexStr, this->Suffixes);
 
+  // Check whether to use OpenBSD-style library version comparisons.
+  this->OpenBSD =
+    this->Makefile->GetCMakeInstance()
+    ->GetPropertyAsBool("FIND_LIBRARY_USE_OPENBSD_VERSIONING");
+
   this->TryRawName = false;
 
   // No library file has yet been found.
   this->BestPrefix = this->Prefixes.size();
   this->BestSuffix = this->Suffixes.size();
+  this->BestMajor = 0;
+  this->BestMinor = 0;
 }
 
 //----------------------------------------------------------------------------
@@ -368,6 +380,10 @@ void cmFindLibraryHelper::SetName(std::string const& name)
   regex += this->PrefixRegexStr;
   this->RegexFromLiteral(regex, name);
   regex += this->SuffixRegexStr;
+  if(this->OpenBSD)
+    {
+    regex += "(\\.[0-9]+\\.[0-9]+)?";
+    }
   regex += "$";
   this->NameRegex.compile(regex.c_str());
 }
@@ -414,15 +430,27 @@ bool cmFindLibraryHelper::CheckDirectory(std::string const& path)
         {
         // This is a matching file.  Check if it is better than the
         // best name found so far.  Earlier prefixes are preferred,
-        // followed by earlier suffixes.
+        // followed by earlier suffixes.  For OpenBSD, shared library
+        // version extensions are compared.
         size_type prefix = this->GetPrefixIndex(this->NameRegex.match(1));
         size_type suffix = this->GetSuffixIndex(this->NameRegex.match(2));
+        unsigned int major = 0;
+        unsigned int minor = 0;
+        if(this->OpenBSD)
+          {
+          sscanf(this->NameRegex.match(3).c_str(), ".%u.%u", &major, &minor);
+          }
         if(this->BestPath.empty() || prefix < this->BestPrefix ||
-           (prefix == this->BestPrefix && suffix < this->BestSuffix))
+           (prefix == this->BestPrefix && suffix < this->BestSuffix) ||
+           (prefix == this->BestPrefix && suffix == this->BestSuffix &&
+            (major > this->BestMajor ||
+             (major == this->BestMajor && minor > this->BestMinor))))
           {
           this->BestPath = this->TestPath;
           this->BestPrefix = prefix;
           this->BestSuffix = suffix;
+          this->BestMajor = major;
+          this->BestMinor = minor;
           }
         }
       }

+ 7 - 0
Source/cmake.cxx

@@ -3326,6 +3326,13 @@ void cmake::DefineProperties(cmake *cm)
      "FIND_LIBRARY command should automatically search the lib64 variant of "
      "directories called lib in the search path when building 64-bit "
      "binaries.");
+  cm->DefineProperty
+    ("FIND_LIBRARY_USE_OPENBSD_VERSIONING", cmProperty::GLOBAL,
+     "Whether FIND_LIBRARY should find OpenBSD-style shared libraries.",
+     "This property is a boolean specifying whether the FIND_LIBRARY "
+     "command should find shared libraries with OpenBSD-style versioned "
+     "extension: \".so.<major>.<minor>\".  "
+     "The property is set to true on OpenBSD and false on other platforms.");
   cm->DefineProperty
     ("ENABLED_FEATURES", cmProperty::GLOBAL,
      "List of features which are enabled during the CMake run.",