In order to run the unit tests in one of my projects, I have a custom command which copies the executable, libraries, and other related files to somewhere else so that they can be run with a specific setup rather than running them where they're built. On Linux, this is quite straightforward. But on Windows, I've hit a bit of a snag due to the fact that cmake appends the configuration name to the ouput directories (which I like in general, but it screws up what I'm doing in this case). It makes it hard to determine the paths to the generated libraries or executables. For instance, if I had a custom command which just copied the executable to another directory
set(EXE_PATH "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/exeName${CMAKE_EXECUTABLE_SUFFIX}")
set(NEW_EXE_PATH "${RUN_UNITTESTS_DIR}/exeName${CMAKE_EXECUTABLE_SUFFIX}")
add_custom_command(TARGET unitTests POST_BUILD
COMMAND ${CMAKE_COMMAND} ARGS -E copy "${EXE_PATH}" "${NEW_EXE_PATH}")
it's going to choke on Windows, because the executable isn't really in CMAKE_RUNTIME_OUTPUT_DIRECTORY
. Depending on the configuration type, it's in either ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Release
or ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Debug
. On Linux, that could be trivially fixed by using CMAKE_BUILD_TYPE
and adding it to the path, but that doesn't work with Windows, because on Windows, cmake generates multiple configurations rather than just one. So, what I'd like to be able to do is something like
add_custom_command(TARGET unitTests POST_BUILD
debug
COMMAND ${CMAKE_COMMAND} ARGS -E copy "${DEBUG_EXE_PATH}" "${DEBUG_NEW_EXE}")
add_custom_command(TARGET unitTests POST_BUILD
release
COMMAND ${CMAKE_COMMAND} ARGS -E copy "${RELEASE_EXE_PATH}" "${RELEASE_NEW_EXE}")
and some cmake commands see to be able to do that (e.g. target_link_libraries
), but as far as I can tell, add_custom_target
doesn't provide that capability. So, the question is how I would do that? How can I make a custom command be configuration-specific on Windows?
It could be solved with the help of the next "generator expressions" (CMake 2.8.10):
$<0:...>
= empty string (ignores "...")$<1:...>
= content of "..."$<CONFIG:cfg>
= '1' if config is "cfg", else '0'You can combine them to reach behaviour that you need (pseudocode):
if debug then ${DEBUG_EXE_PATH} elseif release then ${RELEASE_EXE_PATH}
which translates to:
$<$<CONFIG:debug>:${DEBUG_EXE_PATH}>$<$<CONFIG:release>:${RELEASE_EXE_PATH}>
So your string will look like:
add_custom_command(TARGET unitTests POST_BUILD
COMMAND ${CMAKE_COMMAND} ARGS -E copy "$<$<CONFIG:debug>:${DEBUG_EXE_PATH}>$<$<CONFIG:release>:${RELEASE_EXE_PATH}>" "$<$<CONFIG:debug>:${DEBUG_NEW_EXE}>$<$<CONFIG:release>:${RELEASE_NEW_EXE}>")
Details: CMake:add_custom_command
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With