Wrap part of //aos:init for Rust
Just enough to run tests for now.
Change-Id: I714fbabfe713b34494a0a47a5679c409cce211c4
Signed-off-by: Brian Silverman <bsilver16384@gmail.com>
diff --git a/aos/BUILD b/aos/BUILD
index a1c92e7..5fcb7cf 100644
--- a/aos/BUILD
+++ b/aos/BUILD
@@ -178,6 +178,18 @@
],
)
+autocxx_library(
+ name = "init_rs",
+ srcs = ["init.rs"],
+ crate_name = "aos_init",
+ libs = [
+ ":init",
+ ],
+ override_cc_toolchain = "@llvm_toolchain//:cc-clang-x86_64-linux",
+ target_compatible_with = ["//tools/platforms/rust:has_support"],
+ visibility = ["//visibility:public"],
+)
+
cc_library(
name = "realtime",
srcs = [
diff --git a/aos/init.cc b/aos/init.cc
index 3b298fa..9b00f1c 100644
--- a/aos/init.cc
+++ b/aos/init.cc
@@ -39,4 +39,25 @@
initialized = true;
}
+void InitFromRust(const char *argv0) {
+ CHECK(!IsInitialized()) << "Only initialize once.";
+
+ FLAGS_logtostderr = true;
+
+ google::InitGoogleLogging(argv0);
+
+ // TODO(Brian): Provide a way for Rust to configure C++ flags.
+ char fake_argv0_val[] = "rust";
+ char *fake_argv0 = fake_argv0_val;
+ char **fake_argv = &fake_argv0;
+ int fake_argc = 1;
+ gflags::ParseCommandLineFlags(&fake_argc, &fake_argv, true);
+
+ // TODO(Brian): Where should Rust binaries be configured to write coredumps?
+
+ // TODO(Brian): Figure out what to do with allocator hooks for C++ and Rust.
+
+ initialized = true;
+}
+
} // namespace aos
diff --git a/aos/init.h b/aos/init.h
index 1e2b7a4..29480eb 100644
--- a/aos/init.h
+++ b/aos/init.h
@@ -10,6 +10,11 @@
// ShmEventLoop can confirm the world was initialized before running.
bool IsInitialized();
+// A special initialization function that initializes the C++ parts in a way
+// compatible with Rust. This requires careful coordination with `:init_rs`, do
+// not use it from anywhere else.
+void InitFromRust(const char *argv0);
+
} // namespace aos
#endif // AOS_INIT_H_
diff --git a/aos/init.rs b/aos/init.rs
new file mode 100644
index 0000000..8a5f262
--- /dev/null
+++ b/aos/init.rs
@@ -0,0 +1,29 @@
+use std::{ffi::CString, sync::Once};
+
+autocxx::include_cpp! (
+#include "aos/init.h"
+
+safety!(unsafe)
+
+generate!("aos::InitFromRust")
+);
+
+/// Initializes things for a test.
+///
+/// TODO(Brian): Should we provide a proc macro attribute that handles calling this?
+///
+/// # Panics
+///
+/// Panics if non-test initialization has already been performed.
+pub fn test_init() {
+ static ONCE: Once = Once::new();
+ ONCE.call_once(|| {
+ let argv0 = std::env::args().next().expect("must have argv[0]");
+ let argv0 = CString::new(argv0).expect("argv[0] may not have NUL");
+ // SAFETY: argv0 is a NUL-terminated string.
+ unsafe { ffi::aos::InitFromRust(argv0.as_ptr()) };
+ });
+
+ // TODO(Brian): Do we want any of the other stuff that `:gtest_main` has?
+ // TODO(Brian): Call `aos::SetShmBase` like `:gtest_main` does.
+}