为什么要学CMake
- 大部分C++开源项目都是用CMake进行管理的,CMake对项目的管理更加方便
- CMake可以方便跨平台,可以在多种操作系统上使用,如 Linux、macOS、Windows 等
- CMake可以方便进行代码版本的管理,可以与版本控制系统(如 Git、SVN 等)结合使用,简化版本控制和项目管理
对CMake的基本了解
- CMake是一种弱类型语言,靠变量支撑整个项目
- CMake同样有变量、函数、宏等概念,也有变量生命周期
- CMake使用层级的方式管理项目,在项目顶层存在一个Makefile负责包含对子目录中 Makefile 的调用。在项目的每个子目录中,可以有一个自己的 Makefile,用于定义该目录下特定目标的构建规则
- CMake通过将源代码文件(如 C、C++、Java 等)自动转换成Makefile文件,然后由编译器如VS来生成对应的工程项目
CMake的基本使用
在cmake所在目录的bin目录中找到cmake-gui.exe并打开
- 红色并不是报错,而是提醒该配置是第一次出现,再进行一次配置红色就会消失
- 先配置源码路径和生成路径
- 设置构建变量,对这些变量保持默认就行,当需要修改某些设置的时候,再进行修改
- 然后依次点击配置、生成、打开工程
-
CMake运行信息和报错信息都会出现在底部窗口
CMake语法入门
message命令:主要用于记录消息,一般使用STATUS来输出日志信息,使用FATAL_ERROR来生成错误信息并停止处理和生成,详细使用参考文章CMake中message的使用
根目录(顶层)CMakeLists文件的编写
1.工程基础配置
#使用此项目版本不能低于3.20,若低于则报错并停止生成
cmake_minimum_required(VERSION 3.20 FATAL_ERROR)
#项目名称 版本 语言
project(项目名称 LANGUAGES CXX)
#设置c++语言使用标准
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
2.定义binary和library路径
#变量 XX
_ROOT
,其值为当前源目录的路径(${CMAKE_CURRENT_SOURCE_DIR}
),并将其存储在 CMake 缓存中,以便在不同的构建过程中保持一致。PATH
表示这个变量是一个路径。set(XX_ROOT ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH "XX root")
#变量 XX
_DEBUG_BUILD_DIR
,指定了调试构建的输出目录。${XX_RROT}
是一个指向项目根目录的变量,/Build
是构建目录的名称。这个变量也被存储在 CMake 缓存中。set(XX_DEBUG_BUILD_DIR "${XX_ROOT}/Build" CACHE PATH "Debug Bulid Dir")
#下面表示把生成的归档文件、库文件、可执行文件都放在指定的路径下
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${XX_DEBUG_BUILD_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${XX_DEBUG_BUILD_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${XX_DEBUG_BUILD_DIR})
3.设置支持VS工程文件夹
if(MSVC) #检查当前使用的编译器是否是 Microsoft Visual Studio 编译器
message(STATUS "set MSVC use folders")
#设置全局属性
USE_FOLDERS
为ON
。set_property(GLOBAL PROPERTY USE_FOLDERS ON)
#添加了
/MP
编译选项到全局编译选项中。/MP
是 MSVC 编译器的一个选项,用于启用多处理器编译,这可以加快大型项目的编译速度。add_compile_options(/MP)#开启全局优化
endif()
4.配置编译的选择项
list(
APPEND
XX_BUILD_LIST
XX_BUILD_XX_XX
...
)
#将所有编译选项都设为ON打开
foreach(BUILD_ITEM ${XX_BUILD_LIST})
option(${BUILD_ITEM } "${BUILD_ITEM}" ON)
message(STATUS "set ${BUILD_ITEM}: ${${BUILD_ITEM}}")
endforeach()
5.选项为打开的将对应的子目录项目加入到项目中
if(${XX_BUILD_XX_XX})
message(STATUS "add XX folder")
add_subdirectory(子项目名称)
endif()
子目录CMakeLists文件的编写
#设置工程名称
project(项目名称 LANGUAGES CXX)
#添加文件树
file(
GLOB _SRCS #变量名自定义
main.cpp
#...
)
#添加到可执行文件
add_executable(${PROJECT_NAME} ${_SRCS})
使用时出现的错误
解决方案
以管理员身份运行 CMake GUI(右键单击 CMake GUI 图标,选择“以管理员身份运行”)。
注意:使用时cmake的源目录和生成目录不能带有中文字符否则也会报错