【问题标题】:CMake "find_package" command on a package that was not installed is unexpectedly successful未安装的包上的 CMake“find_package”命令意外成功
【发布时间】:2019-02-05 18:56:48
【问题描述】:

我在“CMake Cookbook”中关注chapter-02/recipe-06。此特定示例需要Eigen C++ libraries

我尝试构建示例并得到 Eigen 未找到的错误。

CMake Error at CMakeLists.txt:9 (find_package):
  Could not find a package configuration file provided by "Eigen3" (requested
  version 3.3) with any of the following names:

    Eigen3Config.cmake
    eigen3-config.cmake

  Add the installation prefix of "Eigen3" to CMAKE_PREFIX_PATH or set
  "Eigen3_DIR" to a directory containing one of the above files.  If "Eigen3"
  provides a separate development package or SDK, be sure it has been
  installed.

这是意料之中的,因为我的系统上没有安装该库。

然后我下载了 Eigen 库的“.zip”文件并将其解压缩到我的项目之外的任意位置。我在 Eigen 目录中创建了一个“build”文件夹,并在“build”文件夹中运行 cmake ..(我只运行了 cmake - 我没有构建或安装包。)


在 Eigen 构建目录上运行 CMake 后,我回到“recipe-06”的示例代码,即使 Eigen 从未构建或安装,它也能神奇地找到 Eigen 库并成功构建。

不知何故,只是在 Eigen 项目中运行 CMake 就让 CMake 知道了 Eigen 库的位置。完成此操作后,任何通过 find_package 查找 Eigen3 的项目都会以某种方式定义 ${Eigen3_DIR} 变量并能够找到它。


查看find_package 的 CMake 文档,我没有看到任何解释为什么会这样。 Eigen 不在find_package 搜索的任何典型位置。根据the documentation 看来应该找不到它。

更有趣的是——我将 Eigen 放在我的系统的哪个位置并不重要。我可以把它放在任何地方,它仍然会找到它。

根据我在文档中看到的所有内容,它不应该被找到......但它被找到了。那么问题是如何?为什么会这样?

附加信息:我使用的是 CMake 版本 3.13.3

【问题讨论】:

  • 好吧,在 Eigen 上运行 CMake 会创建 cmake 文件,所以你将它安装在某个地方,你将你的其他 CMake 项目指向它,你会惊讶于它的工作原理?
  • 我没有做任何形式的指点。我只是将 Eigen 代码粘贴到任意位置并在其上运行 CMake。 (我只运行了 cmake 步骤 - 我没有构建或安装它。) Eigen 代码与其他项目完全分开。
  • 对不起,我不明白你在做什么。您是在 Eigen 上还是在您自己的项目上运行 CMake?
  • 我在两者中都独立运行 CMake。它们位于两个完全不同的位置。我的项目对“Eigen”的唯一引用是其 CMakeLists.txt 文件中的 find_package(Eigen3 3.3 REQUIRED CONFIG) 行。我不告诉它在哪里看,所以它会做任何“巫毒魔法”find_package 默认做的事情。
  • 然后您的其他项目指向正确的 Eigen 位置?您是否检查过您没有 CMAKE_MODULE_PATH 或类似的指向 CMake 放置 .cmake 文件的位置?因为否则,这是极不可能的

标签: c++ cmake


【解决方案1】:

XXXConfig.cmake 文件有 2 个“来源”,由 find_package() 调用内部使用。

通常,XXXConfig.cmake 文件是在项目安装时生成的,该文件包含有关已安装库和头文件的信息。

但 CMake 还提供了一个export() 命令,允许导出构建树

export(PACKAGE <name>)

将当前构建目录存储在包<name> 的CMake 用户包注册表中。 find_package 命令在搜索包<name> 时可能会考虑目录。

Eigen 的 CMakeLists.txt 使用 export() 命令,因此在为 Eigen 运行 cmake 后,该项目就可以使用 find_package 检测到。

【讨论】:

  • 我没有意识到,但是export 创建了一个 Windows 注册表项,CMake 使用它来查找它。现在说得通了!
猜你喜欢
  • 1970-01-01
  • 2018-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-27
  • 2012-04-14
相关资源
最近更新 更多