blob: e0fe7884dac53b345682e07326ebb1f6c4759590 [file] [view]
<!-- go/cmark -->
<!--* freshness: {owner: 'boivie' owner: 'danilchap' reviewed: '2026-09-10'} *-->
# Rust in WebRTC
## Current status
WebRTC is adopting [Rust] to advance memory safety. Rust targets and build
infrastructure have been integrated into the repository and are enabled by
default.
Currently there are few Rust component integrated into tests, but not production
code.
As a next step we plan to integrate a small Rust component into production code,
but keep a c++ fallback.
## rtc_rust build flag
Rust support is controlled by the GN build argument `rtc_rust` in `webrtc.gni`:
```gn
# Enables or disables Rust targets in WebRTC.
rtc_rust = true
```
C++ code can check if Rust is enabled by checking `WEBRTC_WITHOUT_RUST` define.
We plan to eventually remove the `rtc_rust` build flag and `WEBRTC_WITHOUT_RUST`
define and require all downstream builds to provide a working Rust toolchain.
## GN Templates
- **`rtc_rust_library`**: Defines a Rust static library.
- **`rtc_rust_cxx_bridge`**: Defines a single-source C++/Rust FFI bridge using
the [CXX] crate.
- **`rtc_rust_unittest`**: Defines a single Rust unit test binary.
- **`rtc_rust_test_suite`**: Aggregates multiple Rust unit test targets into a
test suite group.
## Style guide
With few exceptions, WebRTC follows
[Chromium Rust Style guide][rust-chromium-style-guide], which in turn follows
[Rust Style Guide][rust-style-guide] and [Rust API Guidelines][rust-api-guide].
### Use webrtc::import! macro
```rust
webrtc::import! {
// Crates can be imported using their target name (e.g. `time_delta_rs`):
"//api/unit:time_delta_rs";
// Target names can be overridden for brevity:
"//modules/rtp_rtcp:corruption_detection_extension" as cde;
}
```
### Use Rust standard test framework
See [Rust Book][rust-test] for the guidance.
Support for [Chromium's test framework][rust-chromium-test] or
[Googles test framework][rust-google-test] is currently not implemented.
## C++/Rust Interoperability
Interoperability between C++ and Rust is handled through the [CXX] crate.
We plan to switch to [Crubit] when its support will be implemented in more
environments, in particular when it will be fully
[supported][crubit-in-chromium-issue] by chromium infrastructure.
FFI bindings are declared in Rust source files using `#[cxx::bridge]`. Use C++
namespace `webrtc` for all bindings. Declare bindings in Rust mod `ffi`.
**Examples:**
```rust
// bindings to call C++ from Rust
#[cxx::bridge(namespace = "webrtc")]
mod ffi {
unsafe extern "C++" {
include!("path/to/a_cpp_library.h");
fn CppFunction(value: i32) -> i64;
}
}
pub fn cpp_function(value: i32) -> i64 {
ffi::CppFunction(value)
}
```
```rust
// bindings to call Rust from C++
webrtc::import! {
"//path/to/rust:a_rust_library";
}
use a_rust_library::rust_function;
#[cxx::bridge(namespace = "webrtc")]
mod ffi {
extern "Rust" {
fn rust_function(value: i64) -> u64;
}
}
```
```gn
import("../../webrtc.gni")
rtc_library("cpp_only_library") {
sources = [
"cpp_only_library.cc",
"cpp_only_library.h",
]
}
if (rtc_rust) {
rtc_rust_cxx_bridge("call_cpp_from_rust_cxx") {
allow_unsafe = true
source = "call_cpp_from_rust_cxx.rs"
deps = [
":cpp_only_library",
"//build/rust:cxx_rustdeps",
]
}
rtc_rust_library("my_rust_feature") {
crate_root = "my_rust_feature.rs"
sources = [ "my_rust_feature.rs" ]
deps = [
":call_cpp_from_rust_cxx",
]
}
rtc_rust_unittest("my_rust_feature_test") {
crate_root = "my_rust_feature.rs"
sources = [ "my_rust_feature.rs" ]
deps = [
":call_cpp_from_rust_cxx",
]
}
rtc_rust_cxx_bridge("call_rust_from_cpp_cxx") {
allow_unsafe = true
source = "call_rust_from_cpp_cxx.rs"
deps = [
":my_rust_feature",
"//build/rust:cxx_rustdeps",
]
}
}
rtc_library("cpp_maybe_use_rust") {
sources = [
"cpp_maybe_use_rust.cc"
]
deps = [...]
if (rtc_rust) {
deps += [":call_rust_from_cpp_cxx"]
}
}
```
```cpp
// cpp_maybe_use_rust.cc
#ifndef WEBRTC_WITHOUT_RUST
#include "call_rust_from_cpp_cxx.rs.h"
#endif
...
uint64_t MaybeUseRust(int64_t value) {
#ifdef WEBRTC_WITHOUT_RUST
return CallCppFallback(value);
#else
return rust_function(value);
#endif
}
```
[crubit]: http://crubit.rs/
[crubit-in-chromium-issue]: http://crbug.com/351793625
[cxx]: http://cxx.rs/
[rust]: https://rust-lang.org/
[rust-api-guide]: https://rust-lang.github.io/api-guidelines/
[rust-chromium-style-guide]: https://chromium.googlesource.com/chromium/src/+/main/styleguide/rust/rust.md
[rust-chromium-test]: https://source.chromium.org/chromium/chromium/src/+/main:testing/rust_gtest_interop/
[rust-google-test]: https://github.com/google/googletest-rust
[rust-style-guide]: https://doc.rust-lang.org/style-guide/
[rust-test]: https://doc.rust-lang.org/book/ch11-01-writing-tests.html