【问题标题】:Is it possible to alter CMAKE_MODULE_PATH from CMake commandline?是否可以从 CMake 命令行更改 CMAKE_MODULE_PATH?
【发布时间】:2017-05-11 20:15:28
【问题描述】:

编辑:接受的答案实际上表明通常可以将 CMAKE_MODULE_PATH 设置为任何其他 CMake 变量,例如通过-DCMAKE_MODULE_PATH path CLI 参数。在我的情况下,似乎包含一些调用 set(CMAKE_MODULE_PATH /library_path) 的 CMake 脚本,它会删除所有以前设置为变量的路径。这就是为什么我不能让变量做我想做的事。我会把问题留在这里,以防其他人遇到这种情况。


我正在构建一个使用 Protobuf 库的(第 3 方)项目(但这个问题很笼统)。我的系统在系统范围内安装了比项目兼容的更新版本的 Protobuf。所以我从源代码下载并编译了一个旧版本的 Protobuf。

项目使用CMake,在其CMakeLists.txt中有:

find_package(Protobuf REQUIRED)

但是,它会找到(不兼容的)系统安装。当然,CMake 不知道我自定义的 Protobuf 构建。但是我该怎么说呢?

我在~/usr/share/cmake-3.0/Modules/ 中创建了一个FindProtobuf.cmake 文件,并希望构建过程使用这个文件来查找Protobuf。但是我没有成功强迫 CMake 选择这个而不是系统一个。我认为原因在find_package 的 CMake 文档中非常明显:

该命令有两种搜索包的模式:“模块”模式和“配置”模式。当使用上述简化签名调用命令时,模块模式可用。 CMake 在 CMAKE_MODULE_PATH 中搜索名为 Find.cmake 的文件,然后进行 CMake 安装。如果找到该文件,则由 CMake 读取并处理该文件。 ... 如果没有找到模块并且没有给出 MODULE 选项,则命令进入配置模式。

所以在我成功更改CMAKE_MODULE_PATH 之前,CMake 只会选择安装到默认系统路径的FindProtobuf.cmake,并且永远不会进入我可能会使用CMAKE_PREFIX_PATH 的“配置”模式.

不要编辑 CMakeLists.txt 对我来说很重要,因为它属于我不维护的第 3 方项目。

我尝试过的(都没有成功):

  • 调用CMAKE_MODULE_PATH=~/usr/share/cmake-3.0/Modules cmake ...(环境变量未“转移”到同名的CMake变量)
  • 调用cmake -DCMAKE_MODULE_PATH=~/usr/share/cmake-3.0/Modules ...(不起作用,可能是设计使然?)
  • 调用Protobuf_DIR=path/to/my/protobuf cmake ...(项目不支持这种对Protobuf的覆盖)

不幸的是,在我看来,更改find_package 使用的CMAKE_MODULE_PATH 的唯一方法是从CMakeLists.txt 内部更改它,这正是我想要避免的。

对于如何不碰CMakeLists.txt 并仍然说服find_package 找到我的自定义 Protobuf,您有任何想法/解决方法吗?

作为参考,这个项目的CMake部分是on github。

【问题讨论】:

  • 你使用错误的方式来强制 CMake 使用 protobuf 的非默认安装。您需要提示现有脚本以找到您的 Protobuf 安装,而不是替换 FindProtobuf.cmake 脚本。例如。您可以设置 CMAKE_PREFIX_PATH 变量。有关此类“提示”的更多信息,请参阅问题stackoverflow.com/questions/34795816/…。
  • 谢谢@Tsyvarev,根据您的建议,我说服了项目编译。但是你能指出我的来源解释为什么我想做的事情是错误的吗?
  • 这只是一个通用的方法:如果您可以调整环境以使现有代码工作,那么就这样做而不是修改代码。

标签: cmake


【解决方案1】:

作为对您问题的直接回答,是的,您可以通过运行cmake -DCMAKE_MODULE_PATH=/some/path -S /path/to/src -B /path/to/build 在命令行中设置CMAKE_MODULE_PATH。

但这可能不会做你想做的事;见下文。


您提供的 Bitbucket 链接已失效,但这里有一些建议可能会有所帮助。

  1. 避免编写自己的查找模块,尤其是当上游提供 CMake 配置模块时。
  2. 您可以通过将CMAKE_PREFIX_PATH 或Protobuf_ROOT (v3.12+) 之一设置为 Protobuf 安装根目录,将 CMake 定向到您的自定义 Protobuf 安装。
  3. 您可以通过将CMAKE_FIND_PACKAGE_PREFER_CONFIG 设置为true (v3.15+) 来告诉find_package 首先尝试CONFIG 模式。然后将Protobuf_DIR设置为包含ProtobufConfig.cmake的目录。
  4. 如果失败,您可以手动设置 CMake 自己的 FindProtobuf 模块中记录的变量,此处:https://cmake.org/cmake/help/latest/module/FindProtobuf.html

所有这些变量都可以在配置命令行中使用-D 标志进行设置。

填充 CMake 变量的环境变量很少,我会避免依赖它们。这里有一个详尽的列表:https://cmake.org/cmake/help/latest/manual/cmake-env-variables.7.html。 CMAKE_MODULE_PATH 不在其中。

【讨论】:

  • 我更新了存储库迁移位置的链接。感谢您指出新的 CMake 提供的可能性。不过,假设这个项目是用 3.10 构建的,我会坚持下去。但正如@Tsyvarev 已经建议的那样,CMAKE_PREFIX_PATH 在这里有所帮助。设置 CMAKE_FIND_PACKAGE_PREFER_CONFIG 似乎是一个非常危险的选项,它可能会破坏许多其他代码(预计将使用 Find 模块)。这两个答案都没有提供更改 CMAKE_MODULE_PATH 的方法,这是问题的最终目标,因此我不会将您的答案标记为已接受。
  • 在命令行中使用 -D 设置 CMAKE_MODULE_PATH 确实会改变 CMAKE_MODULE_PATH,句号。除非您的 CMakeLists 中有明确的代码来覆盖您没有向我们展示的缓存变量,否则就是这样。
  • 该变量是否符合您的要求是一个不同的问题。这是XY problem。
  • 哦,你是对的!因此,它必须是调用 set(CMAKE_MODULE_PATH /mypath) 的包含的 CMake 脚本之一,而不考虑变量的先前内容。通过快速搜索,我找不到任何这样的脚本,但它可能以某种方式泄漏......这不是我第一次看到它......
  • 我编辑了这个问题,以便为未来的读者提供一个快速声明,即我的问题很可能是由一些错误的 CMake 脚本造成的。
猜你喜欢
  • 1970-01-01
  • 2012-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-20
  • 2022-11-23
  • 2012-09-21
相关资源
最近更新 更多