CMake是一款跨平台的开源构建工具,广泛用于C/C++项目的构建与管理。它通过简洁的配置脚本描述项目结构,并能根据这些脚本生成适用于不同平台和编译环境的构建系统(如Makefile、Visual Studio工程文件等),从而实现高效的跨平台开发。
接下来的内容将逐步解析《CMake的使用》教程中的各个关键部分,帮助读者系统掌握其用法。
目标是在Ubuntu系统中完成CMake的安装与验证。
执行以下命令进行安装:
sudo apt install cmake
安装完成后,使用如下命令检查是否成功:
cmake --version
示例中所使用的CMake版本为3.16.3。此步骤主要用于确保开发环境已准备就绪。
本节旨在创建一个最基础的CMake项目,熟悉基本操作流程。
yhpcmake/ ├── CMakeLists.txt └── main.cpp
main.cpp:输出“hello yhping”的简单程序。
CMakeLists.txt 内容如下:
cmake_minimum_required(VERSION 3.0) project(demo) add_executable(main main.cpp)
cmake .
make
main
./main
执行编译后会生成大量中间产物(如CMakeCache.txt、CMakeFiles/等):
cmake
CMakeCache.txt
Makefile
若需清理所有生成文件,可使用:
make clean
该部分完整展示了CMake的标准工作流:配置 → 生成 → 编译 → 运行。
直接在add_executable中列出所有源文件:
add_executable(main main.cpp funa.cpp)
利用AUX_SOURCE_DIRECTORY自动收集当前目录下的所有源文件:
aux_source_directory(. SRC_LIST)
然后在构建目标中引用变量:
add_executable(main ${SRC_LIST})
add_executable
使用set()指令显式定义源文件集合:
set
set(SRC_LIST ./main.cpp ./funa.cpp ./funb.cpp)
project_root/
├── CMakeLists.txt
├── src/
│ ├── main.cpp
│ └── utils.cpp
└── include/
└── utils.h
在主CMakeLists.txt中包含子目录,并设置头文件搜索路径:
include_directories(include) add_subdirectory(src)
在src/CMakeLists.txt中定义目标:
add_executable(app main.cpp utils.cpp)
MyProject/ ├── CMakeLists.txt ├── src/ │ └── CMakeLists.txt ├── lib/ │ └── CMakeLists.txt ├── include/ │ └── mylib.h └── build/
在根目录CMakeLists.txt中调用子目录:
add_subdirectory(src) add_subdirectory(lib)
使用target_include_directories()为特定目标设置头文件路径:
target_include_directories(target_name PUBLIC include/)
library_demo/
├── CMakeLists.txt
├── src/
│ └── math_func.cpp
└── include/
└── math_func.h
创建静态库:
add_library(math STATIC src/math_func.cpp)
创建动态库:
add_library(math SHARED src/math_func.cpp)
导出头文件路径:
target_include_directories(math PUBLIC include)
app_with_lib/ ├── CMakeLists.txt ├── main.cpp └── libmath.a (或 .so)
链接外部库到可执行文件:
target_link_libraries(myapp math)
若库位于非标准路径,需指定库搜索目录:
link_directories(${PROJECT_SOURCE_DIR}/lib)
使用option()命令定义可选开关:
option(ENABLE_DEBUG_LOG "Enable debug logging" ON)
if(ENABLE_TOOLS) add_executable(tool tool.cpp) endif()
在CMake中传递宏:
if(ENABLE_DEBUG_LOG) target_compile_definitions(myapp PRIVATE DEBUG_LOG) endif()
对应C++代码中可通过#ifdef DEBUG_LOG启用调试输出。
在cmake命令中通过-D参数开启或关闭选项:
cmake -DENABLE_DEBUG_LOG=ON ..
查找并链接cjson库:
find_package(cjson REQUIRED) target_link_libraries(myapp cjson::cjson)
若系统未安装,可通过FetchContent从GitHub拉取:
include(FetchContent) FetchContent_Declare( cjson GIT_REPOSITORY https://github.com/DaveGamble/cJSON.git GIT_TAG v1.7.14 ) FetchContent_MakeAvailable(cjson)
tasks.json 示例:
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"command": "cmake --build ./build"
}
]
}
launch.json 示例:
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/main",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{ "text": "-enable-pretty-printing" }
],
"preLaunchTask": "build"
}
]
}
set()赋值,${VAR}引用变量。| cmake_minimum_required | 设定最低CMake版本 |
| project | 定义项目名称 |
| add_executable | 添加可执行目标 |
| add_library | 添加库目标 |
| target_link_libraries | 链接依赖库 |
| include_directories | 添加头文件路径(旧式) |
| target_include_directories | 为特定目标添加头文件路径(推荐) |
| set | 设置变量 |
| option | 定义布尔型配置选项 |
《CMake的使用》是一份结构清晰、循序渐进的CMake学习指南。从环境配置起步,涵盖单文件构建、多文件处理、库的生成与链接、条件编译、外部依赖集成,直至VSCode调试环境搭建,全面覆盖了现代C/C++项目开发所需的核心技能。通过本教程的学习,开发者能够快速掌握CMake的基本用法,并具备构建中大型项目的实际能力。
项目结构示例如下:
yhpcmake
├── CMakeLists.txt
├── main.cpp
├── tfuna/
│ ├── funa.cpp
│ └── funa.hpp
└── tfunb/
├── funb.cpp
└── funb.hpp
核心命令说明:
include_directories(tfuna tfunb)
用于添加头文件的搜索路径,确保编译器能够找到所需的 .hpp 文件。
aux_source_directory
通过该命令收集分布在不同子目录中的源文件,便于统一管理与构建。
本节内容旨在引导读者掌握如何组织包含多个源文件和多级目录的项目,并利用 CMake 实现高效构建与维护。
目标:将源码、头文件、构建中间文件及最终输出文件分别归类存放,提升项目整体清晰度与可维护性。
推荐的项目结构如下:
yhpcmake ├── bin/ # 存放生成的可执行程序 ├── build/ # 构建过程产生的中间文件目录 ├── include/ # 集中存放所有公共头文件 │ ├── funa.hpp │ └── funb.hpp ├── src/ # 所有源代码文件所在目录 │ ├── funa.cpp │ ├── funb.cpp │ ├── main.cpp │ └── CMakeLists.txt └── CMakeLists.txt
关键指令包括:
add_subdirectory(src)
用于递归或显式地编译指定子目录下的源码内容。
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
设定最终生成的可执行文件的输出位置,通常指向 bin/ 目录。
两种常见的组织方式:
此部分内容强调了项目结构的规范性和构建目录的隔离原则,有效防止构建产物混入源码目录,保持代码仓库整洁。
示例项目布局:
yhpcmake ├── build/ ├── lib/ ├── tfuna/ │ ├── funa.cpp │ └── funa.hpp └── CMakeLists.txt
涉及的关键命令有:
add_library(tfuna_shared SHARED ${SRC_LIST})
用于创建共享库(即动态库),扩展名为 .so(Linux)或 .dll(Windows)。
add_library(tfuna_static STATIC ${SRC_LIST})
用于生成静态库,扩展名为 .a(Linux)或 .lib(Windows)。
set_target_properties
自定义输出库的名称,支持去除默认前缀或后缀,实现更灵活的命名控制。
set(LIBRARY_OUTPUT_PATH ...)
指定生成的库文件存放路径,一般指向项目的 lib/ 目录。
使用场景示例结构:
testlib ├── src/ │ └── testmain.cpp ├── tfuna/ │ ├── include/ │ │ └── funa.hpp │ └── lib/ │ ├── libtfuna.a │ └── libtfuna.so └── CMakeLists.txt
主要命令如下:
find_library(TFUNA_LIB tfuna HINTS ...)
在系统或指定路径中查找所需链接的库文件。
target_link_libraries(main ${TFUNA_LIB})
将查找到的库文件链接到目标可执行程序中,完成依赖集成。
本章节深入讲解了静态库与动态库的生成流程及其在实际项目中的调用方法,是 C/C++ 工程实践中不可或缺的核心技能。
使用该命令可在 CMake 配置阶段传入自定义参数,影响后续构建行为。
可用于控制是否构建特定目标文件,例如:
option(MYDEBUG "启用调试编译" OFF) if(MYDEBUG) add_executable(main_2 main_2.cpp) endif()
也可用于控制代码中的宏定义开关:
option(YYY1 "启用 YYY1 宏" OFF) if(YYY1) add_definitions(-DYYY1) endif()
从命令行启用选项的方式:
cmake .. -DMYDEBUG=ON
add_compile_options(-std=c++2a -Wall)
option
本部分内容帮助开发者掌握如何借助 CMake 实现编译时的条件判断,灵活区分调试版本与发布版本的构建逻辑。
目标:演示如何在 CMake 项目中正确链接外部第三方库(如 jsoncpp)。
核心命令:
target_link_libraries(testjson libjsoncpp.so)
用于将 jsoncpp 的动态库链接至当前目标。
注意事项:
需提前在系统中安装 jsoncpp 的开发包,例如通过包管理器安装 libjsoncpp-dev 等组件。
libjsoncpp-dev
本节展示了如何对接已安装在系统环境中的第三方库,满足实际工程中对功能扩展的需求。
在
launch.json
中配置
"preLaunchTask"
,实现启动调试前自动触发编译动作,确保运行的是最新代码。
支持设置断点、单步执行、变量查看等标准调试功能。
本节内容实现了 CMake 构建系统与现代开发工具链(VSCode)的无缝整合,显著提升开发效率与调试体验。
语法特性说明:
${}
形式获取变量值。
注释符号为:
#
常用指令汇总:
cmake_minimum_required
project
set
include_directories
add_executable
add_library常用变量:
CMAKE_CXX_FLAGS:C++ 编译选项。
CMAKE_BUILD_TYPE:编译类型(Debug/Release)。
EXECUTABLE_OUTPUT_PATH/LIBRARY_OUTPUT_PATH:输出路径。
target_link_libraries
add_subdirectory
aux_source_directory
总结:
本教程以最基础的 Hello World 程序为起点,循序渐进地讲解了多目录项目管理、静态库与动态库的生成及链接、条件编译的实现方式、第三方库的集成方法以及调试环境的配置等内容。涵盖了 CMake 的核心功能与实际应用技巧,结构清晰,内容全面,非常适合初学者系统性地掌握 CMake 的基本用法和项目构建流程。
扫码加好友,拉您进群



收藏
