2013-07-15 25 views
0

this的啓發,我試圖創建一個macro,它會在構建時複製一個文件列表。cmake中的一個宏的參數的部分循環

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

這是我結束了與實施,我願意接受更好的解決方案

  • 迭代!
    注意:第二個函數(也複製目錄的函數)可能更安全,以防某些目標目錄不存在。

    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) 
    
  • +0

    我可以看到的唯一小改進是定義了ARGV副本的e FUNCTION。這隻會讓代碼更清晰一些。 –

    +0

    @GabrielPetrovay你的意思只是'SET(ARGN_COPY $ {ARGN})'這一行嗎?我不會使用該功能... – Antonio

    +0

    我的意思是SET MATH LIST LIST。當然,這取決於你是否在更多的宏中使用它。否則它沒有多大意義。 –

    2

    ${ARGV${DEST_INDEX}})在MACROS中不支持(至少從我的經驗來看)。您必須執行LIST(...)操作,以使用參數列表處理MACRO參數。

    二者必選其一:

    • LIST(REMOVE_AT, ...)或類似的列表操作,以刪除參數或使用FOREACH(loop_var IN ...)
    +0

    +1感謝確認我的恐懼:)請檢查我的編輯。 – Antonio