cmake

优势

  1. 跨平台性:CMake能够在多种操作系统和编译器上生成构建文件,包括Windows、Linux、macOS以及GCC、Visual Studio等。这使得CMake成为一个理想的工具,用于构建和管理需要在多个平台上运行的项目,大大提高了项目的可移植性。
  2. 模块化设计:CMake支持模块化的项目配置,使得开发者可以将项目的构建规则组织成独立的CMake模块。这不仅方便了项目的管理和维护,也提高了代码的可读性和可维护性。
  3. 可扩展性:CMake允许开发者编写自定义的CMake模块和宏,以满足项目特定的需求。这种灵活性使得CMake能够适用于各种项目类型,无论是小型项目还是大型复杂项目。
  4. 自动化构建和测试:CMake能够自动化项目的构建和测试过程,大大简化了编译和链接的步骤。此外,它还能生成本地构建环境,如Makefile或Visual Studio项目文件,使得开发者能够使用熟悉的工具进行构建。
  5. 集成外部库和工具:CMake支持集成多种外部库和工具,如Boost和Qt,降低了配置和管理外部依赖的复杂性。这有助于开发者更有效地利用现有的库和工具,提高开发效率。
  6. 易于配置和维护:CMake的配置文件(CMakeLists.txt)相对简单且易于理解,使得开发者能够轻松地进行配置和维护。此外,CMake还提供了丰富的系统检测接口和工具链实现,使得开发者能够更方便地处理各种平台和环境差异。

基础语法

命令功能描述
cmake_minimum_required(VERSION major.minor)指定构建此项目所需的最低 CMake 版本
project(project_name)定义项目的名称(和版本-可选)
add_executable(targetName source1 source2 ... sourceN)添加一个可执行目标到项目中,并指定其源代码文件。
# 0. cmake 最低版本号要求
cmake_minimum_required(VERSION 3.8)

# 0. 项目信息
project(demo VERSION 1.0)

# 0. 指定生成目标
add_executable(demo main.c)

随后使用命令行,在项目根目录下执行。或者写成mk.bat文件(windows下),双击执行。

# windows下
cmake -B build -G "MinGW Makefiles"
make -C build

project

设置项目名称,并将其存储在变量PROJECT_NAME中。当从顶级CMakeLists.txt调用时,还将项目名称存储在可变CMAKE_PROJECT_NAME中。

多个文件

同一目录下

命令功能描述
aux_source_directory(<dir> <var>)搜集所有在指定路径下的源文件的文件名,并将输出结果列表储存在指定的变量中
# 0. cmake 最低版本号要求
cmake_minimum_required(VERSION 3.8)

# 0. 项目信息
project(demo)

# 0. 查找当前目录下的所有文件,并将名称保存在DIR_SRC中
aux_source_directory(. SRCS)

# 0. 指定生成目标
add_executable(demo  ${SRCS})

多个目录下

命令作用
add_subdirectory(src)向 CMake 工程中添加一个子目录。它接受一个参数,即子目录的路径,然后在当前 CMakeLists.txt 文件中的对应位置包含子目录中的 CMakeLists.txt 文件并执行其中的命令。这有助于将大型项目分解为多个模块,提高工程的可维护性。
include_directories向编译器添加头文件搜索路径。它接受一个或多个文件夹路径或已定义的 CMake 变量作为参数,告诉编译器在哪里查找头文件。
target_link_libraries指定链接给定目标和/或其依赖项时要使用的库或标志。为特定的目标(如可执行文件或库)指定需要链接的库。
# 0. cmake 最低版本号要求
cmake_minimum_required(VERSION 3.8)

# 0. 项目信息
project(demo)

# 0. 查找当前目录下的所有文件,并将名称保存在DIR_SRC中
aux_source_directory(. DIR_SRC)

# 0. 指定生成目标
add_executable(demo  ${DIR_SRC})

# 1. 添加子目录
add_subdirectory(src)

# 1. 添加头文件路径
include_directories(src)

# 1. 添加链接库,这里使用的是list静态库
target_link_libraries(
    ${PROJECT_NAME}
    list
)

链接库

命令功能描述
add_library(name [STATIC|SHARED] source...创建“静态|动态”库

子目录下的CMakeLists.txt示例如下:

project(list)

# 当前目录下的文件 -> 写入变量
aux_source_directory(. SRCS)

# 生成链接库
# add_library(${PROJECT_NAME} STATIC ${SRCS})
add_library(${PROJECT_NAME} SHARED ${SRCS})

文件搜索

命令功能描述
file文件操作命令,如GLOB_RECURSECOPY
# GLOB_RECURSE 递归搜索,并返回所有匹配的文件
# SRCS 变量名
# CONFIGURE_DEPENDS 配置依赖,即当CMakeLists.txt文件有改动时,重新执行GLOB_RECURSE

file(GLOB_RECURSE SRCS CONFIGURE_DEPENDS
    "${CMAKE_CURRENT_SOURCE_DIR}/libusb/*.h"
    "${CMAKE_CURRENT_SOURCE_DIR}/libusb/*.c"
    "${CMAKE_CURRENT_SOURCE_DIR}/libusb/os/*.h"
    "${CMAKE_CURRENT_SOURCE_DIR}/libusb/os/*.c"
)
# 自动地收集libusb/目录及其os/子目录下所有的.h和.c文件,并将这些文件的路径存储在SRCS变量中

变量

变量功能描述
CMAKE_SOURCE_DIR指向顶层的CMakeLists.txt文件所在的目录
CMAKE_BINARY_DIR指向构建树(build tree)的顶层目录,也就是CMake生成Makefile的目录
CMAKE_CURRENT_SOURCE_DIR指向当前处理的CMakeLists.txt文件所在的目录
CMAKE_CURRENT_BINARY_DIR指向当前CMakeLists.txt文件构建的输出目录
CMAKE_C_COMPILER指定C编译器的路径
CMAKE_CXX_COMPILER指定C++编译器的路径
CMAKE_BUILD_TYPE设置构建类型(如Debug, Release, RelWithDebInfo, MinSizeRel等)
CMAKE_INSTALL_PREFIX设置安装目录的前缀,也就是make install时文件安装的根目录
PROJECT_NAME项目名称,由project()命令设置
PROJECT_SOURCE_DIRCMAKE_SOURCE_DIR相同,指向项目的顶层源代码目录
PROJECT_BINARY_DIRCMAKE_BINARY_DIR相同,指向项目的顶层构建目录
CMAKE_C_COMPILERC语言编译器路径
CMAKE_C_FLAGSC语言编译器的参数
CMAKE_CXX_COMPILERC++语言编译器路径
CMAKE_CXX_FLAGSC++语言编译器的参数
CMAKE_CXX_STANDARD设置C++标准,如17、20等
CMAKE_CXX_STANDARD_REQUIRED设置为ON时,要求C++标准必须为CMAKE_CXX_STANDARD所指定的值
CMAKE_CXX_EXTENSIONS设置为ON时,启用C++标准扩展
CMAKE_EXE_LINKER_FLAGS设置链接器(linker)的标志(flags),用于生成可执行文件
CMAKE_MODULE_PATH设置CMake查找模块文件的路径
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_INCLUDE_CURRENT_DIR ON)

完整示例

cmake_demo在新窗口打开