CMake实践:CMake3.30版本之前和之后链接boost的方式差异

发布于:2025-07-23 ⋅ 阅读:(13) ⋅ 点赞:(0)

目录

1.背景

2.boost引入CMake时机

3.CMake 3.30 之前(含 3.29)链接 Boost 的方式

4.CMake 3.30 及之后链接 Boost 的方式

5.CMake3.30后引入Boost的步骤

6.迁移建议(3.30 之前 → 3.30 之后)

7.CMake 3.30 移除FindBoost的原因

8.常见问题

9.总结

相关链接


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++11 std::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 配置文件模式(推荐),可通过策略控制警告。

CMake指令:find_package

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_LIBRARIESBoost_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)

变化点

  1. 无需设置 cmake_policy(SET CMP0167 OLD),因为旧模块已移除;
  2. find_package 默认使用 CONFIG 模式,CONFIG 关键字可省略;
  3. 必须确保 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 模块广泛使用,但存在以下固有问题:

  1. 依赖 CMake 版本:模块由 CMake 维护,对 Boost 新版本的支持可能滞后(如 Boost 新增组件无法被旧模块识别);
  2. 库名解析复杂:Boost 库命名规则复杂(含编译器、线程模型等后缀),模块容易因命名不匹配导致查找失败;
  3. 跨平台兼容性差:不同平台的库命名和安装路径差异大,模块需大量条件判断适配,易出现边缘 case;
  4. 不支持现代 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 配置文件即可。

相关链接


网站公告

今日签到

点亮在社区的每一天
去签到