CMake 語法及總結

##cmake中一些預約義變量##react

  • PROJECT_SOURCE_DIR 工程的根目錄
  • CMAKE_INCLUDE_PATH 環境變量,非cmake變量
  • CMAKE_LIBRARY_PATH 環境變量
  • CMAKE_CURRENT_SOURCE_DIR 當前處理的CMakeLists.txt所在的路徑
  • CMAKE_CURRENT_BINARY_DIR target編譯目錄 使用ADD_SURDIRECTORY(src bin)能夠更改此變量的值 SET(EXECUTABLE_OUTPUT_PATH <新路徑>)並不會對此變量有影響,只是改變了最終目標文件的存儲路徑
  • CMAKE_CURRENT_LIST_FILE 輸出調用這個變量的CMakeLists.txt的完整路徑
  • CMAKE_CURRENT_LIST_LINE 輸出這個變量所在的行
  • CMAKE_MODULE_PATH 定義本身的cmake模塊所在的路徑 SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake),而後能夠用INCLUDE命令來調用本身的模塊
  • EXECUTABLE_OUTPUT_PATH 從新定義目標二進制可執行文件的存放位置
  • LIBRARY_OUTPUT_PATH 從新定義目標連接庫文件的存放位置
  • PROJECT_NAME 返回經過PROJECT指令定義的項目名稱
  • CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS 用來控制IF ELSE語句的書寫方式

系統信息正則表達式

  • CMAKE_MAJOR_VERSION cmake主版本號,如2.8.6中的2
  • CMAKE_MINOR_VERSION cmake次版本號,如2.8.6中的8
  • CMAKE_PATCH_VERSION cmake補丁等級,如2.8.6中的6
  • CMAKE_SYSTEM 系統名稱,例如Linux-2.6.22
  • CAMKE_SYSTEM_NAME 不包含版本的系統名,如Linux
  • CMAKE_SYSTEM_VERSION 系統版本,如2.6.22
  • CMAKE_SYSTEM_PROCESSOR 處理器名稱,如i686
  • UNIX 在全部的類UNIX平臺爲TRUE,包括OS X和cygwin
  • WIN32 在全部的win32平臺爲TRUE,包括cygwin

開關選項express

  • BUILD_SHARED_LIBS 控制默認的庫編譯方式。若是未進行設置,使用ADD_LIBRARY時又沒有指定庫類型,默認編譯生成的庫都是靜態庫 (可在t3中稍加修改進行驗證)
  • CMAKE_C_FLAGS 設置C編譯選項
  • CMAKE_CXX_FLAGS 設置C++編譯選項

##基本語法規則##windows

  • cmake變量使用${}方式取值,可是在IF控制語句中是直接使用變量名oop

  • 環境變量使用$ENV{}方式取值,使用SET(ENV{VAR} VALUE)賦值ui

  • 指令(參數1 參數2…).net

    參數使用括弧括起,參數之間使用空格或分號分開。code

    #以ADD_EXECUTABLE指令爲例:
    
    ADD_EXECUTABLE(hello main.c func.c)
    #或者
    ADD_EXECUTABLE(hello main.c;func.c)
  • 指令是大小寫無關的,參數和變量是大小寫相關的。推薦你所有使用大寫指令。blog

