INTERFACE_LINK_LIBRARIES_DIRECT: Honor link dependencies through LINK_ONLY

In commit f3ad061858 (Add usage requirements to update direct link
dependencies, 2022-01-12, v3.23.0-rc1~44^2), we evaluated the transitive
closure of `INTERFACE_LINK_LIBRARIES` as a non-linking usage requirement.
That left out `INTERFACE_LINK_LIBRARIES_DIRECT` link dependencies that
appear behind private dependencies of a static library, guarded by the
`$<LINK_ONLY:...>` generator expression.  At the time, that decision was
intentional, in order to prevent arbitrary usage requirements from
leaking out of `PRIVATE` dependencies.

Since then, we've revised evaluation of `LINK_LIBRARIES` to distinguish
between collecting link dependencies and other usage requirements.  Use
that information when following `INTERFACE_LINK_LIBRARIES` to collect
the matching kind of requirements from `INTERFACE_LINK_LIBRARIES_DIRECT`.

Fixes: #22496
This commit is contained in:
Brad King
2022-03-22 09:49:11 -04:00
parent 73337cb383
commit 41a6b4a53b
5 changed files with 66 additions and 23 deletions

View File

@@ -52,7 +52,7 @@ set_property(TARGET A APPEND PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT
add_library(static_A_public STATIC static_A_public.c)
target_link_libraries(static_A_public PUBLIC A)
# Uses A's usage requirements, but does not propagate them.
# Uses A's usage requirements, but propagates only the linking requirements.
# Does not use the exe-only usage requirement. Does use the optional one.
add_library(static_A_private STATIC static_A_private.c)
target_link_libraries(static_A_private PRIVATE A)
@@ -63,10 +63,15 @@ add_executable(exe_use_static_A_public exe_use_static_A_public.c)
target_link_libraries(exe_use_static_A_public PRIVATE static_A_public)
set_property(TARGET exe_use_static_A_public PROPERTY A_LINK_OPTIONAL 1)
# Does not use A's usage requirements.
# Does not use A's usage requirements, but does use its non-optional linking requirements.
add_executable(exe_use_static_A_private exe_use_static_A_private.c)
target_link_libraries(exe_use_static_A_private PRIVATE static_A_private)
# Uses A's usage requirements, including an optional one, but overrides the link ordering.
add_executable(exe_use_static_A_public_explicit exe_use_static_A_public_explicit.c)
target_link_libraries(exe_use_static_A_public_explicit PRIVATE static_A_public A direct_from_A direct_from_A_for_exe direct_from_A_optional)
set_property(TARGET exe_use_static_A_public_explicit PROPERTY A_LINK_OPTIONAL 1)
#----------------------------------------------------------------------------
# Test how original and injected dependencies get ordered.

View File

@@ -9,15 +9,15 @@
#endif
extern void static_A_private(void);
extern void not_direct_from_A(void);
extern void not_direct_from_A_for_exe(void);
extern void direct_from_A(void);
extern void direct_from_A_for_exe(void);
extern void not_direct_from_A_optional(void);
int main(void)
{
static_A_private();
not_direct_from_A();
not_direct_from_A_for_exe();
direct_from_A();
direct_from_A_for_exe();
not_direct_from_A_optional();
return 0;
}

View File

@@ -0,0 +1,23 @@
#ifndef DEF_DIRECT_FROM_A
# error "DEF_DIRECT_FROM_A incorrectly not defined"
#endif
#ifndef DEF_DIRECT_FROM_A_FOR_EXE
# error "DEF_DIRECT_FROM_A_FOR_EXE incorrectly not defined"
#endif
#ifndef DEF_DIRECT_FROM_A_OPTIONAL
# error "DEF_DIRECT_FROM_A_OPTIONAL incorrectly not defined"
#endif
extern void static_A_public(void);
extern void not_direct_from_A(void);
extern void not_direct_from_A_for_exe(void);
extern void not_direct_from_A_optional(void);
int main(void)
{
static_A_public();
not_direct_from_A();
not_direct_from_A_for_exe();
not_direct_from_A_optional();
return 0;
}