From d29fc33900ff8278dba2eda06bb37a17ecd68a35 Mon Sep 17 00:00:00 2001
From: Bruce Stephens <bruce.stephens@isode.com>
Date: Sat, 20 Feb 2016 19:35:18 +0000
Subject: [PATCH] Add OS X dylib versioning to Ninja generator

In the Unix Makefiles generator, when one specifies VERSION and
SOVERSION then the -current_version and -compatibility_version flags are
used when constructing dynamic libraries. This moves the logic to
cmCommonTargetGenerator and adds use of it to the Ninja generator.

With this change, lib/libverFoo.dylib from the LibName test ends up with
the same version information (as seen using otool -L) with the Ninja and
Makefiles generators.

This resolves issue #0014140.

Signed-off-by: Bruce Stephens <bruce.r.stephens@gmail.com>
---
 Source/cmCommonTargetGenerator.cxx          | 32 +++++++++++++++++++++++++++
 Source/cmCommonTargetGenerator.h            |  3 +++
 Source/cmMakefileLibraryTargetGenerator.cxx | 34 -----------------------------
 Source/cmMakefileLibraryTargetGenerator.h   |  3 ---
 Source/cmNinjaNormalTargetGenerator.cxx     |  8 +++++++
 5 files changed, 43 insertions(+), 37 deletions(-)

diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index 76ed038..b5688a8 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -426,3 +426,35 @@ std::string cmCommonTargetGenerator::GetManifests()
 
   return cmJoin(manifests, " ");
 }
+
+void cmCommonTargetGenerator
+::AppendOSXVerFlag(std::string& flags, const std::string& 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);
+
+  // Skip if no such flag.
+  if(!flag)
+    {
+    return;
+    }
+
+  // Lookup the target version information.
+  int major;
+  int minor;
+  int patch;
+  this->GeneratorTarget->GetTargetVersion(so, major, minor, patch);
+  if(major > 0 || minor > 0 || patch > 0)
+    {
+    // Append the flag since a non-zero version is specified.
+    std::ostringstream vflag;
+    vflag << flag << major << "." << minor << "." << patch;
+    this->LocalGenerator->AppendFlags(flags, vflag.str());
+    }
+}
diff --git a/Source/cmCommonTargetGenerator.h b/Source/cmCommonTargetGenerator.h
index 0c17500..bfb6b79 100644
--- a/Source/cmCommonTargetGenerator.h
+++ b/Source/cmCommonTargetGenerator.h
@@ -79,6 +79,9 @@ protected:
   virtual void AddIncludeFlags(std::string& flags,
                                std::string const& lang) = 0;
 
+  void AppendOSXVerFlag(std::string& flags, const std::string& lang,
+                        const char* name, bool so);
+
   typedef std::map<std::string, std::string> ByLanguageMap;
   std::string GetFlags(const std::string &l);
   ByLanguageMap FlagsByLanguage;
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 1923ea4..435844e 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -841,37 +841,3 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
   this->CleanFiles.insert(this->CleanFiles.end(),
                           libCleanFiles.begin(),libCleanFiles.end());
 }
-
-//----------------------------------------------------------------------------
-void
-cmMakefileLibraryTargetGenerator
-::AppendOSXVerFlag(std::string& flags, const std::string& 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);
-
-  // Skip if no such flag.
-  if(!flag)
-    {
-    return;
-    }
-
-  // Lookup the target version information.
-  int major;
-  int minor;
-  int patch;
-  this->GeneratorTarget->GetTargetVersion(so, major, minor, patch);
-  if(major > 0 || minor > 0 || patch > 0)
-    {
-    // Append the flag since a non-zero version is specified.
-    std::ostringstream vflag;
-    vflag << flag << major << "." << minor << "." << patch;
-    this->LocalGenerator->AppendFlags(flags, vflag.str());
-    }
-}
diff --git a/Source/cmMakefileLibraryTargetGenerator.h b/Source/cmMakefileLibraryTargetGenerator.h
index 68980c3..009f15d 100644
--- a/Source/cmMakefileLibraryTargetGenerator.h
+++ b/Source/cmMakefileLibraryTargetGenerator.h
@@ -38,9 +38,6 @@ protected:
 
   // Store the computd framework version for OS X Frameworks.
   std::string FrameworkVersion;
-
-  void AppendOSXVerFlag(std::string& flags, const std::string& lang,
-                        const char* name, bool so);
 };
 
 #endif
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 17561b5..e0e542a 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -504,6 +504,14 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
       }
     }
 
+  // Add OSX version flags, if any.
+  if(this->GeneratorTarget->GetType() == cmState::SHARED_LIBRARY ||
+     this->GeneratorTarget->GetType() == cmState::MODULE_LIBRARY)
+    {
+    this->AppendOSXVerFlag(vars["LINK_FLAGS"], this->TargetLinkLanguage, "COMPATIBILITY", true);
+    this->AppendOSXVerFlag(vars["LINK_FLAGS"], this->TargetLinkLanguage, "CURRENT", false);
+    }
+
   this->addPoolNinjaVariable("JOB_POOL_LINK", &gt, vars);
 
   this->AddModuleDefinitionFlag(vars["LINK_FLAGS"]);
-- 
2.8.0.rc0

