56

私のプロジェクトのインクルードを仮定しCMakeLists.txtますfoo.cmake:

include(foo)

foo.cmake、 のパスが知りたいですfoo.cmake
どうやってやるの?

included のディレクトリではなく、includedCMAKE_CURRENT_LIST_DIRのディレクトリを与えるため、私が望むものではないことに注意してください。CMakeLists.txtfoo.cmake

もちろん、foo.cmake複数のプロジェクト (つまり、複数のCMakeLists.txtファイル) に含まれる場合があります。

4

4 に答える 4

81

CMAKE_CURRENT_LIST_DIR がどのように動作するかについて、一見矛盾した事実が報告されています。今、私は混乱の理由を知っています:

まず、私の Linux 環境で:

$ cd /path/to/home  
$ mkdir cmake-test  
$ cd cmake-test  
$ mkdir source  
$ mkdir source/subdirectory  
$ mkdir build  

次の 2 つのファイルを作成します。

$ 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  
[...]  

ただし、CMakeLists.txt から呼び出す関数を foo.cmake に追加します。

$ 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 のディレクトリにアクセスするための 1 つの解決策を次に示します。

$ 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  
[...]  
于 2012-10-12T07:53:41.257 に答える
9

参照CMAKE_CURRENT_LIST_DIR:

現在処理中のリストファイルの完全なディレクトリ。

CMake がプロジェクト内のリストファイルを処理するとき、この変数は常に、現在処理中のリストファイル (CMAKE_CURRENT_LIST_FILE) があるディレクトリに設定されます。値には動的スコープがあります。CMake がソース ファイル内のコマンドの処理を開始すると、この変数がこのファイルが置かれているディレクトリに設定されます。CMake がファイルからのコマンドの処理を終了すると、以前の値が復元されます。したがって、マクロまたは関数内の変数の値は、マクロまたは関数の定義を含むファイルのディレクトリではなく、コール スタックの一番下のエントリを呼び出すファイルのディレクトリです。

私は次の構造を持っています:

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}" )

CMake を実行したときに得られる結果C:\Work\cmake-testは次のとおりです。

現在のディレクトリ: C:/Work/cmake-test/サブフォルダー

于 2012-10-10T19:40:17.090 に答える
9

CMake 3.17 では、関数内で使用できるという新しい変数が利用可能になりました。CMAKE_CURRENT_FUNCTION_LIST_DIR関数定義の外では未定義です。

function(foo)
  configure_file(
    "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/some.template.in"
    some.output
  )
endfunction()

CMake 3.17 より前では、CMake のドキュメントから抜粋した次の回避策でCMAKE_CURRENT_FUNCTION_LIST_DIR機能を近似する必要があります。CMAKE_CURRENT_LIST_DIR

set(_THIS_MODULE_BASE_DIR "${CMAKE_CURRENT_LIST_DIR}")

function(foo)
  configure_file(
    "${_THIS_MODULE_BASE_DIR}/some.template.in"
    some.output
  )
endfunction()
于 2020-05-16T14:32:22.450 に答える
2

このinclude()コマンドは、最初にモジュールを検索し${CMAKE_MODULE_PATH}、次に CMake Modulesdir で検索します。

したがって、ファイルの存在を確認するだけで済みますif(EXISTS ${CMAKE_MODULE_PATH}/foo.cmake)if(EXISTS ${CMAKE_ROOT}/Modules/foo.cmake).

于 2012-10-09T14:47:06.007 に答える