How do you create add_custom_command configuration for Windows?

To run unit tests in one of my projects, I have a custom command that copies the executable, libraries, and other related files to another location so that they can be run with a specific setting, and not run where they are built. On Linux, this is pretty simple. But on Windows, I got a little hit because cmake adds the configuration name to the drop-down directories (which I like in general, but in this case, I hammer in what I'm doing). This makes it difficult to determine the paths to the generated libraries or executable files. For example, if I had a user command that 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 will suffocate on Windows because the executable is really not in CMAKE_RUNTIME_OUTPUT_DIRECTORY . Depending on the type of configuration, it is located in ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Release or ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Debug . On Linux, this can be trivially fixed with CMAKE_BUILD_TYPE and adding it to the path, but this does not work with Windows, because on Windows cmake generates several configurations, not just one. So, what I would like 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 that they can do this (for example, target_link_libraries ), but as far as I can tell, add_custom_target does not provide this feature. So the question is, how do I do this? How to configure a custom command for configuration on Windows?

+8
cmake
source share
2 answers

This is an example of generator expressions provided for use with add_custom_command .

In your case, you need the full path to your compiled exe, as well as its name to add to your target directory. These are $<TARGET_FILE:unitTests> and $<TARGET_FILE_NAME:unitTests> respectively.

Your complete team:

 add_custom_command(TARGET unitTests POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:unitTests> ${RUN_UNITTESTS_DIR}/$<TARGET_FILE_NAME:unitTests>) 
+7
source share

This can be solved using the following "generator expressions" (CMake 2.8.10):

  • $<0:...> = empty string (ignores "...")
  • $<1:...> = content "..."
  • $<CONFIG:cfg> = '1' if the config is "cfg", otherwise "0"

You can combine them to achieve the desired behavior (pseudo-code):

if debug then ${DEBUG_EXE_PATH} elseif release then ${RELEASE_EXE_PATH}

which translates as:

$<$<CONFIG:debug>:${DEBUG_EXE_PATH}>$<$<CONFIG:release>:${RELEASE_EXE_PATH}>

So your line will look like this:

 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

+11
source share

All Articles