如何使用#![no_std]测试crate?

19

我正在使用Rust编写一个编程语言实现的运行时。我计划将这个运行时与我生成的编译代码链接起来,因此为了保持二进制文件较小,我不想依赖于std

当我尝试用cargo test测试我的运行时时,我会收到错误提示,说找不到std::slice::AsSlice。我发现这是因为一些测试工具需要std库的代码。

我该如何测试这段代码呢?是否有一种方法可以有条件地包含#![no_std] ?即在测试时仍然包含std库?我还尝试创建了一个带有std库的单独测试crate,将runtime crate引入其中并在那里运行我的测试,但这引入了一整套新问题。

2个回答

24

您可以使用cfg_attr来有条件地设置no_std。

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

4
这是2022年更好的答案,特别是考虑到extern crate是不必要的。 - Los Frijoles

17
#[cfg(test)]
#[macro_use]
extern crate std;

#[macro_use]部分是可选的。)


2
如果你将extern crate std;变成无条件的,那么你就失去了#![no_std]的全部意义。在这种情况下,你应该提供自己的std模块,像这样:mod std { pub use core::cmp; } - Chris Morgan
1
我弄清楚了我的问题所在。除了#[cfg(test)] extern crate std;这行代码外,我还需要添加#[cfg(test)] use std::prelude::*;,因为预导入不再自动导入了。还有一个快速的问题,如果你不介意的话:在这种设置下,是否仍然可以使用#[derive(Debug, PartialEq)]这样的指令? - Zach Smith
1
@ZachSmith:mod std { pub use core::fmt; pub use core::cmp; } 等等,这样就可以让它工作了。 - Chris Morgan
在进行此操作时,我仍然会因为缺少分配器而出现错误。 - jhpratt
#[macro_use] 部分在 Rust 2015 中是可选的,在 Rust 2018 中不是必需的。 - Błażej Michalik
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接