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])
不要同時在多個相互獨立的目標中執行上述命令產生相同的檔案,主要是為了防止衝突產生。如果有多條命令,它們將會按順序執行。ARGS是為了向後相容,使用過程中可以忽略。MAIN_DEPENDENCY完全是可選的,它主要是針對Visual Studio給出的一個建議。在Makefile中,它會產生一個這樣的新目標:
OUTPUT: MAIN_DEPENDENCY DEPENDS
COMMAND
add_custom_command(TARGET target
PRE_BUILD | PRE_LINK| POST_BUILD
COMMAND command1[ARGS] [args1...]
[COMMAND command2[ARGS] [args2...] ...]
[WORKING_DIRECTORYdir]
[COMMENT comment][VERBATIM])
命令執行的時機由如下引數決定:
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。
IMPLICIT_DEPENDS選項請求掃描一個輸入檔案的隱含依賴項。特定的語言會指明對應程式語言,它會使用相應的依賴項掃描器。目前僅支援C和CXX語言依賴項掃描器。目前IMPLICIT_DEPENDS 選項僅被Makefile產生器支援,其它構建檔案的產生器將會忽略該選項。
如果COMMAND指定了一個可執行的目標(由ADD_EXECUTABLE建立),那麼它會自動地被在構建時建立的可執行檔案路徑替換。另外,也會新增一個目標級的依賴,使得可執行目標總會在使用了該客制命令的任何目標之前構建。然而,它不會增加一個檔案級的依賴,這種依賴會使得只要該可執行程式被重新編譯,該客制命令也會重新執行。
DEPENDS選項指定了該命令所依賴的檔案。如果任何依賴項是同一目錄中其他另一個客制命令 OUTPUT(CMakeLists.txt)。那麼CMake會自動地將其引入到執行該客制命令的目標中來。如果沒有指定DEPENDS,那麼只要OUTPUT不見了,該命令就會執行。如果該命令並沒有實際去建立OUTPUT,那麼該規則總是執行。如果DEPENDS指定了任何一個目標 (由ADD_* 系列命令建立) ,那麼就會建立一個目標級的依賴以確保該目標比任何使用該客制命令的目標要先構建。另外,如果該目標是一個可執行檔案或是一個庫,那麼就會建立一個檔案級的依賴,這樣會使得只要該目標重新編譯,該客制命令就會重新執行。
- 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