mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-05 21:31:08 -06:00
INTERFACE_SOURCES: Fix per-config link libs on multi-config generators
In multi-config generators we memoize the computed set of source files
for a target to avoid repeating the computation when the set does not
depend on the configuration. We already track whether generator
expressions in `SOURCES` or `INTERFACE_SOURCES` reference the
configuration (`$<CONFIG:...>`). However, we previously forgot to track
whether the set of libraries whose `INTERFACE_SOURCES` are considered
depends on the configuration. This caused multi-config generators to
use the first configuration's set of sources for all configurations
in cases such as
target_link_libraries(tgt PRIVATE $<$<CONFIG:Debug>:iface_debug>)
where the `iface_debug` target has `INTERFACE_SOURCES`.
Fix this by also tracking config-dependence of the list of libraries for
evaluation of the list of source files.
Fixes: #20683
This commit is contained in:
@@ -241,6 +241,7 @@ EvaluatedTargetPropertyEntry EvaluateTargetPropertyEntry(
|
||||
struct EvaluatedTargetPropertyEntries
|
||||
{
|
||||
std::vector<EvaluatedTargetPropertyEntry> Entries;
|
||||
bool HadContextSensitiveCondition = false;
|
||||
};
|
||||
|
||||
EvaluatedTargetPropertyEntries EvaluateTargetPropertyEntries(
|
||||
@@ -1251,6 +1252,9 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
|
||||
|
||||
if (cmLinkInterfaceLibraries const* iface = this->GetLinkInterfaceLibraries(
|
||||
context->Config, headTarget, usage_requirements_only)) {
|
||||
context->HadContextSensitiveCondition =
|
||||
context->HadContextSensitiveCondition ||
|
||||
iface->HadContextSensitiveCondition;
|
||||
for (cmLinkItem const& lib : iface->Libraries) {
|
||||
// Broken code can have a target in its own link interface.
|
||||
// Don't follow such link interface entries so as not to create a
|
||||
@@ -1378,6 +1382,7 @@ void AddInterfaceEntries(cmGeneratorTarget const* headTarget,
|
||||
{
|
||||
if (cmLinkImplementationLibraries const* impl =
|
||||
headTarget->GetLinkImplementationLibraries(config)) {
|
||||
entries.HadContextSensitiveCondition = impl->HadContextSensitiveCondition;
|
||||
for (cmLinkImplItem const& lib : impl->Libraries) {
|
||||
if (lib.Target) {
|
||||
EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace);
|
||||
@@ -1404,6 +1409,7 @@ void AddObjectEntries(cmGeneratorTarget const* headTarget,
|
||||
{
|
||||
if (cmLinkImplementationLibraries const* impl =
|
||||
headTarget->GetLinkImplementationLibraries(config)) {
|
||||
entries.HadContextSensitiveCondition = impl->HadContextSensitiveCondition;
|
||||
for (cmLinkImplItem const& lib : impl->Libraries) {
|
||||
if (lib.Target &&
|
||||
lib.Target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
|
||||
@@ -1436,7 +1442,7 @@ bool processSources(cmGeneratorTarget const* tgt,
|
||||
{
|
||||
cmMakefile* mf = tgt->Target->GetMakefile();
|
||||
|
||||
bool contextDependent = false;
|
||||
bool contextDependent = entries.HadContextSensitiveCondition;
|
||||
|
||||
for (EvaluatedTargetPropertyEntry& entry : entries.Entries) {
|
||||
if (entry.ContextDependent) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
project(ConfigSources CXX)
|
||||
|
||||
# Per-config sources via INTERFACE_SOURCES.
|
||||
add_library(iface INTERFACE)
|
||||
target_sources(iface INTERFACE
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/iface_src.cpp"
|
||||
@@ -12,10 +13,45 @@ target_compile_definitions(iface INTERFACE
|
||||
"$<$<CONFIG:Debug>:CFG_DEBUG>"
|
||||
"$<$<NOT:$<CONFIG:Debug>>:CFG_OTHER>"
|
||||
)
|
||||
|
||||
add_executable(ConfigSources
|
||||
$<$<CONFIG:Debug>:main_debug.cpp>
|
||||
$<$<NOT:$<CONFIG:Debug>>:main_other.cpp>
|
||||
$<$<CONFIG:NotAConfig>:does_not_exist.cpp>
|
||||
)
|
||||
target_link_libraries(ConfigSources iface)
|
||||
|
||||
# Per-config sources via LINK_LIBRARIES.
|
||||
add_library(iface_debug INTERFACE)
|
||||
target_sources(iface_debug INTERFACE
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/iface_src.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/iface_debug_src.cpp"
|
||||
)
|
||||
add_library(iface_other INTERFACE)
|
||||
target_sources(iface_other INTERFACE
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/iface_src.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/iface_other_src.cpp"
|
||||
)
|
||||
add_executable(ConfigSourcesLink main.cpp)
|
||||
target_compile_definitions(ConfigSourcesLink PRIVATE
|
||||
"$<$<CONFIG:Debug>:CFG_DEBUG>"
|
||||
"$<$<NOT:$<CONFIG:Debug>>:CFG_OTHER>"
|
||||
)
|
||||
target_link_libraries(ConfigSourcesLink PRIVATE
|
||||
"$<$<CONFIG:Debug>:iface_debug>"
|
||||
"$<$<NOT:$<CONFIG:Debug>>:iface_other>"
|
||||
"$<$<CONFIG:NotAConfig>:iface_does_not_exist>"
|
||||
)
|
||||
|
||||
# Per-config sources via INTERFACE_LINK_LIBRARIES.
|
||||
add_library(ConfigSourcesIface INTERFACE)
|
||||
target_link_libraries(ConfigSourcesIface INTERFACE
|
||||
"$<$<CONFIG:Debug>:iface_debug>"
|
||||
"$<$<NOT:$<CONFIG:Debug>>:iface_other>"
|
||||
"$<$<CONFIG:NotAConfig>:iface_does_not_exist>"
|
||||
)
|
||||
add_executable(ConfigSourcesLinkIface main.cpp)
|
||||
target_compile_definitions(ConfigSourcesLinkIface PRIVATE
|
||||
"$<$<CONFIG:Debug>:CFG_DEBUG>"
|
||||
"$<$<NOT:$<CONFIG:Debug>>:CFG_OTHER>"
|
||||
)
|
||||
target_link_libraries(ConfigSourcesLinkIface ConfigSourcesIface)
|
||||
|
||||
9
Tests/ConfigSources/main.cpp
Normal file
9
Tests/ConfigSources/main.cpp
Normal file
@@ -0,0 +1,9 @@
|
||||
#if !defined(CFG_DEBUG) && !defined(CFG_OTHER)
|
||||
# error "Neither CFG_DEBUG or CFG_OTHER is defined."
|
||||
#endif
|
||||
#ifdef CFG_DEBUG
|
||||
# include "main_debug.cpp"
|
||||
#endif
|
||||
#ifdef CFG_OTHER
|
||||
# include "main_other.cpp"
|
||||
#endif
|
||||
Reference in New Issue
Block a user