我需要在#[no_std]
环境中
测试构建依赖关系。 Cargo 为构建依赖项创建的环境主要是主机的环境,而不是目标的环境,但如果要编译的 crate 是
#[no_std]
,则存在细微的差异。作为集成测试的一部分,我可以做的是在磁盘上创建一个最小的虚拟板条箱(这取决于要测试的构建依赖项),并生成一个新的 Cargo 进程来构建该板条箱,使用 Cargo 的退出状态作为测试的固定装置。问题是如何使用 Cargo 构建 #[no_std]
二进制文件,而不需要当前安装 rustc
来包含外部目标(例如 arm...
、thumb...
)或隐式依赖于当前执行测试的平台。
构建(不是运行!)这样一个最小的
#[no_std]
板条箱的最基本设置是
[package]
name = "nostd"
version = "0.1"
build = true
[build-dependencies]
to_be_tested = ...
[profile.dev]
panic = "abort" # we don't need no panic-handling
...和
main.rs
如下所示;它必须是 main.rs
,因为图书馆无法决定最终的箱子是否链接到 std
。
#![no_main]
#![no_std]
use core::panic::PanicInfo;
#[panic_handler]
fn panic(_panic: &PanicInfo<'_>) -> ! {
// won't ever get executed anyway
loop {}
}
但是,这无法构建
rror: linking with `cc` failed: exit status: 1
|
= note: [...]
= note: ld: warning: no platform load command found in '[...]/symbols.o', assuming: macOS
ld: Undefined symbols:
_main, referenced from:
<initial-undefines>
clang: error: linker command failed with exit code 1 (use -v to see invocation)
缺少
main
存根的关键是 - afaics - 它的签名取决于当前目标,我想在当前正在测试的构建依赖项上构建所述虚拟板条箱。怎么做?我是否需要包含主要平台和 main
的特定于平台的 #[cfg]
?或者可以完全避免这个问题 - 板条箱实际上不需要运行,它只需要构建!
AFAICS,您需要一个与您的硬件兼容的
no-std
target
。我想 x86_64-unknown-none
在大多数情况下应该有效。
然后,您需要在
main.rs
中添加适当的入口点:
#[no_mangle]
pub unsafe extern "C" fn main() -> ! {
loop {}
}
cargo build --target x86_64-unknown-none
就会执行build.rs
并编译成功。