CMake find_package 不处理多重配置

CMake find_package not handling multi-configurations

我们使用 Jenkins 2.60.2 和 CMake 3.9.1 来自动化我们的构建系统。这一切都适用于多个版本的构建工具、体系结构和 debug/release 目标(如果所有配置都已构建和安装,那么 DebugRelease).

A Debug-only 配置使用 find_package() 通常会忽略 CMAKE_BUILD_TYPE 发现。在内部,脚本搜索文件和库并将位置存储在变量中。在脚本末尾,扫描变量以查找 _NOTFOUND 字符串,这是在所有引用 paths/hints 中未找到文件或库的结果。因此,如果找不到 Release lib,本质上 find_package() 将失败,并将整个包标记为未正确安装,即使构建只对以下内容感兴趣Debug 目标。

通常 XXXConfig.cmake 文件使用对 find_package_handle_standard_args(.. PATH_TO_LIB) 扫描库路径变量中的 _NOTFOUND 字符串。这些变量通常通过先前调用 find_library(PATH_TO_LIB libname ..) 设置为 _NOTFOUND。有关详细信息,请参阅 CMake 文档。

用户确实可以使用 'debug' 标记调试库并使用 'optimized' 发布库,但这似乎在库发现期间没有帮助,并且仅在链接期间使用。

有人知道如何正确处理吗?

亲切的问候

这是 find_package 经典用法的不幸缺点之一。

请注意 find_package,基于配置文件包,这非常适合解决这个特定问题,但需要对您的构建系统进行一些更改。您将需要所有库的配置脚本(如果库本身也是由 CMake 构建的,CMake 可以为您生成它们;如果不是,这可能会有点麻烦),并且依赖目标将通过导入的目标引用这些库而不是变量(对于那些依赖目标的人来说,这通常会让事情变得更容易)。我强烈建议您采用此作为长期解决方案。

如果由于某种原因您不能这样做,您将不得不修改您的查找脚本。一种常见的技术是分别搜索调试和发布二进制文件,然后将这些调用中的查找库组合到一个变量中(连同 debugoptimized 说明符),然后 that 变量作为 find_package_handle_standard_args 的参数。这样,只要找到两者之一,您的查找脚本就会很高兴,尽管您最终可能无法构建所有可能的配置。或者,您也可以完全跳过对 find_package_handle_standard_args 的调用,并手动实现您自己的逻辑来检测是否找到库。正如您从 manpage for that function 中看到的那样,它主要执行样板文件,并且可以在必要时轻松地替换为更灵活的手写实现。