一:
#是行注釋 ,[[ 塊注釋 ]]
0.cmake_minimum_required:? 指定使用的cmake的最低版本
1.project()? 定義工程名稱
并可以指定工程的版本,工程描述,web主頁地址,支持的語言(默認情況支持所有語言)
2.add_executable(可執行程序名 源文件)? 源文件可以為多個,可以使用空格或分號間隔
例子 add_executable(app add.c div.c main.c)? ??add_executable(app add.c;div.c;main.c)??
CMakeLists.txt例子
#cmake本地最小版本要求3.0.9
cmake_minimum_required(VERSION 3.0.9)
#工程名稱為test
project(test)
#根據源文件生成可執行文件
add_executable(app add.cpp div.cpp mult.cpp main.cpp sub.cpp)
執行命令
#cmake 后面跟上CMakeLists.txt的路徑
#CMakeLists.txt在當前路徑
cmake ./
cmake執行后,會多出來一些文件,生成的文件在主目錄中會讓文件結構較為混亂
CMakeCache.txt #生成的
CMakeFile #生成的文件
app #生成的可執行文件
cmake_install.cmake #
Makefile #生成的
在linux系統下,在CMakeLists.txt所在目錄touch/mkdir創建一個build文件,進入其中,執行
cmake ../
#就會生成上面哪些文件在build中,在此目錄生成了makefile,執行make
make #就會執行可執行文件
通過這種方式可以生成一個簡單項目的構建,如果這個項目里面文件特別多的情況下,是沒有辦法通過這種方式構建的,cmake提供了文件搜索命令解決這種問題
在CMakeLists.txt所在目錄要刪除執行cmake命令生成的文件,重新執行cmake才會讓哪些文件生成在build文件中,然后在build文件目錄下執行make命令才會生成可執行文件
二:add_executable(可執行文件 源文件),SET用法
可以在cmake中定義變量
set(string字符串)? cmake里面set命令里面一切皆為字符串
#VAR是變量名 VALUE是變量值
set(VAR VALUE)
例子:
#相當于變量值所有會存儲在變量名里面,相當于對這個變量做了初始化
set(exe add.c;div.c;main.c;sub.c)
#根據初始化的變量,也就是定義的源文件生成可執行文件
#${變量名} 通過這種方式才能取變量的值
add_excutable(app ${exe})
C++標準,在編寫C++程序時候,可能會用到C++11,C++14,C++17,C++20等新特性,那么就需要在編譯的時候指定出要使用那個標準
1.在CMakeLists.txt通過set命令指定一個固定的宏的值
#添加-std=c++11
set(CMAKE_CXX_STANDARD 11) #使用C++11的標準
#添加-std=C++14 CMAKE_CXX_STANDARD是一個標準宏,用于指定標準
set(CMAKE_CXX_STANDARD 14)
2.在執行cmake命令的時候指定出這個宏的值
#增加-std=c++11,運行這個命令會生成一個makefile,指定的標準就會生成在這個makefile文件里面去了
# -D的作用是指定宏的值
cmake CMakeLists.txt文件路徑 -DCMAKE_CXX_STANDARD=11
#同樣
3.在CMake中指定可執行程序指定輸出的路徑,也對應一個宏,叫做EXCUTABLE_OUTPUT_PATH,它的值也是通過set()命令進行設置
set(HOME /home/robin/Linux/Sort)
#指定生成可執行文件的路徑,最好為絕對路徑,這樣項目地址更改后生成的可執行文件絕對地址不變
set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin)
三.搜索文件 、
set(變量名 變量值)
?add_executable(可執行文件 源文件)
生成可執行文件時候,當源文件較多的時候,就要用到cmake提供的aux_source_dirctory命令查找某個路徑下的所有源文件,命令格式為
方式1.aux_source_dirctory(<div> <variable>)? <div>要搜索的目錄? <variable>:將從dir目錄下搜索到的源文件列表存儲到該變量中
#將
aux_source_directory(<目錄> <variable>)
#上條命令將目錄下的源文件搜索到變量中
#使用以下命令生成可執行文件通過源文件搜索到變量
add_executable(app ${variable})#宏PROJECT_SOURCE_DIR是CMakeLists.txt所在目錄
aux_source_directory(${PROJECT_SOURCE_DIR} SRC)
#將SRC變量搜索到的文件作為源文件生成app
add_executable(app ${SRC})
方式2.?如果一個項目中源文件過多,在編寫CMakeLists.txt文件的時候不可能將項目中目錄的各個文件一一羅列出來,所以在cmake中我們提供了搜索文件的命令,就是file,當然除了搜索外。file也可以做其他事情
file(GLOB/GLOB_RECURSE 變量名 要搜索的文件路徑和文件類型)
GLOB:將指定目錄下搜索到的滿足條件的所有文件名生成一個列表,并將其存儲到變量中
GLOB_RECURSE:遞歸搜索指定目錄,將搜索到的滿足條件的文件名生成一個列表,并將其存儲到變量中。
#將目錄下的.c或.h文件搜集到變量中
#file(GLOB/GLOB_RECURSE 變量名 要搜索的文件路徑和文件類型)
file(GLOB MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
file(GLOB MAIN_HEAD ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h)
在完整CMakeLists.txt中file用法
cmake_mimimum_required(VERSION x.x.x)
project(test)
#使用以下命令通過源文件搜索到變量
#aux_source_directory(${PROJECT_SOURCE_DIR} SRC)
file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
set(EXECUTABLE_OUTPUT_PATH /home/xx/xx/xx)
#通過file文件搜索到的CMakeLists.txt所在目錄下所有文件作為源文件
add_executable(app ${SRC})
指定頭文件路徑命令
#PROJECT_SOURCE_DIR這個宏是CMakeLists.txt所在目錄下的,它下面的include文件就是頭文件路徑,按實際情況而定
#指定存儲頭文件所在的目錄
include_directories(${PROJECT_SOURCE_DIR}/include)
四.通過cmake制定庫文件
1.靜態庫和動態庫
add_library(庫名稱 STATIC 源文件1 【源文件2】 ...)
add_library(庫名稱 SHARED 源文件1 【源文件2】 ...)? ?生成動態庫 ,庫名稱
在linux中,靜態庫名字分為三部分:lib+庫名字+.a,此處只需要指定出庫的名字就可以了,另外兩部分在生成該文件的時候會自動填充
.名字組成為: lib+xxx+.a? xxx是名字, 如果是動態庫,.a后綴在linux中是so,在windows里面是dll
.如果是靜態庫 :lib+xxx+ .lib(windows系統中)? 如果是linux系統后綴是.a
動態庫和靜態庫都由三部分組成
#動態庫的制作,將SRC對應文件制作為動態庫calc.so 或者calc.dll(windows下)
add_library(calc SHARED ${SRC})
#cmake會生成calc.so,動態庫是具有可執行權限的
#靜態庫則為
add_library(calc STATIC ${SRC})
#靜態庫命令執行后會生成calc.a 但是不具有可執行權限
庫文件的制作本質是將源代碼的文本形式轉換為二進制形式
2.指定庫生成路徑
使用宏LIBRARY_OUTPUT_PATH?
#指定庫文件生成路徑,如果沒有這個路徑,生成庫文件之前會生成這個路徑
set(LIBRARY_OUTPUT_PATH /home/xx/xx/xx)
add_library(calc STATIC ${SRC})
#執行cmake命令則會生成calc.a靜態庫文件在/home/xx/xx/xx路徑下
add_library(calc SHARED ${SRC})
#執行cmake命令會將SRC源文件生成calc.so動態庫文件在同樣目錄下
五.在程序中鏈接靜態庫文件
測試生成的動態庫或靜態庫能不能用
首先,我們要把制作出的庫文件發布出去,然后就是打包頭文件,因為頭文件里面有庫文件里面一系列函數的聲明。
#將靜態庫和動態庫放置在不同庫目錄下