diff options
author | Brad King <brad.king@kitware.com> | 2022-03-22 15:09:23 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2022-03-24 12:23:55 (GMT) |
commit | cf312a2e5423c49cc5da446f5407a6f4a596a3cb (patch) | |
tree | 3bde9691ad13e40b06744b63a2c53dda75cbdf2a | |
parent | 41a6b4a53ba844ef986b0bc4efe8938b97eea810 (diff) | |
download | CMake-cf312a2e5423c49cc5da446f5407a6f4a596a3cb.zip CMake-cf312a2e5423c49cc5da446f5407a6f4a596a3cb.tar.gz CMake-cf312a2e5423c49cc5da446f5407a6f4a596a3cb.tar.bz2 |
LINK_LIBRARIES: Add support for LINK_ONLY genex
Previously we always used content guarded by `$<LINK_ONLY:...>`
in `LINK_LIBRARIES`, even when evaluating for non-linking usage
requirements. Add a policy to honor `LINK_ONLY` in `LINK_LIBRARIES`
the same way we already do in `INTERFACE_LINK_LIBRARIES`.
-rw-r--r-- | Help/manual/cmake-generator-expressions.7.rst | 15 | ||||
-rw-r--r-- | Help/manual/cmake-policies.7.rst | 1 | ||||
-rw-r--r-- | Help/policy/CMP0131.rst | 31 | ||||
-rw-r--r-- | Help/release/dev/link-interface-direct.rst | 4 | ||||
-rw-r--r-- | Source/cmGeneratorTarget.cxx | 14 | ||||
-rw-r--r-- | Source/cmPolicies.h | 8 | ||||
-rw-r--r-- | Tests/InterfaceLinkLibraries/CMakeLists.txt | 9 | ||||
-rw-r--r-- | Tests/InterfaceLinkLibraries/foo_link_only.c | 8 | ||||
-rw-r--r-- | Tests/InterfaceLinkLibraries/use_foo_link_only.c | 16 | ||||
-rw-r--r-- | Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt | 1 |
10 files changed, 99 insertions, 8 deletions
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index b79cf3a..530a406 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -1106,12 +1106,15 @@ Output-Related Expressions .. versionadded:: 3.1 - Content of ``...`` except when evaluated in a link interface while - propagating :ref:`Target Usage Requirements`, in which case it is the - empty string. - Intended for use only in an :prop_tgt:`INTERFACE_LINK_LIBRARIES` target - property, perhaps via the :command:`target_link_libraries` command, - to specify private link dependencies without other usage requirements. + Content of ``...``, except while collecting :ref:`Target Usage Requirements`, + in which case it is the empty string. This is intended for use in an + :prop_tgt:`INTERFACE_LINK_LIBRARIES` target property, typically populated + via the :command:`target_link_libraries` command, to specify private link + dependencies without other usage requirements. + + .. versionadded:: 3.24 + ``LINK_ONLY`` may also be used in a :prop_tgt:`LINK_LIBRARIES` target + property. See policy :policy:`CMP0131`. .. genex:: $<LINK_LIBRARY:feature,library-list> diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index dfc5de6..9bf2913 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -58,6 +58,7 @@ Policies Introduced by CMake 3.24 .. toctree:: :maxdepth: 1 + CMP0131: LINK_LIBRARIES supports the LINK_ONLY generator expression. </policy/CMP0131> CMP0130: while() diagnoses condition evaluation errors. </policy/CMP0130> Policies Introduced by CMake 3.23 diff --git a/Help/policy/CMP0131.rst b/Help/policy/CMP0131.rst new file mode 100644 index 0000000..e85b8ab --- /dev/null +++ b/Help/policy/CMP0131.rst @@ -0,0 +1,31 @@ +CMP0131 +------- + +.. versionadded:: 3.24 + +:prop_tgt:`LINK_LIBRARIES` supports the :genex:`$<LINK_ONLY:...>` +generator expression. + +CMake 3.23 and below documented the :genex:`$<LINK_ONLY:...>` generator +expression only for use in :prop_tgt:`INTERFACE_LINK_LIBRARIES`. +When used in :prop_tgt:`LINK_LIBRARIES`, the content guarded inside +:genex:`$<LINK_ONLY:...>` was always used, even when collecting non-linking +usage requirements such as :prop_tgt:`INTERFACE_COMPILE_DEFINITIONS`. + +CMake 3.24 and above prefer to support :genex:`$<LINK_ONLY:...>`, when +used in :prop_tgt:`LINK_LIBRARIES`, by using the guarded content only +for link dependencies and not other usage requirements. This policy +provides compatibility for projects that have not been updated to +account for this change. + +The ``OLD`` behavior for this policy is to use :prop_tgt:`LINK_LIBRARIES` +content guarded by :genex:`$<LINK_ONLY:...>` even for non-linking +usage requirements. The ``NEW`` behavior for this policy is to to use +the guarded content only for link dependencies. + +This policy was introduced in CMake version 3.24. Use the +:command:`cmake_policy` command to set this policy to ``OLD`` or ``NEW`` +explicitly. Unlike many policies, CMake version |release| does *not* +warn when this policy is not set, and simply uses ``OLD`` behavior. + +.. include:: DEPRECATED.txt diff --git a/Help/release/dev/link-interface-direct.rst b/Help/release/dev/link-interface-direct.rst index 2e9a59e..8b858e2 100644 --- a/Help/release/dev/link-interface-direct.rst +++ b/Help/release/dev/link-interface-direct.rst @@ -5,3 +5,7 @@ link-interface-direct :prop_tgt:`INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE` target properties were added to express usage requirements affecting a consumer's direct link dependencies. + +* The :prop_tgt:`LINK_LIBRARIES` target property now supports + the :genex:`$<LINK_ONLY:...>` generator expression. + See policy :policy:`CMP0131`. diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 6c804b5..1a13bdb 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -8152,6 +8152,20 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries( // Keep this logic in sync with ExpandLinkItems. cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_LIBRARIES", nullptr, nullptr); + // The $<LINK_ONLY> expression may be used to specify link dependencies + // that are otherwise excluded from usage requirements. + if (implFor == LinkInterfaceFor::Usage) { + switch (this->GetPolicyStatusCMP0131()) { + case cmPolicies::WARN: + case cmPolicies::OLD: + break; + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::NEW: + dagChecker.SetTransitivePropertiesOnly(); + break; + } + } cmGeneratorExpression ge(entry.Backtrace); std::unique_ptr<cmCompiledGeneratorExpression> const cge = ge.Parse(entry.Value); diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 7d4012d..3b9d067 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -390,7 +390,10 @@ class cmMakefile; "Compiler id for MCST LCC compilers is now LCC, not GNU.", 3, 23, 0, \ cmPolicies::WARN) \ SELECT(POLICY, CMP0130, "while() diagnoses condition evaluation errors.", \ - 3, 24, 0, cmPolicies::WARN) + 3, 24, 0, cmPolicies::WARN) \ + SELECT(POLICY, CMP0131, \ + "LINK_LIBRARIES supports the LINK_ONLY generator expression.", 3, \ + 24, 0, cmPolicies::WARN) #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1) #define CM_FOR_EACH_POLICY_ID(POLICY) \ @@ -426,7 +429,8 @@ class cmMakefile; F(CMP0108) \ F(CMP0112) \ F(CMP0113) \ - F(CMP0119) + F(CMP0119) \ + F(CMP0131) /** \class cmPolicies * \brief Handles changes in CMake behavior and policies diff --git a/Tests/InterfaceLinkLibraries/CMakeLists.txt b/Tests/InterfaceLinkLibraries/CMakeLists.txt index 9e14c44..07a747b 100644 --- a/Tests/InterfaceLinkLibraries/CMakeLists.txt +++ b/Tests/InterfaceLinkLibraries/CMakeLists.txt @@ -59,3 +59,12 @@ set_property(TARGET bar_static_private APPEND PROPERTY INTERFACE_LINK_LIBRARIES add_executable(InterfaceLinkLibraries main_vs6_4.cpp) set_property(TARGET InterfaceLinkLibraries APPEND PROPERTY LINK_LIBRARIES bar_static_private) + +add_library(foo_link_only STATIC foo_link_only.c) +target_compile_definitions(foo_link_only PUBLIC FOO_LINK_ONLY) +add_executable(use_foo_link_only_CMP0131_OLD use_foo_link_only.c) +target_link_libraries(use_foo_link_only_CMP0131_OLD PRIVATE "$<LINK_ONLY:foo_link_only>") +target_compile_definitions(use_foo_link_only_CMP0131_OLD PRIVATE EXPECT_FOO_LINK_ONLY) +cmake_policy(SET CMP0131 NEW) +add_executable(use_foo_link_only_CMP0131_NEW use_foo_link_only.c) +target_link_libraries(use_foo_link_only_CMP0131_NEW PRIVATE "$<LINK_ONLY:foo_link_only>") diff --git a/Tests/InterfaceLinkLibraries/foo_link_only.c b/Tests/InterfaceLinkLibraries/foo_link_only.c new file mode 100644 index 0000000..9ca1c01 --- /dev/null +++ b/Tests/InterfaceLinkLibraries/foo_link_only.c @@ -0,0 +1,8 @@ +#ifndef FOO_LINK_ONLY +# error "FOO_LINK_ONLY incorrectly not defined" +#endif + +int foo_link_only(void) +{ + return 0; +} diff --git a/Tests/InterfaceLinkLibraries/use_foo_link_only.c b/Tests/InterfaceLinkLibraries/use_foo_link_only.c new file mode 100644 index 0000000..e975c1b --- /dev/null +++ b/Tests/InterfaceLinkLibraries/use_foo_link_only.c @@ -0,0 +1,16 @@ +#ifdef EXPECT_FOO_LINK_ONLY +# ifndef FOO_LINK_ONLY +# error "FOO_LINK_ONLY incorrectly not defined" +# endif +#else +# ifdef FOO_LINK_ONLY +# error "FOO_LINK_ONLY incorrectly defined" +# endif +#endif + +extern int foo_link_only(void); + +int main(void) +{ + return foo_link_only(); +} diff --git a/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt b/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt index 3846d7c..97c3394 100644 --- a/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt +++ b/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt @@ -35,6 +35,7 @@ \* CMP0112 \* CMP0113 \* CMP0119 + \* CMP0131 Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\) |