一、概述
1、CMake作用
CMake是一个跨平台、开源的构建系统。它是一个集软件构建、测试、打包于一身的软件。比如它能根据源码和预先配置好的构建配置文件构建出Visual Studio的.sln文件或者Linux中的Makefile、启动编译过程、启动单元测试、打包可执行文件及依赖到指定目录。
2、CMake优点
跨平台,支持Windows、Linux、Mac、Android系统;
扩展性好,支持逻辑控制语法、条件编译等;
二、CMake的Helloworld示例
CMake通过CMakeLists.txt文件配置项目构建过程,该文件通常位于项目根目录。其他还有xxx.cmake格式的文件,这种文件的功能类似C++中的头文件,可以被include进CMakeLists.txt中,实现对构建配置的扩展。
1、项目目录、配置CMakeLists.txt
-
创建src目录,包含hello.cpp文件;
-
根目录创建CMakeLists.txt;
-
build目录是空目录,执行构建过程(构建过程会产生一些配置文件,为了防止污染源码,在一个独立文件夹中构建);
上图CMakeLists.txt文件解释: -
project(hello)
配置项目名为hello; -
add_executable(hello src/hello.cpp)
配置生成可执行文件,可执行文件名为hello,参与链接的文件是src/hello.cpp
;
2、生成解决方案
通过使用cmake命令,指定根目录的CMakeLists.txt位置,生成项目解决方案。
以上便生成了Visual Studio的解决方案hello.sln
和hello项目的工程配置hello.vcxproj
。
3、构建
上一步只是生成了解决方案,我们想要的hello.exe
还没有生成。可以用图形界面打开hello.vcproj
生成,也可以直接通过命令行生成。
在build目录执行 cmake --build
.:
三、CMake常用关键字
1、工程管理
(1) include_directory
配置头文件路径,可以同时配置多个路径。比如:include_directory(CMAKE_SOURCE_DIR/include1 CMAKE_CURRENT_SOURCE_DIR/../include2)
上面包含了两个变量CMAKE_SOURCE_DIR、CMAKE_CURRENT_SOURCE_DIR
:
CMAKE_SOURCE_DIR
:最开始的CMakeLists.txt的路径,比如使用cmake ..
构建时,指的是项目根目录下的CMakeLists.txt路径;CMAKE_CURRENT_SOURCE_DIR
:当前CMakeLists.txt所在路径(CMakeLists.txt可以有多个);
(2) add_executable、add_library
前者配置如何生成可执行文件,后者配置如何生成库文件。如:
add_executable(可执行文件名 源码列表)
add_library(动态链接库名称 SHARED 源码列表)
add_library(静态链接库名称 STATIC 源码列表)
在执行链接时,通常要指定其他链接库。CMake通过library_directory
指定链接库路径、通过target_link_libraries
指定链接库名,相当于Makefile
里面的-L
和-l
如:
library_directory(CMAKE_BINARY_DIR/lib) # CMAKE_BINARY_DIR是执行cmake命令的目录
target_link_libraries(二进制文件名 链接库名列表)
(3) add_subdirectory、include
对于上面helloworld
的简单使用,你可能觉得写Makefile
更简单,但如果整个解决方案像下面这样,你还会写Makefile
吗?
单个解决方案项目太大,CMake使用分而治之解决。通过在每个模块单独使用一个CMake配置文件,在根目录引入这些配置文件。
add_subdirectory
的参数是一个模块目录。CMake会在该目录下查找CMakeLists.txt
文件,并执行里面的配置脚本;include
的参数是一个文件名,通常是类似xxx.cmake
的文件;
2、开关选项
CMake通过执行cmake命令
时的-D
选项,控制某一个编译选项的开关。比如有以下CMakeLists.txt
:
project(hello)
option("ENABLE_FEATURE", "whether enable some feature", OFF) # 定义一个开关,是否开启某一个指定功能,默认关闭
if(ENABLE_FEATURE)
add_executable(hello src/hello.cpp feature.cpp) # 假设特定功能就是多链接一个文件
else
add_executable(hello src/hello.cpp)
endif
构建时使用cmake .. -DENABLE_FEATURE=ON
开启指定功能,若没有-D
选项或者把ON
改为OFF
,则关闭指定功能。
option定义的选项只能在CMakeLists.txt中使用,如果想在源码中识别是否定义了某一个开关呢
? add_definition可以完成该功能。比如:
if(ENABLE_FEATURE)
add_definition(FEATURE) # 如果ENABLE_FEATURE开启,则定义FEATURE宏
elsec
endif
通过增加宏定义,在源码中判断该宏达到同样的开关作用。
3、调试信息
(1) message
打印信息。格式:message(<mode> "debug info: value of arg: ${arg}")
。
message函数至少有以下几种模式(mode):STATUS、INFO、WARNING、FATAL_ERROR
。其中FATAL_ERROR
模式会停止构建并以失败退出。
4、其他CMake变量
(1) CMAKE_C_FLAGS、CMAKE_CXX_FLAGS
分辨控制C/C++编译选项。比如:set(CMAKE_CXX_FLAGS "std-c++11 ${CMAKE_CXX_FLAGS}")
# 扩展CMAKE_CXX_FLAGS
的值,增加对C++11的支持。
(2) CMAKE_BUILD_TYPE
指定构建类型,通过在使用cmake命令构建时传入。比如:cmake .. -DCMAKE_BUILD_TYPE=Release
C/C++Linux服务器开发/架构师面试题、学习资料、教学视频和学习路线图(资料包括C/C++,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg等),免费分享有需要的可以自行添加学习交流群960994558