CMake入門以及學習筆記

使用cef3替代chromium內核開發產品過程當中,第一次接觸到系統構建,使用了最多見的CMake。CMake雖然在構建系統中用的比較多,可是使用到的程序員仍是不多的。如今在國內能找到的相關資料和博客比較多,本人在學習中也看了不少人的博客,好比 CMake學習(一)  , CMake語法之流程控制 等。再次感謝這些做者的分享。下邊提供一些系統學習的資料。html

CMake的官網地址:http://www.cmake.org/java

CMake主要的文檔《learning_cmake》 《CMake Practice》,這個百度上搜索一下,很容易下載到。python

學習CMake以前,借用下 《CMake Practice》中的一段話,若是你的狀況符合如下幾條就不要浪費時間在CMake上。程序員

1,若是你沒有實際的項目需求,那麼看到這裏就能夠停下來了,由於cmake的學習過程就是實踐過程,沒有實踐,讀的再多幾天後也會忘記。
2,若是你的工程只有幾個文件,直接編寫Makefile是最好的選擇。
3,若是使用的是C/C++/Java以外的語言,請不要使用cmake(至少目前是這樣)。
4,若是你使用的語言有很是完備的構建體系,好比java的ant,也不須要學習cmake,雖然有成功的例子,好比QT4.3的csharp綁定qyoto。
5,若是項目已經採用了很是完備的工程管理工具,而且不存在維護問題,沒有必要遷移到cmake。
6,若是僅僅使用qt編程,沒有必要使用cmake,由於qmake管理Qt工程的專業性和自動化程度比cmake要高不少。編程

 

學習CMake以前,最好能找到一個比較簡單地例子對照教程看,而且一開始編寫一些簡單地例子。這樣不只能學得快,也容易創建學習的自信。編程語言

下邊主要講三點,也是最經常使用到的三點。函數

1、CMake經常使用命令:工具

CMakelist中,命令名字是不區分大小寫的,而參數和變量是大小寫相關的。學習

CMake中使用"#"表示註釋該行代碼。ui

命令:

與其餘語言編程語言不一樣的是,CMake腳本的語法中沒有賦值操做,不管是賦值,仍是比較、判斷操做,都是經過內置命令來完成的,例如"set(),math()等"。全部的內置命令調用形式爲:

command(arg1 arg2 arg3 ... argn)

每一個參數均以空格,或者分號分割。注:不建議使用分號分割參數.

message():顯示一個消息。如message("Hello world");

cmake_minimum_required():須要的最低版本; cmake_minimum_required(version 2.6)  

project():項目的名稱 如project(hello)

set():Cmake中的賦值操做都是經過這個來作的。如 SET(HELLO_SRCS  Hello.c Hello.cpp  world.c   world.cpp)

add_definitions():設置編譯選項;

subdirs:CMake 是以遞歸的方式工做;處理完當前目錄,再去 SUBDIRS 中的目錄

add_library :生成一個連接庫;

add_executable:添加生成文件;如:ADD_EXECUTABLE (Hello ${HELLO_SRCS})

add_dependencies:包含一個依賴庫文件夾;

add_subdirectory:向當前工程添加存放源文件的子目錄;

aux_source_directory :不在當前目錄下的其餘地方的源文件;

include_directories:  指明文件所在路徑;

set_target_properties:設置文件爲另一個名字。set_target_properties(libhello PROPERTIES OUTPUT_NAME "hello")

source_group:當文件都在同一個路徑下面使用

 

2、CMake變量以及變量的引用

    CMake中的變量無需聲明,而且沒有類型概念,這一點相似於python;變量能夠認爲都是全局的,哪怕在一個宏中定義的變量,也能夠在宏的外面被訪問到;全部的變量都是一個列表變量,下文在舉例時會詳細說明這一點;CMake對於變量是大小寫敏感的。

    在CMake中,有兩種引用方式:對於變量值的引用,和直接引用這個變量自己,使用方式分別是:${varName} 和 varName。

 

3、CMake的宏與函數

    同大多數腳本語言同樣,CMake中也有宏和函數的概念,關鍵字分別爲"macro"和"function",具體用法以下:

# 宏

macro( [arg1 [arg2 [arg3 ...]]])

     COMMAND1(ARGS ...)

     COMMAND2(ARGS ...)

     ...

endmacro()
 

# 函數

function( [arg1 [arg2 [arg3 ...]]])

     COMMAND1(ARGS ...)

     COMMAND2(ARGS ...)

     ...

endfunction()

以簡單的求和函數爲例,咱們來看宏的一個示例:

macro(sum outvar)

     set(_args ${ARGN})

     set(result 0)

     foreach(_var ${_args})

         math(EXPR result "${result}+${_var}")

     endforeach()

     set(${outvar} ${result})

endmacro()

sum(addResult 1 2 3 4 5)

message("Result is :${addResult}")

    上面是一段求和宏定義,咱們來解讀一下代碼:"${ARGN}"是CMake中的一個變量,指代宏中傳入的多餘參數。由於咱們這個宏sum中只定義了一個 參數"outvar",其他須要求和的數字都是不定形式傳入的,因此須要先將多餘的參數傳入一個單獨的變量中。固然,在這個示例中,第一行代碼顯得多餘, 由於彷佛不必將額外參數單獨放在一個變量中,可是建議這麼作。對上面這個宏再進一步增強:若是咱們想限制這個宏中傳入的參數數目(儘管在這個宏中實際上 是沒必要要的),那麼能夠將宏改寫一下:

macro(sum outvar)

     set(_args ${ARGN})

     list(LENGTH _args argLength)

     if(NOT argLength LESS 4) # 限制不能超過4個數字

         message(FATAL_ERROR "to much args!")

     endif()

     set(result 0)

     foreach(_var ${ARGN})

         math(EXPR result "${result}+${_var}")

     endforeach()

     set(${outvar} ${result})

endmacro()

sum(addResult 1 2 3 4 5)

message("Result is :${addResult}")

    而CMake中的函數("function")與宏惟一的區別就在於,函數不能像宏那樣將計算結果傳出來(也不是徹底不能,只是複雜一些),而且函數中的變量是局部的,而宏中的變量在外面也能夠被訪問到,請看下例:

macro(macroTest)

     set(test1 "aaa")

endmacro()

function(funTest)

     set(test2 "bbb")

endfunction()

macroTest()

message("${test1}")

funTest()

message("${test2}")

運行這段代碼後,只會打印出一條信息"aaa",由此能夠看到宏與函數的區別

相關文章
相關標籤/搜索