外殼覆蓋

Fuchsia 使用外部 Rust Crate。外部 Rust Crate 會放在 //third_party/rust_crates/vendor 中。這組 Crate 是以 //third_party/rust_crates/Cargo.toml 中列出的依附元件為基礎。

一般來說,新增或更新外部 Crate 涉及下列事項:

  • 計算外部 Crate 的依附元件。

  • 要求開放原始碼審查委員會 (OSRB) 核准。

  • 等待 OSRB 核准。

  • 上傳變更以進行程式碼審查。

新增外部 Crate

如果找不到要使用的現有 Crate,可以將外部 Crate 新增至 Fuchsia。

如要新增外部 Crate,請按照下列步驟操作:

  1. 切換至 Fuchsia 存放區的基底目錄。

    舉例來說,如果你的 Fuchsia 目錄是 ~/fuchsia,請執行下列指令:

      cd ~/fuchsia
  2. 在 third_party/rust_crates/Cargo.toml 中新增要加入 Crate 的項目。

  3. 執行下列指令,下載所需 Crate 並計算該 Crate 的依附元件:

      fx update-rustc-third-party

    fx update-rustc-third-party 會下載 rust_crates/Cargo.toml 中列出的所有 Crate 及其依附元件,將下載的 Crate 放在 vendor 目錄中,然後更新 Cargo.toml 和 Cargo.lock。

    如果 Crate 使用 build.rs 指令碼,您可能需要提供額外設定。這項設定會取代指令碼,而 GN 建構系統刻意不支援指令碼。設定應放在下列位置:

    • Cargo.toml 檔案內的 [gn.package.<crate>] 區段。

      執行 fx update-rustc-third-party 時,這些設定會自動轉換為 //build/bazel/update-rustc-third-party/crate_annotations.bzl 中的 Bazel 註解。如果 Crate 需要 Bazel 專屬設定 (例如停用不支援的建構指令碼或指定自訂 Bazel 目標標籤),覆寫應放在下列位置:

    • //build/bazel/update-rustc-third-party/crate_annotation_overwrites.bzl

      詳情請參閱 cargo-gnaw 的 README。

      在本機提交變更後,請再次執行 fx update-rustc-third-party,並確認作業順利完成,且未產生任何變更。您可以執行 git status 來確認。

  4. 執行下列指令來進行建構測試:

      fx set core.x64 && fx build
  5. 請按照下列步驟要求 OSRB 核准:

    • 使用開放原始碼審查委員會 (OSRB) 範本建立問題。
    • 在問題中執行下列操作:

      • 將「擁有者」欄位留空。
        • OSRB 團隊會定期開會檢討問題。我們會在約一週內回覆。
      • 指定要新增的所有 Crate (不必列出先前核准的 Crate)。加入要新增的 Crate,以及執行 fx update-rustc-third-party 後識別出的依附元件 Crate。
      • 如果來源存放區中有任何檔案未納入供應商提供的檔案,請在向 OSRB 回報問題時指定這些檔案。舉例來說,如果字型檔案僅用於測試,但當 Crate 供應商排除這些檔案時,就必須將其納入 OSRB 問題。
  6. 如果獲得 OSRB 核准,請將變更上傳至 Gerrit 供審查。 請在變更中加入 OSRB 問題 ID 編號。

  7. 將外部 Rust Crate 目錄的「OWNER」新增為程式碼審查員。您必須向其中一位存放區擁有者取得 Code Review Label +2。

  8. 如果您有權將核准的變更提交至 Commit Queue (CQ),請提交變更,將該變更合併至 third_party/rust_crates。

    如果無法提交核准的變更,請回覆 Gerrit 變更,並要求其中一位存放區擁有者提交變更。

    如要進一步瞭解每個貢獻者角色可執行的相關動作,請參閱角色矩陣。

更新外部 Crate

