c++如何用CMake链接第三方库 c++ find_package用法【必看】

7次阅读

CMake链接第三方库应优先使用find_package查找已安装库并链接imported target。它按CMAKE_PREFIX_PATH、系统路径顺序查找Config.cmake或Find*.cmake,成功后定义_FOUND、_INCLUDE_DIRS、_LIBRARIES等变量,并推荐target_link_libraries(myapp private Package::component)方式链接。

c++如何用CMake链接第三方库 c++ find_package用法【必看】

c++ 项目中用 CMake 链接第三方库,核心是让 CMake 找到库的头文件路径、链接库文件,并把它们正确传递给编译器和链接器。find_package 是最常用、最推荐的方式,尤其对已提供 *Config.cmake*-config.cmake 文件(或 Find*.cmake 模块)的库而言。

find_package 的基本用法和查找逻辑

find_package 不是“自动下载安装”,而是“定位已安装的库”。它按固定顺序查找:

  • 先查 CMAKE_PREFIX_PATH 指定的路径下是否有 Config.cmake-config.cmake
  • 再查系统默认路径(如 /usr/local/lib/cmake/xxx//opt/homebrew/lib/cmake/xxx/windows 的 C:/Program Files/xxx/share/xxx/ 等)
  • 若没找到 Config 版本,且没加 NO_MODULE,则尝试加载内置或自定义的 Find.cmake 模块(比如 Findopencv.cmake

成功后,通常会定义:
_FOUND(是否找到)、
_INCLUDE_DIRS_INCLUDE_DIR(头文件路径)、
_LIBRARIES_LIBRARY(要链接的库目标或路径)。

实际写法:以 OpenCV 和 Boost 为例

✅ 正确写法(推荐使用目标式链接,现代 CMake 风格):

立即学习C++免费学习笔记(深入)”;

# 查找 OpenCV(要求 4.5.0+,REQUIred 表示找不到就报错) find_package(OpenCV 4.5 REQUIRED) 

创建可执行文件

add_executable(myapp main.cpp)

直接链接 OpenCV 提供的 imported target(无需手动处理路径和依赖)

target_link_libraries(myapp PRIVATE ${OpenCV_LIBS}) # 旧写法(兼容性好)

或更推荐:

target_link_libraries(myapp PRIVATE OpenCV::opencv_core OpenCV::opencv_imgproc)

✅ Boost 示例(组件式查找):

# 查找 Boost,只找需要的组件(thread + system),静态链接 find_package(Boost 1.70 REQUIRED COMPONENTS thread system) 

add_executable(myapp main.cpp) target_link_libraries(myapp PRIVATE Boost::thread Boost::system)

⚠️ 注意:Boost::* 这类 imported target 是 CMake 从 1.70+ 官方推荐方式,比 ${Boost_LIBRARIES} 更安全(自动处理调试/发布、静态/动态、依赖传递)。

找不到库?常见解决办法

  • 确认库已安装:运行 pkg-config --modversion opencv4linux/macOS)或检查安装目录是否存在 *Config.cmake
  • 手动指定路径:用 -DCMAKE_PREFIX_PATH=/path/to/opencv 传给 cmake 命令,或在 CMakeLists.txt 中提前设置:set(CMAKE_PREFIX_PATH "/opt/mylib;/usr/local")
  • 用 find_path + find_library 手动定位(兜底方案,不推荐但有时必须):
find_path(MYLIB_INCLUDE_DIR NAMES mylib.h PATHS /usr/include/mylib /opt/mylib/include) find_library(MYLIB_LIBRARY NAMES mylib PATHS /usr/lib /opt/mylib/lib) 

if(NOT MYLIB_INCLUDE_DIR OR NOT MYLIB_LIBRARY) message(FATAL_ERROR "mylib not found!") endif()

add_library(mylib_imported INTERFACE) target_include_directories(mylib_imported INTERFACE ${MYLIB_INCLUDE_DIR}) target_link_libraries(mylib_imported INTERFACE ${MYLIB_LIBRARY})

进阶技巧:导入自定义库或未提供 Config 的库

如果第三方库只提供 .a/.so/.dll 和头文件(比如某些 SDK),可封装IMPORTED 库:

add_library(thirdparty_lib SHARED IMPORTED) set_target_properties(thirdparty_lib PROPERTIES   IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/lib/libthirdparty.so"   INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_SOURCE_DIR}/include" ) 

add_executable(app main.cpp) target_link_libraries(app PRIVATE thirdparty_lib)

这样既复用 CMake 的依赖管理,又避免硬编码路径。

不复杂但容易忽略:始终优先用 find_package(... REQUIRED) + imported target;手动路径是备选,不是默认方案。

text=ZqhQzanResources