lang | compiler (ffi)
Add the ability to export symbols from executables, not just dylibs, via a new
compiler flag: -C export-executable-symbols
.
Java and C# can't statically link against C/Rust code. Both require dylib symbols for their common native interop solution. Which is fine if you let their executables call your dylib, but is a problem if you want your Rust executable to load a JVM instance, and let it call back into your executable. You might want to do this to allow you to:
For this last case, I manually export executable symbols via LINK. This is ugly, brittle, and rustc already knows how to do this automatically, across more platforms, and better.
https://doc.rust-lang.org/rustc/codegen-options/index.html could gain:
## export-executable-symbols
This flag causes `rustc` to export symbols from executables, as if they were dynamic libraries.
You might use this to allow the JVM or MSCLR to call back into your executable's
Rust code from Java/C# when embedding their runtimes into your Rust executable.
rustc -C help
could gain:
-C export-executable-symbols -- export symbols from executables, as if they were dynamic libraries.
My Java interop Quick Start
would start recommending a .cargo/config
with:
[build]
rustflags = ["-C", "export-executable-symbols"]
On a technical level, this just involves preventing an early bailout when
calling fn export_symbols
on executables with MSVC or GNU linker backends.
Other linker backends (EmLinker, WasmLd, PtxLinker) do not have this early
bailout in the first place, and remain unaffected.
This is very simple to implement, leverages existing code to enable it to do exactly what it was meant to do, and has few drawbacks.
Alternatives:
#![export_all_symbols]
? #![export_symbols]
?)C and C++ compilers can already do this via __declspec(dllexport)
annotations.
Most people don't really notice it, for good or for ill.
We could introduce a new source annotation, #[export]
. For backwards
compatibility with current behavior, #[no_mangle]
symbols could be exported
by default - and possibly disabled with #[export(false)]
. This would
reduce the need to hide this change to compiler/linker behavior behind a
compiler flag or crate annotation.
Maybe other options to control what symbols get exported? Although I'd fear turning rustc into yet another linker script implementation, so maybe not.
My own building atop this in the wider language ecosystem would be for improved Java/Rust interop/testing, with the eventual goal of improved Android API support for Rust. Many APIs are only exposed via Java, and I'd like said APIs to be usable in a safe and sound fashion.