Set default target for `cargo build` but not for `cargo test`

#1

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 build/check/run subcommands, but not for test/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.

4 Likes

#2

I’ve run into this myself with wanting examples compiled one way and tests compiled another.

cargo just isn’t smart enough (yet?)

0 Likes