使用 `find_package()` 排除 cmake 自己的分发模块

Excluding cmake's own distribution modules with `find_package()`

Cmake 包含各种分发模块(即,填充在 cmake 安装的 Modules/ 目录中;例如,/usr/share/cmake-3.5/Modules/FindBoost.cmake)。

这会在开发包含名称与这些分发模块冲突的内部库的代码时带来挑战,因为 find_package(Xyz) 找到分发模块 (/usr/share/cmake-3.5/Modules/FindXyz.cmake) 而不是用户模块 (/home/user/opt/lib/cmake/Xyz-config.cmake).我已经尝试设置 CMAKE_FIND_ROOT_PATHCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY,但无济于事。

如何在评估时强制 cmake 排除它自己的分发模块?find_package()

作为该项目的作者,您可能会发现“遗留”发现脚本(FindXXX.cmake)不合适适合您并且更喜欢使用“现代”config 脚本(XXXConfig.cmakeconfig-xxx.cmake)。在这种情况下,您可以将额外的 CONFIGNO_MODULE 选项传递给 find_package:

find_package(Boost NO_MODULE)

这将阻止 CMake 搜索 FindBoost.cmake 脚本并强制它搜索 BoostConfig.cmake(或 config-boost.cmake)。

如果config脚本找不到NO_MODULECONFIG选项,那么CMake即使对应也会报错发现 脚本存在。

或者,您可以设置 CMAKE_FIND_PACKAGE_PREFER_CONFIG 变量:

set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)

所以 CMake 会首先检查 config 脚本。但是如果缺少这个脚本,那么 CMake 将尝试使用 find script.


作为项目的 user,您可能会发现某些包的 config 脚本比 find 一个...但在这种情况下最好什么都不改变:可能是您正在使用的项目只能与 find 脚本,并且不能与 config 一起使用。 (例如,该项目使用 variables,它们由 find 脚本创建以引用库,但 config脚本通常创建 IMPORTED targets).