Fuchsia 建構系統:變化版本

Fuchsia GN 建構機器可建構個別元件 不同的「變化版本」變化版本通常只是使用額外編譯器 但如果您編寫更多 GN 程式碼,功能就會有更多功用。 到目前為止定義的變化版本可用於許多用途,例如: 消毒液LTO

指定變化版本

變化版本規格會使用 GN 建構引數傳入建構。 select_variant。請注意 變數選取器非常重要,如以下語法章節所述。

使用 fx set 傳遞帶有 --variant= 標記的字串變體選取器:

fx set core.x64 --variant=asan/cat --variant=asan/ledger --variant=host_asan

這個範例會指示 版本編譯「貓」以及「ledger」Fuchsia 二進位檔和所有主機工具 使用位址清理程式 (如需這些字串的確切語法,請參閱下文)。

如果已有建構目錄,則可藉由編輯 GN 引數來新增或修改變化版本 直接 (請視需要為 out/default 取代建構的 GN 輸出目錄):

fx gn args out/default

這個指令會開啟編輯器。請在該檔案中附加一行,用於指派變化版本選取器 做為 select_variant 建構引數的字串清單:

select_variant = [ "asan/cat", "asan/ledger", "host_asan" ]

選取器語法

通常您會為變體選取器使用一組字串。每個變數都會定義變化版本名稱 以及可選擇是否要套用規則系統會按照您指定的順序測試選取器,以及第一個 就會套用相符的規則

  • 使用變化版本名稱單獨套用名稱的變化版本,例如 asanhost_ubsan。這些全域選取器應位於最後。

  • 使用以下格式將具名變化版本套用至特定目標:variant_name/target_output_name 例如 asan-ubsan/ledgerhost_asan/zxdb_tests。請在全域之前列出 來覆寫一般規則

系統會將變化版本與二進位檔 (例如 executableloadable_moduletest、 或 fuchsia_driver),而非 Fuchsia 套件、Fchsia 元件、共用程式庫、靜態程式庫或 來源集。一旦變化版本與目標相符,系統就會使用其依附的所有程式庫進行編譯 該變數。Fuchsia 套件和元件與選擇變化版本無關, 如果在變化版本規格中指定套件或元件名稱,並不會產生任何影響。每個執行檔 套件中的或模組都可以指定專屬的變數。

根據預設,目標輸出名稱就是您提供給 GN 目標定義的引號中的名稱。 這個目標會定義 my_program 目標,而您會透過選取器將目標套用至該目標 asan/my_program:

executable("my_program") { ... }

部分目標會使用 GN output_name 變數覆寫輸出名稱 (通常為 提供全域唯一的二進位檔名稱以避免衝突)。在本例中 與覆寫的輸出名稱相符,因此您還是能使用 asan/my_program 將其套用至該輸出:

executable("bin") {
  output_name = "my_program"
}

在某些情況下,範本可能會以不明顯的方式覆寫輸出名稱。如果看到 變數不一致,一個簡單的做法是直接在建構目錄中查看 然後以該名稱命名

進階選取器

您也可以提供做為變化版本選取器 精確控管比對目標的建構方式這些變數必須在「gn args」中設定替代 而非「fx set」指令列詳情請參閱 select_variant 建構引數說明文件 瞭解詳情

查看可用變化版本清單,並進一步瞭解如何定義 新內容,請參閱 known_variants敬上 建構引數

常見變化版本名稱

  • debug:未最佳化編譯。
  • release:最佳化編譯。
  • asan:適用於編譯時間的 Address Sanitizer 檢查記憶體濫用的狀況,例如釋放後使用和跳出的陣列存取。
  • ubsan:適用於編譯時間檢查的未定義行為清理工具 發生未定義的行為,例如整數溢位和未對齊指標。
  • asan-ubsan:Aasan + ubsan 的組合。
  • lto:以下項目的連結時間最佳化: 整個計劃最佳化
  • thinlto精簡連結時間最佳化為 對整體程式進行最佳化的輕量級,加快編譯速度。
  • coverage:用於產生的檢測編譯 程式碼涵蓋率資訊。
  • coverage-rust:適用於 Rust。因「coverage」過期而無法使用 Rust 和 C++ 編譯器之間的 LLVM 程式庫版本偏差。
  • kasan:僅將 asan 套用至核心。
  • gcc:使用 GCC 而非 Clang 編譯。支援啟動設定 且只會影響某些目標 (包括核心)。

