Cdylib + cargo test + no_std = impossible combo?

Hey all. I'm trying to write a library that's supposed to compile into a DLL, so I set the cdylib crate type.

Then I wanted to use cargo test with it, and cargo test seems to skip stuff that's just cdylib so I also set rlib:

crate-type = ["rlib","cdylib"]

this has worked for me in the past, and it works for me now as well. Then I thought, "well, none of this should allocate, let's make it no_std to enforce that", and when I add #![no_std] to the top of my lib.rs file cargo somehow thinks that I'm missing the panic_fmt and eh_personality language items and so it won't compile things for me. If I take out the crate-type specifiers it'll compile a no_std lib, but then I don't get my DLL. If I specify only cdylib it'll build that no_std but then won't run doctests at all.

Is there some way to build a DLL, also run my doc tests, and also have no_std on the library all at once? Or is this situation just weird enough to fall through the cracks somehow?

Repo with the example files: https://github.com/Lokathor/galaxy-break

The problem is that during testing a binary is built, but no_std is not usable with binaries on non nightly rustc. You could add

#[cfg(test)] extern crate std;

to your code, to link in std during testing. Even libstd itself links in an extern std when during testing:

https://github.com/rust-lang/rust/blob/master/src/libstd/lib.rs#L384

2 Likes

That works if I add the extern crate line unconditionally (with or without the "as realstd" part), but it does not work with the #[cfg(test)] part, even in test mode.

Upon further testing, it seems that simply making a cdylib with no_std is the trouble.

And it's fine if that can't be done, but that should be documented some place more obvious if so. The cargo docs that explain crate types don't say anything about it.

2 Likes