目錄
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_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) # 如果使用靜態運行時庫,則設置為 ONfind_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