在以下位置執行測試時,系統會使用 asan-fuzzer 等模糊變化版本 模糊和消毒液。這些子類並非 ,請改為按照模糊操作說明設定版本。

另外還有一些簡短選取器,可將變化版本套用至主機二進位檔 (工具 能在 Linux 或 Mac 主機電腦上運作): * host_asan * host_asan-ubsan * host_coverage * host_coverage-rust * host_profile

某些預先建構項目可能不適用於所有變化版本。關於 ffmpeg,請參閱 //src/media/lib/ffmpeg/BUILD.gn.

疑難排解附註

檢查變化版本是否已套用至二進位檔

每個變化版本都有專屬的輸出目錄和工具鍊名稱,名稱為 <architecture>-<variant name>。接著,這些二進位檔會複製到根目錄中的 建構過程例如,指定 x64 裝置的 Asan-ubsan 變化版本就會使用 //build/toolchain/fuchsia:x64-asan-ubsan 工具鍊並會將二進位檔放入 out/default/x64-asan-ubsan (將「default」替換成建構目錄)。

執行 GN (通常是建構的第一個步驟) 後,會產生一個檔案 binaries.json ,其中包含每個二進位的資訊。您可以透過 dist 檔案名稱和 label ( Toolchain 名稱位於括號中),也就是用來編譯二進位檔的變化版本。如果您的二進位檔 可能同時在目標和主機上編譯,但請留意記錄中的 os 欄位。這是 使用「asan-ubsan」為 x64 編譯的 Fuchsia 二進位檔範例子類:

  {
    "cpu": "x64",
    "debug": "x64-asan-ubsan/exe.unstripped/blobfs",
    "dist": "x64-asan-ubsan/blobfs",
    "elf_build_id": "x64-asan-ubsan/blobfs.build-id.stamp",
    "label": "//src/storage/blobfs/bin:blobfs(//build/toolchain/fuchsia:x64-asan-ubsan)",
    "os": "fuchsia",
    "type": "executable"
  },

複製 ASan 失敗

我們的基礎架構會在啟用 ASan 的設定中執行測試。複製 支援 ASan 的基礎架構建構作業,使用 fx repro <build_id> 並執行 發出指令

請注意,這項操作會建構由基礎架構執行的所有測試 並在系統映像檔中安裝這些項目造成您不理想的原因有兩個:

  • 建立所有測試通常速度緩慢且非必要。開發人員可以 就能更有效率地將套件標籤限制在需要的測試中。
  • 預先安裝系統映像檔中的所有測試項目後, 不會練習軟體部署工作流程

從已啟用 ASan 的二進位檔啟動執行檔

嘗試使用 ASan 變化版本時,可能會遇到 輸入:

launcher: error: Launch: elf_load: handle_interp failed
dlsvc: could not open 'asan/ld.so.1'

Fuchsia 的架構是以套件和元件為主。每個元件都包含 所需的所有共用程式庫這有助於 Fuchsia 避免使用程式庫 會對其他作業系統造成困擾的版本管理問題。這也意味著 如果您想從元件內執行二進位檔,就必須提供 適用於該二進位檔的適當共用程式庫載入器

您可以在 /boot/ 目錄中使用一組指令列程式 不在套件內,但在開機檔案系統中安裝的 Fuchsia 安裝項目。 這些程式沒有專屬的共用程式庫載入器,因此會使用 執行元件提供的共用程式庫這通常 的運作方式,因為 shls 等程式很少、很常見 依附元件不過,我們無法保證元件的套件會 具備充分或相容的共用程式庫,以便用於指令列程式 系統會按照資料類型和業務需求 將資料儲存到不同類型的儲存空間支援 ASan 的套件通常不含適用於這些程式的正確啟動器 因此,大多數已啟用 ASan 的元件就無法 /boot。如果支援 ASan 的元件嘗試執行這項作業,就會收到上述錯誤。

幸好,修正結果涉及所有套件應執行的操作 而是明確宣告其依附元件如果您的套件: 二進位檔,應宣告為依附元件,然後使用該二進位檔 宣告的依附元件,而不是 /boot 目錄中的依附元件。如果選擇 建構系統,zircon_extras_manifest 規則定義在 //build/config/fuchsia/zircon_images.gni 可讓您依賴 /boot 目錄中的二進位檔。並將安裝於 /pkg/bin/,您應從這裡執行這些函式。