組態設定
如果有許多組態選項,透過編譯器旗標傳遞它們會變得非常麻煩。它也會使組態設定難以檢視。為了簡化操作,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
中設定的各自值。您可以多次使用單個 configuration_data
物件,但在將其傳遞給 configure_file
函數後,它會變成不可變的。也就是說,一旦它被使用來產生輸出,set
函數將變得無法使用,嘗試呼叫它會導致錯誤。不可變的 configuration_data
的複本仍然是不可變的。
對於更複雜的組態檔案產生,Meson 提供了第二種形式。要使用它,請在您的組態檔案中放入如下的一行。
#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 的編碼,請參閱標準編碼。
使用字典
自0.49.0 configuration_data()
開始,可以使用可選的字典作為第一個引數。如果提供了字典,則會將每個鍵/值對加入到 configuration_data
中,如同為每個鍵/值對呼叫了 set()
方法一樣。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,
}
)
完整範例
產生和使用組態檔案需要以下步驟
- 產生檔案
- 為包含該檔案的目錄建立一個 include 目錄物件
- 在目標中使用它
我們將使用傳統的方法在頂層目錄中產生標頭檔。常用的名稱是 config.h
,但我們將使用唯一的名稱。這可以避免在建置具有多個子專案的專案時意外包含錯誤標頭檔的問題。
在頂層,我們產生檔案
conf_data = configuration_data()
# Set data
configure_file(input : 'projconfig.h.in',
output : 'projconfig.h',
configuration : conf_data)
隨後立即產生 include 物件。
configuration_inc = include_directories('.')
最後,我們在任何子目錄中的目標中指定它。
executable(..., include_directories : configuration_inc)
現在,此目標中的任何原始程式檔都可以像這樣包含組態標頭
#include<projconfig.h>
搜尋結果如下