Tests/RunCMake/Codegen: Extend coverage

Cover additional cases pertaining to add_dependencies:

* dependencies followed through an intermediate target,
* a dependency's non-CODEGEN commands must not run,
* dependencies of EXCLUDE_FROM_ALL targets are not followed,
* a dependency in an EXCLUDE_FROM_ALL subdirectory is reached.

Also verify that codegen re-runs a command only when its inputs change.
This commit is contained in:
Tyler Yankee committed 2026-10-25 19:52:43 -04:00
1 parent fe95f96096
commit 36fcfb3e01
12 files changed
+123 -1

No files matched your search

@@ -0,0 +1,21 @@
add_custom_command(
OUTPUT
${CMAKE_CURRENT_BINARY_DIR}/generated.h
COMMAND
${CMAKE_COMMAND} -E
copy ${CMAKE_CURRENT_SOURCE_DIR}/../generated.h.in
${CMAKE_CURRENT_BINARY_DIR}/generated.h
CODEGEN
)
add_custom_target(h_creator DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/generated.h)
# Nothing depends on this, and the directory is EXCLUDE_FROM_ALL,
# so codegen must not run it.
add_custom_command(
OUTPUT
${CMAKE_CURRENT_BINARY_DIR}/unreached.h
COMMAND
${CMAKE_COMMAND} -E false
CODEGEN
)
add_custom_target(unreached DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/unreached.h)
+18
View File
@@ -27,6 +27,9 @@ run_codegen("add-dependencies")
run_codegen("add-custom-command-depends")
run_codegen("byproducts")
run_codegen("add-dependencies-not-all")
run_codegen("add-dependencies-transitive")
run_codegen("add-dependencies-exclude-from-all")
run_codegen("add-dependencies-subdir")
# Outputs that differ per configuration
block()
@@ -55,6 +58,21 @@ block()
endif()
endblock()
# codegen re-runs commands only when their inputs change
block()
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/rebuild-build)
run_cmake(rebuild)
set(RunCMake_TEST_NO_CLEAN 1)
run_cmake_command(rebuild-build1 ${CMAKE_COMMAND} --build . --target codegen --config Debug)
# Make the output newer than its input but with different content.
file(WRITE ${RunCMake_TEST_BINARY_DIR}/generated.h "stale")
run_cmake_command(rebuild-build2 ${CMAKE_COMMAND} --build . --target codegen --config Debug)
# Ensure the input is newer than the output.
execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1)
file(WRITE ${RunCMake_TEST_BINARY_DIR}/input.txt "2")
run_cmake_command(rebuild-build3 ${CMAKE_COMMAND} --build . --target codegen --config Debug)
endblock()
# Error handling
run_cmake("implicit-depends")
run_cmake("implicit-depends-append-codegen")
@@ -0,0 +1,10 @@
add_custom_command(
OUTPUT generated.h
COMMAND ${CMAKE_COMMAND} -E false
CODEGEN
)
add_custom_target(h_creator DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/generated.h)
# codegen should not follow dependencies of targets that are EXCLUDE_FROM_ALL.
add_executable(main EXCLUDE_FROM_ALL main.c)
add_dependencies(main h_creator)
@@ -9,8 +9,17 @@ add_custom_command(
CODEGEN
)
# Not marked CODEGEN, so codegen must not run it.
add_custom_command(
OUTPUT not-codegen.h
COMMAND ${CMAKE_COMMAND} -E false
)
# N.B. h_creator is *not* added to ALL.
add_custom_target(h_creator DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/generated.h)
add_custom_target(h_creator DEPENDS
${CMAKE_CURRENT_BINARY_DIR}/generated.h
${CMAKE_CURRENT_BINARY_DIR}/not-codegen.h
)
# This test will fail if add_dependencies isn't accounted for in the
# codegen build graph
@@ -0,0 +1,5 @@
set(filename "${RunCMake_TEST_BINARY_DIR}/AddDependenciesSubDir/generated.h")
if (NOT EXISTS "${filename}")
set(RunCMake_TEST_FAILED "expected file NOT created:\n ${filename}")
return()
endif()
@@ -0,0 +1,8 @@
add_subdirectory(AddDependenciesSubDir EXCLUDE_FROM_ALL)
add_executable(main
main.c
)
# codegen must reach h_creator in the excluded directory through main.
add_dependencies(main h_creator)
@@ -0,0 +1,5 @@
set(filename "${RunCMake_TEST_BINARY_DIR}/generated.h")
if (NOT EXISTS "${filename}")
set(RunCMake_TEST_FAILED "expected file NOT created:\n ${filename}")
return()
endif()
@@ -0,0 +1,23 @@
add_executable(main
main.c
)
add_custom_command(
OUTPUT generated.h
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/generated.h.in
${CMAKE_CURRENT_BINARY_DIR}/generated.h
CODEGEN
)
add_custom_target(h_creator DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/generated.h)
# Not marked CODEGEN, so codegen must not run it.
add_custom_command(
OUTPUT not-codegen.h
COMMAND ${CMAKE_COMMAND} -E false
)
add_custom_target(middle DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/not-codegen.h)
# Neither middle nor h_creator is in ALL, so codegen must reach h_creator
# through middle without building middle itself.
add_dependencies(main middle)
add_dependencies(middle h_creator)
@@ -0,0 +1,4 @@
file(READ "${RunCMake_TEST_BINARY_DIR}/generated.h" actual)
if (NOT actual STREQUAL "1")
set(RunCMake_TEST_FAILED "generated.h has wrong content:\n expected: 1\n actual: ${actual}")
endif()
@@ -0,0 +1,4 @@
file(READ "${RunCMake_TEST_BINARY_DIR}/generated.h" actual)
if (NOT actual STREQUAL "stale")
set(RunCMake_TEST_FAILED "generated.h re-generated even though it is up to date:\n expected: stale\n actual: ${actual}")
endif()
@@ -0,0 +1,4 @@
file(READ "${RunCMake_TEST_BINARY_DIR}/generated.h" actual)
if (NOT actual STREQUAL "2")
set(RunCMake_TEST_FAILED "generated.h NOT re-generated after its input changed:\n expected: 2\n actual: ${actual}")
endif()
+11
View File
@@ -0,0 +1,11 @@
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/input.txt "1")
add_custom_command(
OUTPUT generated.h
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/input.txt
${CMAKE_CURRENT_BINARY_DIR}/generated.h
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/input.txt
CODEGEN
)
add_custom_target(h_creator ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/generated.h)