From 9c23d41ac024d6fcf11352fb38bf3b801b474d03 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] Copy logic for 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 copies exactly that
behaviour to the Ninja generator (using basically the same code). (It
might be possible for the two generators to share some of the same
implementation, but the code seems fairly minimal so I just copied it.)

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/cmNinjaNormalTargetGenerator.cxx | 54 +++++++++++++++++++++++++++++++++
 Source/cmNinjaNormalTargetGenerator.h   |  5 +++
 2 files changed, 59 insertions(+)

diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 17561b5..0734b21 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"]);
@@ -793,3 +801,49 @@ void cmNinjaNormalTargetGenerator::WriteObjectLibStatement()
   this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(),
                                              this->GetGeneratorTarget());
 }
+
+//----------------------------------------------------------------------------
+void
+cmNinjaNormalTargetGenerator
+::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->AppendFlags(flags, vflag.str());
+    }
+}
+void cmNinjaNormalTargetGenerator::AppendFlags(std::string& flags,
+                                   const std::string& newFlags)
+{
+  if(!newFlags.empty())
+    {
+    if(!flags.empty())
+      {
+      flags += " ";
+      }
+    flags += newFlags;
+    }
+}
diff --git a/Source/cmNinjaNormalTargetGenerator.h b/Source/cmNinjaNormalTargetGenerator.h
index 556ed5e..5da5b72 100644
--- a/Source/cmNinjaNormalTargetGenerator.h
+++ b/Source/cmNinjaNormalTargetGenerator.h
@@ -48,6 +48,11 @@ private:
   std::string TargetNameImport;
   std::string TargetNamePDB;
   std::string TargetLinkLanguage;
+
+  void AppendOSXVerFlag(std::string& flags, const std::string& lang,
+                        const char* name, bool so);
+  void AppendFlags(std::string& flags,
+                   const std::string& newFlags);
 };
 
 #endif // ! cmNinjaNormalTargetGenerator_h
-- 
2.8.0.rc0

