假设我的项目CMakeLists.txt
包括foo.cmake
:
include(foo)
Run Code Online (Sandbox Code Playgroud)
在foo.cmake
,我想知道的道路foo.cmake
.
我怎样才能做到这一点?
请注意,CMAKE_CURRENT_LIST_DIR
给出包含的目录CMakeLists.txt
,而不是包含的目录,foo.cmake
因此不是我想要的.
当然,foo.cmake
可能包括几个项目(即几个CMakeLists.txt
文件).
use*_*866 60
人们已经报道了关于CMAKE_CURRENT_LIST_DIR如何表现的看似矛盾的事实.现在我知道混淆的原因:
首先,在我的Linux环境中:
$ cd /path/to/home
$ mkdir cmake-test
$ cd cmake-test
$ mkdir source
$ mkdir source/subdirectory
$ mkdir build
Run Code Online (Sandbox Code Playgroud)
我创建了这两个文件:
$ cat source/CMakeLists.txt
include(subdirectory/foo.cmake)
$ cat source/subdirectory/foo.cmake
message("CMAKE_CURRENT_LIST_DIR is ${CMAKE_CURRENT_LIST_DIR}")
Run Code Online (Sandbox Code Playgroud)
根据弗雷泽和罗伯特戴利的报告,CMake工作:
$ cd build
$ cmake ../source
CMAKE_CURRENT_LIST_DIR is /path/to/home/cmake-test/source/subdirectory
[...]
Run Code Online (Sandbox Code Playgroud)
但是,我向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()
Run Code Online (Sandbox Code Playgroud)
然后:
$ 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
[...]
Run Code Online (Sandbox Code Playgroud)
因此,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()
Run Code Online (Sandbox Code Playgroud)
之后我得到了我正在寻找的行为:
$ cmake ../source
DIR_OF_FOO_CMAKE in bar() is /path/to/home/cmake-test/source/subdirectory
[...]
Run Code Online (Sandbox Code Playgroud)
在 CMake 3.17 中,您有一个名为的新变量可用CMAKE_CURRENT_FUNCTION_LIST_DIR
,它可以在函数内部使用。它在函数定义之外是未定义的。
function(foo)
configure_file(
"${CMAKE_CURRENT_FUNCTION_LIST_DIR}/some.template.in"
some.output
)
endfunction()
Run Code Online (Sandbox Code Playgroud)
在 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()
Run Code Online (Sandbox Code Playgroud)
当前正在处理的列表文件的完整目录.
当CMake处理项目中的列表文件时,该变量将始终设置为当前正在处理的列表文件(CMAKE_CURRENT_LIST_FILE)所在的目录.该值具有动态范围.当CMake开始处理源文件中的命令时,它将此变量设置为此文件所在的目录.当CMake完成从文件处理命令时,它将恢复先前的值.因此,宏或函数内部变量的值是调用调用堆栈上最底部条目的文件的目录,而不是包含宏或函数定义的文件的目录.
我有以下结构:
C:\Work\cmake-test\CMakeLists.txt
C:\Work\cmake-test\subfolder\test.cmake
Run Code Online (Sandbox Code Playgroud)
在我的CMakeLists.txt
:
include( subfolder/test.cmake )
Run Code Online (Sandbox Code Playgroud)
在我的test.cmake
:
message( "Current dir: ${CMAKE_CURRENT_LIST_DIR}" )
Run Code Online (Sandbox Code Playgroud)
我从CMake运行时得到的结果C:\Work\cmake-test
是:
当前目录:C:/ Work/cmake-test /子文件夹