Cargo workspace members with different target architectures

Is it possible to specify different target architectures when building different Cargo workspace members? This would allow for use-cases where some binaries are meant for local execution and others are meant for embedded targets, wasm, or other cross-compiled targets, without splitting them into separate repositories or workspaces.

As far as I can see, the only place I can specify a default target is in .cargo/config.toml, which is sensitive to the directory that I stand in. So having a single .cargo/config.toml at the workspace root, I would have one default target for all workspace members. I might be able to have multiple of these in a single workspace (I haven't tried), but they would be sensitive to what directory I'm in, which is less ideal as a trigger.

I might be able to pull this off using Nix, since I can have multiple Nix derivations in a single project directory, but it would be adaptive for nix ... commands and not for cargo ... commands, which is less ideal for a low-complexity, Cargo-centric workflow.

I could also simply have a justfile that provides just ... commands that specify the target for building different crates. That might be the simplest, low-tech solution.

What are people's experience combining embedded crates with non-embedded crates in the same workspace?

I believe as of right now you need the nightly per-package-target to force the target of your package. As per the docs on configuration files in workspaces:

At present, when being invoked from a workspace, Cargo does not read config files from crates within the workspace. i.e. if a workspace has two crates in it, named /projects/foo/bar/baz/mylib and /projects/foo/bar/baz/mybin, and there are Cargo configs at /projects/foo/bar/baz/mylib/.cargo/config.toml and /projects/foo/bar/baz/mybin/.cargo/config.toml, Cargo does not read those configuration files if it is invoked from the workspace root (/projects/foo/bar/baz/).

Cargo reading the configuration file per workspace member, rather than stabilising per-package-target, would probably be my preference for allowing building workspace members for distinct target platforms the future.

I currently use multiple workspaces, but another stable option is to use #[cfg] to stub out the code when it is compiled for the wrong target. This does not help with building binaries for the right target, but it means that cargo test and similar will be able to succeed instead of erroring out due to code that cannot compile on the selected target.