How to build for multiple archs?

Hi, my first Rust project is a firmware for avr, stm32 and rp2040, using their respective embedded-hals. I've a workspace with 3 subs, each of them have a .cargo/config.toml with their proper 'target = triplet'.
If I start the build process in any of the 3 subs, the build process for that single target works. If I cd .. to the root of the workspace, it doesn't work. I've found a post on stackexchange pointing to the book, saying the config.toml files are ignored if the build process is started from the workspace's root.

What's the best practice for building multiple targets using multiple toolchains?

Thanks

that statement is misleading, or, inaccurate, to say the least.

when invoked from a workspace, the .cargo/config.toml files of each individual crate is NOT read, but cargo will instead read the .cargo/config.toml file located at the workspace root.

you should use multiple workspaces, one for each target archtecture.

Is this the recommended practice?

Is there a way to specify a toolchain+target in the main .cargo/config.toml at the workspace root?

I don't know what counts as "recommended" practice, but I would for sure recommend it personally.

see the following template for an example:

you can read the blog post linked in the README, but the short summary is, the root directory is a workspace (with virtual manifest Cargo.toml and configuration .cargo/config.toml) for library crates containing portable code (i.e. architecture independent) and tests that can be run on the host machine; then the subdirectory cross is also a workspace containing target specific crates, including drivers for the target board, the entry point for the app, and tests that can only be run on the target.

you can adapt this template to suit your use case. for example, you can have multiple cross-compiling workspaces, one for each target, and maybe name them after the target architectures (unlike crates, workspace doesn't have a name, no need to avoid namespace collision, you just name the directory however you like). also, if your project has many library crates with portable code, you may want to put them under a subdirectory (again, name the directory however you see fit, like crates/ or libs/, etc) to reduce the clutter in the root.

the "target" is a cargo configuration, it can be set in the config file .cargo/config.toml, or you can override using environment variable or command line flags:

https://doc.rust-lang.org/stable/cargo/reference/config.html#buildtarget

the "toolchain" is an option for rustup, it can be specifiied using a rust-toolchain.toml file, or can be set using rustup override command; it can also be specified using environment variable or command line flags:

https://rust-lang.github.io/rustup/overrides.html

1 Like

Thanks, that example is pretty self-explanatory. I had spotted that blog entry a few days ago but I skipped the reading because I'm pretty far from the test part... learning...

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.