For embedded/OS development one often writes code for a specific
no_std target, so it makes sense to override the default target by setting the
build.target configuration key. This allows running
cargo build and
cargo check without passing an explicit
--target argument on every invocation. It is even possible to override the runner and then use
cargo run, for example for running the executable in QEMU or flashing it to a connected development board.
The problem is
cargo test. Rust’s test library requires the standard library so we can’t use it in
no_std environments. But what we can do is to run platform independent unit tests on the host system (example). The problem is that cargo uses the specified default target for all subcommands and tries to compile the std-dependent tests for our bare metal system, which of course fails.
To work around this, we need to pass the host target triple as an explicit
--target argument on each invocation of
cargo test. This is problematic since it makes the command platform specific. Users on Linux need to invoke
cargo test --target x86_64-unknown-linux-gnu and users on Windows need to invoke
cargo test --target 86_64-pc-windows-msvc.
I’m not sure what the best solution to this could be. One solution could be to add a new
.cargo/config key that sets the default target only for the
run subcommands, but not for
bench. Alternatively, we could add a
--target HOST alias that at least provides a platform independent way to clear the
build.target default and compile for the host target.
What do you think about this? Maybe there are other/better solutions?
Edit: I experimented a bit with adding a new
.cargo/config key. The implementation was much simpler than I thought, so I opened a PR at https://github.com/rust-lang/cargo/pull/6825.