find_package 的相对路径始终相对于当前 CMakeLists.txt 所在目录;应使用 ${CMAKE_CURRENT_LIST_DIR} 拼接,避免 ./ 或反斜杠;CMAKE_PREFIX_PATH 仅设安装前缀,由 CMake 自动搜索标准子路径。

find_package 指定目录时,相对路径是相对于当前 CMakeLists.txt 文件位置的
不是相对于构建目录(build dir),也不是相对于 CMake 安装路径,而是你调用 find_package() 的那个 CMakeLists.txt 所在目录。这点最容易搞错——很多人把路径写成相对于 build 目录,结果始终找不到。
- 如果
CMakeLists.txt在/src/project/,而你想从同级的deps/mylib/cmake/加载配置,就写:set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../deps/mylib/cmake" ${CMAKE_MODULE_PATH}) -
find_package(MyLib REQUIRED)之后,CMake 会依次在CMAKE_MODULE_PATH各路径下找FindMyLib.cmake;若库自带MyLibConfig.cmake,则会在这些路径下找匹配的mylib-config.cmake或MyLibConfig.cmake - 避免用
./开头——CMake 不解析当前工作目录,./subdir会被当作字面量路径,很可能失效;一律用${CMAKE_CURRENT_LIST_DIR}显式拼接
用 CMAKE_PREFIX_PATH 指向安装根目录时,相对路径必须是相对于该前缀的子路径
当库已安装(比如你手动 make install 到 /opt/mylib),且希望 CMake 在那里找 MyLibConfig.cmake,就得设 CMAKE_PREFIX_PATH。此时“相对路径”概念不适用——你提供的是前缀,CMake 自动在 <pre class="brush:php;toolbar:false;" fix>/lib/cmake/MyLib/</pre>、<pre class="brush:php;toolbar:false;" fix>/share/MyLib/</pre> 等标准子路径里搜索。
- 正确做法:
set(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_LIST_DIR}/../install"),然后find_package(MyLib REQUIRED) - 错误写法:
set(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_LIST_DIR}/../install/lib/cmake/MyLib")——这会导致 CMake 去找<pre class="brush:php;toolbar:false;" fix>/lib/cmake/MyLib/lib/cmake/MyLib/MyLibConfig.cmake</pre>,显然多套了一层 - 如果 Config 文件不在标准路径下(比如在
install/mylib-cfg/),就别走CMAKE_PREFIX_PATH,改用CMAKE_MODULE_PATH+ 显式路径
Windows 下路径分隔符不用转义,但斜杠正反都得小心
CMake 内部统一用正斜杠 / 处理路径,即使在 Windows 上也推荐全用 /。混用 \ 可能触发转义问题(比如 "C:\path\to\config" 中的 \t、\o 被解释为制表符、空字符)。
- 安全写法:
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../3rdparty/zlib/cmake" ${CMAKE_MODULE_PATH}) - 危险写法:
set(CMAKE_MODULE_PATH "C:\dev\zlib\cmake")—— 字符串字面量中反斜杠会逃逸 - 绝对路径建议用
file(TO_CMAKE_PATH "...")标准化,但相对路径直接用/即可,无需额外处理
调试找不到包?先看 CMake 输出里的 find_package 搜索路径列表
加 -DCMAKE_VERBOSE_MAKEFILE=ON 不管用;真正有用的是打开 CMake 的查找日志:在 find_package() 前加 set(CMAKE_FIND_DEBUG_MODE TRUE),它会把所有尝试过的路径、文件、失败原因全打出来。
- 输出里看到类似
Checking prefix: /home/user/project/../deps/foo...,说明路径拼接逻辑没问题;如果压根没出现你预期的路径,八成是CMAKE_MODULE_PATH或CMAKE_PREFIX_PATH没生效 - 注意区分
find_package(XXX NO_MODULE)(只走 Config 模式)和默认行为(先 Module 后 Config),路径查找逻辑不同 - 如果路径没错但 still not found,检查目标文件名是否匹配:CMake 对大小写敏感,
MyLibConfig.cmake≠mylib-config.cmake(Linux/macOS),而 Windows 上虽不敏感,但某些生成器仍严格校验
find_dependency 又去查别的路径,或者 IMPORTED 目标依赖的 INTERFACE_INCLUDE_DIRECTORIES 是硬编码绝对路径——这些藏得深,得一层层 message() 出来看。


















