Build workspace with multiple target subprojects

Hey,
I am currently developing a project where I have one cargo workspace, with multiple subprojects, of which one compiles to thumbv6m-none-eabi (with nostd) .
The other binaries are "normal" x86_64 projects.
There are also 2 library subprojects which are depended on by both the thumbv6m and the other binaries, as they provide utility functions and data transfer structs.

Seperately, the projects compile, but when I run cargo build in the root directory, I get the following issue:

`error: duplicate lang item in crate `std` (which `rand` depends on): `panic_impl`.
  |
  = note: the lang item is first defined in crate `panic_halt` (which `subproject_2` depends on)
  = note: first definition in `panic_halt` loaded from ~/implementation/target/debug/deps/libpanic_halt-b61cb123f19c3931.rlib
  = note: second definition in `std` loaded from ~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-5670385a2fe8b60b.so, ~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-5670385a2fe8b60b.rlib

error: could not compile `subproject_2` due to previous error`

Does someone know how to solve this issue?

2 Likes

Do you have any libraries that are conditionally #![no_std]? If so feature unification will enable the std feature for all targets. You can try enabling the v2 feature resolver (resolver = 2 in the [workspace] section of the workspace Cargo.toml) Make sure to not build the std and no_std targets using a single cargo invocation though as that will unify the features again. You will have to use separate cargo invocations.

I activated the v2 resolver, but I still got the error.
I also use edition = "2021 in all projects, so I think the resolver was also already used before?

Make sure to not build the std and no_std targets using a single cargo invocation though as that will unify the features again. You will have to use separate cargo invocations.

Do you mean I should not run cargo build from the top level, but cargo build -p project_x86_1 -p project_x68_2 and cargo build -p project_armv6 separately?

I now implemented a solution by specifying the x86 projects as default-members, and only did stuff w/ the armv6 project if specified by -p armv6_project, and now the x86 projects compile without problem, but when I run cargo build -p armv6_project I get the error

error: language item required, but not found: `eh_personality`
  |
  = note: this can occur when a binary crate with `#![no_std]` is compiled for a target where `eh_personality` is defined in the standard library
  = help: you may be able to compile for a target that doesn't need `eh_personality`, specify a target with `--target` or in `.cargo/config`

If I compile with cargo build -p armv6_project --target thumbv6m-none-eabi, it works without issues, but shouldn't cargo be able to figure out the target on its own, since it is specified in armv6_project/.cargo/config.toml?

Cargo takes .cargo/config.toml from the current directory and it's parent directories, not from the directory in which the crate you are trying to build is located.

So would there be a correct way to specify the target for the subproject so that the workspace would use it as well?

I'm not sure there is a way other than explicitly passing --target to cargo right now.

Ok, thank you!

I basically have your same requirements, but I haven't found a good way of using a workspace for that.

I ended up ditching the workspace workflow, and setting up some custom recipes with just instead. There's also cargo-make that should be useful in this case, but I haven't properly looked into it yet.

I had great experiences with cargo-make before, but I wanted to avoid introducing another toolset into my project