假设我的项目CMakeLists.txt
包含foo.cmake
:
include(foo)
在foo.cmake
中,我想知道foo.cmake
的路径。
我该怎么做?
请注意,CMAKE_CURRENT_LIST_DIR
会提供包含CMakeLists.txt
的目录,而不是包含foo.cmake
的目录,因此不是我想要的。
当然,几个项目(即几个foo.cmake
文件)可能包含CMakeLists.txt
。
答案 0 :(得分:50)
人们已经报道了关于CMAKE_CURRENT_LIST_DIR如何表现的看似矛盾的事实。现在我知道混淆的原因:
首先,在我的Linux环境中:
$ cd /path/to/home
$ mkdir cmake-test
$ cd cmake-test
$ mkdir source
$ mkdir source/subdirectory
$ mkdir build
我创建了这两个文件:
$ cat source/CMakeLists.txt
include(subdirectory/foo.cmake)
$ cat source/subdirectory/foo.cmake
message("CMAKE_CURRENT_LIST_DIR is ${CMAKE_CURRENT_LIST_DIR}")
CMake按照Fraser和Robert Dailey的报道工作:
$ cd build
$ cmake ../source
CMAKE_CURRENT_LIST_DIR is /path/to/home/cmake-test/source/subdirectory
[...]
但是,我向foo.cmake添加了一个函数,我从CMakeLists.txt调用它:
$ cat ../source/subdirectory/foo.cmake
message("CMAKE_CURRENT_LIST_DIR is ${CMAKE_CURRENT_LIST_DIR}")
function(bar)
message("CMAKE_CURRENT_LIST_DIR in bar() is ${CMAKE_CURRENT_LIST_DIR}")
endfunction()
$ cat ../source/CMakeLists.txt
include(subdirectory/foo.cmake)
bar()
然后:
$ cmake ../source
CMAKE_CURRENT_LIST_DIR is /path/to/home/cmake-test/source/subdirectory
CMAKE_CURRENT_LIST_DIR in bar() is /path/to/home/cmake-test/source
[...]
因此,foo.cmake中CMAKE_CURRENT_LIST_DIR的值在包含foo.cmake时和调用bar()时不一样。这是根据CMAKE_CURRENT_LIST_DIR的规范。
以下是从bar()中访问foo.cmake目录的一种可能解决方案:
$ cat ../source/subdirectory/foo.cmake
set(DIR_OF_FOO_CMAKE ${CMAKE_CURRENT_LIST_DIR})
function(bar)
message("DIR_OF_FOO_CMAKE in bar() is ${DIR_OF_FOO_CMAKE}")
endfunction()
之后我得到了我正在寻找的行为:
$ cmake ../source
DIR_OF_FOO_CMAKE in bar() is /path/to/home/cmake-test/source/subdirectory
[...]
答案 1 :(得分:6)
当前正在处理的列表文件的完整目录。
当CMake处理项目中的listfile时,这个变量会 始终设置为当前listfile的目录 正在处理(CMAKE_CURRENT_LIST_FILE)。价值有 动态范围。当CMake开始处理源文件中的命令时 它将此变量设置为此文件所在的目录。 当CMake完成从文件处理命令时,它将恢复 以前的价值。因此宏或内部变量的值 function是调用最底部条目的文件的目录 在调用堆栈上,而不是包含宏的文件的目录 或功能定义。
我有以下结构:
C:\Work\cmake-test\CMakeLists.txt
C:\Work\cmake-test\subfolder\test.cmake
在我的CMakeLists.txt
:
include( subfolder/test.cmake )
在我的test.cmake
:
message( "Current dir: ${CMAKE_CURRENT_LIST_DIR}" )
从C:\Work\cmake-test
运行CMake时得到的结果是:
当前目录:C:/ Work / cmake-test /子文件夹
答案 2 :(得分:3)
在CMake 3.17中,您have a new variable可用,称为CMAKE_CURRENT_FUNCTION_LIST_DIR
,可在函数内部使用。在函数定义之外未定义。
function(foo)
configure_file(
"${CMAKE_CURRENT_FUNCTION_LIST_DIR}/some.template.in"
some.output
)
endfunction()
在CMake 3.17之前,CMAKE_CURRENT_FUNCTION_LIST_DIR
功能必须通过以下变通方法与CMAKE_CURRENT_LIST_DIR
近似,该变通方法取自CMake文档:
set(_THIS_MODULE_BASE_DIR "${CMAKE_CURRENT_LIST_DIR}")
function(foo)
configure_file(
"${_THIS_MODULE_BASE_DIR}/some.template.in"
some.output
)
endfunction()
答案 3 :(得分:1)
include()
命令首先在${CMAKE_MODULE_PATH}
中搜索模块,然后在CMake Modules
目录中搜索模块。
因此,您只需使用if(EXISTS ${CMAKE_MODULE_PATH}/foo.cmake)
和if(EXISTS ${CMAKE_ROOT}/Modules/foo.cmake)
检查文件状态。