Improve Rust build infrastructure

Further usage of this (coming in future changes) revealed some issues.

Change-Id: Ib60968c580db4e7bb4bd60c782ce7f93a7fc594d
Signed-off-by: Brian Silverman <bsilver16384@gmail.com>
diff --git a/tools/platforms/BUILD b/tools/platforms/BUILD
index 37fed2e..1d79f06 100644
--- a/tools/platforms/BUILD
+++ b/tools/platforms/BUILD
@@ -42,7 +42,12 @@
         "@platforms//cpu:armv7",
         "//tools/platforms/hardware:roborio",
         "//tools/platforms/go:lacks_support",
-        "//tools/platforms/rust:has_support",
+        # TODO(Brian): This almost works, but cxx assumes llvm-ld's linking
+        # behavior and doesn't have an easy way to support GNU ld. See
+        # https://github.com/dtolnay/cxx/pull/1069 for a bit more explanation.
+        # Bazel needs to group multiple things into a single cc_library to
+        # handle that, need to figure out how to do that here or switch linkers.
+        "//tools/platforms/rust:lacks_support",
         "//tools/platforms/nodejs:lacks_support",
     ],
 )
diff --git a/tools/rust/BUILD b/tools/rust/BUILD
index 74ed92d..a5a2f89 100644
--- a/tools/rust/BUILD
+++ b/tools/rust/BUILD
@@ -98,7 +98,7 @@
     exec_triple = "none",
     os = "none",
     rust_doc = ":noop_error_exit",
-    rust_lib = ":empty_stdlib",
+    rust_std = ":empty_stdlib",
     rustc = ":noop_error_exit",
     rustc_lib = ":noop_error_exit",
     rustc_srcs = None,
@@ -124,7 +124,7 @@
 rust_binary(
     name = "tweak_cargo_raze_output",
     srcs = ["tweak_cargo_raze_output.rs"],
-    target_compatible_with = ["@platforms//os:linux"],
+    target_compatible_with = ["//tools/platforms/rust:has_support"],
     visibility = ["//visibility:public"],
     deps = [
         "//third_party/cargo:anyhow",
diff --git a/tools/rust/forward_allocator.c b/tools/rust/forward_allocator.c
index 3e6ba96..a321af3 100644
--- a/tools/rust/forward_allocator.c
+++ b/tools/rust/forward_allocator.c
@@ -2,7 +2,8 @@
 
 // This file has some exciting magic to get Rust code linking in a cc_binary.
 // The Rust compiler generates some similar symbol aliases when it links, so we
-// have to do it manually.
+// have to do it manually. We mark all our symbols as weak so that linking this
+// via Rust tooling to produce a binary with a Rust main works.
 //
 // It is intended to be used in rust_toolchain.allocator_library.
 //
@@ -20,27 +21,32 @@
 // not work with any other allocated switched in via `#[global_allocator]`.
 
 // New feature as of https://github.com/rust-lang/rust/pull/88098.
-uint8_t __rust_alloc_error_handler_should_panic = 0;
+__attribute__((weak)) uint8_t __rust_alloc_error_handler_should_panic = 0;
 
 uint8_t *__rdl_alloc(uintptr_t size, uintptr_t align);
+__attribute__((weak))
 uint8_t *__rust_alloc(uintptr_t size, uintptr_t align) {
   return __rdl_alloc(size, align);
 }
 void __rdl_dealloc(uint8_t *ptr, uintptr_t size, uintptr_t align);
+__attribute__((weak))
 void __rust_dealloc(uint8_t *ptr, uintptr_t size, uintptr_t align) {
   __rdl_dealloc(ptr, size, align);
 }
 uint8_t *__rdl_realloc(uint8_t *ptr, uintptr_t old_size, uintptr_t align,
                        uintptr_t new_size);
+__attribute__((weak))
 uint8_t *__rust_realloc(uint8_t *ptr, uintptr_t old_size, uintptr_t align,
                         uintptr_t new_size) {
   return __rdl_realloc(ptr, old_size, align, new_size);
 }
 uint8_t *__rdl_alloc_zeroed(uintptr_t size, uintptr_t align);
+__attribute__((weak))
 uint8_t *__rust_alloc_zeroed(uintptr_t size, uintptr_t align) {
   return __rdl_alloc_zeroed(size, align);
 }
 void __rdl_oom(uintptr_t size, uintptr_t align);
+__attribute__((weak))
 void __rust_alloc_error_handler(uintptr_t size, uintptr_t align) {
   __rdl_oom(size, align);
 }