<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                #八、cmake 常用指令 [TOC] 前面我們講到了cmake 常用的變量,相信“cmake 即編程的感覺會越來越明顯,無論如何,我們仍然可以看到cmake 比autotools要簡單很多。接下來我們就要集中的看一看cmake 所提供的常用指令。在前面的章節我們已經討論了很多指令的用法,如PROJECT,ADD_EXECUTABLE,INSTALL,ADD_SUBDIRECTORY,SUBDIRS,INCLUDE_DIRECTORIES,LINK_DIRECTORIES,TARGET_LINK_LIBRARIES,SET等。 本節會引入更多的cmake指令,為了編寫的方便,我們將按照cmake man page的順序來介紹各種指令,不再推薦使用的指令將不再介紹,INSTALL系列指令在安裝部分已經做了非常詳細的說明,本節也不在提及。(你可以將本章理解成選擇性翻譯,但是會加入更多的個人理解) ##一,基本指令 1,ADD_DEFINITIONS 向C/C++ 編譯器添加-D定義,比如: ADD_DEFINITIONS(-DENABLE_DEBUG -DABC),參數之間用空格分割。 如果你的代碼中定義了:`#ifdef ENABLE_DEBUG #endif `這個代碼塊就會生效。如果要添加其他的編譯器開關,可以通過CMAKE_C_FLAGS 變量和CMAKE_CXX_FLAGS 變量設置。 2,ADD_DEPENDENCIES 定義target 依賴的其他target ,確保在編譯本target 之前,其他的target 已經被構建。 `ADD_DEPENDENCIES(target-name depend-target1depend-target2 ...)` 3,ADD_EXECUTABLE 、ADD_LIBRARY 、ADD_SUBDIRECTORY 前面已經介紹過了,這里不再羅唆。 4,ADD_TEST 與ENABLE_TESTING 指令。 ENABLE_TESTING 指令用來控制Makefile 是否構建test目標,涉及工程所有目錄。語法很簡單,沒有任何參數,ENABLE_TESTING() ,一般情況這個指令放在工程的主CMakeLists.txt 中. ADD_TEST 指令的語法是: ADD_TEST(testname Exename arg1 arg2 ...) testname 是自定義的test 名稱,Exename 可以是構建的目標文件也可以是外部腳本等等。后面連接傳遞給可執行文件的參數。如果沒有在同一個CMakeLists.txt 中打開ENABLE_TESTING() 指令,任何ADD_TEST 都是無效的。 比如我們前面的Helloworld 例子,可以在工程主CMakeLists.txt 中添加ADD_TEST(mytest ${PROJECT_BINARY_DIR}/bin/main) ENABLE_TESTING() 生成Makefile 后,就可以運行make test 來執行測試了。 5,AUX_SOURCE_DIRECTORY 基本語法是: AUX_SOURCE_DIRECTORY(dir VARIABLE) 作用是發現一個目錄下所有的源代碼文件并將列表存儲在一個變量中,這個指令臨時被用來自動構建源文件列表。因為目前cmake 還不能自動發現新添加的源文件。 比如 AUX_SOURCE_DIRECTORY(. SRC_LIST)ADD_EXECUTABLE(main ${SRC_LIST}) 你也可以通過后面提到的FOREACH 指令來處理這個LIST 6,CMAKE_MINIMUM_REQUIRED其語法為CMAKE_MINIMUM_REQUIRED(VERSION versionNumber [FATAL_ERROR])比如CMAKE_MINIMUM_REQUIRED(VERSION 2.5 FATAL_ERROR)如果cmake 版本小與2.5,則出現嚴重錯誤,整個過程中止。 7,EXEC_PROGRAM 在CMakeLists.txt 處理過程中執行命令,并不會在生成的Makefile 中執行。具體語法為: EXEC_PROGRAM(Executable [directory in which to run][ARGS <arguments to executable>][OUTPUT_VARIABLE <var>][RETURN_VALUE <var>]) 用于在指定的目錄運行某個程序,通過ARGS 添加參數,如果要獲取輸出和返回值,可通過 OUTPUT_VARIABLE 和RETURN_VALUE 分別定義兩個變量. 這個指令可以幫助你在CMakeLists.txt 處理過程中支持任何命令,比如根據系統情況去修改代碼文件等等。 舉個簡單的例子,我們要在src目錄執行ls命令,并把結果和返回值存下來。 可以直接在src/CMakeLists.txt 中添加: EXEC_PROGRAM(ls ARGS "*.c" OUTPUT_VARIABLE LS_OUTPUT RETURN_VALUELS_RVALUE)IF(not LS_RVALUE)MESSAGE(STATUS "ls result: " ${LS_OUTPUT})ENDIF(not LS_RVALUE) 在cmake 生成Makefile的過程中,就會執行ls命令,如果返回0,則說明成功執行,那么就輸出ls *.c 的結果。關于IF語句,后面的控制指令會提到。 8,FILE指令 文件操作指令,基本語法為: FILE(WRITE filename "message to write"... ) FILE(APPEND filename "message to write"... ) FILE(READ filename variable) FILE(GLOB variable [RELATIVE path] [globbing expressions]...)FILE(GLOB_RECURSE variable [RELATIVE path] [globbing expressions]...)FILE(REMOVE [directory]...)FILE(REMOVE_RECURSE [directory]...)FILE(MAKE_DIRECTORY [directory]...)FILE(RELATIVE_PATH variable directory file)FILE(TO_CMAKE_PATH path result)FILE(TO_NATIVE_PATH path result) 這里的語法都比較簡單,不在展開介紹了。 9,INCLUDE 指令,用來載入CMakeLists.txt 文件,也用于載入預定義的cmake 模塊. INCLUDE(file1 [OPTIONAL]) INCLUDE(module [OPTIONAL]) OPTIONAL 參數的作用是文件不存在也不會產生錯誤。你可以指定載入一個文件,如果定義的是一個模塊,那么將在CMAKE_MODULE_PATH 中搜索這個模塊并載入。 載入的內容將在處理到INCLUDE 語句是直接執行。 ##二,INSTALL 指令 INSTALL 系列指令已經在前面的章節有非常詳細的說明,這里不在贅述,可參考前面的安裝部分。 ##三,FIND_ 指令 FIND_ 系列指令主要包含一下指令: FIND_FILE(<VAR> name1 path1 path2 ...) VAR 變量代表找到的文件全路徑,包含文件名 FIND_LIBRARY(<VAR> name1 path1 path2 ...) VAR 變量表示找到的庫全路徑,包含庫文件名 FIND_PATH(<VAR> name1 path1 path2 ...) VAR 變量代表包含這個文件的路徑。 FIND_PROGRAM(<VAR> name1 path1 path2 ...) VAR 變量代表包含這個程序的全路徑。 `FIND_PACKAGE(<name> [major.minor] [QUIET] [NO_MODULE][[REQUIRED|COMPONENTS] [componets...]])` 用來調用預定義在CMAKE_MODULE_PATH 下的Find<name>.cmake 模塊,你也可以自己定義Find<name> 模塊,通過SET(CMAKE_MODULE_PATH dir) 將其放入工程的某個目錄中供工程使用,我們在后面的章節會詳細介紹FIND_PACKAGE 的使用方法和Find 模塊的編寫。 FIND_LIBRARY 示例: ``` FIND_LIBRARY(libX X11 /usr/lib) IF(NOT libX) MESSAGE(FATAL_ERROR “libX not found”) ENDIF(NOT libX) ``` ##四,控制指令 1,IF 指令,基本語法為: ``` IF(expression)# THEN section.COMMAND1(ARGS ...) COMMAND2(ARGS ...) ... ELSE(expression)# ELSE section.COMMAND1(ARGS ...)COMMAND2(ARGS ...)... ENDIF(expression) ``` 另外一個指令是ELSEIF,總體把握一個原則,凡是出現IF的地方一定要有對應的ENDIF. 出現ELSEIF 的地方,ENDIF 是可選的。 表達式的使用方法如下: IF(var) ,如果變量不是:空,0,N, NO, OFF, FALSE, NOTFOUND 或<var>_NOTFOUND 時,表達式為真。 IF(NOT var ),與上述條件相反。 IF(var1 AND var2) ,當兩個變量都為真是為真。 IF(var1 OR var2) ,當兩個變量其中一個為真時為真。 IF(COMMAND cmd) ,當給定的cmd 確實是命令并可以調用是為真。 IF(EXISTS dir) 或者IF(EXISTS file) ,當目錄名或者文件名存在時為真。 IF(file1 IS_NEWER_THAN file2) ,當file1 比file2 新,或者file1/file2 其中有一個不存在時為真,文件名請使用完整路徑。 IF(IS_DIRECTORY dirname) ,當dirname 是目錄時,為真。 IF(variable MATCHES regex)IF(string MATCHES regex)當給定的變量或者字符串能夠匹配正則表達式regex 時為真。比如:IF("hello" MATCHES "ell")MESSAGE("true")ENDIF("hello" MATCHES "ell") IF(variable LESS number)IF(string LESS number)IF(variable GREATER number)IF(string GREATER number)IF(variable EQUAL number)IF(string EQUAL number) 數字比較表達式 IF(variable STRLESS string)IF(string STRLESS string)IF(variable STRGREATER string)IF(string STRGREATER string)IF(variable STREQUAL string)IF(string STREQUAL string) 按照字母序的排列進行比較.IF(DEFINED variable) ,如果變量被定義,為真。 一個小例子,用來判斷平臺差異: IF(WIN32) MESSAGE(STATUS “This is windows.”) #作一些Windows 相關的操作 ELSE(WIN32) MESSAGE(STATUS “This is not windows”) #作一些非Windows 相關的操作 ENDIF(WIN32) 上述代碼用來控制在不同的平臺進行不同的控制,但是,閱讀起來卻并不是那么舒服,ELSE(WIN32) 之類的語句很容易引起歧義。 這就用到了我們在常用變量一節提到的CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS開關。可以SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)這時候就可以寫成:IF(WIN32)ELSE()ENDIF() 如果配合ELSEIF 使用,可能的寫法是這樣:IF(WIN32)#do something related to WIN32ELSEIF(UNIX)#do something related to UNIXELSEIF(APPLE)#do something related to APPLEENDIF(WIN32) 2,WHILEWHILE 指令的語法是: WHILE(condition)COMMAND1(ARGS ...)COMMAND2(ARGS ...)... ENDWHILE(condition) 其真假判斷條件可以參考IF指令。3,FOREACH FOREACH 指令的使用方法有三種形式:1,列表 FOREACH(loop_var arg1 arg2 ...)COMMAND1(ARGS ...)COMMAND2(ARGS ...)... ENDFOREACH(loop_var) 像我們前面使用的AUX_SOURCE_DIRECTORY 的例子AUX_SOURCE_DIRECTORY(. SRC_LIST) FOREACH(F ${SRC_LIST}) MESSAGE(${F})ENDFOREACH(F) 2,范圍FOREACH(loop_var RANGE total)ENDFOREACH(loop_var)從0到total 以1為步進 舉例如下: FOREACH(VAR RANGE 10)MESSAGE(${VAR})ENDFOREACH(VAR) 最終得到的輸出是: >0 1 2 3 4 5 6 7 8 9 10 3,范圍和步進 FOREACH(loop_var RANGE start stop [step])ENDFOREACH(loop_var) 從start 開始到stop結束,以step為步進,舉例如下 FOREACH(A RANGE 5 15 3)MESSAGE(${A})ENDFOREACH(A) 最終得到的結果是: >5 8 11 14 這個指令需要注意的是,知道遇到ENDFOREACH 指令,整個語句塊才會得到真正的執行。 ##五、小結 本小節基本涵蓋了常用的cmake 指令,包括基本指令、查找指令、安裝指令以及控制語句等,特別需要注意的是,在控制語句條件中使用變量,不能用${} 引用,而是直接應用變量名。掌握了以上的各種控制指令,你應該完全可以通過cmake 管理復雜的程序了,下一節,我們將介紹一個比較復雜的例子,通過他來演示本章的一些指令,并介紹模塊的概念。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看