1
0
Эх сурвалжийг харах

ENH: Set version info for shared libs on OSX.

  - Map SOVERSION major.minor.patch to compatibility_version
  - Map VERSION major.minor.patch to current_version
  - See issue #4383.
Brad King 17 жил өмнө
parent
commit
0d54001276

+ 5 - 0
Modules/Platform/Darwin.cmake

@@ -27,6 +27,11 @@ SET(CMAKE_SHARED_MODULE_SUFFIX ".so")
 SET(CMAKE_MODULE_EXISTS 1)
 SET(CMAKE_DL_LIBS "")
 
+SET(CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG -Wl,-dylib_compatibility_version,)
+SET(CMAKE_C_OSX_CURRENT_VERSION_FLAG -Wl,-dylib_current_version,)
+SET(CMAKE_CXX_OSX_COMPATIBILITY_VERSION_FLAG "${CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG}")
+SET(CMAKE_CXX_OSX_CURRENT_VERSION_FLAG "${CMAKE_C_OSX_CURRENT_VERSION_FLAG}")
+
 SET(CMAKE_C_LINK_FLAGS "-headerpad_max_install_names")
 SET(CMAKE_CXX_LINK_FLAGS "-headerpad_max_install_names")
 

+ 32 - 4
Source/cmGlobalXCodeGenerator.cxx

@@ -1459,10 +1459,6 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
 
     buildSettings->AddAttribute("LIBRARY_STYLE",
                                 this->CreateString("DYNAMIC"));
-    buildSettings->AddAttribute("DYLIB_COMPATIBILITY_VERSION",
-                                this->CreateString("1"));
-    buildSettings->AddAttribute("DYLIB_CURRENT_VERSION",
-                                this->CreateString("1"));
     break;
     }
     case cmTarget::EXECUTABLE:
@@ -1680,6 +1676,38 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
                               this->CreateString(
                                 "-Wmost -Wno-four-char-constants"
                                 " -Wno-unknown-pragmas"));
+
+  // Runtime version information.
+  if(target.GetType() == cmTarget::SHARED_LIBRARY)
+    {
+    int major;
+    int minor;
+    int patch;
+
+    // VERSION -> current_version
+    target.GetTargetVersion(false, major, minor, patch);
+    if(major == 0 && minor == 0 && patch == 0)
+      {
+      // Xcode always wants at least 1.0.0
+      major = 1;
+      }
+    cmOStringStream v;
+    v << major << "." << minor << "." << patch;
+    buildSettings->AddAttribute("DYLIB_CURRENT_VERSION",
+                                this->CreateString(v.str().c_str()));
+
+    // SOVERSION -> compatibility_version
+    target.GetTargetVersion(true, major, minor, patch);
+    if(major == 0 && minor == 0 && patch == 0)
+      {
+      // Xcode always wants at least 1.0.0
+      major = 1;
+      }
+    cmOStringStream vso;
+    vso << major << "." << minor << "." << patch;
+    buildSettings->AddAttribute("DYLIB_COMPATIBILITY_VERSION",
+                                this->CreateString(vso.str().c_str()));
+    }
 }
 
 //----------------------------------------------------------------------------

+ 42 - 0
Source/cmMakefileLibraryTargetGenerator.cxx

@@ -364,6 +364,14 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
   std::string linkFlags;
   this->LocalGenerator->AppendFlags(linkFlags, extraFlags);
 
+  // Add OSX version flags, if any.
+  if(this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
+     this->Target->GetType() == cmTarget::MODULE_LIBRARY)
+    {
+    this->AppendOSXVerFlag(linkFlags, linkLanguage, "COMPATIBILITY", true);
+    this->AppendOSXVerFlag(linkFlags, linkLanguage, "CURRENT", false);
+    }
+
   // Construct the name of the library.
   std::string targetName;
   std::string targetNameSO;
@@ -905,3 +913,37 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
   this->CleanFiles.insert(this->CleanFiles.end(),
                           libCleanFiles.begin(),libCleanFiles.end());
 }
+
+//----------------------------------------------------------------------------
+void
+cmMakefileLibraryTargetGenerator
+::AppendOSXVerFlag(std::string& flags, const char* lang,
+                   const char* name, bool so)
+{
+  // Lookup the flag to specify the version.
+  std::string fvar = "CMAKE_";
+  fvar += lang;
+  fvar += "_OSX_";
+  fvar += name;
+  fvar += "_VERSION_FLAG";
+  const char* flag = this->Makefile->GetDefinition(fvar.c_str());
+
+  // Skip if no such flag.
+  if(!flag)
+    {
+    return;
+    }
+
+  // Lookup the target version information.
+  int major;
+  int minor;
+  int patch;
+  this->Target->GetTargetVersion(so, major, minor, patch);
+  if(major > 0 || minor > 0 || patch > 0)
+    {
+    // Append the flag since a non-zero version is specified.
+    cmOStringStream vflag;
+    vflag << flag << major << "." << minor << "." << patch;
+    this->LocalGenerator->AppendFlags(flags, vflag.str().c_str());
+    }
+}

+ 3 - 0
Source/cmMakefileLibraryTargetGenerator.h

@@ -41,6 +41,9 @@ protected:
 
   // Store the computd framework version for OS X Frameworks.
   std::string FrameworkVersion;
+
+  void AppendOSXVerFlag(std::string& flags, const char* lang,
+                        const char* name, bool so);
 };
 
 #endif