受到this的启发,我试图创建一个macro,它会在构建时复制文件列表。
macro (copy_files_at_build_time targetname) #usage: copy_files_at_build_time(<targetname> <file> [<files>] <destination>)
if(ARGC LESS 3)
message(ERROR "copy_files_at_build_time called with less than 3 arguments")
endif(ARGC LESS 3)
MATH(EXPR LAST_INDEX "${ARGC}-2")
MATH(EXPR DEST_INDEX "${ARGC}-1")
set(MY_DESTINATION ${ARGV${DEST_INDEX}})
foreach(I RANGE 1 ${LAST_INDEX})
message (STATUS "${CMAKE_COMMAND} -E copy ${ARGV${I}} ${MY_DESTINATION}")
add_custom_command(TARGET ${targetname} PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ARGV${I}} ${MY_DESTINATION})
endforeach(I)
endmacro(copy_files_at_build_time)
正如您所看到的那样,有一条调试消息,不幸的是,当我打印它们时,${ARGV${I}}
和${MY_DESTINATION}
(${ARGV${DEST_INDEX}}
)都是空的。因此,似乎无法通过使用变量作为变量名的最后一部分来访问ARGV1,ARGV2等(请参阅macro documentation)。我现在将使用list命令实现一种解决方法,但我的问题是:
如果必须跳过某些元素(例如第一个和最后一个元素),是否有更简单的方法在ARGV0,ARGV1,ARGV2元素上循环?
修改
可悲的是,我发现即使是LIST命令也无法在ARGV上运行!但是如果我首先创建一个ARGV副本然后在其上执行LIST命令,它们就可以工作。
答案 0 :(得分:2)
${ARGV${DEST_INDEX}})
(至少根据我的经验)。您必须使用LIST(...)
参数列表执行${ARGV}
操作来处理MACRO参数。
使用:
LIST(REMOVE_AT, ...)
或类似的列表操作,用于删除参数或FOREACH(loop_var IN ...)
答案 1 :(得分:0)
这是我最终的实施,我愿意接受更好的解决方案! 注意:如果某些目标目录不存在,第二个函数(也复制目录的那个)可能更安全。
macro (copy_files_at_build_time targetname) #usage: copy_files_at_build_time(<targetname> <file> [<files>] <destination>)
if(ARGC LESS 3)
message(ERROR "copy_files_at_build_time called with less than 3 arguments")
endif(ARGC LESS 3)
SET(ARGN_COPY ${ARGN})
MATH(EXPR DEST_INDEX "${ARGC}-2") #It should be "${ARGC}-1", but we are using ARGN that doesn't contain the first element of the list
list(GET ARGN_COPY ${DEST_INDEX} MY_DESTINATION)
list(REMOVE_AT ARGN_COPY ${DEST_INDEX})
foreach(MY_FILE ${ARGN_COPY})
# message (STATUS "${CMAKE_COMMAND} -E copy_if_different ${MY_FILE} ${MY_DESTINATION}")
add_custom_command(TARGET ${targetname} PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${MY_FILE} ${MY_DESTINATION})
endforeach(MY_FILE)
endmacro(copy_files_at_build_time)
如果我们想复制目录(注意:如果递归工作则不测试!)
macro (copy_at_build_time targetname) #usage: copy_at_build_time(<targetname> <file|directory> [<files|directories>] <destination>)
if(ARGC LESS 3)
message(ERROR "copy_files_at_build_time called with less than 3 arguments")
endif(ARGC LESS 3)
SET(ARGN_COPY ${ARGN})
MATH(EXPR DEST_INDEX "${ARGC}-2") #It should be "${ARGC}-1", but we are using ARGN that doesn't contain the first element of the list
list(GET ARGN_COPY ${DEST_INDEX} MY_DESTINATION)
list(REMOVE_AT ARGN_COPY ${DEST_INDEX})
foreach(MY_FILE ${ARGN_COPY})
get_filename_component(LEAF_NAME "${MY_FILE}" NAME)
if (IS_DIRECTORY ${MY_FILE})
add_custom_command(TARGET ${targetname} PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${MY_FILE} ${MY_DESTINATION}/${LEAF_NAME})
else(IS_DIRECTORY ${MY_FILE})
add_custom_command(TARGET ${targetname} PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${MY_FILE} ${MY_DESTINATION}/${LEAF_NAME})
endif(IS_DIRECTORY ${MY_FILE})
endforeach(MY_FILE)
endmacro(copy_at_build_time)