cmake整理:在編譯時拷貝文件之add_custom_comand 和 add_custom_target

第一種通用形式:
add_custom_command: 增長客製化的構建規則到生成的構建系統中。對於add_custom_command,有兩種使用形式。第一種形式是增長一個客制命令用來產生一個輸出。編程

 add_custom_command(OUTPUT output1 [output2 ...]
                     COMMAND command1[ARGS] [args1...]
                     [COMMAND command2 [ARGS] [args2...] ...]
                     [MAIN_DEPENDENCYdepend]
                     [DEPENDS[depends...]]
                     [IMPLICIT_DEPENDS<lang1> depend1 ...]
                     [WORKING_DIRECTORYdir]
                     [COMMENT comment] [VERBATIM] [APPEND])app

不要同時在多個相互獨立的目標中執行上述命令產生相同的文件,主要是爲了防止衝突產生。若是有多條命令,它們將會按順序執行。ARGS是爲了向後兼容,使用過程當中能夠忽略。MAIN_DEPENDENCY徹底是可選的,它主要是針對Visual Studio給出的一個建議。在Makefile中,它會產生一個這樣的新目標:編程語言

 OUTPUT: MAIN_DEPENDENCY DEPENDS
          COMMANDui

 

第二種形式是爲某個目標如庫或可執行程序添加一個客制命令。這對於要在構建一個目標以前或以後執行一些操做很是有用。該命令自己會成爲目標的一部分,僅在目標自己被構建時纔會執行。若是該目標已經構建,命令將不會執行。.net

第二種:標記爲在何時執行命令:編譯前,編譯後,連接前 
 add_custom_command(TARGET target
                     PRE_BUILD | PRE_LINK| POST_BUILD
                     COMMAND command1[ARGS] [args1...]
                     [COMMAND command2[ARGS] [args2...] ...]
                     [WORKING_DIRECTORYdir]
                     [COMMENT comment][VERBATIM])blog

命令執行的時機由以下參數決定: get

PRE_BUILD - 命令將會在其餘依賴項執行前執行
  PRE_LINK - 命令將會在其餘依賴項執行完後執行
  POST_BUILD - 命令將會在目標構建完後執行。源碼

其中,PRE_BUILD只被Visual Studio 7及以後的版本支持,其餘全部的構建文件產生器將視PRE_BUILD爲PRE_LINK。若是指定了WORKING_DIRECTORY,那麼命令將會在指定的目錄下執行。若是是相對路徑,那麼該路徑將被解釋爲與當前源碼目錄對應的構建目錄相對的路徑。 若是設置了COMMENT,那麼在編譯時,命令執行前會將COMMENT的內容當作信息輸出。若是指定了APPEND ,那麼COMMAND 和 DEPENDS 選項的值將會被追加到第一個指定的輸出對應的客制命令中。目前,若是指定了APPEND選項,那麼COMMENT, WORKING_DIRECTORY, 和 MAIN_DEPENDENCY選項將會忽略。可是未來可能會使用。若是指定了VERBATIM選項,那麼,全部傳遞到命令的參數將會被適當地轉義,這樣命令接受到的參數將不會改變。建議使用VERBATIM選項,若是客制命令的輸出不是建立一個存儲在磁盤上的文件,須要使用命令SET_SOURCE_FILES_PROPERTIES把它標記爲SYMBOLIC。qt

    IMPLICIT_DEPENDS選項請求掃描一個輸入文件的隱含依賴項。特定的語言會指明對應編程語言,它會使用相應的依賴項掃描器。目前僅支持C和CXX語言依賴項掃描器。目前IMPLICIT_DEPENDS 選項僅被Makefile產生器支持,其它構建文件的產生器將會忽略該選項。io

若是COMMAND指定了一個可執行的目標(由ADD_EXECUTABLE建立),那麼它會自動地被在構建時建立的可執行文件路徑替換。另外,也會添加一個目標級的依賴,使得可執行目標總會在使用了該客制命令的任何目標以前構建。然而,它不會增長一個文件級的依賴,這種依賴會使得只要該可執行程序被從新編譯,該客制命令也會從新運行。

DEPENDS選項指定了該命令所依賴的文件。若是任何依賴項是同一目錄中其餘另外一個客制命令 OUTPUT(CMakeLists.txt)。那麼CMake會自動地將其引入到執行該客制命令的目標中來。若是沒有指定DEPENDS,那麼只要OUTPUT不見了,該命令就會運行。若是該命令並無實際去建立OUTPUT,那麼該規則老是執行。若是DEPENDS指定了任何一個目標 (由ADD_* 系列命令建立) ,那麼就會建立一個目標級的依賴以確保該目標比任何使用該客制命令的目標要先構建。另外,若是該目標是一個可執行文件或是一個庫,那麼就會建立一個文件級的依賴,這樣會使得只要該目標從新編譯,該客制命令就會從新運行。

 

