SUMMARY: To enable Crubit on a C++ target and make it usable from Rust, use
cc_library(..., aspect_hints=["//features:supported"]). No additional work is necessary for Rust targets to make them usable from C++.The other features are more rarely useful, and mostly form a testing or release staging area for making changes to
:supported.
C++/Rust interop is configured per target using “features”: aspect hints which are applied onto a build target in order to configure its automatically generated bindings.
Features control which capabilities Crubit has. For example, the layout-compatible std::string type is gated behind the :layout_compat_string feature. If a target is configured to use :layout_compat_string, then std::string in its bindings will use the layout-compatible Rust type, otherwise it will use the bridged string_wrapper type.
Features are also used for gradual rollouts of new capabilities, and to allow for separate build modes for un-annotated code, code which opts into C++/Rust interop, and internal test code.
To use a feature, add it to your target:
# Enables the `:supported` feature on a C++ library `:example`. cc_library( name = "example", hdrs = ["example.h"], aspect_hints = ["//features:supported"], )
This causes the generated bindings for that target to use all the Crubit capabilities in :supported.
By default, Rust targets enable Crubit, and C++ targets do not.
Bindings are only generated for code without feature hints if this has minimal or generally-agreed upon impositions on library owners.
Rust targets are well behaved, and are expected to support C++ callers and integrate into the existing C++ codebase. For that reason, Crubit is automatically enabled on all Rust targets. See crubit.rs/rust.
However, by default, Crubit does not run at all on C++ targets. On a sufficiently “strange” target, Crubit can fail arbitrarily badly. As a real-world example, some libraries in third_party have headers that do not even parse, and which disable the header parsing check. See e.g. b/348557947. Crubit cannot run on these without manual intervention.
In addition, unexpected Rust callers could frustrate C++ library owners, as Rust (even via Crubit) constrains the C++ API changes users can make. (For example, changing a type from trivial to nontrivial is potentially mostly nonbreaking in C++, but a very major API break in Rust.) So, even if the technical ability were there, enabling Crubit by default would still require conversation and cooperation with the C++ ecosystem, and the resulting compromise might be short of what you get with :supported.
"//features:supported"The supported feature enables generally-available C++/Rust interop capabilities, for libraries that specifically support FFI callers.
See crubit.rs/cpp for documentation on what this includes.
This is a no-op on Rust targets.
"//features:experimental"WARNING: experimental is deprecated, visibility-restricted to Crubit itself, and slated for removal. Use :supported plus the individual feature hints described in Other features instead.
The other features float over time, as new features are taken from :experimental and moved into a separate, individual feature, and then released as part of :supported in a Bazel configuration change.
See crubit.rs/team/release for why features are released this way.
Crubit developers may want to temporarily enable features without respect to visibility restrictions or level of support. The build flag:
--//common/bazel_support:globally_enabled_features
accepts a comma-separated list of unstable internal feature names (like supported, experimental, or the special alias all) and overrides the baseline feature set for all targets for the duration of the build.