docs/rust/cpp_api_from_rust.md
cpp_api_from_rustcpp_api_from_rust support is currently considered experimental and unstable.
TODO(https://crbug.com/470466915): Edit this section once we officially declare
and announce support for using cpp_api_from_rust for some Rust libraries.
("some" because of toolchain availability caveats in the other section below.)
Chromium's //third_party/rust-toolchain includes cpp_api_from_rust, but
other projects may not.
This means that Chromium code that is built in such other projects should
not depend on cpp_api_from_rust. Examples of code that should not
depend on cpp_api_from_rust:
//base, //net and other Cronet
dependencies.
(This restriction should go away when/if Android support for
cpp_api_from_rust hopefully comes later in 2026.)cpp_api_from_rust support in Bazel)cpp_api_from_rust
(with some Chromium support - see "availability" above) and
rust_api_from_cpp (with no Chromium support at this point).cpp_api_from_rust in Chromiumcpp_api_from_rust for a rust_static_library crateExample:
// build/rust/tests/test_cpp_api_from_rust/lib.rs:
pub fn mul_two_ints_via_rust(x: i32, y: i32) -> i32 {
x * y
}
# build/rust/tests/test_cpp_api_from_rust/BUILD.gn
import("//build/rust/rust_static_library.gni")
rust_static_library("rust_lib") {
crate_root = "lib.rs"
sources = [ crate_root ]
cpp_api_from_rust = {
target_name = "rust_lib_bindings"
cpp_namespace = "rust_lib"
}
}
source_set("unittests") {
sources = [ "unittests.cc" ]
deps = [
":rust_lib_bindings",
]
}
// build/rust/tests/test_cpp_api_from_rust/unittests.cc:
#include "build/rust/tests/test_cpp_api_from_rust/rust_lib.h"
void foo() {
auto product = rust_lib::mul_two_ints_via_rust(3, 4);
}
cpp_api_from_rust for a third_party/rust crateTODO: This is not implemented yet.
Let's assume that cpp_api_from_rust bindings are generated for
//some/dir:some_target - e.g.:
# some/dir/BUILD.gn
import("//build/rust/rust_static_library.gni")
rust_static_library("some_target") {
crate_root = "lib.rs"
sources = [ crate_root ]
cpp_api_from_rust = {
target_name = "some_target_bindings"
}
}
The generated bindings can then be found and inspected in
<out_dir>/gen/some/dir/some_target.h. For example:
$ cat out/rel/gen/build/rust/tests/test_cpp_api_from_rust/rust_lib.h | head -3
// Automatically @generated C++ bindings for the following Rust crate:
// rust_lib_1dc874e1
// Features: <none>
If public APIs of a crate depend on types from another crate, then the
dependency on the other crate needs to be explicitly specified in BUILD.gn.
1st-party Rust libraries can specify dependencies of their bindings as follows:
// build/rust/tests/test_cpp_api_from_rust/lib.rs:
chromium::import! {
"//build/rust/tests/test_cpp_api_from_rust:internal_helper";
"//build/rust/tests/test_cpp_api_from_rust:other_lib";
}
pub fn create_multiplier(x: i32) -> other_lib::Multiplier {
internal_helper::do_something();
other_lib::Multiplier::new(x)
}
# build/rust/tests/test_cpp_api_from_rust/BUILD.gn
import("//build/rust/rust_static_library.gni")
rust_static_library("rust_lib") {
crate_root = "lib.rs"
sources = [ crate_root ]
deps = [
":other_lib",
":internal_helper",
]
cpp_api_from_rust = {
target_name = "rust_lib_bindings"
cpp_namespace = "rust_lib"
deps = [ "//some/other/lib:other_lib_bindings" ]
}
}
Note how other_lib_bindings are listed in deps of cpp_api_from_rust above.
Note that types from internal_helper are not used in public APIs of
rust_lib and therefore internal_helper is not listed
in deps attribute of cpp_api_from_rust.
//third_party/rust librariesTODO: gnrt_config.toml equivalent for //third_party/rust libraries.
C++ bindings for Rust standard library
(i.e. the //build/rust/std:std_bindings target)
are automatically injected as a dependency of all other bindings
(i.e. there is no need to specify them explicitly in a deps entry).
C++ bindings for Rust standard library are placed in a C++ namespace that corresponds to the original Rust crate as follows:
std crate => rs_std namespacecore crate => rs_core namespacealloc crate => rs_alloc namespaceIf cpp_api_from_rust is unable to generate bindings for a given Rust API,
then the generated .h file will contain a comment explaining why.
The sections below describe a few errors that are somewhat related to
how Chromium integrates Crubit into its build system.
--crate-header was specified for this crateIf you see an error like:
$ cat out/rel/gen/build/rust/tests/test_cpp_api_from_rust/rust_lib.h
...
// Error generating bindings for `create_multiplier` defined at
// ../../build/rust/tests/test_cpp_api_from_rust/lib.rs;l=22: Error formatting
// function return type `other_lib::Multiplier`: Type `other_lib::Multiplier`
// comes from the `other_lib_1dc874e1` crate, but no `--crate-header` was
// specified for this crate
...
Then you want to read the "Specifying binding dependencies" section above.