add_custom_target dependencies wrong with CMAKE_CROSS_CONFIGS=all
Consider the attached project custom_target_deps.tar.gz:
cmake_minimum_required(VERSION 3.20)
project(custom_command_deps)
add_executable(generator generator.cpp)
add_executable(XY::generator ALIAS generator)
add_custom_command(
OUTPUT generated1.cpp
COMMAND "$<TARGET_FILE:generator>" generated1.cpp 1
VERBATIM)
add_custom_target(foo1 DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/generated1.cpp")
add_custom_command(
OUTPUT generated2.cpp
COMMAND "NARF=zort" "$<TARGET_FILE:generator>" generated2.cpp 2
VERBATIM)
add_custom_target(foo2 DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/generated2.cpp")
add_custom_command(
OUTPUT generated3.cpp
COMMAND "NARF=zort" "$<COMMAND_CONFIG:$<TARGET_FILE:generator>>" generated3.cpp 3
VERBATIM)
add_custom_target(foo3 DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/generated3.cpp")
add_custom_command(
OUTPUT generated4.cpp
COMMAND "NARF=zort" "$<TARGET_FILE:generator>" generated4.cpp 4
DEPENDS generator
VERBATIM)
add_custom_target(foo4 DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/generated4.cpp")
add_custom_command(
OUTPUT generated5.cpp
COMMAND "NARF=zort" "$<TARGET_FILE:generator>" generated5.cpp 5
DEPENDS XY::generator
VERBATIM)
add_custom_target(foo5 DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/generated5.cpp")
We have a code generator and five custom commands that each create a .cpp file by calling that generator. Each custom command's output is depended on by a custom target.
We're building this project with
cmake -G"Ninja Multi-Config" -DCMAKE_CONFIGURATION_TYPES=Release\;Debug -DCMAKE_CROSS_CONFIGS=all -DCMAKE_DEFAULT_CONFIGS=all <source-dir>
All fooX:Release
targets depend on Release/generator
. This is expected.
The dependencies to the generator differ in the fooX:Debug
targets, which is unexpected:
foo1:Debug
is connected to the command that creates generated1.cpp
Command: COMMAND "$<TARGET_FILE:generator>" generated1.cpp 1
Dependency: foo1:Debug -> Release/generator
This dependency is expected.
foo2:Debug
is connected to the command that creates generated2.cpp
Command: COMMAND "NARF=zort" "$<TARGET_FILE:generator>" generated2.cpp 2
Dependency: foo2:Debug -> Debug/generator
Here, the TARGET_FILE
generator expression is not the first argument after COMMAND
.
But that should not make a difference, since the documentation states:
If either OUTPUT or BYPRODUCTS names a path that is common to more than one configuration (e.g. it does not use any generator expressions), all arguments are evaluated in the command config by default.
Wrapping TARGET_FILE
in $<COMMAND_CONFIG>
as done for foo3
fixes the dependency, so we have a work-around.
Another observation:
When adding an explicit DEPENDS
, it makes a difference whether we depend on generator
or an alias target of generator
. This is demonstrated by the targets foo4
and foo5
:
Command: COMMAND "NARF=zort" "$<TARGET_FILE:generator>" generated4.cpp 4
Depends: DEPENDS generator
Dependency: foo4:Debug -> Debug/generator
Command: COMMAND "NARF=zort" "$<TARGET_FILE:generator>" generated5.cpp 5
Depends: DEPENDS XY::generator
Dependency: foo5:Debug -> Release/generator
For reference, this is with CMake 3.21.1.