Fuchsia 建構系統會使用多個「資訊清單」檔案,指出如何將檔案安裝到容器中,例如將檔案複製到 Fuchsia 套件封存檔,或複製到
本頁說明這些檔案格式,這些格式會用於建構作業,但不應在建構作業外部公開。
請注意,產生及處理這些檔案的 .gni
檔案和指令碼位於 Fuchsia 來源樹狀結構中的 //build/dist/
下方。
FINI (Fuchsia INI) 資訊清單檔案格式
在建構期間叫用的多個工具會使用 FINI 資訊清單格式:產生 Fuchsia 套件封存檔的 ffx package build
指令,或產生 ZBI 映像檔的 zbi
工具。
語法非常簡單:每行文字看起來都像 <destination>=<source>
,其中 <destination>
是相對於最終容器頂端的目標檔案路徑,而 <source>
是相對於目前目錄 (在大多數情況下為建構目錄) 的來源內容檔案路徑。
請注意,目的地路徑「不應」以目錄分隔符號開頭,且 FINI 檔案不支援 Windows INI 檔案格式的註解、區段和其他功能。
例如:
bin/foo=foo
lib/ld.so.1=user.libc_x64/libc.so
meta/foo.cm=obj/src/foo/cml/foo_component/foo.cm
meta/package=gen/src/foo/foo_meta_package.txt
發布資訊清單檔案格式
這個 JSON 檔案必須包含清單,其中每個項目都是 JSON 物件,做為單一「發布」項目,說明如何將一個來源檔案安裝到容器中,並為產生該檔案的目標提供 GN 標籤。這裡使用的結構定義如下:
source
:來源路徑字串 (必要)。destination
:目的地路徑字串 (必要)。label
:GN 標籤,指向產生來源檔案的目標。僅適用於偵錯 (選用)。
範例:
{
"destination": "bin/foo",
"source": "x64-asan/foo",
"label": "//some/dir:foo"
}
雖然概念上與 FINI 資訊清單類似,但發布資訊清單提供的資訊 (GN 標籤) 稍多一些,因此在發生錯誤時,非常適合用於偵錯。並且會由不同的工具組合使用。
部分發布資訊清單檔案格式
FINI 和發布資訊清單是由處理名為「部分發布資訊清單」的中繼檔案產生。
系統會透過 GN 中繼資料收集,針對相同依附元件樹狀結構中的目標產生部分資訊清單。這是一個包含物件「項目」清單的 JSON 檔案。
數種項目類型用於說明建構和安裝需求的各個層面。這些資訊都會合併至 FINI 或發布資訊清單。
//build/dist/distribution_manifest.py
中的 Python 模組包含用來處理這些檔案的函式。
一般項目
這些項目與用於發布資訊清單的結構定義相符。這些檔案對應至簡單的原始碼檔案,可安裝至指定的目標路徑。
source
:來源路徑字串 (必要)。destination
:目的地路徑字串 (必要)。label
:GN 標籤,指向產生來源檔案的目標。僅適用於偵錯 (選用)。elf_runtime_dir
:僅用於 ELF 可執行檔和可載入的模組,這是選用的目的地目錄路徑,可指定這個二進位檔的 ELF 依附元件應在執行階段位於何處。預設值為「lib」
當用於產生發行資訊清單時,系統會原封不動地複製這些檔案,但不會將 elf_runtime_dir
鍵複製到輸出檔案中,除非符合下列任一條件:
這些項目的來源與另一個一般項目相同 (詳情請參閱本節說明),在此情況下,系統只會保留其中一個項目。
其來源路徑會由重新命名的項目使用 (請參閱下文)。
範例:
{
"destination": "bin/foo",
"source": "x64-asan/foo",
"label": "//some/dir:foo",
"elf_runtime_dir": "lib/asan"
},
複製項目。
這些項目用於指出建構作業將特定檔案複製至新的輸出位置。這項資訊之後會用於正確處理重新命名的項目 (請參閱下方說明),否則會遭到忽略。其結構定義如下:
copy_from
:相對於建構目錄的來源路徑字串 (必要)。copy_to
:相對於建構目錄的目標路徑字串 (必要)。label
:GN 標籤,指向產生此項目的目標 (選用)。
舉例來說,下列項目用於指出以 ${BUILD_DIR}/x64-asan/foo
中的「asan」建構變數建構的「foo」可執行二進位檔,也已複製到 ${BUILD_DIR}/foo
。
範例:
{
"copy_from": "x64-asan/foo",
"copy_to": "foo"
"label": "//some/dir:foo"
}
請參閱下文,瞭解複製和重新命名的項目如何互動,並附上實際範例。
已重新命名的項目
這些項目用於指出應在替代目的地位置安裝指定的一般項目。這對某些程式 (例如 busybox
) 非常實用,因為這類程式的行為會因用來啟動程式的名稱而有所不同。renamed_binary()
GN 範本會依賴這些檔案。其結構定義如下:
destination
:目的地路徑字串 (必要)。renamed_source
:與其他一般項目相符的來源路徑 (必要)。label
:GB 標籤,指向產生此項目的目標 (選用)。keep_original
:設為 true 的布林值標記,表示仍應在容器中安裝原始重新命名的二進位檔 (選用)。
請注意,重新命名的項目只能指向一般項目的 source
路徑,或指向複製項目的 copy_to
路徑。使用不明路徑或其他重新命名項目的目標路徑會導致建構錯誤。
您可以多次重新命名同一個項目。如果需要以不同名稱多次安裝相同的原始二進位檔,這項功能就非常實用。
以下範例說明 busybox
二進位檔會如何在同一個容器中安裝為 bin/cp
、bin/cat
和 bin/ls
。請注意,bin/busybox
不會安裝到容器中。
{
"destination": "bin/busybox",
"source": "busybox",
"label": "//third_party/busybox:busybox"
},
{
"destination": "bin/cp",
"renamed_from": "busybox"
},
{
"destination": "bin/cat",
"renamed_from": "busybox"
},
{
"destination": "bin/ls",
"renamed_from": "busybox"
}
如有任何重新命名項目將 keep_original
標記設為 true,原始項目不會從資訊清單中移除,而是保留原始二進位檔,如下所示:
{
"destination": "bin/busybox",
"source": "busybox",
"label": "//third_party/busybox:busybox"
},
{
"destination": "bin/cp",
"renamed_from": "busybox",
"keep_original": true
}
這可確保 bin/busybox
和 bin/cp
都安裝到容器中。
檔案項目
這些項目用於納入其他發行資訊清單檔案,這些檔案可能由其他目標產生。其結構定義如下:
file
:指向其他發布資訊清單檔案的檔案路徑字串 (必要)。label
:一個預設的 GN 標籤,如果指定檔案中的所有項目沒有專屬的label
值 (選用),就會套用至納入檔案中的所有項目。
發布檔案的包含項目可以是遞迴項目。
範例:
{
"file": "path/to/other.dist_manifest",
"label": "//some/dir:label"
}
資訊清單檔案中的重複項目
由於 Fuchsia 版本的運作方式,資訊清單檔案 (任何格式) 可能會提供多個使用相同 <destination>
路徑的項目。不過,只要來源路徑或內容相同,這項設定就有效;在這種情況下,系統會直接忽略重複項目。
如有多個項目具有相同的目的地路徑,但來源路徑「和」內容不同,處理指令碼會將這些記錄視為建構錯誤。
複製項目與重新命名項目之間的互動
為釐清複製和重新命名項目的互動方式,請參考下列範例,其中指定的 renamed_binary()
目標用於重新命名 foo
二進位檔的安裝位置。如未選取任何建構變數,對應的建構資訊清單就會包含兩個項目,如下所示:
{
"destination": "bin/foo",
"source": "foo",
"label": "//src:foo",
},
{
"destination": "bin/foo_renamed",
"renamed_from": "foo",
},
第一個一般項目指出 ${BUILD_DIR}/foo
是由預設工具鍊中的 //src:foo
目標建構,且應安裝至容器內的 bin/foo
。
第二個副本項目指出,以 ${BUILD_DIR}/foo
建構的二進位檔應實際安裝至 bin/foo_renamed
,而非其預設位置 (即 bin/foo
)。
從邏輯上來說,這等同於單一項目:
{
"destination": "bin/foo_renamed",
"source": "foo",
"label": "//src/foo",
},
例如第一個項目,只有目的地路徑有所變更。
不過,如果啟用 asan
變數來建構相同內容,資訊清單內容會與先前略有不同:
{
"destination": "bin/foo",
"source": "x64-asan/foo",
"label": "//src:foo(//build/toolchain:x64-asan)",
},
{
"copy_from": "x64-asan/foo",
"copy_to": "foo",
},
{
"destination": "bin/foo_renamed",
"renamed_from": "foo",
},
現在,第一個項目會指出 ${BUILD_DIR}/x64-asan/foo
是由 asan 工具鍊 (//build/toolchain:x64-asan
) 中的 //src:foo
目標建構,且預設會安裝至 bin/foo
。
第二個項目說明 ${BUILD_DIR}/foo
是 ${BUILD_DIR}/x64-asan/foo
的實際副本,因為這是我們的建構系統。
第三個項目與先前相同,因為 renamed_binary()
目標不知道用來建構 ${BUILD_DIR}/foo
的工具鍊或變化版本。
在邏輯上,這一切都等同於單一項目,如下所示:
{
"destination": "bin/foo_renamed",
"source": "x64-shared/foo",
"label": "//src/foo(//build/toolchain:x64-asan)",
},
只有在啟用建構變化版本時,才會使用複製項目,這些項目會將重新命名的項目連結至特定變化版本的一般項目。之所以會散布所有資訊,是因為每個項目都是透過建構圖表中的不同目標產生,而且在 GN 產生階段,無法將所有項目連結在一起。