find_package通过两种模式指定自定义路径:配置模式设<PackageName>_DIR(指向Config.cmake所在目录)或CMAKE_PREFIX_PATH(指向库根目录,需配合NO_DEFAULT_PATH避免系统路径干扰);模块模式则通过list(APPEND CMAKE_MODULE_PATH)添加Find<Package>.cmake路径并显式使用MODULE参数。

find_package 怎么指定自定义库安装路径?
不能直接让 find_package 去“扫描”某个目录找库,它只认两类文件:Find<packagename>.cmake</packagename>(模块模式)或 <packagename>Config.cmake</packagename>(配置模式)。你得把路径告诉它——但方式取决于你用哪种模式。
用配置模式时:设 <packagename>_DIR</packagename> 或 CMAKE_PREFIX_PATH
这是现代库(如 OpenCV、yaml-cpp)推荐的方式。CMake 会从你指定的根目录出发,在 lib/cmake/<packagename>/</packagename> 或 share/cmake/<packagename>/</packagename> 下找 <packagename>Config.cmake</packagename>。
- 最常用的是设置
<packagename>_DIR</packagename>变量,值为包含Config.cmake的**完整目录路径**(不是库安装根目录):set(yaml-cpp_DIR "/path/to/yaml-cpp-1.12/lib/cmake/yaml-cpp")
- 如果 Config 文件在标准子路径下(比如
lib/cmake/xxx/xxxConfig.cmake),也可以设根目录:set(CMAKE_PREFIX_PATH "/path/to/mylib/install")
,然后调用find_package(yaml-cpp REQUIRED)即可 - 必须加
NO_DEFAULT_PATH才能屏蔽系统路径干扰,否则 CMake 可能优先找到系统里装的旧版本:find_package(yaml-cpp 1.12 REQUIRED NO_DEFAULT_PATH)
用模块模式时:往 CMAKE_MODULE_PATH 加自定义 FindXXX.cmake 路径
适用于没有提供 Config 文件的老库,或你自己写的轻量封装。CMake 会按顺序在 CMAKE_MODULE_PATH 列表里找 Find<packagename>.cmake</packagename>。
- 先确保你写了
FindMyLib.cmake,放在项目某处(比如cmake/modules/) - 在
CMakeLists.txt开头添加搜索路径:list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/modules") - 显式启用模块模式,避免 CMake 自动 fallback 到配置模式:
find_package(MyLib MODULE REQUIRED)
- 注意:
MODULE参数必须写,否则 CMake 默认先走配置模式,找不到再退到模块模式,容易误报错
常见坑:路径拼错、权限问题、缓存残留
很多失败不是逻辑错,而是环境细节没处理好:
-
<packagename>_DIR</packagename>必须精确指向含Config.cmake的目录,多一级或少一级都会失败;例如/opt/mylib/lib/cmake/mylib对,/opt/mylib错 - Linux 下若库装在非 root 目录(如
~/local),确保路径可读,且 CMake 进程有权限访问 - CMake 缓存会记住上次查找结果,改了路径后不清理缓存(
CMakeCache.txt)或不删 build 目录,find_package仍会返回旧结果 - Windows 上路径分隔符用正斜杠
/更稳妥,CMake 内部统一处理,避免反斜杠转义问题
真正麻烦的从来不是写哪行命令,而是搞清你手里的库到底提供的是 Config 文件还是靠 Find 模块驱动——看它安装后有没有 *Config.cmake,比猜参数靠谱得多。


