重要:使用target標記爲老是過時,這樣每次編譯時都會執行上面規定的command
add_custom_target: 增長一個沒有輸出的目標,使得它老是被構建。  add_custom_target(Name [ALL] [command1 [args1...]]
                    [COMMAND command2 [args2...] ...]
                    [DEPENDS depend depend depend ... ]
                    [WORKING_DIRECTORY dir]
                    [COMMENT comment] [VERBATIM]
                    [SOURCES src1 [src2...]])
增長一個指定名字的目標,並執行指定的命令。該目標沒有輸出文件,老是被認爲是過時的,即便是在試圖用目標的名字建立一個文件。使用ADD_CUSTOM_COMMAND命令來建立一個具備依賴項的文件。默認狀況下,沒有任何目標會依賴該客制目標。使用ADD_DEPENDENCIES 來添加依賴項或成爲別的目標的依賴項。若是指定了ALL選項,那就代表該目標會被添加到默認的構建目標,使得它每次都被運行。(該命令的名稱不能命名爲 ALL). 命令和參數都是可選的,若是沒有指定,將會建立一個空目標。若是設置了WORKING_DIRECTORY ,那麼該命令將會在指定的目錄中運行。若是它是個相對路徑,那它會被解析爲相對於當前源碼目錄對應的構建目錄。若是設置了 COMMENT,在構建的時候,該值會被當成信息在執行該命令以前顯示。DEPENDS參數能夠是文件和同一目錄中的其餘客制命令的輸出。

若是指定了VERBATIM, 全部傳遞給命令的參數將會被適當地轉義。建議使用該選項。

SOURCES選項指定了包含進該客制目標的額外的源文件。即便這些源文件沒有構建規則,可是它們會被增長到IDE的工程文件中以方便編輯。


例子:

set(TEST_FILE "log.txt")
add_custom_command(OUTPUT  ${TEST_FILE}
  COMMAND echo "Generating log.txt file..."
  COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_LIST_FILE} ${TEST_FILE}
  COMMENT  "This is a test"
 )
add_custom_target(Test1 ALL DEPENDS ${TEST_FILE})


add_custom_command(TARGET Test1
  PRE_BUILD 
  COMMAND echo "executing a fake command"
  COMMENT "This command will be executed before building target Test1"
 )

結果:

[100%] This is a test
Generating log.txt file...
This command will be executed before building target Test1
executing a fake command
[100%] Built target Test1


(這是 make 時候進行執行)

set(COPYITEM test_res)

add_custom_command(OUTPUT  COPY_RES
  COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/${COPYITEM} ${EXECUTABLE_OUTPUT_PATH}/${COPYITEM}
 )
 
add_custom_target(CopyTask ALL DEPENDS COPY_RES)


另一種用法:直接執行命令:

execute_process(COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_CURRENT_SOURCE_DIR} $ENV{PROTOC} --cpp_out=. proto/Echo.proto conti/beagent/msg_catalog.proto
        COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_CURRENT_SOURCE_DIR} $ENV{PROTOC} --cpp_out=. proto/Echo.proto conti/beagent/connmgr/topic_parameterize.proto 
        COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_CURRENT_SOURCE_DIR} $ENV{PROTOC} --cpp_out=. proto/Echo.proto conti/beagent/connmgr/subscribe.proto 
        COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_CURRENT_SOURCE_DIR} $ENV{PROTOC} --cpp_out=. proto/Echo.proto conti/beagent/connmgr/service_connection_manager.proto 
        COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_CURRENT_SOURCE_DIR} $ENV{PROTOC} --cpp_out=. proto/Echo.proto conti/beagent/connmgr/out_data.proto 
        COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_CURRENT_SOURCE_DIR} $ENV{PROTOC} --cpp_out=. proto/Echo.proto conti/beagent/connmgr/in_data.proto 
        COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_CURRENT_SOURCE_DIR} $ENV{PROTOC} --cpp_out=. proto/Echo.proto conti/beagent/connmgr/app_status.proto 
        COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_CURRENT_SOURCE_DIR} $ENV{PROTOC} --cpp_out=. proto/Echo.proto conti/beagent/connmgr/advertise.proto 
        COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_CURRENT_SOURCE_DIR} $ENV{PROTOC} --cpp_out=. proto/mqtt_diag_message.proto 
        COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_CURRENT_SOURCE_DIR} $ENV{PROTOC} --cpp_out=. proto/carriers.proto
        )

(這是 cmake 時候進行執行)

相關文章
相關標籤/搜索