Browse Source

Merge topic 'osx-version-flags'

6a84f0b791 macOS: Test OSX_COMPATIBILITY_VERSION and OSX_CURRENT_VERSION properties
4a62e3d97c macOS: Add OSX_COMPATIBILITY_VERSION and OSX_CURRENT_VERSION properties

Acked-by: Kitware Robot <[email protected]>
Merge-request: !4274
Brad King 5 năm trước cách đây
mục cha
commit
b6da71e299

+ 2 - 0
Help/manual/cmake-properties.7.rst

@@ -302,6 +302,8 @@ Properties on Targets
    /prop_tgt/OBJCXX_STANDARD_REQUIRED
    /prop_tgt/OSX_ARCHITECTURES_CONFIG
    /prop_tgt/OSX_ARCHITECTURES
+   /prop_tgt/OSX_CURRENT_VERSION
+   /prop_tgt/OSX_COMPATIBILITY_VERSION
    /prop_tgt/OUTPUT_NAME_CONFIG
    /prop_tgt/OUTPUT_NAME
    /prop_tgt/PDB_NAME_CONFIG

+ 14 - 0
Help/prop_tgt/OSX_COMPATIBILITY_VERSION.rst

@@ -0,0 +1,14 @@
+OSX_COMPATIBILITY_VERSION
+-------------------------
+
+What current version number is this target for OSX.
+
+For shared libraries on Mach-O systems (e.g. macOS, iOS)
+the ``OSX_COMPATIBILITY_VERSION`` property correspond to
+``compatibility version`` and :prop_tgt:`OSX_CURRENT_VERSION` to
+``current version``.
+See the :prop_tgt:`FRAMEWORK` target property for an example.
+
+Versions of Mach-O binaries may be checked with the ``otool -L <binary>``
+command.  If ``OSX_COMPATIBILITY_VERSION`` is not set, the value of
+the :prop_tgt:``SOVERSION`` property will be used.

+ 13 - 0
Help/prop_tgt/OSX_CURRENT_VERSION.rst

@@ -0,0 +1,13 @@
+OSX_CURRENT_VERSION
+-------------------
+
+What current version number is this target for OSX.
+
+For shared libraries on Mach-O systems (e.g. macOS, iOS)
+the :prop_tgt:`OSX_COMPATIBILITY_VERSION` property correspond to
+``compatibility version`` and ``OSX_CURRENT_VERSION`` to ``current version``.
+See the :prop_tgt:`FRAMEWORK` target property for an example.
+
+Versions of Mach-O binaries may be checked with the ``otool -L <binary>``
+command.  If ``OSX_CURRENT_VERSION`` is not set, the value of
+the :prop_tgt:``VERSION`` property will be used.

+ 6 - 4
Help/prop_tgt/SOVERSION.rst

@@ -21,7 +21,9 @@ Mach-O Versions
 ^^^^^^^^^^^^^^^
 
 For shared libraries and executables on Mach-O systems (e.g. macOS, iOS),
-the ``SOVERSION`` property corresponds to *compatibility version* and
-:prop_tgt:`VERSION` to *current version*.  See the :prop_tgt:`FRAMEWORK` target
-property for an example.  Versions of Mach-O binaries may be checked with the
-``otool -L <binary>`` command.
+the ``SOVERSION`` property is a fallback to
+:prop_tgt:`OSX_COMPATIBILITY_VERSION` property which corresponds to
+*compatiblity version* and :prop_tgt:`VERSION` is a fallback to
+:prop_tgt:`OSX_CURRENT_VERSION` which corresponds to *current version*.
+See the :prop_tgt:`FRAMEWORK` target property for an example.  Versions
+of Mach-O binaries may be checked with the ``otool -L <binary>`` command.

+ 4 - 2
Help/prop_tgt/VERSION.rst

@@ -23,7 +23,9 @@ Mach-O Versions
 ^^^^^^^^^^^^^^^
 
 For shared libraries and executables on Mach-O systems (e.g. macOS, iOS),
