Fuchsia Build 系統使用的資訊清單檔案格式

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/cpbin/catbin/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/busyboxbin/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 產生階段,無法將所有項目連結在一起。