1.Cmake介绍
- cmake是一个跨平台的,用于构建项目的工具。
- 关于项目的构建,我们并不陌生,广为人知的,诸如:makefile(使用make命令),与IDE集成的vs的nmake,linux下的GNU make,Qt的qmake等。
- 如果自己动手写makefile,就会发现,makefile通常依赖于当前的编译平台,并且编译makefile的工作量比较大,解决依赖关系时通常会出错。cmake恰好可以解决上述问题,其允许开发者指定整个工程的编译流程,再根据编译平台,自动化生成本地的makefile和工程文件,最后用户只需要make编译即可,所以,可以把cmake看成一款自动生成makefile的编译工具,其编译流程如下:
2.Cmake的简单使用
2.1 注释
注释分为单行注释和多行注释
- 单行注释:#注释内容
- 多行注释: #[[注释内容]]
2.2基本命令
1.cmake_minimum_required(VERSION ..*)最小版本号
2.project(项目名)
3.add_executable(app a.cpp b.cpp)生成.exe可执行文件
2.3 生成项目构建文件
一般而言,在build文件夹下执行cmake+CMakeLists.txt相对于本目录的路径;然后在执行
make命令编译生成可执行文件,就可以运行了。
3.set的使用
3.1使用set定义变量
例子如下
set(rsc_list a.cpp b.cpp c.cpp d.cpp)//.cpp之间用空格隔开
set(rsc_list a.cpp;b.cpp;c.cpp;d.cpp)//.cpp之间用;隔开add_executable(app ${rsc_list})//使用$对大括号{}中的变量做提取
注意:cmake中变量都是字符串,就算set(r 123),r也是以字符串形式存储
3.2指定使用C++的标准
例子如下
set(CMAKE_XXX_STANDARD 11)//设置C++的标准为11
set(CMAKE_XXX_STANDARD 17)//设置C++的标准为17
3.3指定输出的标准
在cmake中指定可执行程序的输出路径,也对应一个宏,叫做EXECUTABLE_OUTPUT_PATH, 它的值还是通过set来设置
例子如下
set(HOME /home/robin/linux/Sort) //定义一个变量用于存储一个绝对值
set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin)//将拼接好的路径值设置给EXECUTABLE_OUTPUT_PATH宏
4.搜索文件
方式1
在cmake中可以使用aux_source_directory命令来查找某个路径下的所有源文件
例子如下
在介绍例子前,先来介绍两个宏
1.PROJECT_SOURCE_DIR
2.CMAKE_CURRENT_SOURCE_DIR
以上各两个宏代表着CMakeLists.txt所在的目录
aux_source_directory(${PROJECT_SOURCE_DIR} SRC)//将PROJECT_SOURCE_DIR目录下的源文件字符串全部放在SRC中
add_executable(app ${SRC})
方式2
file命令
file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
add_executable(app ${SRC})
5.指定头文件路径
include_directories命令
例子
include_directories(${PROJECT_SOURCE_DIR}/include)
6.通过cmake制作库文件
制作静态库
在cmake中,如果要制作静态库,我们需要如下命令
add_library(库名称 STATIC 源文件)
制作动态库
与制作静态库相似,就是改了一个参数
add_library(库名称 SHARED 源文件)
输出库文件的路径
关键宏:LIBRARY_OUTPUT_PATH
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/build/library)
7.在程序中链接库文件
首先,我们知道要想在程序中使用库,必须要包含两个文件,一个是提供api信息的.h文件,另一个是存储二进制“源程序”的库文件(windows下的.lib/.dll,linux下的.so,.a)。
7.1在程序中链接静态库
两个关键命令
link_libraries(库名1,库名2,库名3......)#注意,库的名字必须是完整的文件名+扩展名
如果不是系统的库,我们可能需要使用另一个命令来指定库所在路径
link_directories(库的路径,比如${PROJECT_SOURCE_DIR})
7.2在程序中链接动态库
总体来说,链接动态库与链接静态库最大的不同在于生成可执行文件时,库文件的二进制源码并不会合并到可执行文件中,然后从cmake的命令来看,多了一个target
和链接动态库差不多,只不过,第一个命令需要写成,并且需要放在add_executable()后边
target_link_libraries(库名)
link_directories()
8.日志
在cmake中,有一条可以向用户打印信息的命令message
message([] "message to build")
9.变量操作
9.1追加
有时候项目中的源文件不一定在同一个目录中,但是这些源文件最后却需要一起编译来形成最终的可执行文件或者库文件。如果我们通过file命令对各个目录下的源文件进行搜索,最后还需要做一个字符串拼接的操作,关于字符串拼接可以使用set命令,也可以使用list命令
1.使用set拼接
如果使用set命令拼接,对应的格式如下
set(变量名 ${变量名1} ${变量名2}...)
关于上面的命令其实就是将从第二个参数开始往后所有的字符串进行拼接,最后将结果存储到第一个参数中,如果第一个参数中原来有数据,就会对第一个参数进行覆盖。
实例
2.使用list追加
如果使用list命令进行拼接,对应的命令格式如下
list(APPEND<list>[<element>...])
9.2字符串移除
1.使用list命令做字符串的移除
9.3其他字符串操作
10.宏定义
在进行程序测试的时候,我们可以在代码中添加一些宏定义,通过这些宏来控制代码是否生效,实例如下
#include<iostream>
int main(){
# ifdef DEBUGstd::cout<<"debug information"<<std::endl;
#endifstd::cout<<"code running"<<std::endl;
}