2015-11-13 3 views
2

Я хотел бы иметь функцию Cmake для копирования некоторых двоичных файлов в определенное место. Fo этого у меня есть следующее определение функции:Cmake: add_custom_command аргумент на основе содержимого переменной

function (collect_binaries TARGET_NAME DEST_DIR) 
    set (targetsToCopy ${ARGN}) 

    set (copy_cmd "COMMAND ${CMAKE_COMMAND} -E make_directory ${DEST_DIR}\n") 

    foreach (target ${targetsToCopy}) 
     LIST(APPEND copy_cmd "COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${target}> ${DEST_DIR}$<TARGET_FILE_NAME:${target}>\n") 
    endforeach(target ${targetsToCopy}) 

    #message(FATAL_ERROR ${copy_cmd}) 
    add_custom_target(${TARGET_NAME}) 
    add_custom_command(TARGET ${TARGET_NAME} PRE_BUILD ${copy_cmd}) 

endfunction(collect_binaries) 

И следующее использование:

collect_binaries(bin_copy ${PROJECT_BINARY_DIR}/out/ target_1 target_2 target3) 

Я Target_1, target_2 и target_3, определенный в моем проекте дерева. Имея это в виду, я получил следующее Cmake настроить выход:

CMake Предупреждение (DEV) в binary_copy.cmake: 15 (add_custom_command):

Политика CMP0040 не установлено: Мишень в TARGET подписи add_custom_command() должен существовать. Запустите «cmake -help-policy CMP0040» для получения информации о политике. Используйте команду cmake_policy, чтобы установить политику и подавить это предупреждение.

Похоже, что цель в неизвестности в этом контексте ... но она существует и нет опечатки. В чем проблема?

+0

Я пробовал делать то же, что и вы, с помощью специальной команды, возможно, но уродливой. То, что вы действительно хотите сделать, это установить двоичные файлы INSTALL в место, меньше кода и лучше – GameDeveloper

ответ

1

Вы настраиваете переменную copy_cmd в функции collect_binaries как строку CMake. add_custom_command однако требует список CMake, чтобы правильно разобрать аргументы, т.е .:

function (collect_binaries TARGET_NAME DEST_DIR) 
    set (targetsToCopy ${ARGN}) 

    set (copy_cmd COMMAND ${CMAKE_COMMAND} -E make_directory ${DEST_DIR}) 

    foreach (target ${targetsToCopy}) 
     LIST(APPEND copy_cmd COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${target}> "${DEST_DIR}$<TARGET_FILE_NAME:${target}>") 
    endforeach(target ${targetsToCopy}) 

    #message(FATAL_ERROR ${copy_cmd}) 
    add_custom_target(${TARGET_NAME}) 
    add_custom_command(TARGET ${TARGET_NAME} PRE_BUILD ${copy_cmd}) 

endfunction(collect_binaries) 
+0

Большое спасибо за ваше решение и объяснения - это работает! – Dmitry

0

Command поток add_custom_command(TARGET ...) является только библиотеки и исполняемые мишеням. Он не предназначен для целей, созданных с помощью add_cusom_target.

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

function (collect_binaries TARGET_NAME DEST_DIR) 
    set (targetsToCopy ${ARGN}) 

    set (create_directory_cmd COMMAND ${CMAKE_COMMAND} -E make_directory ${DEST_DIR}) 

    # Create one custom command per every file to be copied. 
    # Also collect list of output files. 
    set(output_files) 
    foreach (target ${targetsToCopy}) 
     set(output_file "${DEST_DIR}/$<TARGET_FILE_NAME:${target}>") 
     add_custom_command(OUTPUT ${output_file} 
      ${create_directory_cmd} 
      COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${target}> ${output_file}) 
     list(APPEND output_files ${output_file}) 
     # It is sufficient to create directory only once. Just clear corresponded variable. 
     set(create_directory_cmd) 
    endforeach(target ${targetsToCopy}) 

    add_custom_target(${TARGET_NAME} DEPENDS ${output_files}) 
endfunction(collect_binaries) 

Если вы хотите иметь только скопированные двоичные файлы, но оригинальные из них не интересует вас, это проще сказать CMake для создания исполняемых файлов, где они нужны. Либо

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/out/) 

до создания мишени или

set_target_properties(target_1 target_2 target3 
    PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/out/) 

после создания цели достаточно.

Смежные вопросы