##部分經常使用命令列表##字符串

  • PROJECT PROJECT(projectname [CXX] [C] [Java]) 指定工程名稱,並可指定工程支持的語言。支持語言列表可忽略,默認支持全部語言\

  • SET SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]]) 定義變量(能夠定義多個VALUE,如SET(SRC_LIST main.c util.c reactor.c))

  • MESSAGE MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] 「message to display」 …) 向終端輸出用戶定義的信息或變量的值 SEND_ERROR, 產生錯誤,生成過程被跳過 STATUS, 輸出前綴爲—的信息 FATAL_ERROR, 當即終止全部cmake過程

  • ADD_EXECUTABLE ADD_EXECUTABLE(bin_file_name ${SRC_LIST}) 生成可執行文件

  • ADD_LIBRARY ADD_LIBRARY(libname [SHARED | STATIC | MODULE] [EXCLUDE_FROM_ALL] SRC_LIST) 生成動態庫或靜態庫 SHARED 動態庫 STATIC 靜態庫 MODULE 在使用dyld的系統有效,若不支持dyld,等同於SHARED EXCLUDE_FROM_ALL 表示該庫不會被默認構建

  • SET_TARGET_PROPERTIES 設置輸出的名稱,設置動態庫的版本和API版本

  • CMAKE_MINIMUM_REQUIRED CMAKE_MINIMUM_REQUIRED(VERSION version_number [FATAL_ERROR]) 聲明CMake的版本要求

  • ADD_SUBDIRECTORY ADD_SUBDIRECTORY(src_dir [binary_dir] [EXCLUDE_FROM_ALL]) 向當前工程添加存放源文件的子目錄,並能夠指定中間二進制和目標二進制的存放位置 EXCLUDE_FROM_ALL含義:將這個目錄從編譯過程當中排除

  • SUBDIRS deprecated,再也不推薦使用 (hello sample)至關於分別寫ADD_SUBDIRECTORY(hello),ADD_SUBDIRECTORY(sample)

  • INCLUDE_DIRECTORIES INCLUDE_DIRECTORIES([AFTER | BEFORE] [SYSTEM] dir1 dir2 … ) 向工程添加多個特定的頭文件搜索路徑,路徑之間用空格分隔,若是路徑包含空格,可使用雙引號將它括起來,默認的行爲爲追加到當前頭文件搜索路徑的後面。 有以下兩種方式能夠控制搜索路徑添加的位置:

  • CMAKE_INCLUDE_DIRECTORIES_BEFORE,經過SET這個cmake變量爲on,能夠將添加的頭文件搜索路徑放在已有路徑的前面

  • 經過AFTER或BEFORE參數,也能夠控制是追加仍是置前

  • LINK_DIRECTORIES LINK_DIRECTORIES(dir1 dir2 …) 添加非標準的共享庫搜索路徑

  • TARGET_LINK_LIBRARIES TARGET_LINK_LIBRARIES(target lib1 lib2 …) 爲target添加須要連接的共享庫

  • ADD_DEFINITIONS 向C/C++編譯器添加-D定義 ADD_DEFINITIONS(-DENABLE_DEBUG -DABC),參數之間用空格分隔

  • ADD_DEPENDENCIES ADD_DEPENDENCIES(target-name depend-target1 depend-target2 …) 定義target依賴的其餘target,確保target在構建以前,其依賴的target已經構建完畢

  • AUX_SOURCE_DIRECTORY AUX_SOURCE_DIRECTORY(dir VAR) 發現一個目錄下全部的源代碼文件並將列表存儲在一個變量中 把當前目錄下的全部源碼文件名賦給變量DIR_HELLO_SRCS

  • EXEC_PROGRAM EXEC_PROGRAM(Executable [dir where to run] [ARGS <args>][OUTPUT_VARIABLE <var>] [RETURN_VALUE <value>]) 用於在指定目錄運行某個程序(默認爲當前CMakeLists.txt所在目錄),經過ARGS添加參數,經過OUTPUT_VARIABLE和RETURN_VALUE獲取輸出和返回值,以下示例

    #在src中運行ls命令,在src/CMakeLists.txt添加
    
    	EXEC_PROGRAM(ls ARGS "*.c" OUTPUT_VARIABLE LS_OUTPUT RETURN_VALUE LS_RVALUE)
    	IF (not LS_RVALUE)
    		MESSAGE(STATUS "ls result: " ${LS_OUTPUT}) # 縮進僅爲美觀,語法無要求
    	ENDIF(not LS_RVALUE)
  • INCLUDE

    INCLUDE(file [OPTIONAL]) 用來載入CMakeLists.txt文件

    INCLUDE(module [OPTIONAL])用來載入預約義的cmake模塊

    OPTIONAL參數的左右是文件不存在也不會產生錯誤 能夠載入一個文件,也能夠載入預約義模塊(模塊會在CMAKE_MODULE_PATH指定的路徑進行搜索) 載入的內容將在處理到INCLUDE語句時直接執行

  • FIND_

  • FIND_FILE(<VAR> name path1 path2 …) VAR變量表明找到的文件全路徑,包含文件名

  • FIND_LIBRARY(<VAR> name path1 path2 …) VAR變量表明找到的庫全路徑,包含庫文件名

    FIND_LIBRARY(libX X11 /usr/lib)
    	IF (NOT libx)
    		MESSAGE(FATAL_ERROR "libX not found")
    	ENDIF(NOT libX)
  • FIND_PATH(<VAR> name path1 path2 …) VAR變量表明包含這個文件的路徑

  • FIND_PROGRAM(<VAR> name 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)將其放入工程的某個目錄供工程使用

  • IF 語法:

    IF (expression)
    		COMMAND1(ARGS ...)
    		COMMAND2(ARGS ...)
    		...
    	ELSE (expression)
    		COMMAND1(ARGS ...)
    		COMMAND2(ARGS ...)
    		...
    	ENDIF (expression) # 必定要有ENDIF與IF對應
  • IF (expression), expression不爲:空,0,N,NO,OFF,FALSE,NOTFOUND或<var>_NOTFOUND,爲真

  • IF (not exp), 與上面相反

  • 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 dir) 當dir是目錄時,爲真

  • IF (DEFINED var) 若是變量被定義,爲真

  • IF (var MATCHES regex) 此處var能夠用var名,也能夠用${var}

  • 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 (WIN32)
    		MESSAGE(STATUS 「This is windows.」)
    	ELSE (WIN32)
    		MESSAGE(STATUS 「This is not windows」)
    	ENDIF (WIN32)
    
    	#上述代碼用來控制在不一樣的平臺進行不一樣的控制,可是,閱讀起來卻並非那麼舒服,ELSE(WIN32)之類的語句很容易引發歧義。
    	能夠SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)
    	這時候就能夠寫成:
    
    	IF (WIN32)
    	ELSE ()
    	ENDIF ()
    
    	配合ELSEIF使用,可能的寫法是這樣:
    
    	IF (WIN32)
    		#do something related to WIN32
    	ELSEIF (UNIX)
    		#do something related to UNIX
    	ELSEIF(APPLE)
    		#do something related to APPLE
    	ENDIF (WIN32)
  • WHILE 語法:

    WHILE(condition)
    		COMMAND1(ARGS ...)
    		COMMAND2(ARGS ...)
    		...
    	ENDWHILE(condition)

    其真假判斷條件能夠參考IF指令

  • FOREACH

    FOREACH指令的使用方法有三種形式:

  1. 列表