-the :prop_tgt:`SOVERSION` property correspond to *compatibility version* and
-``VERSION`` to *current version*.  See the :prop_tgt:`FRAMEWORK` target
+the ``VERSION`` property is a fallback to :prop_tgt:`OSX_CURRENT_VERSION`
+property which corresponds to *current version* and :prop_tgt:`SOVERSION`
+is a fallback to :prop_tgt:`OSX_COMPATIBILITY_VERSION` which corresponds
+to *compatiblity version*.  See the :prop_tgt:`FRAMEWORK` target
 property for an example.  Versions of Mach-O binaries may be checked with the
 ``otool -L <binary>`` command.

+ 9 - 0
Help/release/dev/osx-version-flags.rst

@@ -0,0 +1,9 @@
+add_osx_compatiblity_property
+-----------------------------
+
+* Target properties :prop_tgt:`OSX_COMPATIBILITY_VERSION` and
+  :prop_tgt:`OSX_CURRENT_VERSION` were added to set the
+  ``compatibility_version`` and ``curent_version`` respectively
+  on macOS. For backwards compatibility, if these properties
+  are not set, :prop_tgt:`SOVERSION` and :prop_tgt:`VERSION`
+  are used respectively as fallbacks.

+ 4 - 1
Source/cmCommonTargetGenerator.cxx

