If you just link some rust code into a C program without #[no_std], once you call anything that makes use of the runtime, it will abort with a lovecraftian error message and a stack trace because it asserts that the runtime exists and has placed some info into thread-local storage. It'll run until then, though!
If you'll only call into rust from a single C-created thread, you could start that thread through a shim that starts up the rust runtime. Rust code can then spawn its own threads in there and all of std might just work.
I don't think #[no_std] has any effect here, other that guaranteeing that know runtime-using functions are called (by not linking in any runtime at all).
I believe you can also just start runtimes in each call into Rust. Obviously it won't be particularly efficient.
Would it be possible to lazily start libnative if a call into the runtime is made but there's none there, but then keep it running for that thread for subsequent calls?
Maybe? The current design is starting a runtime is a blocking call, though, i.e. I think you'd call `native::run`[1] and run anything needing a runtime inside that (I haven't experimented with this part of our FFI in detail).
If you'll only call into rust from a single C-created thread, you could start that thread through a shim that starts up the rust runtime. Rust code can then spawn its own threads in there and all of std might just work.