From a61c9afdf8b2c9cd424734c430b55de0581a67d5 Mon Sep 17 00:00:00 2001 From: Asit Dhal Date: Sun, 17 Mar 2024 21:15:16 +0100 Subject: add_library: Reject shared libraries on platforms that do not support them Add policy CMP0164 to provide compatibility. Fixes: #25759 --- Help/command/add_library.rst | 7 ++++ Help/manual/cmake-policies.7.rst | 1 + Help/policy/CMP0164.rst | 31 ++++++++++++++++++ .../release/dev/add_library-no-static-fallback.rst | 6 ++++ Source/cmAddLibraryCommand.cxx | 38 +++++++++++++++++----- Source/cmPolicies.h | 6 +++- Tests/RunCMake/add_library/RunCMakeTest.cmake | 4 +++ ...GET_SUPPORTS_SHARED_LIBS_CMP0164_NEW-result.txt | 1 + ...GET_SUPPORTS_SHARED_LIBS_CMP0164_NEW-stderr.txt | 5 +++ .../TARGET_SUPPORTS_SHARED_LIBS_CMP0164_NEW.cmake | 4 +++ .../TARGET_SUPPORTS_SHARED_LIBS_CMP0164_OLD.cmake | 9 +++++ ...ET_SUPPORTS_SHARED_LIBS_CMP0164_WARN-stderr.txt | 7 ++++ .../TARGET_SUPPORTS_SHARED_LIBS_CMP0164_WARN.cmake | 3 ++ 13 files changed, 113 insertions(+), 9 deletions(-) create mode 100644 Help/policy/CMP0164.rst create mode 100644 Help/release/dev/add_library-no-static-fallback.rst create mode 100644 Tests/RunCMake/add_library/TARGET_SUPPORTS_SHARED_LIBS_CMP0164_NEW-result.txt create mode 100644 Tests/RunCMake/add_library/TARGET_SUPPORTS_SHARED_LIBS_CMP0164_NEW-stderr.txt create mode 100644 Tests/RunCMake/add_library/TARGET_SUPPORTS_SHARED_LIBS_CMP0164_NEW.cmake create mode 100644 Tests/RunCMake/add_library/TARGET_SUPPORTS_SHARED_LIBS_CMP0164_OLD.cmake create mode 100644 Tests/RunCMake/add_library/TARGET_SUPPORTS_SHARED_LIBS_CMP0164_WARN-stderr.txt create mode 100644 Tests/RunCMake/add_library/TARGET_SUPPORTS_SHARED_LIBS_CMP0164_WARN.cmake diff --git a/Help/command/add_library.rst b/Help/command/add_library.rst index 5b22cb1..cab380e 100644 --- a/Help/command/add_library.rst +++ b/Help/command/add_library.rst @@ -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 ^^^^^^^^^^^^^^^^ diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index 821a39a..d874363 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -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. CMP0163: The GENERATED source file property is now visible in all directories. CMP0162: Visual Studio generators add UseDebugLibraries indicators by default. diff --git a/Help/policy/CMP0164.rst b/Help/policy/CMP0164.rst new file mode 100644 index 0000000..5ab2ee9 --- /dev/null +++ b/Help/policy/CMP0164.rst @@ -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 diff --git a/Help/release/dev/add_library-no-static-fallback.rst b/Help/release/dev/add_library-no-static-fallback.rst new file mode 100644 index 0000000..72de12b --- /dev/null +++ b/Help/release/dev/add_library-no-static-fallback.rst @@ -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`. diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx index fe71333..9113dfd 100644 --- a/Source/cmAddLibraryCommand.cxx +++ b/Source/cmAddLibraryCommand.cxx @@ -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 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. diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 1af530e..e526dce 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -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) \ diff --git a/Tests/RunCMake/add_library/RunCMakeTest.cmake b/Tests/RunCMake/add_library/RunCMakeTest.cmake index 3283625..26b94f8 100644 --- a/Tests/RunCMake/add_library/RunCMakeTest.cmake +++ b/Tests/RunCMake/add_library/RunCMakeTest.cmake @@ -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) diff --git a/Tests/RunCMake/add_library/TARGET_SUPPORTS_SHARED_LIBS_CMP0164_NEW-result.txt b/Tests/RunCMake/add_library/TARGET_SUPPORTS_SHARED_LIBS_CMP0164_NEW-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/add_library/TARGET_SUPPORTS_SHARED_LIBS_CMP0164_NEW-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/add_library/TARGET_SUPPORTS_SHARED_LIBS_CMP0164_NEW-stderr.txt b/Tests/RunCMake/add_library/TARGET_SUPPORTS_SHARED_LIBS_CMP0164_NEW-stderr.txt new file mode 100644 index 0000000..2a13236 --- /dev/null +++ b/Tests/RunCMake/add_library/TARGET_SUPPORTS_SHARED_LIBS_CMP0164_NEW-stderr.txt @@ -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\)$ diff --git a/Tests/RunCMake/add_library/TARGET_SUPPORTS_SHARED_LIBS_CMP0164_NEW.cmake b/Tests/RunCMake/add_library/TARGET_SUPPORTS_SHARED_LIBS_CMP0164_NEW.cmake new file mode 100644 index 0000000..0f4d34b --- /dev/null +++ b/Tests/RunCMake/add_library/TARGET_SUPPORTS_SHARED_LIBS_CMP0164_NEW.cmake @@ -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) diff --git a/Tests/RunCMake/add_library/TARGET_SUPPORTS_SHARED_LIBS_CMP0164_OLD.cmake b/Tests/RunCMake/add_library/TARGET_SUPPORTS_SHARED_LIBS_CMP0164_OLD.cmake new file mode 100644 index 0000000..3c90403 --- /dev/null +++ b/Tests/RunCMake/add_library/TARGET_SUPPORTS_SHARED_LIBS_CMP0164_OLD.cmake @@ -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() diff --git a/Tests/RunCMake/add_library/TARGET_SUPPORTS_SHARED_LIBS_CMP0164_WARN-stderr.txt b/Tests/RunCMake/add_library/TARGET_SUPPORTS_SHARED_LIBS_CMP0164_WARN-stderr.txt new file mode 100644 index 0000000..89a61c0 --- /dev/null +++ b/Tests/RunCMake/add_library/TARGET_SUPPORTS_SHARED_LIBS_CMP0164_WARN-stderr.txt @@ -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.$ diff --git a/Tests/RunCMake/add_library/TARGET_SUPPORTS_SHARED_LIBS_CMP0164_WARN.cmake b/Tests/RunCMake/add_library/TARGET_SUPPORTS_SHARED_LIBS_CMP0164_WARN.cmake new file mode 100644 index 0000000..1f5cc84 --- /dev/null +++ b/Tests/RunCMake/add_library/TARGET_SUPPORTS_SHARED_LIBS_CMP0164_WARN.cmake @@ -0,0 +1,3 @@ +enable_language(CXX) +set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE) +add_library(someLib SHARED test.cpp) -- cgit v0.12