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 など (マクロのドキュメントを参照) にアクセスすることはできないようです。リストコマンドを使用して回避策を実装しますが、私の質問は次のとおりです。

一部の要素 (最初と最後の要素など) をスキップする必要がある場合、ARGV0、ARGV1、ARGV2 要素を循環させる簡単な方法はありますか?

編集

悲しいことに、ARGV では LIST コマンドでさえ機能しないことがわかりました。しかし、最初に ARGV のコピーを作成してから、そのコピーに対して LIST コマンドを実行すると機能します。

4

2 に答える 2

2

${ARGV${DEST_INDEX}}) is not supported in MACROS (at least form my experience). You must perform LIST(...) operations to handle the MACRO arguments using the ${ARGV} list of arguments.

Use either:

  • LIST(REMOVE_AT, ...) or similar list operations to remove arguments or
  • iterate using FOREACH(loop_var IN ...)
于 2013-07-15T13:36:56.190 に答える
0

これは私が最終的に実装したものです。私はより良い解決策を受け入れています!
注: 2 番目の関数 (ディレクトリもコピーする関数) は、宛先ディレクトリの一部が存在しない場合に備えて、おそらくより安全です。

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 に答える