add_library: Reject shared libraries on platforms that do not support them

Add policy CMP0164 to provide compatibility.

Fixes: #25759
This commit is contained in:
Asit Dhal
2024-03-17 21:15:16 +01:00
committed by Brad King
parent f852f33c69
commit a61c9afdf8
13 changed files with 113 additions and 9 deletions

View File

@@ -84,6 +84,13 @@ See also :prop_sf:`HEADER_FILE_ONLY` on what to do if some sources are
pre-processed, and you want to have the original sources reachable from
within IDE.
.. versionchanged:: 3.30
On platforms that do not support shared libraries, ``add_library``
now fails on calls creating ``SHARED`` libraries instead of
automatically converting them to ``STATIC`` libraries as before.
See policy :policy:`CMP0164`.
Object Libraries
^^^^^^^^^^^^^^^^

View File

@@ -57,6 +57,7 @@ Policies Introduced by CMake 3.30
.. toctree::
:maxdepth: 1
CMP0164: add_library() rejects SHARED libraries when not supported by the platform. </policy/CMP0164>
CMP0163: The GENERATED source file property is now visible in all directories. </policy/CMP0163>
CMP0162: Visual Studio generators add UseDebugLibraries indicators by default. </policy/CMP0162>

31
Help/policy/CMP0164.rst Normal file
View File

@@ -0,0 +1,31 @@
CMP0164
-------
.. versionadded:: 3.30
:command:`add_library` rejects ``SHARED`` libraries when not supported by
the platform.
In CMake 3.29 and below, on platforms that do not support shared libraries
(:prop_gbl:`TARGET_SUPPORTS_SHARED_LIBS` is ``false``), the
:command:`add_library` command automatically converted ``SHARED`` libraries to
``STATIC`` libraries to help users build projects on such platforms. However,
the semantics of shared and static libraries are different enough that such
automatic conversion cannot work in general. Projects using shared libraries
need to be ported to such platforms on a case-by-case basis.
In CMake 3.30 and above, :command:`add_library` prefers to reject creation
of shared libraries on platforms that do not support them, and fail with a
fatal error message. This policy provides compatibility for projects that
happened to work with the automatic conversion to static libraries and have
not been updated with an explicit port.
The ``OLD`` behavior for this policy is to implicitly create a static
library with a developer warning. The ``NEW`` behavior for this policy is
to fail.
.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 3.30
.. |WARNS_OR_DOES_NOT_WARN| replace:: does *not* warn about the behavior change
.. include:: STANDARD_ADVICE.txt
.. include:: DEPRECATED.txt

View File

@@ -0,0 +1,6 @@
add_library-no-static-fallback
------------------------------
* On platforms that do not support shared libraries, the :command:`add_library`
command now rejects creation of shared libraries instead of automatically
converting them to static libraries. See policy :policy:`CMP0164`.

View File

@@ -11,6 +11,7 @@
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmValue.h"
@@ -226,14 +227,35 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
if ((type == cmStateEnums::SHARED_LIBRARY ||
type == cmStateEnums::MODULE_LIBRARY) &&
!mf.GetState()->GetGlobalPropertyAsBool("TARGET_SUPPORTS_SHARED_LIBS")) {
mf.IssueMessage(
MessageType::AUTHOR_WARNING,
cmStrCat(
"ADD_LIBRARY called with ",
(type == cmStateEnums::SHARED_LIBRARY ? "SHARED" : "MODULE"),
" option but the target platform does not support dynamic linking. ",
"Building a STATIC library instead. This may lead to problems."));
type = cmStateEnums::STATIC_LIBRARY;
switch (status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0164)) {
case cmPolicies::WARN:
mf.IssueMessage(
MessageType::AUTHOR_WARNING,
cmStrCat(
"ADD_LIBRARY called with ",
(type == cmStateEnums::SHARED_LIBRARY ? "SHARED" : "MODULE"),
" option but the target platform does not support dynamic "
"linking. ",
"Building a STATIC library instead. This may lead to problems."));
CM_FALLTHROUGH;
case cmPolicies::OLD:
type = cmStateEnums::STATIC_LIBRARY;
break;
case cmPolicies::NEW:
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
mf.IssueMessage(
MessageType::FATAL_ERROR,
cmStrCat(
"ADD_LIBRARY called with ",
(type == cmStateEnums::SHARED_LIBRARY ? "SHARED" : "MODULE"),
" option but the target platform does not support dynamic "
"linking."));
cmSystemTools::SetFatalErrorOccurred();
return false;
default:
break;
}
}
// Handle imported target creation.

View File

@@ -501,7 +501,11 @@ class cmMakefile;
SELECT( \
POLICY, CMP0163, \
"The GENERATED source file property is now visible in all directories.", \
3, 30, 0, cmPolicies::WARN)
3, 30, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0164, \
"add_library() rejects SHARED libraries when not supported by the " \
"platform.", \
3, 30, 0, cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \

View File

@@ -22,3 +22,7 @@ run_cmake(STATICwithNoSourcesButLinkObjects)
run_cmake(SHAREDwithNoSourcesButLinkObjects)
run_cmake(MODULEwithNoSourcesButLinkObjects)
run_cmake(UNKNOWNwithNoSourcesButLinkObjects)
run_cmake(TARGET_SUPPORTS_SHARED_LIBS_CMP0164_OLD)
run_cmake(TARGET_SUPPORTS_SHARED_LIBS_CMP0164_NEW)
run_cmake(TARGET_SUPPORTS_SHARED_LIBS_CMP0164_WARN)

View File

@@ -0,0 +1,5 @@
^CMake Error at TARGET_SUPPORTS_SHARED_LIBS_CMP0164_NEW.cmake:[0-9]+ \(add_library\):
ADD_LIBRARY called with SHARED option but the target platform does not
support dynamic linking.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)$

View File

@@ -0,0 +1,4 @@
enable_language(CXX)
cmake_policy(SET CMP0164 NEW)
set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
add_library(someLib SHARED test.cpp)

View File

@@ -0,0 +1,9 @@
enable_language(CXX)
cmake_policy(SET CMP0164 OLD)
set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
add_library(someLib SHARED test.cpp)
get_target_property(someLibType someLib TYPE)
if(NOT someLibType STREQUAL "STATIC_LIBRARY")
message(FATAL_ERROR "expected type does not match")
endif()

View File

@@ -0,0 +1,7 @@
^CMake Warning \(dev\) at TARGET_SUPPORTS_SHARED_LIBS_CMP0164_WARN.cmake:[0-9]+ \(add_library\):
ADD_LIBRARY called with SHARED option but the target platform does not
support dynamic linking. Building a STATIC library instead. This may lead
to problems.
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.$

View File

@@ -0,0 +1,3 @@
enable_language(CXX)
set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
add_library(someLib SHARED test.cpp)