Merge topic 'fix_compile_only_genex_dependencies'

3f811dc56f Add target ordering dependencies guarded by $<COMPILE_ONLY> genex

Acked-by: Kitware Robot <kwrobot@kitware.com>
Tested-by: buildbot <buildbot@kitware.com>
Merge-request: !12015
This commit is contained in:
Brad King
2026-05-11 15:18:19 +00:00
committed by Kitware Robot
5 changed files with 73 additions and 0 deletions

View File

@@ -219,6 +219,7 @@ void cmComputeTargetDepends::CollectTargetDepends(size_t depender_index)
emitted.insert(cmLinkItem(depender, false, cmListFileBacktrace()));
emitted.insert(cmLinkItem(depender, true, cmListFileBacktrace()));
// Build link dependencies before the current target.
if (cmLinkImplementation const* impl = depender->GetLinkImplementation(
it, cmGeneratorTarget::UseTo::Link)) {
for (cmLinkItem const& lib : impl->Libraries) {
@@ -236,6 +237,18 @@ void cmComputeTargetDepends::CollectTargetDepends(size_t depender_index)
}
}
// Build compile dependencies before the current target.
if (cmLinkImplementation const* impl = depender->GetLinkImplementation(
it, cmGeneratorTarget::UseTo::Compile)) {
for (cmLinkItem const& lib : impl->Libraries) {
// Don't emit the same library twice for this target.
if (emitted.insert(lib).second) {
this->AddTargetDepend(depender_index, lib, true, false, emitted);
this->AddInterfaceDepends(depender_index, lib, it, emitted);
}
}
}
// Add dependencies on object libraries not otherwise handled above.
std::vector<cmSourceFile const*> objectFiles;
depender->GetExternalObjects(objectFiles, it);

View File

@@ -96,6 +96,23 @@
},
"archive": null,
"dependencies": [
{
"id": "^usage_lib::@79b6367c9e05c77f6a80$",
"backtrace": [
{
"file": "^direct/CMakeLists\\.txt$",
"line": 40,
"command": "target_link_libraries",
"hasParent": true
},
{
"file": "^direct/CMakeLists\\.txt$",
"line": null,
"command": null,
"hasParent": false
}
]
},
{
"id": "^ZERO_CHECK::@79b6367c9e05c77f6a80$",
"backtrace": null

View File

@@ -0,0 +1,4 @@
#include "generated.h"
void consume(void)
{
}

View File

@@ -0,0 +1,21 @@
enable_language(C)
# A custom command produces a header that does not exist at configure time.
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/generated.h"
COMMAND "${CMAKE_COMMAND}" -E touch "${CMAKE_CURRENT_BINARY_DIR}/generated.h"
)
# An INTERFACE library generates the header.
add_library(header_provider INTERFACE ${CMAKE_CURRENT_BINARY_DIR}/generated.h)
target_include_directories(header_provider INTERFACE "${CMAKE_CURRENT_BINARY_DIR}")
# Not in ALL so it is only built when something depends on it.
set_property(TARGET header_provider PROPERTY EXCLUDE_FROM_ALL 1)
# A consumer uses $<COMPILE_ONLY:header_provider> so it gets the include
# path but does not link against header_provider. The build-order
# dependency on header_provider must be propagated through the
# COMPILE_ONLY expression so that generated.h exists when consumer.c
# is compiled.
add_library(consumer SHARED COMPILE_ONLY-custom-target-deps-consumer.c)
target_link_libraries(consumer PRIVATE "$<COMPILE_ONLY:header_provider>")

View File

@@ -75,6 +75,22 @@ function(run_cmake_build test)
run_cmake_command(${test}-build ${CMAKE_COMMAND} --build . --config Release)
endfunction()
function(run_cmake_build_target test target)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_CONFIGURATION_TYPES=Release)
else()
list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Release)
endif()
block()
unset(RunCMake-check-file)
run_cmake(${test})
endblock()
set(RunCMake_TEST_NO_CLEAN TRUE)
run_cmake_command(${test}-build
${CMAKE_COMMAND} --build . --target ${target} --config Release)
endfunction()
function(run_linker_genex test lang type)
set(options_args CHECK_RESULT EXECUTE)
cmake_parse_arguments(PARSE_ARGV 3 RLG "${options_args}" "" "")
@@ -132,6 +148,8 @@ endif()
run_cmake(CONFIG-empty-entries)
unset(RunCMake_TEST_OPTIONS)
run_cmake_build_target(COMPILE_ONLY-custom-target-deps consumer)
run_cmake(CMP0199-WARN)
run_cmake_build(CMP0199-OLD)
run_cmake_build(CMP0199-NEW)