コンフィギュレーション
コンフィギュレーションオプションが複数ある場合、コンパイラフラグを介してそれらを渡すのは非常に負担になります。また、コンフィギュレーション設定の検査も難しくなります。Mesonはコンフィギュレーションファイルの生成をサポートして、作業を容易にします。この機能はCMakeなどの他のビルドシステムで見つかる機能に似ています。
次のMesonスニペットがあるとします。
conf_data = configuration_data()
conf_data.set('version', '1.2.3')
configure_file(input : 'config.h.in',
output : 'config.h',
configuration : conf_data)
そして、config.h.in
の内容は次のようになります。
#define VERSION_STR "@version@"
Mesonはその後、対応するビルドディレクトリに次の内容のconfig.h
というファイルを作成します。
#define VERSION_STR "1.2.3"
より具体的には、Mesonは@varname@
タイプのすべての文字列を見つけて、それらをconf_data
で設定されたそれぞれの値に置き換えます。1つのconfiguration_data
オブジェクトを好きな回数使用できますが、configure_file
関数に渡されると変更不能になります。つまり、一度使用して出力を生成すると、set
関数は使用できなくなり、呼び出すとエラーが発生します。変更不可能なconfiguration_data
のコピーも変更不可能です。
より複雑なコンフィギュレーションファイルの生成の場合、Mesonは2番目のフォームを提供します。それを使用するには、コンフィギュレーションファイルに次のような行を入れます。
#mesondefine TOKEN
行われる置換は、TOKENの値とタイプによって異なります。
#define TOKEN // If TOKEN is set to boolean true.
#undef TOKEN // If TOKEN is set to boolean false.
#define TOKEN 4 // If TOKEN is set to an integer or string value.
/* undef TOKEN */ // If TOKEN has not been set to any value.
C文字列を定義する場合は、次のように引用する必要があることに注意してください。
conf_data.set('TOKEN', '"value"')
これは非常に一般的な操作であるため、Mesonは便利なメソッドを提供します。
plain_var = 'value'
conf_data.set_quoted('TOKEN', plain_var) # becomes #define TOKEN "value"
Mesonではブール値がありますが、C/C++トークンを0または1として定義する必要があります。Mesonはこのユースケースに便利な関数を提供します。
conf_data.set10(token, boolean_value)
# The line above is equivalent to this:
if boolean_value
conf_data.set(token, 1)
else
conf_data.set(token, 0)
endif
入力ファイルなしで構成する
入力ファイルが定義されていない場合、Mesonはコンフィギュレーションデータオブジェクト内のすべてのエントリを持つヘッダーファイルを作成します。置換は、#mesondefine
エントリを生成する場合と同じです。
conf_data.set('FOO', '"string"') => #define FOO "string"
conf_data.set('FOO', 'a_token') => #define FOO a_token
conf_data.set('FOO', true) => #define FOO
conf_data.set('FOO', false) => #undef FOO
conf_data.set('FOO', 1) => #define FOO 1
conf_data.set('FOO', 0) => #define FOO 0
このモードでは、生成されたファイルが自己ドキュメントになるように、値の前に配置されるコメントも指定できます。
conf_data.set('BAR', true, description : 'Set BAR if it is available')
結果は次のようになります。
/* Set BAR if it is available */
#define BAR
ファイルエンコードの処理
ファイルを構成するためのデフォルトのMesonファイルエンコードはutf-8です。utf-8でエンコードされていないファイルを構成する必要がある場合、encoding
キーワードを使用すると、使用するファイルエンコードを指定できます。ただし、可能な限りutf-8以外のファイルをutf-8に変換することを強く推奨します。サポートされているファイルエンコードはpython3のものです。 standard-encodingsを参照してください。
辞書の使用
0.49.0 以降、configuration_data()
は最初の引数としてオプションのディクショナリを取ります。提供された場合、各キーと値のペアは、各ペアに対して set()
メソッドが呼び出されたかのように configuration_data
に追加されます。 configure_file()
の configuration
kwarg も configuration_data オブジェクトではなくディクショナリを受け入れます。
例
cdata = configuration_data({
'STRING' : '"foo"',
'INT' : 42,
'DEFINED' : true,
'UNDEFINED' : false,
})
configure_file(output : 'config1.h',
configuration : cdata,
)
configure_file(output : 'config2.h',
configuration : {
'STRING' : '"foo"',
'INT' : 42,
'DEFINED' : true,
'UNDEFINED' : false,
}
)
完全な例
構成ファイルの生成と使用には、次の手順が必要です
- ファイルの生成
- ファイルのあるディレクトリ用のインクルードディレクトリオブジェクトを作成
- ターゲットでそれを使用
上位ディレクトリにヘッダーファイルを作成する従来の手法を使用します。よく使われる名前は config.h
ですが、一意の名前を使用します。これにより、多くのサブプロジェクトを持つプロジェクトを構築する際に間違ったヘッダーファイルを誤ってインクルードするという問題を回避します。
最上位レベルでファイルを生成します
conf_data = configuration_data()
# Set data
configure_file(input : 'projconfig.h.in',
output : 'projconfig.h',
configuration : conf_data)
直後にインクルードオブジェクトを作成します
configuration_inc = include_directories('.')
最後に、どのサブディレクトリにも存在できるターゲット内でこれを指定します。
executable(..., include_directories : configuration_inc)
これで、このターゲット内のソースファイルはすべて次のように構成ヘッダーを含めることができます
#include<projconfig.h>
検索結果は次のとおりです