rust 在所有平台上构建最小的no_std-binary

ozxc1zmp  于 2023-10-20  发布在  其他
关注(0)|答案(1)|浏览(136)

我需要在#[no_std]环境中测试一个构建依赖。Cargo为构建依赖项创建的环境主要是主机环境,而不是目标环境,但是如果要编译的crate是#[no_std],则会有细微的差异。作为集成测试的一部分,我可以在磁盘上创建一个最小的dummy-crate(它依赖于待测试的构建依赖关系),并生成一个新的Cargo进程来构建该crate,使用Cargo的退出状态作为测试的fixture。问题是如何使用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,因为库不能决定最终的crate是否链接到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-stub的关键是- afaics -它的签名依赖于当前目标,我想在当前正在测试的build-dependency上构建dummy-crate。如何做到这一点?我是否需要为主要平台和#[cfg]平台包括特定于平台的main?或者这个问题可以完全避免--crate实际上不需要运行,它只需要构建!

7lrncoxx

7lrncoxx1#

AFAICS,你需要一个与你的硬件兼容的no-stdtarget。我想x86_64-unknown-none应该在大多数情况下工作。
然后,您需要在main.rs中添加一个适当的入口点:

#[no_mangle]
pub unsafe extern "C" fn main() -> ! {
    loop {}
}

cargo build --target x86_64-unknown-none将执行build.rs并成功编译。

相关问题