Как сделать add custom command configuration-specific в Windows?

для запуска модульных тестов в одном из моих проектов у меня есть пользовательская команда, которая копирует исполняемый файл, библиотеки и другие связанные файлы в другое место, чтобы их можно было запускать с определенной настройкой, а не запускать их там, где они построены. В Linux это довольно просто. Но в Windows я попал в небольшую загвоздку из-за того, что cmake добавляет имя конфигурации в каталоги ouput (что мне нравится в целом, но это портит то, что я делаю в этом случай.) Это затрудняет определение путей к сгенерированным библиотекам или исполняемым файлам. Например, если бы у меня была пользовательская команда, которая просто скопировала исполняемый файл в другой каталог

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}")

он задохнется в Windows, потому что исполняемый файл на самом деле не в CMAKE_RUNTIME_OUTPUT_DIRECTORY. В зависимости от типа конфигурации он находится в любом ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Release или ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Debug. В Linux это может быть тривиально исправлено с помощью CMAKE_BUILD_TYPE и добавить его в путь, но это не работает с Windows, потому что на Windows, cmake генерирует несколько конфигураций, а не только одну. Итак, то, что я хотел бы сделать, это что-то вроде

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}")

и некоторые команды cmake видят, что могут это сделать (например,target_link_libraries), но насколько я могу судить, add_custom_target не обеспечивает эту возможность. Вопрос в том, как я это сделаю? Как сделать пользовательскую команду специфичной для конфигурации в Windows?

2 ответов


это случай для выражений генератора, предоставляемых для использования с add_custom_command.

в вашем случае вы хотите полный путь к вашему скомпилированному exe, а также его имя файла для добавления в целевой каталог. Это $<TARGET_FILE:unitTests> и $<TARGET_FILE_NAME:unitTests> соответственно.

ваша полная команда будет иметь вид:

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

это можно было бы решить с помощью следующих "выражений генератора" (CMake 2.8.10):

  • $<0:...> = пустые строки (игнорирует "...")
  • $<1:...> = содержание "..."
  • $<CONFIG:cfg> = ' 1 'Если config является "cfg", иначе '0'

вы можете объединить их, чтобы достичь поведения, которое вам нужно (псевдокод):

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

что переводится как:

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

Итак, ваша строка будет выглядеть так:

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}>")

детали: CMake: add_custom_command