对于cmake“include”命令,文件和模块有啥区别?
Posted
技术标签:
【中文标题】对于cmake“include”命令,文件和模块有啥区别?【英文标题】:For the cmake "include" command, what is the difference between a file and a module?对于cmake“include”命令,文件和模块有什么区别? 【发布时间】:2021-10-06 00:32:49 【问题描述】:我使用了一些我不想在每个使用它们的项目中构建的库。一个非常容易理解的例子是 LLVM,它有 78 个静态库。即使在每个 cmakefile 中都有 cmake 代码来查找和导入这些代码也是多余的。
显而易见的解决方案似乎是使用“include”命令,并将相关的 cmake 脚本块分解到 *.cmake 文件中,并设置一个 CMAKE_MODULE_PATH 环境变量。
除非它只是简单地不起作用。 Cmake 没有找到我在 include 命令中指定的文件。
在偶然的情况下,我什至尝试用几种方法在环境变量中指定路径 - 一次使用反斜杠,一次使用正斜杠... - 我每次都重新启动命令提示符并检查环境变量是否存在并正确。
在 cmake 手册中,它有点暗示“文件”与“模块”不同——只有模块获得自动添加扩展和搜索路径处理。但是没有解释有什么区别。我猜想缺少的扩展可能就足够了(与标准模块一样),但显然不是。
在手册中搜索“模块”并没有太大帮助,因为这个词似乎已经超载。例如,模块也是使用 LoadLibrary/dl_open 加载的动态库。
谁能解释一下在这种情况下文件和模块之间有什么区别,以及我如何创建自己的模块以便 cmake include 命令可以找到并使用它?
我在 Windows 上使用 cmake 2.8.1。
编辑
我非常确信这里的问题是不了解 cmake 应该如何工作。我认为我应该做的是写一些find_package
可以使用的东西。
尽管如此,我离回答自己的问题还有一段距离。
【问题讨论】:
【参考方案1】:我相信 CMake 的“模块”只是一个可以与find_package
指令一起使用的文件。也就是说,当您运行 find_package(Module)
时,它会在 MODULE_PATH 中搜索名为 FindModule.cmake
的文件。
也就是说,如果你 include
一个没有扩展名的文件,它也会在你的 MODULE_PATH 中搜索那个 file.cmake
。在我正在处理的 CMake 项目中,我的目录结构与您的建议非常相似。
+ root/
+ CMakeLists.txt
+ cmake/
| + FindMatlab.cmake
| + TestInline.cmake
| + stdint.cmake
+ src/
+ include/
在 CMakeLists.txt 我有:
set (CMAKE_MODULE_PATH "$CMAKE_MODULE_PATH;$CMAKE_CURRENT_SOURCE_DIR/cmake")
find_package (Matlab) # runs FindMatlab.cmake
include(TestInline) # defines a macro:
test_inline (CONFIG_C_INLINE)
include(stdint) # simply executes flat CMake code
也许您的问题是您试图从环境中定义模块路径。相反,尝试简单地将您尝试访问模块/文件的 CMakeList 附加到它内。
【讨论】:
现在回头看那个代码,我注意到我没有附加到CMAKE_MODULE_PATH
;我完全破坏了它。您可能想做更多类似的事情:set (CMAKE_MODULE_PATH "$CMAKE_MODULE_PATH;$CMAKE_CURRENT_SOURCE_DIR/cmake")
我现在没有时间检查,但这看起来不错。谢谢。
我不知道为什么我现在认为该变量是环境变量。我猜是看到我正在寻找的东西,而不是那里的东西。我最近刚刚在 YouTube 上观看了 Google techtalk 视频,其中指出环境变量大多是故意避免的。无论如何 - 接受并感谢。
FindPackage,顾名思义,就是找Gtk、Qt等包,就是你项目所依赖的包。
更好的是:list(APPEND CMAKE_MODULE_PATH "$CMAKE_CURRENT_SOURCE_DIR/cmake")
.【参考方案2】:
在阅读了 CMake include()
命令文档后,我也遇到了同样的问题。它指出:
从给定的文件中加载并运行 CMake 代码。 [...为简洁起见...] 如果指定的是模块而不是文件,则首先在 CMAKE_MODULE_PATH 中搜索名为 .cmake 的文件,然后在 CMake 模块目录中搜索。
这留下了很多关于 CMake 认为模块与文件的解释,因为 CMake 模块毕竟是文件系统上的文件。那么有什么区别呢?
CMake 源代码是我唯一能找到答案的地方。基本上,如果 include()
的参数看起来像绝对路径,CMake 会将其视为文件。这意味着:
CMake 假定任何其他不符合上述条件的都是模块。在这种情况下,它将“.cmake”附加到参数并在 CMAKE_MODULE_PATH 中搜索它。
【讨论】:
【参考方案3】:文件是 CMake 列表文件,例如 CMakeLists.txt。使用以下命令获取
中使用的命令列表cmake --help-command-list
Module 是一个包含 cmake 命令的 cmake 文件 (*.cmake)。
正如 Matt B. 所说,CMAKE_MODULE_PATH 不是 shell 的环境变量,而是 cmake 变量。
将你的模块路径附加到 CMAKE_MODULE_PATH
LIST(APPEND CMAKE_MODULE_PATH $YourPath)
或者,如果您希望首先使用您的模块
LIST(INSERT CMAKE_MODULE_PATH 0 $Yourpath)
【讨论】:
以上是关于对于cmake“include”命令,文件和模块有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章
CMake基础教程(26)find_package搜索包完成库链接和头文件添加(module模式)