目录
3.CMake 3.30 之前(含 3.29)链接 Boost 的方式
1.背景
最近在弄一个开源项目的时候,刚好用到了boost库,用CMake编译的时候报了一下错误:
CMake Warning (dev) at CMakeLists.txt:40 (find_package):
Policy CMP0167 is not set: The FindBoost module is removed. Run "cmake
--help-policy CMP0167" for policy details. Use the cmake_policy command to
set the policy and suppress this warning.
This warning is for project developers. Use -Wno-dev to suppress it.
这个警告是由于 CMake 3.25 版本开始弃用了旧的 FindBoost
模块(即 CONFIG
模式未启用时的默认查找方式),并引入了 CMP0167 策略 来提示用户迁移到新的 Boost 查找机制。下面就来讲讲CMake3.30版本之前和之后链接boost的方式的差异。
2.boost引入CMake时机
Boost 库自 2001 年首次发布以来,经过二十多年的发展,已成为 C++ 生态中最重要的跨库之一,其版本迭代反映了 C++ 语言的演进和开发者对功能的需求变化。
1.早期版本(2001–2005):奠定基础
Boost 1.0(2001 年 8 月)
首次正式发布,包含早期核心库,如smart_ptr
(智能指针)、regex
(正则表达式)、tuple
(元组)等,确立了 Boost 作为 C++ 标准库补充的定位。Boost 1.30(2003 年 11 月)
引入filesystem
(文件系统操作)、program_options
(命令行参数解析),这两个库后来被广泛应用于各类项目。Boost 1.32(2004 年 8 月)
加入thread
(多线程库),首次提供跨平台的线程支持,解决了 C++98 标准中缺乏线程库的问题。
2.快速发展期(2006–2010):扩展生态
Boost 1.35(2007 年 8 月)
引入asio
(网络与异步 I/O),成为后续网络编程的核心库(也是 C++11std::async
的重要参考)。Boost 1.40(2009 年 4 月)
加入unordered_map
/unordered_set
(哈希容器),早于 C++11 标准正式引入同类容器。Boost 1.42(2010 年 2 月)
新增locale
(国际化与本地化)库,支持多语言编码、日期时间格式化等功能。
3.标准化推动期(2011–2015):对接 C++ 标准
Boost 1.47(2011 年 8 月)
引入chrono
(时间库)和ratio
(比例算术),这两个库随后被纳入 C++11 标准。Boost 1.51(2012 年 6 月)
加入filesystem v3
版本,改进了路径处理和跨平台兼容性,成为现代文件操作的标杆。Boost 1.56(2014 年 8 月)
新增hana
(元编程库),基于 C++11 constexpr 特性,提供更简洁的编译期编程接口。Boost 1.58(2015 年 4 月)
asio
库支持 C++11 移动语义,性能大幅提升,成为高性能网络库的代表。
4.稳定成熟期(2016–2020):完善与优化
Boost 1.60(2016 年 8 月)
引入outcome
(错误处理库),提供比异常更轻量的错误传递机制,适合高性能场景。Boost 1.64(2017 年 12 月)
filesystem
库完全支持 C++17 标准的文件系统接口,实现与标准库的兼容。Boost 1.70(2019 年 4 月)
重大变化:首次提供完整的 CMake 配置文件(BoostConfig.cmake
),支持现代 CMake 的目标链接方式(Boost::xxx
),为后续 CMake 3.30+ 移除旧模块奠定基础。Boost 1.73(2020 年 8 月)
优化coroutine2
库,支持 C++20 协程特性的过渡,提升异步编程体验。
5.近年版本(2021–至今):适配新标准
Boost 1.76(2021 年 4 月)
增强对 C++20 标准的支持,json
库正式稳定,提供高效的 JSON 解析与生成功能。Boost 1.80(2022 年 12 月)
- 优化
asio
对 TLS 1.3 的支持,网络安全性提升; container
库新增更多 C++20 容器适配器,兼容性更好。
- 优化
Boost 1.83(2023 年 8 月)
支持 C++23 部分特性,math
库扩展了统计分布函数,适合科学计算场景。Boost 1.85(2024 年 4 月)
改进跨平台构建系统,进一步完善与 CMake 3.30+ 的兼容性,移除对旧版本编译器的支持。
可见,boost从1.70版本之后提供 CMake 配置文件,支持现代 CMake 目标链接。
3.CMake 3.30 之前(含 3.29)链接 Boost 的方式
此阶段支持两种模式:传统 FindBoost
模块模式(默认)和 Boost 配置文件模式(推荐),可通过策略控制警告。
1.传统 FindBoost
模块模式(不推荐,逐步废弃)
依赖 CMake 内置的 FindBoost.cmake
模块,通过变量链接库:
cmake_minimum_required(VERSION 3.16)
project(MyProject)
# 可选:关闭 CMP0167 警告(3.25+ 版本会提示)
cmake_policy(SET CMP0167 OLD)
# 查找 Boost(指定版本和组件)
find_package(Boost 1.80.0 REQUIRED COMPONENTS system filesystem)
# 添加可执行文件
add_executable(myapp main.cpp)
# 链接 Boost(通过变量)
target_link_directories(myapp PRIVATE ${Boost_LIBRARY_DIRS})
target_link_libraries(myapp PRIVATE ${Boost_LIBRARIES})
target_include_directories(myapp PRIVATE ${Boost_INCLUDE_DIRS})
- 特点:使用
Boost_LIBRARIES
、Boost_INCLUDE_DIRS
等变量,依赖 CMake 内置模块解析路径。 - 缺点:兼容性差,不支持 Boost 最新特性,3.30+ 版本完全失效。
2.Boost 配置文件模式(推荐,向前兼容)
使用 Boost 自带的 BoostConfig.cmake
配置文件,通过目标链接:
cmake_minimum_required(VERSION 3.16)
project(MyProject)
# 明确使用 CONFIG 模式(调用 Boost 自带的配置文件)
find_package(Boost 1.80.0 REQUIRED CONFIG COMPONENTS system filesystem)
# 添加可执行文件
add_executable(myapp main.cpp)
# 链接 Boost(通过命名空间目标)
target_link_libraries(myapp PRIVATE Boost::system Boost::filesystem)
- 特点:直接链接
Boost::xxx
目标(如Boost::system
),无需手动处理路径。 - 优势:由 Boost 官方维护配置文件,兼容性更好,支持静态 / 动态库自动切换。
链接目标的优势: Boost::<component>
是预定义的 CMake 目标,包含以下信息,无需手动配置:
- 头文件路径(自动添加到
target_include_directories
)。 - 库文件路径(自动添加到
target_link_libraries
)。 - 依赖关系(如
Boost::filesystem
依赖Boost::system
,会自动传递)。 - 编译选项(如宏定义、链接器标志)。
4.CMake 3.30 及之后链接 Boost 的方式
CMake 3.30 彻底移除了 FindBoost.cmake
模块,强制使用 Boost 配置文件模式,无需再设置 CMP0167 策略。
cmake_minimum_required(VERSION 3.30)
project(MyProject)
# 必须使用 CONFIG 模式(默认行为,可省略 CONFIG 关键字)
find_package(Boost 1.80.0 REQUIRED COMPONENTS system filesystem)
# 添加可执行文件
add_executable(myapp main.cpp)
# 链接 Boost(通过命名空间目标,与 3.30 前的推荐方式一致)
target_link_libraries(myapp PRIVATE Boost::system Boost::filesystem)
变化点:
- 无需设置
cmake_policy(SET CMP0167 OLD)
,因为旧模块已移除; find_package
默认使用CONFIG
模式,CONFIG
关键字可省略;- 必须确保 Boost 安装时包含 CMake 配置文件(
BoostConfig.cmake
),否则会报错。
5.CMake3.30后引入Boost的步骤
1.确保 Boost 安装正确
- 版本要求:Boost 1.70+(含
BoostConfig.cmake
),推荐 1.80.0。 - 安装验证:检查 Boost 安装目录是否存在
lib/cmake/Boost-<version>/BoostConfig.cmake
文件,例如:
2.在 CMakeLists.txt
中引入
# 1. 设置 CMake 最低版本(3.16+ 支持 CONFIG 模式,3.30+ 强制使用)
cmake_minimum_required(VERSION 3.30)
project(MyProject)
# 2. (可选)指定 Boost 安装路径(非标准路径时)
# 方式一:通过 BOOST_ROOT 指定根目录
set(BOOST_ROOT "/path/to/boost_1_80_0")
# 方式二:通过 CMAKE_PREFIX_PATH 添加搜索路径(支持多个路径)
# set(CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH};/path/to/boost_1_80_0")
# 3. 查找 Boost(自动加载 BoostConfig.cmake)
# 必须指定所需组件(如 system、filesystem 等)
find_package(Boost 1.80.0 REQUIRED COMPONENTS
system # 示例组件:系统编程
filesystem # 示例组件:文件系统
thread # 示例组件:多线程
)
# 4. 添加可执行文件/库
add_executable(myapp main.cpp)
# 5. 链接 Boost 目标(核心步骤,无需手动处理路径)
target_link_libraries(myapp PRIVATE
Boost::system # 对应 system 组件
Boost::filesystem # 对应 filesystem 组件
Boost::thread # 对应 thread 组件
)
3.控制静态 / 动态链接
在 find_package
前设置 Boost_USE_STATIC_LIBS
变量:
set(Boost_USE_STATIC_LIBS ON) # 使用静态库,如果需要动态库则设置为 OFF
set(Boost_USE_MULTITHREADED ON) # 使用多线程库
set(Boost_USE_STATIC_RUNTIME OFF) # 如果使用静态运行时库,则设置为 ON
find_package(Boost 1.80.0 REQUIRED COMPONENTS system filesystem)
4.启用调试模式(排查查找问题)
若 find_package
失败,通过以下方式输出详细日志:
# 在 find_package 前设置,输出 Boost 查找过程
set(Boost_DEBUG ON)
find_package(Boost 1.80.0 REQUIRED COMPONENTS system filesystem)
6.迁移建议(3.30 之前 → 3.30 之后)
1.确保 Boost 版本 ≥ 1.70
Boost 从 1.70 版本开始提供完整的 CMake 配置文件,1.80.0 完全兼容。
2.替换变量链接为目标链接
移除 Boost_LIBRARIES
和 Boost_INCLUDE_DIRS
,直接使用 Boost::xxx
目标:
# 旧代码
target_link_libraries(myapp PRIVATE ${Boost_LIBRARIES})
target_include_directories(myapp PRIVATE ${Boost_INCLUDE_DIRS})
# 新代码
target_link_libraries(myapp PRIVATE Boost::system Boost::filesystem)
3.指定 Boost 安装路径(若需要)
若 Boost 安装在非标准路径,通过 BOOST_ROOT
或 CMAKE_PREFIX_PATH
指定:
set(BOOST_ROOT "/path/to/boost_1_80_0") # 优先于系统路径
find_package(Boost 1.80.0 REQUIRED COMPONENTS system filesystem)
4.处理静态 / 动态库链接
通过 Boost_USE_STATIC_LIBS
控制链接类型(需在 find_package
前设置):
set(Boost_USE_STATIC_LIBS ON) # 链接静态库
# set(Boost_USE_STATIC_LIBS OFF) # 链接动态库(默认)
find_package(Boost 1.80.0 REQUIRED COMPONENTS system filesystem)
7.CMake 3.30 移除FindBoost的原因
尽管 FindBoost
模块广泛使用,但存在以下固有问题:
- 依赖 CMake 版本:模块由 CMake 维护,对 Boost 新版本的支持可能滞后(如 Boost 新增组件无法被旧模块识别);
- 库名解析复杂:Boost 库命名规则复杂(含编译器、线程模型等后缀),模块容易因命名不匹配导致查找失败;
- 跨平台兼容性差:不同平台的库命名和安装路径差异大,模块需大量条件判断适配,易出现边缘 case;
- 不支持现代 CMake 特性:无法直接生成
Boost::system
等目标,需手动处理链接路径,不符合现代 CMake 最佳实践。
8.常见问题
1.CMake 3.30+ 找不到 Boost 配置文件
- 确保 Boost 安装时生成了配置文件(源码编译需启用
--with-cmake
选项,或使用包管理器安装); - 通过
BOOST_ROOT
明确指定 Boost 安装目录(包含lib/cmake/Boost-1.80.0
子目录)。
2.链接错误(如 undefined reference to Boost::xxx
)
- 检查
find_package
中是否遗漏了所需组件(如使用filesystem
需添加COMPONENTS filesystem
); - 静态链接时,确保定义了
BOOST_ALL_NO_LIB
(部分组件需要)。
target_compile_definitions(myapp PRIVATE BOOST_ALL_NO_LIB)
3. 多版本 Boost 冲突
系统中存在多个 Boost 版本,CMake 找到的不是目标版本。
- 通过
BOOST_ROOT
精确指定目标版本路径; - 结合
NO_DEFAULT_PATH
选项限制搜索范围:
find_package(Boost 1.80.0 REQUIRED COMPONENTS system filesystem NO_DEFAULT_PATH)
9.总结
关键差异:
特性 | CMake 3.30 之前 | CMake 3.30 及之后 |
---|---|---|
依赖模块 | 支持 FindBoost.cmake (默认)和配置文件 |
仅支持 Boost 自带配置文件(BoostConfig.cmake ) |
链接方式 | 支持变量(${Boost_LIBRARIES} )和目标 |
仅支持目标(Boost::xxx ) |
策略要求 | 需设置 CMP0167 OLD 抑制警告 |
无需设置策略(旧模块已移除) |
配置文件依赖 | 可选(可使用旧模块) | 必须(否则无法找到 Boost) |
Boost 版本兼容性 | 支持旧版本 Boost(无配置文件) | 需 Boost 1.70+(自带 CMake 配置文件) |
CMake 3.30 前后链接 Boost 的核心差异在于是否依赖内置 FindBoost
模块。3.30+ 版本强制使用 Boost 自带的配置文件,通过 Boost::xxx
目标链接,简化了配置并提升了兼容性。迁移时只需替换变量链接为目标链接,并确保 Boost 版本支持 CMake 配置文件即可。
相关链接
- CMake 官网 CMake - Upgrade Your Software Build System
- CMake 官方文档:CMake Tutorial — CMake 4.1.0-rc2 Documentation
- CMake 源码:https://github.com/Kitware/CMake
- CMake 源码:CMake · GitLab
- 中文版基础介绍: CMake 入门实战 | HaHack
- wiki: Home · Wiki · CMake / Community · GitLab
- Modern CMake 简体中文版: Introduction · Modern CMake