Cmake:add_custom_command 参数基于变量内容
Cmake: add_custom_command argument based on variable content
我想要一个 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 配置输出:
CMake Warning (dev) at binary_copy.cmake:15 (add_custom_command):
Policy CMP0040 is not set: The target in the TARGET signature of add_custom_command() must exist. Run "cmake --help-policy CMP0040"
for policy details. Use the cmake_policy command to set the policy and suppress this warning.
在这种情况下目标似乎是未知的...但它确实存在并且没有拼写错误。这里有什么问题?
您正在 collect_binaries
函数中将 copy_cmd
变量设置为 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 )
命令流 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/)
在创建目标后就足够了。
我想要一个 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 配置输出:
CMake Warning (dev) at binary_copy.cmake:15 (add_custom_command):
Policy CMP0040 is not set: The target in the TARGET signature of add_custom_command() must exist. Run "cmake --help-policy CMP0040" for policy details. Use the cmake_policy command to set the policy and suppress this warning.
在这种情况下目标似乎是未知的...但它确实存在并且没有拼写错误。这里有什么问题?
您正在 collect_binaries
函数中将 copy_cmd
变量设置为 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 )
命令流 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/)
在创建目标后就足够了。