【问题标题】:Difference between CMAKE_CURRENT_SOURCE_DIR and CMAKE_CURRENT_LIST_DIRCMAKE_CURRENT_SOURCE_DIR 和 CMAKE_CURRENT_LIST_DIR 之间的区别
【发布时间】:2013-03-17 17:59:03
【问题描述】:

来自维基:

CMAKE_CURRENT_SOURCE_DIR 这是当前处理的CMakeLists.txt所在的目录

CMAKE_CURRENT_LIST_DIR (从 2.8.3 开始)这是当前正在处理的列表文件的目录。

来自文档:

CMAKE_CURRENT_SOURCE_DIR:当前正在处理的源目录的路径。 这是 cmake 当前正在处理的源目录的完整路径。

CMAKE_CURRENT_LIST_DIR:当前正在处理的列表文件的完整目录。 当 CMake 处理项目中的列表文件时,此变量将始终设置为当前正在处理的列表文件 (CMAKE_CURRENT_LIST_FILE) 所在的目录。该值具有动态范围。当 CMake 开始处理源文件中的命令时,它会将此变量设置为该文件所在的目录。当 CMake 完成处理来自文件的命令时,它会恢复以前的值。因此,宏或函数中变量的值是调用堆栈中最底部条目的文件的目录,而不是包含宏或函数定义的文件的目录。

这些变量在什么情况下会有不同的值?

【问题讨论】:

  • 还有它们与简单漂亮的./有何不同?

标签: cmake


【解决方案1】:

变量CMAKE_CURRENT_SOURCE_DIRCMAKE_CURRENT_LIST_DIR 可能引用一个CMake 列表文件的不同目录,该文件包含在include 命令的另一个文件中。例如,如果 CMakeLists.txt 存在于目录 project 中并包含以下指令

include(src/CMakeLists.txt)

然后在处理src/CMakeLists.txtCMAKE_CURRENT_LIST_DIR 将引用project/srcCMAKE_CURRENT_SOURCE_DIR 仍指向外部目录project

CMAKE_CURRENT_LIST_DIR 在您需要定位位于当前正在处理的CMakeLists.txt 文件旁边的资源文件(例如模板文件或批处理脚本)时会派上用场。


注意:当使用add_subdirectory()命令而不是include()时,行为是不同的,当src/CMakeLists.txt被处理时,两个变量都会指向project/src

【讨论】:

  • +1。我只想添加CMAKE_CURRENT_LIST_DIR 随您include() 的每个文件而变化;它不必被称为CMakeLists.txt
  • Good discussion here 了解如何在您的项目中有效地使用 CMAKE_CURRENT_LIST_DIRinclude(...)
  • 很容易混淆,因为CMAKE_CURRENT_SOURCE_DIRCMAKE_SOURCE_DIR 比文档所暗示的更相似。
  • add_subdirectory()?两个变量都指向文件夹吗?
  • @einpoklum 是的,他们是。您可以使用message(STATUS "${CMAKE_CURRENT_LIST_DIR} = ${CMAKE_CURRENT_SOURCE_DIR}") 进行测试。
【解决方案2】:

定义

CMAKE_SOURCE_DIR:包含 CMakeList.txt 文件的最顶层文件夹(源目录)。该值在不同的范围内永远不会改变。

PROJECT_SOURCE_DIR:最近的文件夹,包含 CMakeList.txt 文件,有自己的范围,包含 project() 命令。

CMAKE_CURRENT_SOURCE_DIR:最近的文件夹,其中包含具有自己作用域的 CMakeList.txt 文件。 (文件不需要包含 project() 命令)

CMAKE_CURRENT_LIST_DIR: 包含当前处理的 CMakeList.txt 或 .cmake 文件的文件夹。

我的意思是它自己的范围与范围规则有关。虽然 include(file) 命令没有创建新范围,但 add_subdirectory 正在创建一个影响 PROJECT_SOURCE_DIR 和 CMAKE_CURRENT_SOURCE_DIR 值的新范围。

示例

让项目结构如下:

A/
=> CMakeList.txt
=> B/
   => CMakeList.txt

假设我们通过将消息命令放入子文件夹 B 中的 CMakeList.txt 文件来打印所有 cmake 变量。

  • 如果文件夹A中的CMakeList.txt包含一行include("B/CMakeList.txt"),那么

CMAKE_SOURCE_DIR 将是源目录,即“项目/A 的路径”。

PROJECT_SOURCE_DIR 将是“项目/A 的路径”,因为 include 命令不会创建新范围,并且最近的具有自己的范围并包含项目命令的 CMakeList.txt 文件位于文件夹 A 中。

CMAKE_CURRENT_SOURCE_DIR 将是“项目/A 的路径”,因为 include 命令不会创建新范围,并且最近的具有自己范围的 CMakeList.txt 文件位于文件夹 A 中。

CMAKE_CURRENT_LIST_DIR 将是“项目/A/B 的路径”,因为当前处理的文件在子文件夹 B 中。

  • 如果 CMakeList.txt 包含一行 add_subdirectory("./B"),则

CMAKE_SOURCE_DIR 将是源目录,即“项目路径/A”。

PROJECT_SOURCE_DIR 将是“项目/A/B 的路径”,因为 add_subdirectory 命令创建了一个新范围,并且最近的 CMakeList.txt 具有自己的范围并包含项目命令的文件位于子文件夹 B 中。

CMAKE_CURRENT_SOURCE_DIR 将是“项目/A/B 的路径”,因为 add_subdirectory 命令创建了一个新范围,并且最近的具有自己范围的 CMakeList.txt 文件位于子文件夹 B 中。

CMAKE_CURRENT_LIST_DIR 将是“项目/A/B 的路径”,因为当前处理的文件在子文件夹 B 中。

参考https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/Useful-Variables

【讨论】:

  • 我发现您的回答对解决我的问题非常有用,感谢分享!
  • CMAKE_CURRENT_LIST_DIR 不包含当前的 .cmake。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-25
  • 2020-05-10
  • 2014-09-20
  • 2010-10-28
  • 2015-10-04
  • 2012-08-12
相关资源
最近更新 更多