總覽
FIDL 工具鍊大致由三部分組成:
- 前端,又稱
fidlc- 剖析並驗證
.fidl個檔案 - 計算各種結構的大小、對齊方式和偏移量
- 產生 JSON IR (中介表示法)
- 剖析並驗證
- 後端
- 透過 IR 運作 (C 後端除外)
- 產生特定目標語言的程式碼,並繫結至該語言的程式庫
- 執行階段程式庫
- 實作訊息的編碼/解碼/驗證
- 方法調度機制
程式碼位置
編譯器前端
前端位於 //tools/fidl/fidlc/, 測試則位於 //tools/fidl/fidlc/tests。
編譯器後端
| 目標 | Codegen | 執行階段程式庫 | 測試 |
|---|---|---|---|
| HLCPP (舊版) | /tools/fidl/fidlgen_hlcpp | /sdk/lib/fidl/hlcpp | (與執行階段程式庫位於同一位置) |
| 新版 C++ | /tools/fidl/fidlgen_cpp | /sdk/lib/fidl/cpp | /src/lib/fidl/llcpp 和 /sdk/lib/fidl/cpp |
| 查看 | /tools/fidl/fidlgen_go | /third_party/go/src/syscall/zx/fidl | (與執行階段程式庫位於同一位置) |
| 荒漠油廠 | /tools/fidl/fidlgen_rust | /src/lib/fidl/rust | (與執行階段程式庫位於同一位置) |
目標專用後端的支援程式碼位於 /tools/fidl/lib/fidlgen。
測試工具
GIDL
GIDL 是一種工具,用於建立一般「編寫一次,為每個後端生成」的程式。目前 GIDL 用於產生編碼或解碼測試 (「一致性測試」) 和基準測試。
| 路徑 | 說明 |
|---|---|
| /tools/fidl/gidl | GIDL 工具本身的原始碼和建構範本。 |
| /src/tests/fidl/conformance_suite | 一致性測試的測試定義 (.fidl 和 .gidl 檔案)。 |
| /sdk/ctf/tests/pkg/fidl/cpp/test/{test,handle}_util.h | 支援 HLCPP 一致性測試的執行階段。 |
| /src/lib/fidl/llcpp/tests/conformance/conformance_utils.h | 執行階段支援 C++ 導線型別一致性測試。 |
| /src/lib/fidl/rust/gidl_util | Rust 一致性測試的執行階段支援。 |
| /third_party/go/src/syscall/zx/fidl/fidl_test | Go 一致性測試的執行階段支援。 |
| /src/tests/benchmarks/fidl/benchmark_suite | 基準定義 (.fidl 和 .gidl 檔案)。 |
| /src/tests/benchmarks/fidl | 基準的執行階段支援。 |
每個後端的一致性測試實際測試目標,通常會與該後端的對應測試一併定義。詳情請參閱「繫結測試」一節。
相容性
相容性測試是整合測試,會執行來自不同繫結的 FIDL 用戶端和伺服器,以測試兩者是否相容。相容性測試位於 /src/tests/fidl/compatibility/。
危險的 ID
危險 ID 測試位於 /src/tests/fidl/dangerous_identifiers。
其他
其他 FIDL 相關領域包括:
| 路徑 | 目錄 |
|---|---|
| /tools/fidl/fidlgen_* | 其他各種編譯器後端。 |
| /tools/fidl/fidlc/cmd/fidl-format | FIDL 格式器。 |
| /tools/fidl/fidlc/cmd/fidl-lint | FIDL Linter。 |
| /tools/fidl/fidldoc | 生成 FIDL 的說明文件。 |
| /tools/fidl/fidlmerge | 可從 FIDL JSON 生成程式碼的工具。 |
| /tools/fidl/measure-tape | 盡量增加分頁的工具。 |
| /tools/fidl/scripts | 大多是執行遷移作業等一次性指令碼,可供日後參考。 |
| /src/lib/fostr | fidlmerge 工具,以在 C++ 中生成格式化程式碼。 |
| /src/lib/fostr/build | 為 fostr 格式化程式庫建立範本。 |
| /src/lib/fidl_codec | 用於編碼/解碼 FIDL 訊息的程式庫 (由 fidlcat 使用)。 |
其他 FIDL 工具
許多 FIDL 工具都位於 fidl-misc 存放區。如要複製這個存放區,請執行
git clone https://fuchsia.googlesource.com/fidl-misc
然後建議匯出這個目錄的路徑,方便設定別名:
export FIDLMISC_DIR=...
常見開發工具
這是 FIDL 團隊提供的眾包內容,介紹他們用於處理 FIDL 程式碼的實用工具。
IDE
FIDL 團隊大多使用 VS Code 進行開發。以下列舉幾個實用的外掛程式和工作流程:
- 遠端 SSH 功能非常適合在筆電上遠端工作。
- 設定 tmux 或 screen 對遠距工作也有幫助,可保留記錄並管理殼層中的多個工作階段。
- 如需設定語言伺服器的操作說明,請參閱 Fuchsia 說明文件:
- 適用於 C++ 的 clangd
- Rust 適用的 rust-analyzer
- 重新換行擴充功能可自動將行重新換行至特定長度,非常實用 (例如編輯 Markdown 檔案時)。
如要為繫結黃金檔案取得自動語法螢光標示,請更新
file.associations設定:"files.associations": { "*.json.golden": "json", "*.rs.golden": "rust", "*.cc.golden": "cpp", "*.h.golden": "cpp", "*.go.golden": "go", },
修訂訊息格式指南
撰寫變更訊息時,請遵循修訂版本訊息樣式指南。
C++ 樣式指南
我們遵循 Fuchsia C++ 樣式指南,並制定額外規則,進一步消除應用程式或指南解讀方面的模糊空間。
留言
註解必須遵守 80 欄的行大小限制,但程式碼可延伸至 100 欄的行大小限制。
Lambda 擷取
- 如果 lambda 會逸出目前範圍,請明確擷取所有變數。
- 如果 lambda 是本機 (不會逸出目前範圍),建議使用依參照的預設擷取方式 (「
[&]」)。
看到 [&] 是強烈的信號,表示 lambda 只存在於目前範圍內,可用於區分本機和非本機 lambda。
// Correct.
std::set<const flat::Library*, LibraryComparator> dependencies;
auto add_dependency = [&](const flat::Library* dep_library) {
if (!dep_library->HasAttribute("Internal")) {
dependencies.insert(dep_library);
}
};
一般設定
Fuchsia 設定
請先閱讀 Fuchsia 入門指南。
fx set
如果您正在使用 FIDL 工具鍊,請使用:
fx set core.x64 --with-test //bundles/fidl:tests
如果您正在處理 LSC:
fx set terminal.x64 --with //bundles/kitchen_sink \
符號化工具
如要將回溯追蹤符號化,您需要範圍內的符號器:
export ASAN_SYMBOLIZER_PATH="$(find `pwd` -name llvm-symbolizer | grep clang | head -1)"
快速測試版本
FIDL 是系統中非常深層的部分,因此修改 FIDL 通常會導致「重建世界」,小幅變更可能會觸發數萬個編譯動作,並建構數分鐘。如果您只是想建構及執行一些 FIDL 測試,而不是整個系統,這可能會很慢且麻煩。
fx 工具支援隨選、小範圍的建構和套件發布作業,可協助解決這種情況。如要啟用這項功能,請在 ~/.bashrc (或同等項目) 中設定下列環境變數:
export FUCHSIA_DISABLED_incremental=0
編譯及執行測試
我們主要提供單行程式碼,用於測試各個部分。如有疑慮,請參閱 Git 提交訊息中的「Test:」註解;我們會盡量在該處說明用於驗證工作的指令。
測試是使用 fidldev 工具執行。範例假設 fidldev 指令碼位於 PATH 上的某處,例如新增別名:
alias fidldev=$FIDLMISC_DIR/fidldev/fidldev.py
fidlc
# optional; builds fidlc for the host with ASan <https://github.com/google/sanitizers/wiki/AddressSanitizer>
fx set core.x64 --variant=host_asan
fx build host_x64/fidlc
如果您在 fidlc 上進行大量編輯、編譯及測試週期,使用較少的最佳化項目進行建構,建構速度可能會大幅提升。如要這麼做,請在 zircon/public/gn/config/levels.gni 中將 optimization 設定從 default 變更為 debug 或 none。
為避免意外提交這項變更,請執行:
git update-index --skip-worktree zircon/public/gn/config/levels.gni
如要再次允許提交變更,請執行:
git update-index --no-skip-worktree zircon/public/gn/config/levels.gni
fidlc 測試
fidlc 測試位於:
如要建構及執行 fidlc 測試,請按照下列步驟操作:
fx test //tools/fidl/fidlc
如要直接使用 ninja:
fx_build_dir=$(cat .fx-build-dir) \
fidlc_tests_target=$(fx ninja -C $fx_build_dir -t targets all | grep -e 'unstripped.*fidlc-test:' | awk -F : '{ print $1; }') \
fx ninja -C $fx_build_dir $fidlc_tests_target && ./$fx_build_dir/$fidlc_tests_target
如要執行特定測試套件,請使用 --gtest_filter 和適當的模式。例如:
fx_build_dir=$(cat .fx-build-dir) \
fidlc_tests_target=$(fx ninja -C $fx_build_dir -t targets all | grep -e 'unstripped.*fidlc-test:' | awk -F : '{ print $1; }') \
fx ninja -C $fx_build_dir $fidlc_tests_target && ./$fx_build_dir/$fidlc_tests_target --gtest_filter 'EnumsTests.*'
fidlc 偵錯
如要在偵錯版本中輕鬆執行測試,請稍微調整環境設定:
fx set core.x64 --variant=host_asan --with //bundles/fidl:tests
export ASAN_SYMBOLIZER_PATH="$(find `pwd` -name llvm-symbolizer | grep clang | head -1)"
設定完成後,您可以使用先前列出的指令執行測試,並視需要進行篩選。
如要逐步執行測試,可以使用 GDB:
fx_build_dir=$(cat .fx-build-dir) \
fidlc_tests_target=$(fx ninja -C $fx_build_dir -t targets all | grep -e 'unstripped.*fidlc-test:' | awk -F : '{ print $1; }') \
fx ninja -C $fx_build_dir $fidlc_tests_target && fx gdb --args ./$fx_build_dir/$fidlc_tests_target --gtest_filter 'AliasTests.invalid_recursive_alias'
fidlc 測試格式指南
以 C++ 編寫的所有 fidlc 編譯器測試都必須符合下列規則:
- 使用
TEST巨集編寫的測試必須有大寫駝峰式群組名稱,格式為<CATEGORY>Tests。以及大寫駝峰式測試案例名稱。 例如:TEST(BitsTests, GoodValidBits) {...。 - 測試案例名稱不應以「Test」開頭或結尾,因為這是多餘的。
- 測試剖析和/或編譯的測試案例名稱必須加上下列其中一個前置字元:
Good:測試案例預計通過的時間。例如:GoodValidMethod。Bad:測試案例預計通過的時間。例如:BadMustBeDense。Warn:測試案例預期會通過,但有報告器警告。警告適用於導入新檢查時的暫時用途,因此移除檢查時,以Warn為前置字元的測試應變更為Good或Bad。例如:WarnTooManyProvidedLibraries。
此外,如果測試案例預期會發生編譯失敗,則應分別在預期發生一項和兩項錯誤時,使用 ASSERT_ERRORED_DURING_COMPILE 和 ASSERT_ERRORED_TWICE_DURING_COMPILE 巨集。
fidlc 金幣
如要重新產生 fidlc JSON 黃金:
fidldev regen fidlc
這些「黃金」檔案是 JSON IR fidlc 產生的範例,用於追蹤變更。每次以任何方式變更 JSON IR 時,都必須重新產生黃金檔案,否則 json_generator_tests 會失敗。
fidlgen (新版 C++、HLCPP、Rust、Go)
版本:
fx build tools/fidl
執行:
$FUCHSIA_DIR/out/default/host_x64/fidlgen_{cpp,hlcpp,rust,go}
您可以執行的測試範例如下:
fx test fidlgen_hlcpp_golden_tests
fx test fidlgen_golang_lib_tests
fidldev test --no-regen fidlgen
如要重新生成黃金版本:
fidldev regen fidlgen
fidlgen_banjo
版本:
fx build host_x64/fidlgen_banjo
執行測試:
fx build host_x64/fidlgen_banjo_unittests
./out/default/host_x64/fidlgen_banjo_unittests
繫結
fidldev 支援各項繫結的測試。部分繫結測試會在裝置上執行,因此必須在模擬器中執行 Fuchsia。步驟如下:
Tab 1> fx build && fx serve
Tab 2> fx qemu -kN
-k 旗標可啟用 KVM。這不是必要步驟,但如果沒有這個擴充功能,模擬器會慢上許多。-N 旗標會啟用網路功能。
接著,您可以使用 fidldev 執行繫結測試:
fidldev test --no-regen hlcpp
fidldev test --no-regen llcpp
fidldev test --no-regen c
fidldev test --no-regen go
fidldev test --no-regen rust
或者,也可以執行不含引數的 fidldev,測試已變更的檔案:
fidldev test
如要執行特定測試或將標記傳遞至特定測試,請執行 fidldev,並使用 --dry-run、--no-build、--no-regen 標記取得所需測試指令。
相容性測試
如要瞭解相容性測試的運作方式和程式碼位置,請參閱 //src/tests/fidl/compatibility 的 README。
如要執行相容性測試,您必須先在模擬器中執行 Fuchsia:
Tab 1> fx build && fx serve
Tab 2> fx qemu -kN
如要執行相容性測試,請按照下列步驟操作:
Tab 3> fx set core.x64 --with //src/tests/fidl/compatibility
Tab 3> fx test fidl-compatibility-test
GIDL
如要重建 GIDL:
fx build host-tools/gidl
捲尺
fx set core.x64 --with //tools/fidl/measure-tape/src:host
fx build
所有測試
本節提供完整的 fx test 指令,可執行所有 FIDL 相關測試。如要執行特定測試,請使用這些參數,而非 fidldev test。
繫結測試
由於主機僅支援執行部分功能,因此裝置端測試的涵蓋範圍通常比主機測試更廣。不過,主機測試有助於偵錯,解決裝置無法啟動的問題。
裝置上
| 名稱 | 測試指令 | 涵蓋率 |
|---|---|---|
| c 執行階段測試、編碼表 | fx test fidl_c_tests |
//sdk/lib/fidl_base |
| walker, misc | fx test fidl-walker-tests |
//sdk/lib/fidl_base |
| walker tests w/ handle closing checks | fx test fidl-handle-closing-tests |
//sdk/lib/fidl_base |
| hlcpp 繫結測試,包括一致性測試 | fx test fidl_hlcpp_unit_test_package fidl_hlcpp_conformance_test_package |
//sdk/lib/fidl |
| 新的 C++ 線路測試 | fx test //src/lib/fidl/llcpp |
//sdk/lib/fidl/cpp/wire |
| 新的 C++ 測試 | fx test //sdk/lib/fidl/cpp |
//sdk/lib/fidl/cpp |
| go bindings tests | fx test go-fidl-tests |
//third_party/go/syscall/zx/fidl //third_party/go/syscall/zx/fidl/fidl_test //src/tests/fidl/go_bindings_test |
| Rust 繫結測試 | fx test //src/lib/fidl/rust |
//src/lib/fidl/rust |
舉辦派對
| 名稱 | 測試指令 | 涵蓋率 |
|---|---|---|
| walker, misc | fx test --host fidl-walker-host-tests |
//sdk/lib/fidl_base |
| hlcpp unittests | fx test --host fidl_hlcpp_unit_tests |
//sdk/lib/fidl |
| hlcpp 一致性測試 | fx test --host fidl_hlcpp_conformance_tests |
//sdk/lib/fidl |
| C++ 導線型別一致性測試 | fx test --host fidl_llcpp_conformance_tests |
//sdk/lib/fidl/cpp/wire |
| C++ 自然型別一致性測試 | fx test --host fidl_cpp_conformance_tests |
//sdk/lib/fidl/cpp |
| Rust 一致性測試 | fx test --host fidl_rust_conformance_tests |
//src/lib/fidl/rust |
| rust fidl lib tests | fx test --host fidl_rust_lib_tests |
//src/lib/fidl/rust |
| 進行一致性測試 | fx test --host fidl_go_conformance_tests |
//third_party/go/syscall/zx/fidl |
| go fidl tests (extended) | fx test --host go_extended_fidl_test |
//third_party/go/syscall/zx/fidl |
| go unsafevalue test | fx test --host go_unsafevalue_test |
//third_party/go/syscall/zx/fidl/internal/unsafevalue |
fidlgen 測試
| 名稱 | 測試指令 | 涵蓋率 |
|---|---|---|
| fidlgen 型別定義 | fx test fidlgen_lib_test |
//tools/fidl/lib/fidlgen |
| fidlgen C++ 專屬 IR | fx test fidlgen_cpp_ir_test |
//tools/fidl/lib/fidlgen_cpp |
| fidlgen hlcpp | fx test fidlgen_hlcpp_golden_tests |
//tools/fidl/fidlgen_hlcpp |
| fidlgen new C++ | fx test fidlgen_cpp_golden_tests |
//tools/fidl/fidlgen_cpp |
| fidlgen golang | fx test fidlgen_go_{lib,golden}_tests |
//tools/fidl/fidlgen_golang |
| fidlgen rust | fx test fidlgen_rust_{lib,golden}_tests |
//tools/fidl/fidlgen_rust |
| fidlgen syzkaller | fx test fidlgen_syzkaller_golden_tests |
//tools/fidl/fidlgen_syzkaller |
其他
| 名稱 | 測試指令 | 涵蓋率 |
|---|---|---|
| fidlc 編譯器 | fx test fidlc-testfx test fidlc_golden_tests |
//tools/fidl/fidlc |
| gidl 剖析器 | fx test gidl_parser_test |
//tools/fidl/gidl/parser |
| 捲尺測試 | fx test measure-tape_test |
//tools/fidl/measure-tape |
| Rust IR 剖析器 | fx build |
//src/devices/tools/fidlgen_banjo/tests/parser |
所有基準
基準測試可以直接執行,也可以透過下列其中一個測試執行器執行: fuchsia_benchmarks (舊版)、SL4F (新版)。
chromeperf 的基準目前是透過 fuchsia_benchmarks 執行元件產生,但會改用 SL4F。在過渡期間,基準應整合至兩個系統。
直接執行基準測試
確認建構中包含基準:
fx set core.x64 --with //src/tests/benchmarks
您必須fx build並重新啟動qemu,才能使用這些套件。
可用的基準:
| 名稱 | 基準指令 | 附註 |
|---|---|---|
| Go 基準 | fx shell /bin/go_fidl_microbenchmarks |
|
| Rust 基準 | fx shell /bin/rust_fidl_microbenchmarks /tmp/myresultsfile |
您可以使用 fx shell cat /tmp/myresultsfile/ 查看結果 |
| C++ 線路類型基準 | fx shell /bin/llcpp_fidl_microbenchmarks |
|
| lib/fidl 基準 | fx shell /bin/lib_fidl_microbenchmarks |
|
| 往返基準 | fx shell /bin/roundtrip_fidl_benchmarks |
使用 SL4F 基準測試執行元件執行所有基準測試
這會以與 CQ 相同的方式執行基準測試。SL4F 需要 terminal.x64 產品。使用 fx set 切換產品:
fx set terminal.x64 --with //bundles/buildbot/terminal
如要執行所有 FIDL 測試,請使用:
fx test --e2e fidl_microbenchmarks_test
所有重新生成指令
本節提供 fx check-goldens 指令,可重新產生所有 FIDL 相關的黃金檔案。fidldev regen 在內部使用這項功能。
| 名稱 | 重新生成指令 | 輸入 | 輸出 |
|---|---|---|---|
| (所有黃金) | fx check-goldens | ||
| fidlc goldens | fx check-goldens fidlc | tools/fidl/fidlc/testdata | tools/fidl/fidlc/goldens |
| fidlgen goldens | fx check-goldens $TOOL | tools/fidl/fidlc/testdata | tools/fidl/$TOOL/goldens |
| fidldoc goldens | fx check-goldens fidldoc | tools/fidl/fidlc/testdata | tools/fidl/fidldoc/goldens |
| gidl goldens | fx check-goldens gidl | src/tests/fidl/conformance_suite/golden{.gidl,.test.fidl} | tools/fidl/gidl/goldens |
| 第三方 Go | fx exec $FUCHSIA_DIR/third_party/go/regen-fidl |
使用「ninja」編譯
在某些情況下,GN 會建構許多不必要的目標。您可以使用 ninja 建構特定目標,而非 GN。在大多數情況下,您可以 grep 二進位檔名,判斷 ninja 叫用。
舉例來說,你可以對 fidlgen_cpp 執行 grep:
fx ninja -C out/default -t targets all | grep -e 'fidlgen_cpp:'
這個範例會輸出 Ninja 目標清單,包括 host_x64/fidlgen_cpp。因此,如要建構 fidlgen_cpp,請執行下列 ninja 指令:
fx ninja -C out/default host_x64/fidlgen_cpp
偵錯 (主機)
您可以使用多種方法偵錯主機二進位檔的問題。本節提供 fidlc --files test.fidl 當機時的操作說明:
GDB
首先,請 cd 至建構目錄。您也可以留在 $FUCHSIA_DIR,但必須在 GDB 中執行 dir out/default,才能找到來源檔案。
cd $FUCHSIA_DIR/out/default
接著,啟動 GDB。您系統上的副本可能可以運作,但預先建構的副本fx gdb
更有可能與 Fuchsia 專案中的建構構件搭配運作。如需預先建構的 GNU 工具完整清單,請參閱
fx gnu --help。
fx gdb --args host_x64/exe.unstripped/fidlc --files test.fidl
然後輸入「r」啟動程式。如需其他用途和方便的快速參考資料,我們發現這份 GDB 快速參考表非常實用。
ASan
請確認您編譯時已啟用 ASan:
fx set core.x64 --variant=host_asan
fx build host_x64/fidlc
然後執行 out/default/host_x64/fidlc --files test.fidl。該二進位檔應與 out/default/host_x64-asan/fidlc 相同。
Valgrind
在 Google Linux 機器上,您可能需要安裝標準版 Valgrind,而不是使用預先安裝的二進位檔:
sudo apt-get install valgrind
然後︰
valgrind -v -- out/default/host_x64/exe.unstripped/fidlc --files test.fidl
工作流程
前往 fuchsia.io 和 fuchsia.net
如要更新所有已儲存的 fidlgen 檔案,請執行下列指令,
系統會自動搜尋並產生必要的 Go 檔案:
fx exec $FUCHSIA_DIR/third_party/go/regen-fidl
常見問題
為什麼 C 後端與其他後端不同?
目前的 C 繫結已淘汰。如要進一步瞭解日後如何在 C 中使用 FIDL,請參閱 https://fxbug.dev/42159192。
為什麼所有後端不在同一個工具中?
我們希望所有後端都位於不同工具中!
我們計畫在各種工具 (fidlc、fidlfmt、各種後端) 上執行指令碼,讓所有項目都能輕鬆存取,並管理這些項目的串連。舉例來說,您應該可以透過一個指令 (例如:) 生成 Go 繫結:
fidl gen --library my_library.fidl --binding go --out-dir go/src/my/library
或者,使用下列指令格式化現有程式庫:
fidl fmt --library my_library.fidl -i