Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

per-package-target unifies features which can conflict with other targets #9521

Open
MarkSwanson opened this issue May 29, 2021 · 5 comments
Labels
C-bug Category: bug S-needs-design Status: Needs someone to work further on the design for the feature or fix. NOT YET accepted. S-needs-mentor Status: Issue or feature is accepted, but needs a team member to commit to helping and reviewing. Z-per-package-target Nightly: per-package-target

Comments

@MarkSwanson
Copy link

Problem
'cargo build --verbose' seems to indicate that rustc is compiling for the wrong target.

Steps

  1. git clone https://github.com/MarkSwanson/build-failed1.git
  2. cargo build --verbose
    3.Note the rustc error compiling the void (1.0.2) crate
    ...
    std is required by void because it does not declare #![no_std]

Partial Workaround

  1. cd into each workspace package individually and 'cargo build'. For some reason cargo works perfectly this way.
    However, this doesn't work with vscode.
  2. remove "rpi4" from Cargo.toml workspace members.
    Sadly then I can't build the raspberry pi 4 target.

Notes
It seems positive that all build targets (x86, thumbv7em-none-eabihf, thumbv7m-none-eabi, armv7-unknown-linux-musleabihf) work perfectly if I run 'cargo build' from their respective workspace package dirs. (slight graph miscalculation when compiled from the root of the workspace?)

I note that the void crate is designed to work with std and no-std. However, the rustc error might indicate that rustc needs to have a slightly more robust check to detect how the void crate uses cfg or cfg_attr to support both environments?

Output of cargo version:
cargo 1.54.0-nightly (e931e47 2021-05-24)

@Ekleog
Copy link
Contributor

Ekleog commented May 29, 2021

Hmmm… Haven't investigated the linked code much yet, but based on the description I'd guess this is a side-effect of the second checkbox at #9406: void probably has a std feature, one of the crates of the workspace depends on it with the std feature, and the other one depends on it as no_std; thus leading to a problem.

Based on an overall look at the code, I'd think:

  • defmt-gdb transitively depends on void while requiring it to be no_std
  • rpi4 depends on nrf24l01 -> spidev -> nix 0.6.0 (that's an old version, probably bumping it somewhere along the dependency tree would be beneficial) -> void with the std feature

So I'll triage it on the tracking issue as one instance of the second checkbox, thank you for having filed this and linked there :)

@ehuss
Copy link
Contributor

ehuss commented Jun 3, 2021

I think this is somewhat a duplicate of #4463, which is unfortunately not easy to resolve.

@FrankvdStam
Copy link

I think I ran into a similar issue before when I was trying this feature. What ended up working for me was making sure I specify a target for each crate, even if it should be the default. So forced-target = "x86_64-pc-windows-msvc" in Cargo.toml with cargo-features = ["per-package-target"] at the top.

@tmplt
Copy link

tmplt commented Jun 14, 2021

I also hit this. I have a host application that depends on num-traits's std feature-set, and a firmware crate that depends on its no-std feature-set. See https://github.com/tmplt/cargo-rtic-trace/tree/demo/per-package-target. cargo-rtic-trace/ is the host application. examples/ contains the firmware.

@MarkSwanson
Copy link
Author

Fwiw I worked around this by using cargo-make. Example:

[config]
skip_core_tasks = true

[tasks.default]
command = ""
args = []
alias = "custom-default"

[tasks.custom-default]
dependencies = [ "build-rpi4", "build-stm32f103", "build-xtask", "build-defmt-gdb", "build-common" ]

# rustup target add thumbv7m-none-eabi
[tasks.build-stm32f103]
command = "cargo"
args = ["build", "--manifest-path", "stmf103/Cargo.toml"]
dependencies = [
    "readme"
]

...
However, I lose Cargo's workspace ability to ensure dependencies are the same between directories/packages.

I could also make each of these their own separate git repo/crate. But I'd still lose the workspace ability to ensure dependencies are the same.

I found that Cargo has resolver = "2" (a new resolver that includes more things in the dependency/build graph for each package) but it didn't work.

It seems that Cargo is trying hard to be considerate to the developer and ensure that only the minimal set of packages are compiled per workspace member. I appreciate that, but I wonder if we also need an option that says - just create a separate full build graph for each member. I realize this would increase initial compile times, but it would always work. Crazy?

@ehuss ehuss added the Z-per-package-target Nightly: per-package-target label Jul 1, 2021
@ehuss ehuss changed the title per-package-target seems to compile the wrong target per-package-target unifies features which can conflict with other targets May 8, 2023
@ehuss ehuss added S-needs-design Status: Needs someone to work further on the design for the feature or fix. NOT YET accepted. S-needs-mentor Status: Issue or feature is accepted, but needs a team member to commit to helping and reviewing. labels May 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: bug S-needs-design Status: Needs someone to work further on the design for the feature or fix. NOT YET accepted. S-needs-mentor Status: Issue or feature is accepted, but needs a team member to commit to helping and reviewing. Z-per-package-target Nightly: per-package-target
Projects
None yet
Development

No branches or pull requests

5 participants