Support linking Rust code into a C++ binary
This is based on a version of my upstream PR:
https://github.com/bazelbuild/rules_rust/pull/1350
Change-Id: Ica7097c10666d2e0017336cf7d81420605238493
Signed-off-by: Brian Silverman <bsilver16384@gmail.com>
diff --git a/build_tests/BUILD b/build_tests/BUILD
index 29a1275..24fdad8 100644
--- a/build_tests/BUILD
+++ b/build_tests/BUILD
@@ -178,3 +178,16 @@
target_compatible_with = ["@platforms//os:linux"],
deps = [":ts_test"],
)
+
+rust_library(
+ name = "rust_in_cc_rs",
+ srcs = ["rust_in_cc.rs"],
+ target_compatible_with = ["@platforms//os:linux"],
+)
+
+cc_test(
+ name = "rust_in_cc",
+ srcs = ["rust_in_cc.cc"],
+ target_compatible_with = ["@platforms//os:linux"],
+ deps = [":rust_in_cc_rs"],
+)
diff --git a/build_tests/rust_in_cc.cc b/build_tests/rust_in_cc.cc
new file mode 100644
index 0000000..9c13b1b
--- /dev/null
+++ b/build_tests/rust_in_cc.cc
@@ -0,0 +1,19 @@
+// A very minimal rust_library linked into a cc_binary to make sure we still get
+// the allocator symbols linked in.
+
+#include <stdint.h>
+#include <stdio.h>
+
+extern "C" int32_t rust_return5();
+
+extern "C" uint8_t c_return5() { return 5; }
+
+extern "C" void c_take5(uint8_t *) {}
+
+int main() {
+ const int rust_result = rust_return5();
+ printf("Rust says: %d\n", rust_result);
+ if (rust_result != 5) {
+ return 1;
+ }
+}
diff --git a/build_tests/rust_in_cc.rs b/build_tests/rust_in_cc.rs
new file mode 100644
index 0000000..0810609
--- /dev/null
+++ b/build_tests/rust_in_cc.rs
@@ -0,0 +1,19 @@
+extern "C" {
+ fn c_return5() -> u8;
+ fn c_take5(x: *mut u8);
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn rust_return5() -> i32 {
+ let layout = std::alloc::Layout::from_size_align(1, 1).unwrap();
+ let a = std::alloc::alloc(layout);
+ *a = c_return5();
+ // Do something so the compiler can't optimize out the alloc+free pair, which would invalidate
+ // this test.
+ if *a != 5 {
+ c_take5(a);
+ } else {
+ std::alloc::dealloc(a, layout);
+ }
+ 5
+}