Browse Source

Add option to add SOVERSION to DLL names

Add variable/target property `[CMAKE_]DLL_NAME_WITH_SOVERSION`.

Fixes: #24251
Signed-off-by: Ralf Habacker <[email protected]>
Ralf Habacker 2 years ago
parent
commit
a7f9c7da26

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

@@ -202,6 +202,7 @@ Properties on Targets
    /prop_tgt/DEPLOYMENT_REMOTE_DIRECTORY
    /prop_tgt/DEPRECATION
    /prop_tgt/DISABLE_PRECOMPILE_HEADERS
+   /prop_tgt/DLL_NAME_WITH_SOVERSION
    /prop_tgt/DOTNET_SDK
    /prop_tgt/DOTNET_TARGET_FRAMEWORK
    /prop_tgt/DOTNET_TARGET_FRAMEWORK_VERSION

+ 1 - 0
Help/manual/cmake-variables.7.rst

@@ -427,6 +427,7 @@ Variables that Control the Build
    /variable/CMAKE_DEFAULT_CONFIGS
    /variable/CMAKE_DEPENDS_USE_COMPILER
    /variable/CMAKE_DISABLE_PRECOMPILE_HEADERS
+   /variable/CMAKE_DLL_NAME_WITH_SOVERSION
    /variable/CMAKE_ENABLE_EXPORTS
    /variable/CMAKE_EXE_LINKER_FLAGS
    /variable/CMAKE_EXE_LINKER_FLAGS_CONFIG

+ 17 - 0
Help/prop_tgt/DLL_NAME_WITH_SOVERSION.rst

@@ -0,0 +1,17 @@
+DLL_NAME_WITH_SOVERSION
+-----------------------
+
+.. versionadded:: 3.27
+
+This property control whether the :prop_tgt:`SOVERSION` target
+property are added to the filename of generated DLL filenames
+for the Windows platform, which is selected when the
+:variable:`WIN32` variable is set.
+
+The value of the listed property is appended to the
+basename of the runtime component of the shared library
+target as ``-<SOVERSION>``.
+
+Please note that setting this property has no effect
+if versioned filenames are globally disabled with the
+:variable:`CMAKE_PLATFORM_NO_VERSIONED_SONAME` variable.

+ 7 - 0
Help/release/dev/dll-name-soversion.rst

@@ -0,0 +1,7 @@
+dll-name-soversion
+------------------
+
+* The :variable:`CMAKE_DLL_NAME_WITH_SOVERSION` variable and associated
+  :prop_tgt:`DLL_NAME_WITH_SOVERSION` target property were added to
+  optionally append the :prop_tgt:`SOVERSION` to the filename of the
+  ``.dll`` part of a shared library on Windows.

+ 14 - 0
Help/variable/CMAKE_DLL_NAME_WITH_SOVERSION.rst

@@ -0,0 +1,14 @@
+CMAKE_DLL_NAME_WITH_SOVERSION
+-----------------------------
+
+.. versionadded:: 3.27
+
+This variable is used to initialize the :prop_tgt:`DLL_NAME_WITH_SOVERSION`
+property on shared library targets for the Windows platform, which is selected
+when the :variable:`WIN32` variable is set.
+
+See this target property for additional information.
+
+Please note that setting this variable has no effect if versioned filenames
+are globally disabled with the :variable:`CMAKE_PLATFORM_NO_VERSIONED_SONAME`
+variable.

+ 7 - 1
Source/cmGeneratorTarget.cxx

