CMake語法學習筆記
最近一直在忙新需求,本來想記錄一下自己學CMake的一些筆記,拖到了現在……
一、CMakeLists.txt檔案
- 如果工程存在多個目錄,需要確保每個要管理的目錄都存在一個CMakeLists.txt檔案,這是CMake的構建定義檔案。
二、CMake的基本語法規則
- CMake的基本語法規則:指令(引數1 引數2 …),其中引數使用括號括起,引數之間使用空格或分號隔開。
- 指令與大小寫無關的,引數和變數是大小寫相關的。
三、CMake常用指令
project(projectname [CXX][C][Java])
用來定義工程名稱,並指定工程支援的語言,支援的語言列表可忽略不寫,預設支援所有語言。
例如://定義bzip2工程目錄 project(bzip2)
set(var [value])
用來顯示地定義變數,有多個變數用空格或分號隔開。
例如://定義變數FILE_PATH,用來儲存兩個檔案路徑 set(FILE_PATH C:\\cpp\\\main.c C:\\cpp\\bspatch.c)
注:
1.當我們需要用到這個變數FILE_PATH時,可以採用var來引用變量,例如: {FILE_PATH}
2.在IF控制語句中是直接使用變數名的,無需${}cmake_minimun_required(VERSION 3.4.1)
用來指定CMake的最低版本為3.4.1aux_source_directory(dir variable)
將dir目錄下的所有原始碼檔案的名字儲存在變數variable中。
例如://將當前目錄下的原始碼名字儲存在DIR_SRCS變數中 aux_source_directory(. DIR_SRCS)
target_link_libraries(target library1 library2 …)
指定target需要連結的library,這裡的target必須已經被建立。
例如://指定main工程需要連結hello共享庫或so檔案 target_link_libraries(main hello) //或者: target_link_libraries(main libhello.so)
add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
用於向當前工程新增一個需要進行構建的子目錄,並且可以指定中間二進位制檔案和目標二進位制檔案存放的位置。
例如://當執行到該指令時,會進入到bzip2目錄執行此目錄的CMakeLists.txt檔案 add_subdirectory(bzip2)
add_library(name [SHARED | STATIC | MODULE] [EXCLUDE_FROM_ALL] source1 source2 … sourceN)
將一組原始檔source1 source2 … sourceN編譯出一個庫檔案,並且儲存為libname.so檔案(在此不需寫全libname,只需填寫name即可,CMake會自動為你生成libname.so)。
其中SHARED表示動態庫,在程式碼中使用loadLibrary動態呼叫;STATIC表示靜態庫,整合到程式碼中會在編譯時呼叫;MODULE只有在使用dyld的系統有效,如果不支援dyld,則被當作SHARED對待。
EXCLUDE_FROM_ALL表示這個庫不被預設構建,除非有其他元件依賴或手工構建。
例如://將bspatch.c編譯為一個名為libbspatch.so的共享庫 add_library(bspatch SHARED bspatch.c)
add_library命令也可以用來建立匯入的庫目標。
add_library(<name> <SHARED|STATIC|MODULE|UNKNOWN> IMPORTED)
匯入的庫目標是引用了在工程外的一個庫檔案的目標。沒有生成構建這個庫的規則。這個目標名字的作用域在它被建立的路徑及以下有效。它可以向任何在該工程內構建的目標一樣被引用。匯入庫為類似於target_link_libraries命令中引用它提供了便利。關於匯入庫細節可以通過指定那些以IMPORTED_的屬性設定來指定。其中最重要的屬性是IMPORTED_LOCATION(以及它的具體配置版本,**IMPORTED_LOCATION**_),它指定了主庫檔案在磁碟上的位置。
find_library(variable name1 path1 path2 …)
查詢庫檔案name1的全路徑(包含庫檔名),如果找到將路徑儲存在變數variable中,如果沒有找到則結果為variable_NOT_FOUND。
例如://將log庫檔案路徑儲存在變數log_lib中,並將bspatch工程連結引入log庫 find_library(log_lib log) target_link_libraries(bspatch ${log_lib})
set_target_properties(target1 target2 … PRORERTIES prop1 value1 prop2 value2 …)
用來設定輸出的名稱。
例如://匯入libavutil-55.so庫檔案 add_library(avutil-55 SHARED IMPORTED) //設定需要引用的libavutil-55.so庫檔案路徑,其中IMPORTED_LOCATION庫檔案在磁碟上的位置 set_target_properties(avutil-55 PROPERTIES IMPORTED_LOCATION ../libs/armeabi-v7a/libavutil-55.so)
四、CMake常用變數
一般來說,我們可以用set指令顯示定義一個變數,但CMake系統已經幫我們隱式預定義了一些變數,可以採用${VAR}方式來呼叫這些變數,以下記錄一些Android CMakeLists.txt檔案中常用的變數。
PROJECT_SOURCE_DIR
當前工程的原始碼路徑。PROJECT_BINARY_DIR
指向工程構建目錄的全路徑。CMAKE_VERSION
CMake的完整版本號;格式為major.minor.patch[.tweak[-id]]CMAKE_CURRENT_SOURCE_DIR
呼叫這個變數的CMakeLists.txt所在路徑CMAKE_CURRENT_LIST_FILE
呼叫這個變數的CMakeLists.txt的完整路徑CMAKE_CURRENT_LIST_LINE
這個變數所在的行數PROJECT_NAME
返回通過project指令定義的專案名稱
- 以上只是最近學NDK總結出的小部分CMake知識點,對於真正使用CMake的人來說,猶如大海里的一根針般渺小,勿噴