@@ -233,7 +233,10 @@ void cmCommonTargetGenerator::AppendOSXVerFlag(std::string& flags,
   int major;
   int minor;
   int patch;
-  this->GeneratorTarget->GetTargetVersion(so, major, minor, patch);
+  std::string prop = cmStrCat("OSX_", name, "_VERSION");
+  std::string fallback_prop = so ? "SOVERSION" : "VERSION";
+  this->GeneratorTarget->GetTargetVersionFallback(prop, fallback_prop, major,
+                                                  minor, patch);
   if (major > 0 || minor > 0 || patch > 0) {
     // Append the flag since a non-zero version is specified.
     std::ostringstream vflag;

+ 16 - 6
Source/cmGeneratorTarget.cxx

@@ -5280,11 +5280,23 @@ cmComputeLinkInformation* cmGeneratorTarget::GetLinkInformation(
 void cmGeneratorTarget::GetTargetVersion(int& major, int& minor) const
 {
   int patch;
-  this->GetTargetVersion(false, major, minor, patch);
+  this->GetTargetVersion("VERSION", major, minor, patch);
 }
 
-void cmGeneratorTarget::GetTargetVersion(bool soversion, int& major,
-                                         int& minor, int& patch) const
+void cmGeneratorTarget::GetTargetVersionFallback(
+  const std::string& property, const std::string& fallback_property,
+  int& major, int& minor, int& patch) const
+{
+  if (this->GetProperty(property)) {
+    this->GetTargetVersion(property, major, minor, patch);
+  } else {
+    this->GetTargetVersion(fallback_property, major, minor, patch);
+  }
+}
+
+void cmGeneratorTarget::GetTargetVersion(const std::string& property,
+                                         int& major, int& minor,
+                                         int& patch) const
 {
   // Set the default values.
   major = 0;
@@ -5293,9 +5305,7 @@ void cmGeneratorTarget::GetTargetVersion(bool soversion, int& major,
 
   assert(this->GetType() != cmStateEnums::INTERFACE_LIBRARY);
 
-  // Look for a VERSION or SOVERSION property.
-  const char* prop = soversion ? "SOVERSION" : "VERSION";
-  if (const char* version = this->GetProperty(prop)) {
+  if (const char* version = this->GetProperty(property)) {
     // Try to parse the version number and store the results that were
     // successfully parsed.
     int parsed_major;

+ 10 - 2
Source/cmGeneratorTarget.h

@@ -755,11 +755,19 @@ public:
   void GetTargetVersion(int& major, int& minor) const;
 
   /** Get the target major, minor, and patch version numbers
-      interpreted from the VERSION or SOVERSION property.  Version 0
+      interpreted from the given property.  Version 0
       is returned if the property is not set or cannot be parsed.  */
-  void GetTargetVersion(bool soversion, int& major, int& minor,
+  void GetTargetVersion(std::string const& property, int& major, int& minor,
                         int& patch) const;
 
+  /** Get the target major, minor, and patch version numbers
+      interpreted from the given property and if empty use the
+      fallback property.  Version 0 is returned if the property is
+      not set or cannot be parsed.  */
+  void GetTargetVersionFallback(const std::string& property,
+                                const std::string& fallback_property,
+                                int& major, int& minor, int& patch) const;
+
   std::string GetFortranModuleDirectory(std::string const& working_dir) const;
 
   const char* GetSourcesProperty() const;

+ 6 - 4
Source/cmGlobalXCodeGenerator.cxx

@@ -2366,8 +2366,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
     int minor;
     int patch;
 
-    // VERSION -> current_version
-    gtgt->GetTargetVersion(false, major, minor, patch);
+    // OSX_CURRENT_VERSION or VERSION -> current_version
+    gtgt->GetTargetVersionFallback("OSX_CURRENT_VERSION", "VERSION", major,
+                                   minor, patch);
     std::ostringstream v;
 
     // Xcode always wants at least 1.0.0 or nothing
@@ -2377,8 +2378,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
     buildSettings->AddAttribute("DYLIB_CURRENT_VERSION",
                                 this->CreateString(v.str()));
 
-    // SOVERSION -> compatibility_version
-    gtgt->GetTargetVersion(true, major, minor, patch);
+    // OSX_COMPATIBILITY_VERSION or SOVERSION -> compatibility_version
+    gtgt->GetTargetVersionFallback("OSX_COMPATIBILITY_VERSION", "SOVERSION",
+                                   major, minor, patch);
     std::ostringstream vso;
 
     // Xcode always wants at least 1.0.0 or nothing

+ 1 - 0
Tests/RunCMake/CMakeLists.txt

@@ -306,6 +306,7 @@ add_RunCMake_test(test_include_dirs)
 add_RunCMake_test(BundleUtilities)
 if(APPLE)
   add_RunCMake_test(INSTALL_NAME_DIR)
+  add_RunCMake_test(MacOSVersions)
 endif()
 
 function(add_RunCMake_test_try_compile)

+ 3 - 0
Tests/RunCMake/MacOSVersions/CMakeLists.txt

@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.16)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)

+ 27 - 0
Tests/RunCMake/MacOSVersions/MacOSVersions-build-check.cmake

@@ -0,0 +1,27 @@
+set(cfg_dir)
+if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+  set(cfg_dir /Debug)
+endif()
+
+set(lib "${RunCMake_TEST_BINARY_DIR}${cfg_dir}/libfoo.1.0.dylib")
+if(NOT EXISTS "${lib}")
+  set(RunCMake_TEST_FAILED "Library file is missing:\n  ${lib}")
+  return()
+endif()
+
+execute_process(COMMAND otool -l "${lib}" OUTPUT_VARIABLE out ERROR_VARIABLE err RESULT_VARIABLE res)
+if(NOT res EQUAL 0)
+  string(REPLACE "\n" "\n  " err "  ${err}")
+  set(RunCMake_TEST_FAILED "Running 'otool -l' on file:\n  ${lib}\nfailed:\n${err}")
+  return()
+endif()
+
+foreach(ver
+    [[current version 3\.2\.1]]
+    [[compatibility version 2\.1\.0]]
+    )
+  if(NOT "${out}" MATCHES "( |\n)${ver}( |\n)")
+    set(RunCMake_TEST_FAILED "Library file:\n  ${lib}\ndoes not contain '${ver}'")
+    return()
+  endif()
+endforeach()

+ 9 - 0
Tests/RunCMake/MacOSVersions/MacOSVersions.cmake

@@ -0,0 +1,9 @@
+enable_language(C)
+
+add_library(foo SHARED foo.c)
+set_target_properties(foo PROPERTIES
+  VERSION 1.0
+  SOVERSION 1
+  OSX_COMPATIBILITY_VERSION 2.1.0
+  OSX_CURRENT_VERSION 3.2.1
+  )

+ 11 - 0
Tests/RunCMake/MacOSVersions/RunCMakeTest.cmake

@@ -0,0 +1,11 @@
+include(RunCMake)
+
+function(run_MacOSVersions)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/MacOSVersions-build)
+  run_cmake(MacOSVersions)
+
+  set(RunCMake_TEST_NO_CLEAN 1)
+  run_cmake_command(MacOSVersions-build ${CMAKE_COMMAND} --build . --config Debug)
+endfunction()
+
+run_MacOSVersions()

+ 4 - 0
Tests/RunCMake/MacOSVersions/foo.c

@@ -0,0 +1,4 @@
+int foo(void)
+{
+  return 0;
+}