cmake函數參數解析
阿新 • • 發佈:2017-08-13
遍歷 man 而在 taf get reac ... pre val
非常奇怪的是,這裏的${SRC}在function外是完整的4個元素。而在function卻僅僅剩下了頭一個元素(可能跟list的定長有關)。
當然,你也能夠使用cmake的foreach循環遍歷參數。這招對付僅僅有一個list的參數時十分有效。可是在出現多個參數的情況就非常麻煩。例如以下:
原來,ARG把兩個參數混在了一起,盡管後面我們使用while進行了特殊處理,可是這對於cmake的函數不具備普遍性。移植起來非常麻煩。
近期在遷移公司的make系統到cmake上。發現cmake的function參數非常奇怪。比如,假設我們向一個function傳遞list作為參數,在function中,形參會變成例如以下狀況:
set(SRC) list(APPEND SRC a.cpp b.cpp) list(APPEND SRC c.cpp d.cpp) function(tst_arguments src_list) message("src_list = "${src_list}) endfunction() message("SRC = "${SRC}) tst_arguments(${SRC}) ==== output ==== SRC = a.cppb.cppc.cppd.cpp src_list = a.cpp
假設我們要傳給function以n個源文件組成的list,這樣顯然不行。
一種簡單的解決方法是使用ARGV。ARGC配合,他們的含義如同C/C++中main的argv和argc。分別代表參數和參數個數。使用例如以下方法解析參數:
function(tst_arguments src_list) message("ARGC = "${ARGC}) message("ARGV = "${ARGV}) set(INDEX 0) while(INDEX LESS ${ARGC}) message("ARG = "${ARGV${INDEX}}) math(EXPR INDEX "${INDEX} + 1") endwhile() endfunction() tst_arguments(${SRC}) ==== output ==== ARGC = 4 ARGV = a.cppb.cppc.cppd.cpp ARG = a.cpp ARG = b.cpp ARG = c.cpp ARG = d.cpp
# #如果函數link_lib將src_list中的源文件鏈接成庫,依據type制定是鏈接靜態庫還是動態庫 # function(link_lib src_list type) message("ARGC = "${ARGC}) message("ARGV = "${ARGV}) #下面依據參數的實際情做了操作,手動處理。以保證正確獲取src_list和type set(INDEX 0) math(EXPR MAX "${ARGC} - 1") while(INDEX LESS ${MAX}) #do something to link math(EXPR INDEX "${INDEX} + 1") endwhile() endfunction() link_lib(${SRC} , so) ==== output ==== ARGC = 5 ARGV = a.cppb.cppc.cppd.cppso
決定版的solution是使用cmake的cmake_parse_arguments來解析函數參數,它有點像解析一個map鍵值對。首先看下它的函數原型:
include (CMakeParseArguments) #必須包括這個cmake文件才幹使用<span class="highlighted">cmake_parse_arguments</span> CMAKE_PARSE_ARGUMENTS(<prefix> <options> <one_value_keywords> <multi_value_keywords> args...)首先,prefix是一個前綴。等會兒在引用參數的時候會提到,<option>是一個列表。裏面能夠包括一些你感興趣的KeyWord,隨後能夠通過它來看看你所須要的KeyWord是否被設置。<one_value_keywords>是一個單值參數的KeyWord列表。<multi_value_keywords>是一個多值參數的KeyWord列表(如list),以下舉個樣例,看看怎樣使用它們,首先定義所須要的函數,因為參數是由CMAKE_PARSE_ARGUMENTS來解析的,所以在函數聲明中就不須要定義參數了:
function(tst_arguments) CMAKE_PARSE_ARGUMENTS( TEST "" "NAME;COMMAND;BASELINE" "ARGSLIST" ${ARGN} ) message("TEST_DEFAULT_ARGS is ${TEST_DEFAULT_ARGS} from ${ARGN}") message("TEST_NAME is ${TEST_NAME}") message("TEST_COMMAND is ${TEST_COMMAND}") message("TEST_ARGSLIST is ${TEST_ARGSLIST}") message("TEST_BASELINE is ${TEST_BASELINE}") endfunction(tst_arguments)這裏的前綴是TEST,<one_value_keywords>我們設置單值參數的KeyWord(NAME;COMMAND;BASELINE)。這將在隨後的函數調用中註明KeyWord和Value的關系,<multi_value_keywords>我們設置多值參數的KeyWord("ARGSLIST"),調用函數:
TEST_ARGUMENT( NAME testiso COMMAND "RunMe" ARGSLIST ${SRC} BASELINE "/home/sakaue/iWork" ) ==== output ==== TEST_DEFAULT_ARGS is from NAME;testiso;COMMAND;RunMe;ARGSLIST;a.cpp;b.cpp;c.cpp;d.cpp;BASELINE;/home/sakaue/iWork TEST_NAME is testiso TEST_COMMAND is RunMe TEST_ARGSLIST is a.cpp;b.cpp;c.cpp;d.cpp TEST_BASELINE is /home/sakaue/iWork能夠看見,這裏調用時的參數傳遞如同map一樣<NAME ,testiso_${datafile} >,<COMMAND , "RunMe">,<ARGSLIST , ${SRC}>等等。在函數中。使用 前綴+KeyWord 來調用Value,這樣比自己解析參數方便很多,並且也不會在還有list參數時和其它類型函數混在一起的情況。
很多其它訊息參考:http://www.cmake.org/cmake/help/v3.0/module/CMakeParseArguments.html?highlight=cmake_parse_arguments
cmake函數參數解析