Przeglądaj źródła

Make $<LINK_ONLY> available to projects (#14751)

Previously this generator expression was used internally by the
target_link_libraries command to honor private linking requirements of
static libraries in their INTERFACE_LINK_LIBRARIES.  Remove the check
that limits $<LINK_ONLY> to this use case to make it available for
project code to use too.
Brad King 11 lat temu
rodzic
commit
0400cd5dd1

+ 7 - 0
Help/manual/cmake-generator-expressions.7.rst

@@ -188,6 +188,13 @@ property is non-empty::
   Marks ``...`` as being the name of a target.  This is required if exporting
   targets to multiple dependent export sets.  The ``...`` must be a literal
   name of a target- it may not contain generator expressions.
+``$<LINK_ONLY:...>``
+  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.
 ``$<INSTALL_INTERFACE:...>``
   Content of ``...`` when the property is exported using :command:`install(EXPORT)`,
   and empty otherwise.

+ 3 - 11
Source/cmTarget.cxx

@@ -3555,6 +3555,8 @@ void cmTarget::ExpandLinkItems(std::string const& prop,
 {
   cmGeneratorExpression ge;
   cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), prop, 0, 0);
+  // The $<LINK_ONLY> expression may be in a link interface to specify private
+  // link dependencies that are otherwise excluded from usage requirements.
   if(usage_requirements_only)
     {
     dagChecker.SetTransitivePropertiesOnly();
@@ -6057,18 +6059,8 @@ void cmTarget::GetTransitivePropertyTargets(const std::string& config,
                                       cmTarget const* headTarget,
                                       std::vector<cmTarget const*> &tgts) const
 {
-  // The $<LINK_ONLY> expression may be in a link interface to specify private
-  // link dependencies that are otherwise excluded from usage requirements.
-  // Currently $<LINK_ONLY> is internal to CMake and only ever added by
-  // target_link_libraries for PRIVATE dependencies of STATIC libraries in
-  // INTERFACE_LINK_LIBRARIES which is used under CMP0022 NEW behavior.
-  bool usage_requirements_only =
-    this->GetType() == STATIC_LIBRARY &&
-    this->GetPolicyStatusCMP0022() != cmPolicies::WARN &&
-    this->GetPolicyStatusCMP0022() != cmPolicies::OLD;
   if(cmTarget::LinkInterface const* iface =
-     this->GetLinkInterfaceLibraries(config, headTarget,
-                                     usage_requirements_only))
+     this->GetLinkInterfaceLibraries(config, headTarget, true))
     {
     for(std::vector<cmLinkItem>::const_iterator it = iface->Libraries.begin();
         it != iface->Libraries.end(); ++it)

+ 12 - 0
Tests/InterfaceLinkLibraries/CMakeLists.txt

@@ -9,6 +9,9 @@ target_compile_definitions(foo_shared INTERFACE FOO_LIBRARY)
 add_library(bar_shared SHARED bar_vs6_1.cpp)
 target_compile_definitions(bar_shared INTERFACE BAR_LIBRARY)
 set_property(TARGET bar_shared APPEND PROPERTY INTERFACE_LINK_LIBRARIES foo_shared)
+add_library(zot_shared SHARED zot_vs6_1.cpp)
+target_compile_definitions(zot_shared INTERFACE ZOT_LIBRARY)
+set_property(TARGET bar_shared APPEND PROPERTY INTERFACE_LINK_LIBRARIES $<LINK_ONLY:zot_shared>)
 
 add_executable(shared_test main_vs6_1.cpp)
 set_property(TARGET shared_test APPEND PROPERTY LINK_LIBRARIES bar_shared)
@@ -18,6 +21,9 @@ target_compile_definitions(foo_static INTERFACE FOO_LIBRARY)
 add_library(bar_static STATIC bar_vs6_2.cpp)
 target_compile_definitions(bar_static INTERFACE BAR_LIBRARY)
 set_property(TARGET bar_static APPEND PROPERTY INTERFACE_LINK_LIBRARIES foo_static)
+add_library(zot_static STATIC zot_vs6_2.cpp)
+target_compile_definitions(zot_static INTERFACE ZOT_LIBRARY)
+set_property(TARGET bar_static APPEND PROPERTY INTERFACE_LINK_LIBRARIES $<LINK_ONLY:zot_static>)
 
 add_executable(static_test main_vs6_2.cpp)
 set_property(TARGET static_test APPEND PROPERTY LINK_LIBRARIES bar_static)
@@ -31,6 +37,9 @@ target_compile_definitions(bar_shared_private INTERFACE BAR_LIBRARY)
 target_compile_definitions(bar_shared_private PRIVATE BAR_USE_BANG)
 set_property(TARGET bar_shared_private APPEND PROPERTY LINK_LIBRARIES bang_shared_private)
 set_property(TARGET bar_shared_private APPEND PROPERTY INTERFACE_LINK_LIBRARIES foo_shared_private)
+add_library(zot_shared_private SHARED zot_vs6_3.cpp)
+target_compile_definitions(zot_shared_private INTERFACE ZOT_LIBRARY)
+set_property(TARGET bar_shared_private APPEND PROPERTY INTERFACE_LINK_LIBRARIES $<LINK_ONLY:zot_shared_private>)
 
 add_executable(shared_private_test main_vs6_3.cpp)
 set_property(TARGET shared_private_test APPEND PROPERTY LINK_LIBRARIES bar_shared_private)
@@ -44,6 +53,9 @@ target_compile_definitions(bar_static_private INTERFACE BAR_LIBRARY)
 target_compile_definitions(bar_static_private PRIVATE BAR_USE_BANG)
 set_property(TARGET bar_static_private APPEND PROPERTY LINK_LIBRARIES bang_static_private)
 set_property(TARGET bar_static_private APPEND PROPERTY INTERFACE_LINK_LIBRARIES $<LINK_ONLY:bang_static_private> foo_static_private)
+add_library(zot_static_private STATIC zot_vs6_4.cpp)
+target_compile_definitions(zot_static_private INTERFACE ZOT_LIBRARY)
+set_property(TARGET bar_static_private APPEND PROPERTY INTERFACE_LINK_LIBRARIES $<LINK_ONLY:zot_static_private>)
 
 add_executable(InterfaceLinkLibraries main_vs6_4.cpp)
 set_property(TARGET InterfaceLinkLibraries APPEND PROPERTY LINK_LIBRARIES bar_static_private)

+ 6 - 2
Tests/InterfaceLinkLibraries/main.cpp

@@ -11,9 +11,13 @@
 #error Unexpected BANG_LIBRARY
 #endif
 
-#include "bar.h"
+#ifdef ZOT_LIBRARY
+#error Unexpected ZOT_LIBRARY
+#endif
+
+#include "zot.h"
 
 int main(void)
 {
-  return foo() + bar();
+  return foo() + bar() + zot();
 }

+ 6 - 0
Tests/InterfaceLinkLibraries/zot.cpp

@@ -0,0 +1,6 @@
+#include "zot.h"
+
+int zot()
+{
+  return 0;
+}

+ 7 - 0
Tests/InterfaceLinkLibraries/zot.h

@@ -0,0 +1,7 @@
+
+#include "bar.h"
+
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int zot();

+ 1 - 0
Tests/InterfaceLinkLibraries/zot_vs6_1.cpp

@@ -0,0 +1 @@
+#include "zot.cpp"

+ 1 - 0
Tests/InterfaceLinkLibraries/zot_vs6_2.cpp

@@ -0,0 +1 @@
+#include "zot.cpp"

+ 1 - 0
Tests/InterfaceLinkLibraries/zot_vs6_3.cpp

@@ -0,0 +1 @@
+#include "zot.cpp"

+ 1 - 0
Tests/InterfaceLinkLibraries/zot_vs6_4.cpp

@@ -0,0 +1 @@
+#include "zot.cpp"