使用 bindgen 整合 C/C++

如需從 Rust 呼叫 C 或 C++ API,可以使用 bindgen,從 C 和 C++ 標頭產生 Rust 程式碼。如需更多說明文件,請參閱 bindgen 使用手冊。

產生 Rust 繫結

Fuchsia 提供 rustc_bindgen_golden GN 範本,可從 C/C++ 標頭產生 Rust 繫結,並確保這些繫結保持最新狀態。這個範本會在建構期間執行 bindgen,並將輸出內容與已簽入的「黃金」檔案進行比較。

1. 定義 GN 目標

匯入範本,並在 BUILD.gn 中定義 rustc_bindgen_golden 目標。

例如,請參閱 //src/lib/usb_rs/BUILD.gn:

import("//build/rust/rustc_bindgen.gni")

rustc_bindgen_golden("my_bindings_golden") {
  header = "my_header.h"
  checked_in_source = "src/bindings.rs"

  # Optional: configure bindgen behavior
  # e.g., allowlist, denylist, raw_lines, etc.
  # see //build/rust/rustc_bindgen.gni for all options
}

2. 設定 Rust 目標

您必須將黃金目標新增至使用繫結的 Rust 目標 validations 參數,確保檢查作業在建構過程中執行:

rustc_library("my_library") {
  edition = "2024"
  sources = [
    "src/lib.rs",
    "src/bindings.rs",
  ]
  # ...

  validations = [ ":my_bindings_golden" ]
}

接著,您可以在 Rust 程式碼中使用產生的繫結 (例如 mod bindings;)。

3. 更新已簽入的繫結

如果 C 標頭變更,建構作業就會失敗,因為產生的繫結不再與簽入檔案相符。建構輸出內容會顯示差異和更新檔案的操作說明。

如要更新已簽入的檔案,可以採取下列任一做法:

  • 使用建構失敗訊息中提供的 cp 指令,將產生的檔案複製到已簽入的檔案。
  • 將 update_goldens GN 引數設為 true,然後重新建構:

    fx set ... --args=update_goldens=true
    fx build
    

    建構作業完成並更新檔案後,請將 update_goldens 引數還原為 false (或移除),確保日後能偵測到不相符的情況。

在 Bazel 中

BUILD.bazel 檔案可以使用 //build/bazel/rules/rust:rustc_bindgen.bzl 中的 rustc_bindgen_golden() 巨集。其屬性與 GN 範本的參數名稱相同,且 bazel2gn 會將其轉換為 GN 範本。將目標新增至編譯已簽入檔案的 rustc_library() 的 validations 屬性:

load("//build/bazel/rules/rust:rustc_bindgen.bzl", "rustc_bindgen_golden")
load("//build/bazel/rules/rust:rustc_library.bzl", "rustc_library")

rustc_bindgen_golden(
    name = "my_bindings_golden",
    checked_in_source = "src/bindings.rs",
    headers = ["//sdk/lib/foo/include/lib/foo/foo.h"],
    notice_year = 2026,
    deps = ["//sdk/lib/foo"],
)

rustc_library(
    name = "my_library",
    srcs = [
        "src/bindings.rs",
        "src/lib.rs",
    ],
    edition = "2024",
    validations = [":my_bindings_golden"],
)

與 GN 不同,headers 必須是 deps 的標頭。這些是來源路徑,而非標籤,因此擁有這些路徑的套件不需要匯出。