Small cleanup: don't add `C`'s preconditions to `~C`.

The destructor doesn't need to include all feature requirements for the class it is a destructor for. The requirement that the class itself be supported is already implicit in has_bindings -- so all this feature check serves to do is make the true cause of the error less clear (by converting it from a dependency error to a direct error).

This is already implicitly tested by whether or not the bindings for `no_bindings.h` (which has a class and destructor) compile.

(The main motivation for this cleanup is to nix the recursive call, tbh, since it makes it easier to handle error reporting and fix b/318006909.)

PiperOrigin-RevId: 605191864
Change-Id: I0097c971300dcd592d6e9c54d7557cbc63dbe6e6
2 files changed
tree: 82e67d8ea84c0a9a04682d6adf357691692759d8
  1. .bazelci/
  2. bazel/
  3. cc_bindings_from_rs/
  4. common/
  5. docs/
  6. examples/
  7. features/
  8. lifetime_analysis/
  9. lifetime_annotations/
  10. migrator/
  11. nullability/
  12. rs_bindings_from_cc/
  13. support/
  14. .bazelrc
  15. .gitignore
  16. BUILD
  17. Cargo.lock
  18. CODE_OF_CONDUCT
  19. CONTRIBUTING
  20. LICENSE
  21. README.md
  22. WORKSPACE
README.md

Crubit: C++/Rust Bidirectional Interop Tool

Build status

NOTE: Crubit currently expects deep integration with the build system, and is difficult to deploy to environments dissimilar to Google's monorepo. We do not have our tooling set up to accept external contributions at this time.

Crubit is a bidirectional bindings generator for C++ and Rust, with the goal of integrating the C++ and Rust ecosystems. With Crubit, Rust can be used anywhere C++ can be, directly calling and being called by C++. Crubit does not require wrapping C++ or Rust libraries in “FFI-friendly”, simplified APIs. Any C++ interface can be called or implemented by Rust code.

Current status: Crubit is aiming for an initial stable “MVP” version, comparable to bindgen and cbindgen. This will support basic datatypes like integers and pointers, (rust-movable) structs/unions/enums, and extern "C" functions.

Example

Consider the following C++ function:

extern "C" bool IsAbsPath(std::string_view path);

This function, if present in a header file which is processed by Crubit, becomes callable from Rust as if it were defined as:

pub fn IsAbsPath(path: std::string_view) -> bool {...}

There are some temporary restrictions on the API shape. For example, if path were a std::string, or a non-extern "C" function, it would not be callable from Rust directly via Crubit. (For example, std::string is not rust-movable.) These restrictions will be relaxed over time.

For actual copy-pastable examples on getting started with Crubit, see the examples/ subdirectory. examples/cpp includes code which actually calls C++ via Crubit, and a snapshot of what the generated interface looks like.

Building Crubit

$ apt install clang lld bazel
$ git clone git@github.com:google/crubit.git
$ cd crubit
$ bazel build --linkopt=-fuse-ld=/usr/bin/ld.lld //rs_bindings_from_cc:rs_bindings_from_cc_impl

Using a prebuilt LLVM tree

$ git clone https://github.com/llvm/llvm-project
$ cd llvm-project
$ CC=clang CXX=clang++ cmake -S llvm -B build -DLLVM_ENABLE_PROJECTS='clang' -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=install
$ cmake --build build -j
$ # wait...
$ cmake --install build
$ cd ../crubit
$ LLVM_INSTALL_PATH=../llvm-project/install bazel build //rs_bindings_from_cc:rs_bindings_from_cc_impl