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)
    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 等(请参阅宏文档)。我现在将使用list命令实现一个解决方法,但我的问题是:

如果必须跳过某些元素(例如第一个和最后一个),是否有更简单的方法来循环 ARGV0、ARGV1、ARGV2 元素?

编辑

可悲的是,我发现即使 LIST 命令也不能在 ARGV 上运行!但是如果我首先创建 ARGV 的副本然后在其上执行 LIST 命令,它们就可以工作。

4

2 回答 2

2

${ARGV${DEST_INDEX}})MACROS 不支持(至少从我的经验来看)。您必须使用参数列表执行LIST(...)操作来处理 MACRO参数。${ARGV}

使用任一:

  • LIST(REMOVE_AT, ...)或类似的列表操作来删除参数或
  • 迭代使用FOREACH(loop_var IN ...)
于 2013-07-15T13:36:56.190 回答
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)
于 2013-07-15T14:16:35.167 回答