概述
在Linux
開發時常常使用Boost
庫,若項目使用CMake
進行組織管理和編譯,需要掌握在CMake
中實現Boost
庫的引用的基本語法。本片博客結合自己在實際使用過程中的經驗進行總結,以期回顧和進行階段總結。
CMakeLists.txt編寫
find_package
通過調用find_package
可以找到頭文件和所需要的庫文件或者是一個CMake
打包配置文件。
find_package(Boost
[version] [EXACT] # 可選項,最小版本或者確切所需版本
[REQUIRED] # 可選項,如果找不到所需庫,報錯
[COMPONENTS <libs>...] # 所需的庫名稱,比如說. "date_time" 代表 "libboost_date_time"
)
示例
find_package(Boost 1.62.0 REQUIRED
COMPONENTS system filesystem thread)
運行完後可以得到很多變量,下面列了一些主要的。
Boost_FOUND - 如果找到了所需的庫就設爲true
Boost_INCLUDE_DIRS - Boost頭文件搜索路徑
Boost_LIBRARY_DIRS - Boost庫的鏈接路徑
Boost_LIBRARIES - Boost庫名,用於鏈接到目標程序
Boost_VERSION - 從boost/version.hpp文件獲取的版本號
Boost_LIB_VERSION - 某個庫的版本
搜索路徑設置
若Boost
庫是自定義安裝路徑,可以在搜索package之前,通過設置一些變量來幫助boost
庫的查找。
BOOST_ROOT - 首選的Boost安裝路徑
BOOST_INCLUDEDIR - 首選的頭文件搜索路徑 e.g. <prefix>/include
BOOST_LIBRARYDIR - 首選的庫文件搜索路徑 e.g. <prefix>/lib
Boost_NO_SYSTEM_PATHS - 默認是OFF. 如果開啓了,則不會搜索用戶指定路徑之外的路徑
用例
假如目標程序foo需要鏈接Boost庫regex和system,編寫如下的CMakeLists文件
# CMakeLists.txt
project(tutorial-0)
cmake_minimum_required(VERSION 3.7)
set(CMAKE_CXX_STANDARD 14)
set(BOOST_ROOT /usr/local/install/boost_1_62_0) // 設置boost庫搜索路徑
set(Boost_NO_SYSTEM_PATHS ON) // 只搜索上語句設置的搜索路徑
find_package(Boost COMPONENTS regex system REQUIRED)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
MESSAGE( STATUS "Boost_INCLUDE_DIRS = ${Boost_INCLUDE_DIRS}.")
MESSAGE( STATUS "Boost_LIBRARIES = ${Boost_LIBRARIES}.")
MESSAGE( STATUS "Boost_LIB_VERSION = ${Boost_LIB_VERSION}.")
add_executable(foo foo.cpp)
target_link_libraries (foo ${Boost_LIBRARIES})
endif()
- 通過設置BOOST_ROOT來設置首選的搜索路徑
- 通過MESSAGE函數把查找的結果都打印了出來
-- Boost_INCLUDE_DIRS = /usr/local/install/boost_1_62_0/include.
-- Boost_LIBRARIES = /usr/local/install/boost_1_62_0/lib/libboost_regex.so;/usr/local/install/boost_1_62_0/lib/libboost_system.so.
-- Boost_LIB_VERSION = 1_62.
Boost動態庫鏈接
若項目包含多個子模塊,且子模塊只用到頂層模塊find_package
找到的部分庫,則可以使用下述語句實現只鏈接子模塊所需要的Boost
動態庫
target_link_libraries(foo Boost::regex) // 只使用regex
Boost頭文件庫鏈接
在Boost
庫中有部分庫只用頭文件實現,並沒有相應的動態庫,若使用這部分庫可以通過以下語句實現:
target_link_libraries(foo Boost::boost)
or
target_include_directories(${Boost_INCLUDE_DIRS})