回答:
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()
コマンドlist()
コマンドまず、「通常の変数」と、そのスコープについて知っておく必要のあるものがあります。
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
とaを持っていdocstring
ます。通常はGUIを使用しないためset(... CACHE INTERNAL "")
、グローバル値と永続値を設定するために使用します。
ので、予めご了承くださいINTERNAL
キャッシュ変数の型が意味するものではありませんFORCE
CMakeスクリプトでは、set(... CACHE ... FORCE)
構文を使用する場合にのみ、既存のキャッシュエントリを変更できます。この動作は、たとえばCMake自体によって使用されます。これは、通常はキャッシュエントリ自体を強制しないため、別の値で事前定義できるためです。
cmake -D var:type=value
、cmake -D var=value
またはを使用して、キャッシュにエントリを設定できますcmake -C CMakeInitialCache.cmake
。unset(... CACHE)
。キャッシュはグローバルであり、CMakeスクリプトの実質的にどこにでも設定できます。ただし、キャッシュ変数を使用する場所については、2度考えることをお勧めします(これらはグローバルであり、永続的です)。通常、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()
呼び出しで設定されます。したがって、これらのコマンドを使用する前に、いくつかの変数を設定することが重要になる場合があります。デバッグ変数のみが役立つ場合があります。以下が役立ちます。
printf
を使用して、古いデバッグスタイルを使用するだけmessage()
です。また、CMake自体に付属するすぐに使用できるモジュールがいくつかあります:CMakePrintHelpers.cmake、CMakePrintSystemInformation.cmakeCMakeCache.txt
、あなたのバイナリ出力ディレクトリ内のファイル。このファイルは、make環境の実際の生成が失敗した場合にも生成されます。cmake --trace ...
CMakeの完全な解析プロセスを確認するために呼び出します。大量の出力が生成されるため、これは最後の予備です。$ENV{...}
を読み書きできset(ENV{...} ...)
ます$<...>
は、CMakeのジェネレーターがmake環境を作成するときにのみ評価されます(パーサーによって「インプレース」で置き換えられる通常の変数との比較)。${${...}}
て、変数に変数名を付け、その内容を参照できます。if()
コマンドを参照)
if(MyVariable)
あなたが直接、真/偽の(囲んでいるため、ここでは不要のための変数を確認することができます${...}
)1
、ON
、YES
、TRUE
、Y
、またはゼロ以外の数値。0
、OFF
、NO
、FALSE
、N
、IGNORE
、NOTFOUND
、空の文字列、または接尾辞で終了します-NOTFOUND
。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")
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
これはfalseです。 if("MSVC" STREQUAL "1")
if(MSVC)
cmake_policy(SET CMP0054 NEW)
「if()
引用符で囲まれていない場合、引数を変数またはキーワードとしてのみ解釈する」に設定することをお勧めします。option()
コマンド
ON
または依存関係のみのOFF
ような特別な処理が可能ですoption
とset
コマンド。与えられる値option
は、実際には「初期値」(最初の構成ステップ中に一度キャッシュに転送される)のみであり、その後CMakeのGUIを介してユーザーが変更することを意図しています。${MyString}
と、「if given arguments ...」のような一連のエラーが発生します。たとえば、「if given arguments」の後にパラント、「NOT」、「EQUALS」などが続きます。
if (MyString ...)
(コードが警告を発している場合)ただ実行することです。
すばやく簡単に始めるための基本的な例をいくつか示します。
変数を設定:
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}")
if ("${MyString}" ...)
と警告が表示されますPolicy CMP0054 is not set: Only interpret if() arguments as variables or keywords when unquoted
。たとえば、ビルド367を参照してください。何か案は?