如要更新外部 Crate,請按照下列步驟操作:

  1. 增加 Crate 的修補程式編號, third_party/rust_crates/Cargo.toml

    • 如為遞移依附元件 (不會顯示在 third_party_rust_crates/Cargo.toml 中),請改為執行 fx host-tool cargo update --manifest-path third_party/rust_crates/Cargo.toml --package $crate_name。指令輸出內容會顯示 $crate_name 更新後的版本。接著,請在 third_party/rust_crates/BUILD.gn 中檢查 $crate_name 的參照,並據此更新版本字串。
  2. 執行下列指令:

      fx update-rustc-third-party

    您可能需要在 Cargo.toml 檔案的 [gn.package.<crate>] 區段中更新或提供額外設定。如果 Crate 使用 build.rs 指令碼,這項設定會取代該指令碼,而建構系統刻意不支援該指令碼。cargo-gnaw 會使用這項設定,從 Cargo.toml 檔案產生 GN 規則。詳情請參閱 cargo-gnaw 的 README。

  3. 檢查更新後的 Crate 版本字串是否已在 third_party/rust_crates/BUILD.gn 中正確更新,並視需要手動調整。

    在本機修訂變更後,請再次執行 fx update-rustc-third-party,並確保作業順利完成,且未產生任何變更。您可以執行 git status 來確認。

  4. 執行下列指令來進行建構測試:

      fx set core.x64 && fx build
  5. 檢查授權或依附元件是否有任何變更。如有這類變更,您必須通過 OSRB 核准程序。請按照下列步驟要求 OSRB 核准:

    • 使用開放原始碼審查委員會 (OSRB) 範本建立問題。
    • 在問題中執行下列操作:

      • 將「擁有者」欄位留空。
        • OSRB 團隊會定期開會檢討問題。我們會在約一週內回覆您。
      • 指定要新增的所有 Crate。加入您要新增的 Crate,以及執行 fx update-rustc-third-party 後識別出的依附元件 Crate。
      • 如果來源存放區中有任何檔案未納入供應商提供的檔案,請在向 OSRB 回報問題時指定這些檔案。舉例來說,如果字型檔案僅用於測試,但在供應 Crate 時會排除,則必須納入 OSRB 問題。
  6. 更新已修改 Crate 的 OWNERS 檔案。如要進一步瞭解如何更新 OWNERS 檔案,請參閱「OWNERS 檔案」一節。

  7. 收到 OSRB 核准後,請將變更上傳至 Gerrit 供審查。請在變更中加入 OSRB 問題 ID 編號。

  8. 如果沒有授權或依附元件變更,您可以上傳變更內容送審,不必經過 OSRB 核准程序。

新增鏡像

積極參與上游存放區的貢獻,或是維護 Fuchsia 存放區的長期存續分支版本時,使用完整的 Git 存放區匯入 Crate,而非 Cargo 的供應商工具,會很有幫助。雖然這種做法很實用,但相較於預設流程,負擔相當大,因此請審慎使用。

  1. 在 fuchsia.googlesource.com 上要求新增鏡像。
  2. 將鏡像新增至 Rust 執行階段的 Jiri 資訊清單。
  3. 將 Crate 的修補程式區段新增至工作區。
  4. 執行更新指令碼。

匯入 Crate 中的部分檔案

在某些情況下,您可能只想匯入 Crate 中的部分檔案。舉例來說,外部存放區中可能有與 Fuchsia 授權規定不相容的選用授權。以下是發生此情況的 OSRB 審查範例。

如要這麼做,請將 Crate 的檔案新增至 /third_party/rust_crates/forks。

  1. 按照新增外部 Crate 的操作說明操作。
  2. 執行 fx update-rustc-third-party 後,請將下載的 Crate 副本從 /third_party/rust_crates/vendor/<my_crate> 移至 /third_party/rust_crates/forks/<my_crate>。
  3. 對匯入的檔案進行必要變更。
  4. 在 [patch.crates-io] 區段中新增一行,指向新 Crate: /third_party/rust_crates/Cargo.toml

    [patch.crates-io]
    ...
    my_crate = { path = "forks/<my_crate>" }
    ...
    
  5. 重新執行 fx update-rustc-third-party 和 fx build。

  6. 新增 /third_party/rust_crates/forks/<my_crate>/README.fuchsia 檔案,該檔案的格式應與其他 Crate 的 README.fuchsia 檔案格式相符。請參閱/third_party/rust_crates/forks/README.md,瞭解應包含的內容。

Unicode Crate

如果專案需要匯入新的外部 Crate,以處理與 Unicode 和國際化相關的功能,請盡可能使用 UNIC 專案的 Crate。

豁免的非 UNIC Crate

下列非 UNIC Crate 已供應,因此可免除:

  • unicode-bidi
  • unicode-normalization
  • unicode-segmentation
  • unicode-width
  • unicode-xid

標準化理由

