在CMake中,如何找到包含文件的目录?

use*_*866 39 file cmake

假设我的项目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)

  • "_在根CMakeLists.txt文件中输出你的条形函数_"嗯......正如我在第一篇文章中所写的那样:"_当然,foo.cmake可能包含在几个项目中_"你是否建议应该复制bar()因为碰巧需要多少(根)CMakeLists.txt?! (3认同)

use*_*610 8

在 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)


voi*_*ter 6

CMAKE_CURRENT_LIST_DIR:

当前正在处理的列表文件的完整目录.

当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 /子文件夹

  • 仅当您直接在.cmake中访问它时,此方法才有效,如果您在函数或宏中访问变量,则该方法无效。 (3认同)
  • 在这种情况下,“CMAKE_CURRENT_LIST_DIR”没有任何帮助。 (2认同)