commit | 10b1a29ca01f4a13bb9ee545b231f5d326d28606 | [log] [tgz] |
---|---|---|
author | Lukasz Anforowicz <lukasza@google.com> | Mon Apr 03 16:19:08 2023 -0700 |
committer | Copybara-Service <copybara-worker@google.com> | Mon Apr 03 16:19:53 2023 -0700 |
tree | e6d8280e24cec5ad54d4461c87371dddccb63334 | |
parent | d7add542cc60206e70b8ff3df47fed9bc68a7cfc [diff] |
Fix how structs are passed by value in absence of a thunk impl. This CL fixes 2 problems: * Before this CL bindings for `extern "C"`, `#[export_name = ... ]` functions would incorrectly declare the Rust-side original functions with a modified signature - e.g. injecting `__ret_ptr` parameter. Undefined behavior would result when calling a function declared this way and trying to pass `__ret_ptr` argument even when the original function doesn't actually accept such parameter. * Before this CL bindings for `extern "C"`, `#[no_mangle]` functions would incorrectly pass structs by value, even though in the current implementation `#[repr(C)]` structs may also get blobs of bytes injected as artificial fields (e.g. as padding) which may change the ABI classification of such structs. In other words, b/270454629 wasn't really fixed for such functions. The fix is to set `needs_thunk` to true whenever `!is_c_abi_compatible_by_value`. This changes the generated bindings for some `extern "C"` functions (i.e. thunks are now generated for some such functions). PiperOrigin-RevId: 521591455
Crubit is an experimental bidirectional bindings generator for C++ and Rust.
Please don‘t use, this is an experiment and we don’t yet know where will it take us. There will be breaking changes without warning. Unfortunately, we can't take contributions at this point.
Crubit allows for C++ code and Rust code to call each other without manually wrapping the APIs in an FFI-friendly interop layer. For example, a C++ function like this:
bool IsAbsPath(std::string_view path);
... becomes callable from Rust as if it were defined as:
pub fn IsAbsPath(path: std::string_view) -> bool {...}
Crubit automatically generates ABI-compatible bindings for structs (which can be passed both by value and by reference), functions, and methods, for a large variety of types. (Trivial types, nontrivial types, templated types, etc.)
$ 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
$ 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