`$<TARGET_RUNTIME_DLLS:...>` is inconvenient to use with cmake -E copy
The example usage of $<TARGET_RUNTIME_DLLS:...>
in the documentation is bugged:
find_package(foo CONFIG REQUIRED) # package generated by install(EXPORT)
add_executable(exe main.c)
target_link_libraries(exe PRIVATE foo::foo foo::bar)
add_custom_command(TARGET exe POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_RUNTIME_DLLS:exe> $<TARGET_FILE_DIR:exe>
COMMAND_EXPAND_LISTS
)
When in a cross-platform setting, the COMMAND
here will expand to the following on non-DLL systems:
/path/to/cmake -E copy /path/to/exe-dir
which then prints a nondescript error and usage information. The problem here is that there is a destination directory, but no source files, or perhaps the opposite.
Thus, one resolution would be to wrap the add_custom_command
in an if (WIN32)
conditional. But is WIN32
set for all DLL systems? I think so, but such configure-time platform logic has a tendency to be unexpectedly brittle. More robust would be to extend cmake -E copy
with POSIX cp
's -t
flag. It specifies the destination directory first and then lets any number (including zero) of additional arguments be source files. Here's the small excerpt from the man
page:
-t, --target-directory=DIRECTORY copy all SOURCE arguments into DIRECTORY
If cmake -E copy
had this flag, one could instead write the above custom command as:
add_custom_command(
TARGET exe POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy -t $<TARGET_FILE_DIR:exe> $<TARGET_RUNTIME_DLLS:exe>
COMMAND_EXPAND_LISTS
)
This approach is then correct on all systems since it decays to a NO-OP on non-DLL systems (rather than an error)
CC @ben.boeckel