Cmake:基于变量内容

时间:2015-11-13 15:40:09

标签: cmake

我希望有一个Cmake函数将一些二进制文件复制到特定位置。我有以下功能定义:

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配置输出:

  

在binary_copy.cmake上的CMake警告(dev):15(add_custom_command):

     

未设置策略CMP0040:add_custom_command()的TARGET签名中的目标必须存在。运行&#34; cmake --help-policy CMP0040&#34;   政策细节。使用cmake_policy命令设置策略并禁止显示此警告。

在这种背景下似乎未知的目标......但它确实存在并且没有拼写错误。这是什么问题?

2 个答案:

答案 0 :(得分: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 )

答案 1 :(得分:0)

命令流add_custom_command(TARGET ...)仅适用于库和可执行目标。它不适用于使用add_cusom_target创建的目标。

您需要将自定义目标设置为复制二进制文件,并创建用于复制二进制文件的命令。 (注意,任何cmake命令的参数的 list 都不应该用引号括起来。)

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/)
创建目标后

就足够了。