次回CMakeを使用するときには、これを自分自身へのリマインダーとして要求しています。それは固執することはなく、そしてGoogleの結果は素晴らしいものではありません。
CMakeで変数を設定および使用するための構文は何ですか?
CMakeスクリプトを書くときには、CMakeの構文と変数の使い方について知っておくべきことがたくさんあります。
set()
を使った文字列:
set(MyString "Some Text")
set(MyStringWithVar "Some other Text: ${MyString}")
set(MyStringWithQuot "Some quote: \"${MyStringWithVar}\"")
あるいはstring()
と一緒に:
string(APPEND MyStringWithContent " ${MyString}")
set()
を使ったリスト
set(MyList "a" "b" "c")
set(MyList ${MyList} "d")
list()
を使えばもっと良いです。
list(APPEND MyList "a" "b" "c")
list(APPEND MyList "d")
ファイル名のリスト
set(MySourcesList "File.name" "File with Space.name")
list(APPEND MySourcesList "File.name" "File with Space.name")
add_excutable(MyExeTarget ${MySourcesList})
set()
コマンドstring()
Commandlist()
コマンドまず、「正規変数」とその範囲について知っておく必要があるものがあります。
CMakeLists.txt
およびそこから呼び出されるすべてのもの(add_subdirectory()
、include()
、macro()
およびfunction()
)から見えます。add_subdirectory()
とfunction()
コマンドは特別なものです、なぜならそれらは彼ら自身の範囲を開くからです。set(...)
はそこに見えているだけであり、それらはそれらが呼ばれたスコープレベル(親スコープと呼ばれる)のすべての通常の変数のコピーを作ります。set(... PARENT_SCOPE)
を使用して、親スコープ内の既存の変数を変更できます。function(xyz _resultVar)
がset(${_resultVar} 1 PARENT_SCOPE)
を設定することがあります。include()
またはmacro()
スクリプトで設定したものはすべて、変数が呼び出される場所の範囲内で直接変数を変更します。次に、「グローバル変数キャッシュ」があります。キャッシュについて知っておくべきこと:
CMakeCache.txt
ファイルに格納されています。キャッシュ内の値は、生成される前に CMakeのGUI アプリケーションで変更できます。したがって、通常の変数と比較して、それらにはtype
とdocstring
があります。私は通常GUIを使用しないので、グローバル値と永続値を設定するためにset(... CACHE INTERNAL "")
を使用します。
INTERNAL
キャッシュ変数型はFORCE
を意味することに注意してください
CMakeスクリプトでは、set(... CACHE ... FORCE)
構文を使用する場合にのみ既存のキャッシュエントリを変更できます。この振る舞いは、例えばCMake自身によるものです。なぜなら、それは通常Cacheエントリ自身を強制するものではなく、それゆえあなたは別の値でそれを事前に定義することができるからです。
cmake -D var:type=value
、ちょうどcmake -D var=value
、またはcmake -C CMakeInitialCache.cmake
の構文でキャッシュ内のエントリを設定できます。unset(... CACHE)
を使用して、キャッシュ内の 設定解除 エントリを作成できます。キャッシュはグローバルであり、あなたはあなたのCMakeスクリプトのどこにでも事実上それらを設定することができます。しかし、キャッシュ変数をどこで使用するかについて二度考えることをお勧めします(それらはグローバルであり、永続的です)。私は通常、set_property(GLOBAL PROPERTY ...)
とset_property(GLOBAL APPEND PROPERTY ...)
の構文を使って、自分の永続的でないグローバル変数を定義します。
落とし穴を避けるためには、変数について次のことを知っておく必要があります。
find_...
コマンドは - 成功した場合 - "呼び出しが再び検索されないように"キャッシュされた変数として結果を書き込みます。set(MyVar a b c)
は"a;b;c"
で、set(MyVar "a b c")
は"a b c"
ですlist()
コマンドを使いますfunctions()
の代わりにmacros()
を使用することをお勧めします。project()
とenable_language()
の呼び出しで設定されます。そのため、これらのコマンドを使用する前にいくつかの変数を設定することが重要になる可能性があります。場合によっては変数のデバッグだけが役に立ちます。次のことが役に立ちます。
message()
コマンドを使用して、古いprintf
デバッグスタイルを使用するだけです。 CMake自体に同梱されているモジュールを使う準備ができているものもあります。 CMakePrintHelpers.cmake 、 CMakePrintSystemInformation.cmakeCMakeCache.txt
ファイルを調べてください。このファイルは、実際のmake環境の生成に失敗した場合でも生成されます。cmake --trace ...
を呼び出してください。それは大量の出力を生成するので、それは最後の準備のようなものです。$ENV{...}
を読み、set(ENV{...} ...)
環境変数を書くことができます。$<...>
はCMakeのジェネレーターがmake環境を書くときにだけ評価されます(パーサーによって "その場で"置き換えられる通常の変数との比較)${${...}}
を使用すると、変数に変数名を付けてその内容を参照できます。if()
コマンドを参照)if(MyVariable)
を使うと、変数のtrue/falseを直接チェックすることができます(ここで囲む${...}
は不要です)。1
、ON
、YES
、TRUE
、Y
、またはゼロ以外の数値であれば真。0
、OFF
、NO
、FALSE
、N
、IGNORE
、NOTFOUND
、または末尾が-NOTFOUND
である場合はfalseです。if(MSVC)
のようなものによく使われますが、この構文のショートカットを知らない人にとっては混乱を招く可能性があります。set(CMAKE_${lang}_COMPILER ...)
if()
コマンドで頭痛の種になる可能性があります。これはCMAKE_CXX_COMPILER_ID
が"MSVC"
で、MSVC
が"1"
である例です:if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
はif("1" STREQUAL "1")
と評価されるため、trueです。if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
はif("MSVC" STREQUAL "1")
と評価されるため、falseです。if(MSVC)
を直接チェックすることです(上記参照)。cmake_policy(SET CMP0054 NEW)
引数を引用符で囲まないときは変数またはキーワードとしてのみ解釈する」ように常にif()
を設定することをお勧めします。option()
コマンドここでは早くて汚い始めるための基本的な例をいくつか紹介します。
変数を設定します。
SET(INSTALL_ETC_DIR "etc")
変数を使う:
SET(INSTALL_ETC_CROND_DIR "${INSTALL_ETC_DIR}/cron.d")
変数を設定します。
SET(PROGRAM_SRCS
program.c
program_utils.c
a_lib.c
b_lib.c
config.c
)
変数を使う:
add_executable(program "${PROGRAM_SRCS}")
FOOが環境変数から取得されている使用法の$ENV{FOO}
。それ以外の場合は${FOO}
として使用します。ここで、FOOは他の変数です。設定には、cmakeでSET(FOO "foo")
を使用します。