From 16c5977504cfcc25b6ffd331c493841d1e6dc1ec Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 9 Nov 2023 14:21:35 -0500 Subject: Fix per-config sources in multi-config generators when first config adds none Since commit b1c3ae33ea (cmTarget: Short-circuit language computation if context independent., 2014-04-09, v3.1.0-rc1~669^2~1) we've tried to avoid repeating computation of the list of sources for a target for every configuration in the case that a per-config source (or object library) contributes zero sources. However, it is possible that an entry contributes zero sources in the first configuration processed but at least one source in other configurations. Fixes: #25400 --- Source/cmGeneratorTarget.cxx | 13 ++++++------- Tests/ConfigSources/CMakeLists.txt | 8 ++++++++ Tests/ConfigSources/main_one_config.cpp | 8 ++++++++ 3 files changed, 22 insertions(+), 7 deletions(-) create mode 100644 Tests/ConfigSources/main_one_config.cpp diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index d24867f..adca9ce 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -1833,32 +1833,31 @@ std::vector> cmGeneratorTarget::GetSourceFilePaths( AddInterfaceEntries(this, config, "INTERFACE_SOURCES", std::string(), &dagChecker, linkInterfaceSourcesEntries, IncludeRuntimeInterface::No, LinkInterfaceFor::Usage); - std::vector::size_type numFilesBefore = files.size(); bool contextDependentInterfaceSources = processSources( this, linkInterfaceSourcesEntries, files, uniqueSrcs, debugSources); // Collect TARGET_OBJECTS of direct object link-dependencies. bool contextDependentObjects = false; - std::vector::size_type numFilesBefore2 = files.size(); if (this->GetType() != cmStateEnums::OBJECT_LIBRARY) { EvaluatedTargetPropertyEntries linkObjectsEntries; AddObjectEntries(this, config, &dagChecker, linkObjectsEntries); contextDependentObjects = processSources(this, linkObjectsEntries, files, uniqueSrcs, debugSources); + // Note that for imported targets or multi-config generators supporting + // cross-config builds the paths to the object files must be per-config, + // so contextDependentObjects will be true here even if object libraries + // are specified without per-config generator expressions. } // Collect this target's file sets. - std::vector::size_type numFilesBefore3 = files.size(); EvaluatedTargetPropertyEntries fileSetEntries; AddFileSetEntries(this, config, &dagChecker, fileSetEntries); bool contextDependentFileSets = processSources(this, fileSetEntries, files, uniqueSrcs, debugSources); // Determine if sources are context-dependent or not. - if (!contextDependentDirectSources && - !(contextDependentInterfaceSources && numFilesBefore < files.size()) && - !(contextDependentObjects && numFilesBefore2 < files.size()) && - !(contextDependentFileSets && numFilesBefore3 < files.size())) { + if (!contextDependentDirectSources && !contextDependentInterfaceSources && + !contextDependentObjects && !contextDependentFileSets) { this->SourcesAreContextDependent = Tribool::False; } else { this->SourcesAreContextDependent = Tribool::True; diff --git a/Tests/ConfigSources/CMakeLists.txt b/Tests/ConfigSources/CMakeLists.txt index 38475f8..770afb3 100644 --- a/Tests/ConfigSources/CMakeLists.txt +++ b/Tests/ConfigSources/CMakeLists.txt @@ -154,7 +154,15 @@ else() endif() add_library(OneConfigOnly OBJECT "$<$:${CMAKE_CURRENT_SOURCE_DIR}/iface_src.cpp>") set_property(TARGET OneConfigOnly PROPERTY LINKER_LANGUAGE CXX) +add_executable(ConfigSourcesUseOne main_one_config.cpp) +target_compile_definitions(ConfigSourcesUseOne PRIVATE "$<$:CFG_ONE>") +target_link_libraries(ConfigSourcesUseOne PRIVATE "$<$:OneConfigOnly>") +add_library(OneConfigOnlyIface INTERFACE) +target_sources(OneConfigOnlyIface INTERFACE "$<$:${CMAKE_CURRENT_SOURCE_DIR}/iface_src.cpp>") +add_executable(ConfigSourcesUseOneIface main_one_config.cpp) +target_compile_definitions(ConfigSourcesUseOneIface PRIVATE "$<$:CFG_ONE>") +target_link_libraries(ConfigSourcesUseOneIface PRIVATE "$<$:OneConfigOnlyIface>") # --------------------------------------------------------------------------- # Makes sure that each configuration uses the correct generated file. diff --git a/Tests/ConfigSources/main_one_config.cpp b/Tests/ConfigSources/main_one_config.cpp new file mode 100644 index 0000000..318944b --- /dev/null +++ b/Tests/ConfigSources/main_one_config.cpp @@ -0,0 +1,8 @@ +#include "iface.h" +int main() +{ +#ifdef CFG_ONE + iface_src(); +#endif + return 0; +} -- cgit v0.12