@@ -5475,9 +5475,15 @@ cmGeneratorTarget::GetFullNameInternalComponents(
 
   // Name shared libraries with their version number on some platforms.
   if (cmValue soversion = this->GetProperty("SOVERSION")) {
+    cmValue dllProp;
+    if (this->IsDLLPlatform()) {
+      dllProp = this->GetProperty("DLL_NAME_WITH_SOVERSION");
+    }
     if (this->GetType() == cmStateEnums::SHARED_LIBRARY &&
         !isImportedLibraryArtifact &&
-        this->Makefile->IsOn("CMAKE_SHARED_LIBRARY_NAME_WITH_VERSION")) {
+        (dllProp.IsOn() ||
+         (!dllProp.IsSet() &&
+          this->Makefile->IsOn("CMAKE_SHARED_LIBRARY_NAME_WITH_VERSION")))) {
       outBase += "-";
       outBase += *soversion;
     }

+ 6 - 0
Source/cmTarget.cxx

@@ -305,6 +305,8 @@ struct TargetProperty
     LinkableLibraryTarget,
     // Needs to be an executable.
     ExecutableTarget,
+    // Needs to be a shared library (`SHARED`).
+    SharedLibraryTarget,
     // Needs to be a target with meaningful symbol exports (`SHARED` or
     // `EXECUTABLE`).
     TargetWithSymbolExports,
@@ -484,6 +486,7 @@ TargetProperty const StaticTargetProperties[] = {
   // ---- macOS
   { "FRAMEWORK_MULTI_CONFIG_POSTFIX_"_s, IC::LinkableLibraryTarget, R::PerConfig },
   // ---- Windows
+  { "DLL_NAME_WITH_SOVERSION"_s, IC::SharedLibraryTarget },
   { "GNUtoMS"_s, IC::CanCompileSources },
   { "WIN32_EXECUTABLE"_s, IC::CanCompileSources },
   { "WINDOWS_EXPORT_ALL_SYMBOLS"_s, IC::TargetWithSymbolExports },
@@ -1003,6 +1006,9 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
       metConditions.insert(
         TargetProperty::InitCondition::LinkableLibraryTarget);
     }
+    if (this->impl->TargetType == cmStateEnums::SHARED_LIBRARY) {
+      metConditions.insert(TargetProperty::InitCondition::SharedLibraryTarget);
+    }
   }
   if (this->impl->TargetType == cmStateEnums::EXECUTABLE) {
     metConditions.insert(TargetProperty::InitCondition::ExecutableTarget);

+ 1 - 1
Tests/RunCMake/CMakeLists.txt

@@ -394,7 +394,7 @@ if(UNIX AND CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG AND CMAKE_EXECUTABLE_FORMAT STRE
 endif()
 add_RunCMake_test(ScriptMode)
 add_RunCMake_test(Swift -DCMAKE_Swift_COMPILER=${CMAKE_Swift_COMPILER} -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME})
-add_RunCMake_test(TargetArtifacts)
+add_RunCMake_test(TargetArtifacts -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME})
 add_RunCMake_test(TargetObjects)
 add_RunCMake_test(TargetProperties)
 add_RunCMake_test(ToolchainFile)

+ 2 - 0
Tests/RunCMake/TargetArtifacts/DLL-SOVERSION-build-stdout.txt

@@ -0,0 +1,2 @@
+.*exA_name="(libexA\.so\.2|libexA\.2\.dylib|(lib|cyg|msys-|)exA-2\.dll)"
+.*exB_name="(libexB\.so\.2|libexB\.2\.dylib|(lib|cyg|msys-|)exB-2\.dll)"

+ 18 - 0
Tests/RunCMake/TargetArtifacts/DLL-SOVERSION.cmake

@@ -0,0 +1,18 @@
+enable_language(C)
+
+add_library(exA SHARED dll.c)
+set_target_properties(exA PROPERTIES
+  SOVERSION 2
+  DLL_NAME_WITH_SOVERSION 1
+  )
+
+set(CMAKE_DLL_NAME_WITH_SOVERSION 1)
+add_library(exB SHARED dll.c)
+set_property(TARGET exB PROPERTY SOVERSION 2)
+
+add_custom_target(checkNames ALL
+  COMMAND ${CMAKE_COMMAND} -E echo exA_name="$<TARGET_FILE_NAME:exA>"
+  COMMAND ${CMAKE_COMMAND} -E echo exB_name="$<TARGET_FILE_NAME:exB>"
+  VERBATIM
+  )
+add_dependencies(checkNames exA exB)

+ 4 - 0
Tests/RunCMake/TargetArtifacts/RunCMakeTest.cmake

@@ -9,7 +9,11 @@ function(run_cmake_and_verify_after_build case)
   endif()
   run_cmake(${case})
   set(RunCMake_TEST_NO_CLEAN 1)
+  set(RunCMake_TEST_OUTPUT_MERGE 1)
   run_cmake_command("${case}-build" ${CMAKE_COMMAND} --build .)
 endfunction()
 
+if(NOT CMAKE_SYSTEM_NAME STREQUAL "AIX")
+  run_cmake_and_verify_after_build(DLL-SOVERSION)
+endif()
 run_cmake_and_verify_after_build(OutputDirs)

+ 6 - 0
Tests/RunCMake/TargetArtifacts/dll.c

@@ -0,0 +1,6 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+  void dll(void)
+{
+}