【问题标题】:CMake find_package not handling multi-configurationsCMake find_package 不处理多配置
【发布时间】:2018-02-05 20:13:25
【问题描述】:

我们正在使用 Jenkins 2.60.2 和 CMake 3.9.1 来自动化我们的构建系统。这一切都适用于多个版本的构建工具、架构和调试/发布目标(如果所有配置都已构建和安装,那么 Debug 和 Release)。

使用find_package() 的调试 配置通常会在发现时忽略CMAKE_BUILD_TYPE。脚本在内部搜索文件和库并将位置存储在变量中。在脚本结束时,会扫描变量中的 _NOTFOUND 字符串,这是在所有参考路径/提示中都没有找到文件或库的结果。因此,如果找不到 Release 库,基本上 find_package() 将失败,并将整个包标记为未正确安装,即使构建仅对 Debug 严格感兴趣em>目标。

XXXConfig.cmake 文件通常使用对 find_package_handle_standard_args(.. PATH_TO_LIB) 的调用来扫描路径变量中的 _NOTFOUND 字符串以图书馆。这些变量通常通过较早调用 find_library(PATH_TO_LIB libname ..) 设置为 _NOTFOUND。有关更多信息,请参阅 CMake 文档。

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

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

亲切的问候

【问题讨论】:

    标签: c++ jenkins cmake multi-configuration


    【解决方案1】:

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

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

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

    【讨论】:

    • 我不喜欢第二种方法,因为它要求配置文件为每个依赖项使用特定于配置的变量。这种可能的爆炸式增长是相当没有吸引力的。我们尝试了第一个解决方案,但到目前为止,由于 windows 上缺少 lib/dll 问题,我们未能使目标方法正常工作。
    • @StarShine 我完全同意,第二种方法非常麻烦,我不推荐它。但不幸的事实是,某人 必须管理所有这些可能的状态。在第一种方法中,您可以将大部分内容卸载到 CMake,但只要您使用手写的 find 脚本,您或多或少都会被手工做所有事情所困扰。
    • 感谢您的建议,我已经给出了另一种按目标构建的方法,到目前为止它似乎可以工作(在 Windows 上)。无论如何,我们已经有了每个 lib 设置的配置脚本。我只是想知道(以避免重复的脚本代码)导入库的“假”目标是否可以进入自定义 find_package 脚本?现在我在调用后将它们放在 cmake 项目配置中。
    • 当然,查找脚本可以毫无问题地通过导入的目标公开其结果。例如,CMake 附带的 FindBoost script 最近学会了这样做。
    • 没错,谢谢!您提到要删除手写的 find_package 脚本,但我想知道这对人们有何作用。根据经验,CMake 提供的脚本通常很简单(版本控制、调试/发布、平台..)、不一致且有些幼稚,尤其是跨平台开发。我发现没有比通过重写默认脚本来支持每个目标系统更好的选择,然后将所有内容移交给链接到相关子模块的模型目标以进行导入。我可以假设这种设置很常见吗?
    猜你喜欢
    • 2013-11-12
    • 1970-01-01
    • 2016-01-19
    • 2020-01-07
    • 1970-01-01
    • 2018-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多