UNIC Crate 相較於其他 Crate 具有下列優勢:

  • UNIC Crate 是在單一存放區中開發,共用通用程式碼和單一版本配置。

    • 獨立開發的 Crate 不會共用發布時間表、版本控制架構,也不會遵守任何特定版本的 Unicode 標準。
  • UNIC Crate 是從一組一致的 Unicode 資料檔案產生。

    • 每個獨立 Crate 都會使用任意版本和資料子集。舉例來說,不同 Crate 可能對特定程式碼點是否已指派、屬性為何等有不同假設。
  • UNIC 專案的目標是全面涵蓋各項功能,成為 Rust 的 ICU。如果專案成功,我們對不相關的 Unicode Crate 的依附元件應會隨著時間減少。

OWNERS 檔案

所有外部 Rust Crate 都會維護 OWNERS 檔案,指出負責審查和更新的人員。這些檔案是根據建構圖形中繼資料和明確的覆寫檔案組合產生。

update-rustc-third-party 工具會盡可能使用現有資料更新這些檔案,但可能會出錯。update-3p-owners 這項工具可直接從建構圖表重新生成 OWNERS 檔案,進一步提升效能。

執行工具

這項工具會找出依附於特定 Crate 的建構目標,因此需要完成最大「廚房水槽」建構作業的中繼資料:

  1. 執行「fx set core.x64 --with //bundles/buildbot/core --with //bundles/kitchen_sink --with-host '//tools/gn_desc:install_gn_desc(//build/toolchain:host_x64)'」
  2. 執行 fx update-3p-owners --rust-metadata <FUCHSIA_BUILD_DIR>/rustlang/3p-crates-metadata.json。

手動更新 OWNERS

供應商提供的第三方 Crate 的 OWNERS 檔案是從兩個主要來源建構而來:

  1. 依附於第三方 Rust Crate 的目標,會將 OWNERS 檔案匯入依附的 Crate OWNERS。舉例來說,如果 src/lib/foo 這類目標依附於 bar Crate,則 bar Crate 的 OWNERS 檔案會包含 src/lib/foo/OWNERS。
  2. 依附於其他第三方 Rust Crate 的第三方 Rust Crate,會將依附元件的 OWNERS 檔案匯入自己的檔案。舉例來說,如果 bar Crate 依附於 baz Crate,則 bar Crate 的 OWNERS 檔案會包含 third_party/rust_crates/vendor/bar-1.0.0/OWNERS。

如果是現有 Crate 的版本升級,通常只要將 include 陳述式更新為升級後 Crate 的最新版本即可。

新增覆寫

有些 Crate 的使用者人數過多,無法維持 (請參閱「旁觀者效應」)。其他團隊則會實作特定領域 (例如安全性) 的行為,因此我們希望由特定團隊負責審查程式碼。

在這種情況下,請在 //third_party/owners.toml 中新增項目,並提供要參照的其他 OWNERS 檔案路徑,然後重新執行工具。這會以覆寫的路徑取代反向依附元件中繼資料擁有權。

更新頻率

目前由 Rust on Fuchsia 團隊成員負責定期執行這項工具。請參閱 https://fxbug.dev/42152910,追蹤 OWNERS 檔案的自動更新程序。

在本機覆寫

如果您要向上游貢獻內容,並想執行樹狀結構內建構或測試,覆寫第三方 Crate 可能會很有用。請按照下列步驟操作。

  1. 在 third_party/rust_crates/forks/<my_crate> 下複製 (或符號連結) 上游存放區。
  2. 將覆寫項目新增至 third_party/rust_crates/Cargo.toml 中的 [patch.crates-io] 區段。
[patch.crates-io]
my_crate = { path = "forks/<my_crate>" }
  1. 請務必確認 Crate 底下的版本 Cargo.toml 與 third_party/rust_crates/Cargo.toml 中對該 Crate 的所有參照相符。
  2. 執行 fx update-rustc-third-party。

疑難排解

設定檔損毀

執行 fx update-rustc-third-party 後,如果遇到類似下列的錯誤:

Generating GN file from /$HOME/fuchsia/third_party/rust_crates/Cargo.toml
Error: GNaw config exists for crates that were not found in the Cargo
build graph:

library crate, package handlebars version 2.0.0-beta.2
library crate, package core-foundation-sys version 0.7.0
library crate, package pulldown-cmark version 0.6.0
library crate, package nix version 0.18.0

如要修正這個問題,請在 .cargo/config 中註解掉紫紅色目標:

[build]
...
target = "x86_64-unknown-fuchsia"

註解後會變成:

[build]
...
# target = "x86_64-unknown-fuchsia"

這個問題正在上游追蹤中。