How to disable my no_std panic handler when I'm testing with std?

Hi,

I'm working on a no_std project therefore I have a panic handler annotated with #[panic_handler].

However, during development it is helpful to test parts of the project with std. However when I run cargo test, i get:

error[E0152]: found duplicate lang item panic_impl

Prepending the panic handler with #[cfg(test)] doesn't help, which I thought will do because this trick handles the std library import.

Like this:

#[cfg(test)]
#[panic_handler]
fn panic(info: &core::panic::PanicInfo) -> ! {

What should I do?

Thanks.

Something like...

#![cfg_attr(not(test), no_std)]

#[cfg_attr(not(test), panic_handler)]
fn panic(_info: &core::panic::PanicInfo) -> ! { loop {} }

https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute

1 Like

Never mind. #[cfg(not(test))] did it.

======================

Thanks. That works.

Now I ran into multiple definition of 'rust_eh_personality', but the linker complains if I don't include this when building for no_std :-/

#[no_mangle]
extern "C" fn rust_eh_personality() {}

Is there anything similar to #ifdef in C?

Doesn't #[cfg(not(test))] work here too?

Not exactly; conditional compilation isn't driven by source code contents. There was a recent related topic.

I can run tests after also meddling with a different target for cargo test. But now I find myself inserting #[cfg...] before every use core::... and its corresponding use std::.... This looks clumsy, is there any better way to do this?

You can move imports inside the test-only function. Or you can create a separate module to scope it.

That seems not working. Say I have a function called xyz that needs core::..., so there's use core::... on top of the file. By placing use std::... in the test function won't prevent rust from picking up the core::... imports when compling xyz, will it?