cmake函數參數解析,cmake函數解析

來源:互聯網
上載者:User

cmake函數參數解析,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})<pre name="code" class="plain">tst_arguments(${SRC})==== output ====SRC = a.cppb.cppc.cppd.cppsrc_list = a.cpp

很奇怪的是,這裡的${SRC}在function外是完整的4個元素,而在function卻只剩下了頭一個元素(可能跟list的定長有關)。如果我們要傳給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()<pre name="code" class="plain"><pre name="code" class="plain">tst_arguments(${SRC})


<pre name="code" class="plain">==== output ====ARGC = 4ARGV = a.cppb.cppc.cppd.cpp
ARG = a.cppARG = b.cppARG = c.cppARG = d.cpp
當然,你也可以使用cmake的foreach迴圈遍曆參數。這招對付只有一個list的參數時十分有效,但是在出現多個參數的情況,如下:

##假設函數link_lib將src_list中的源檔案連結成庫,根據type制定是連結靜態庫還是動態庫#function(link_lib src_list type)<pre name="code" class="plain">        message("ARGC = "${ARGC})message("ARGV = "${ARGV})

#以下根據參數的實際情做了操作,以保證正確擷取src_list和typeset(INDEX 0)math(EXPR MAX "${ARGC} - 1") while(INDEX LESS ${MAX})#do something to linkmath(EXPR INDEX "${INDEX} + 1")endwhile()endfunction()

link_lib(${SRC} , so)<pre name="code" class="plain"><pre name="code" class="plain"><pre name="code" class="plain">==== output ====


ARGC = 5

ARGV = a.cppb.cppc.cppd.cppso

原來,ARG把兩個參數混在了一起,雖然後面我們使用while進行了特殊處理,但是這對於cmake的函數不具備普遍性,移植起來很麻煩。

決定版的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/iWorkTEST_NAME is testisoTEST_COMMAND is RunMeTEST_ARGSLIST is a.cpp;b.cpp;c.cpp;d.cppTEST_BASELINE is /home/sakaue/iWork





可以看見,這裡調用時的參數傳遞如同map一樣<NAME ,testiso_${datafile} >,<COMMAND , "RunMe">,<ARGSLIST , ${SRC}>等等,在函數中,使用 首碼+KeyWord 來調用Value,這樣比自己解析參數方便許多,而且也不會在還有list參數時和其他類型函數混在一起的情況。





函數的每一個形式參數就是一個 A 運算式 B 常量 C 變數 D 函數調用

c
 
對於主函數main()的參數問題

主函數的參數就是輸入命令列的參數,主函數不能被其他函數調用

int main(int argc, char *argv[]);
int main(int argc, char **argv);
int main(void);

void main(int argc, char *argv[]);
void main(int argc, char **argv);
void main(void);

補充回答:
------------------------------------
WinMain()的第三個參數是LPSTR lpCmdLine,命令列參數
這個就相當於argv,需要自己解析出每個參數
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.