語法:

```
FOREACH(loop_var arg1 arg2 ...)
	 COMMAND1(ARGS ...)
	 COMMAND2(ARGS ...)
	 ...
ENDFOREACH(loop_var)

```

示例:

```
AUX_SOURCE_DIRECTORY(. SRC_LIST)
FOREACH(F ${SRC_LIST})
	 MESSAGE(${F})
ENDFOREACH(F)

```
  1. 範圍

語法:

```
FOREACH(loop_var RANGE total)
	COMMAND1(ARGS ...)
	COMMAND2(ARGS ...)
	...
ENDFOREACH(loop_var)

```

示例:

```
#從0到total以1爲步進
FOREACH(VAR RANGE 10)
   MESSAGE(${VAR})
ENDFOREACH(VAR)
#輸出:
#012345678910
```
  1. 範圍和步進

語法:

```
FOREACH(loop_var RANGE start stop [step])
	COMMAND1(ARGS ...)
	COMMAND2(ARGS ...)
	...
ENDFOREACH(loop_var)
```

從start開始到stop結束,以step爲步進,

注意:直到遇到ENDFOREACH指令,整個語句塊纔會獲得真正的執行。

```
FOREACH(A RANGE 5 15 3)
	MESSAGE(${A})
ENDFOREACH(A)
\#輸出:
\#581114

```

###cmake中如何生成動態庫和靜態庫###

參考ADD_LIBRARY和SET_TARGET_PROPERTIES用法

###cmake中如何使用動態庫和靜態庫(查找庫的路徑)###

參考INCLUDE_DIRECTORIES, LINK_DIRECTORIES, TARGET_LINK_LIBRARIES用法

###cmake中如何指定生成文件的輸出路徑###

  • 如上ADD_SUBDIRECTORY的時候指定目標二進制文件輸出路徑(推薦使用下面這種)

  • 使用SET命令從新定義EXECUTABLE_OUTPUT_PATH和LIBRARY_OUTPUT_PATH變量來指定最終的二進制文件的位置

    SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

    SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)

上面的兩條命令一般緊跟ADD_EXECUTABLE和ADD_LIBRARY,與其寫在同一個CMakeLists.txt便可

###cmake中如何增長編譯選項###

使用變量CMAKE_C_FLAGS添加C編譯選項

使用變量CMAKE_CXX_FLAGS添加C++編譯選項

使用ADD_DEFINITION添加

###cmake中如何增長頭文件路徑###

參考INCLUDE_DIRECTORIES命令用法

###cmake中如何在屏幕上打印信息###

參考MESSAGE用法

###cmake中如何給變量賦值###

參考SET和AUX_SOURCE_DIRECTORY用法

建議: 在Project根目錄先創建build,而後在build文件夾內運行cmake ..,這樣就不會污染源代碼, 若是不想要這些自動生成的文件了,只要簡單的刪除build文件夾就能夠

參考

http://blog.csdn.net/wzzfeitian/article/details/40963457/
相關文章
相關標籤/搜索