Closed newAM closed 2 years ago
As discussed in the embedded rust chat, here are reproducition specifics and the cargo tree
output:
$ git clone git@github.com:newAM/stm32wl-hal.git -b cmrt-issue
$ git rev-parse HEAD
b3301b550342b0b61ef6425b7dce257ba45c6962
$ cargo build -p i2c-testsuite
I think I can offer a couple of explanations for the observed behaviour, at least:
__ONCE__
key is only detected by the linker, and I guess in this case it's complaining about duplicate __INTERRUPTS
before it gets to complaining about duplicate __ONCE__
.links
key failure is because defmt can work with any 0.6
cortex-m-rt, and stm32wl can work with any >=0.6.15,<0.8
. Cargo resolves stm32wl to use cortex-m-rt 0.7.0, then for defmt detects that 0.6.15 can't be linked (because of the links
key) so picks 0.6.14, which is supported by defmt and doesn't specify links
.It would be much better if Cargo could somehow know to resolve this to a single instance of c-m-rt 0.6.15, but as far as it's concerned there's no problem with 0.6.14 and 0.7.0 co-existing, because we didn't use the links key until 0.6.15.
I think if you add cortex-m-rt = "0.6.15"
to your top-level Cargo.toml, it should convince Cargo to resolve to a working solution. I don't know if yanking all previous 0.6.x crates would also work, or just cause a build error, but I guess we could try it and see.
I have yanked 0.6.11
through 0.6.14
, leaving only 0.6.15
in the 0.6 release, which seems to resolve this problem! I'm still a bit amazed, but Cargo now successfully resolves this problem to only using 0.6.15
, which works. Affected projects will probably need to run cargo update
to become fixed.
That's a better outcome than I had hoped for!
I am amazed cargo was able to select the correct version that satisfied all constraints!
$ cargo update
Updating crates.io index
Removing cortex-m-rt v0.6.14
Removing cortex-m-rt v0.7.0
Adding cortex-m-rt v0.6.15
Removing cortex-m-rt-macros v0.1.8
Removing cortex-m-rt-macros v0.7.0
Adding cortex-m-rt-macros v0.6.15
I don't think there is anything that can be done for people with cached copies of 0.6.14
so I will close the issue now.
Problem
I occasionally help people in the rust-embedded matrix chat. The most frequent issue is people trying to figure out why their build does not link. Majority of the time it is because of multiple competing versions of
cortex-m-rt
.Given the volume of embedded-rust newcomers asking for help with this issue I suspect there are many more people giving up after being unable to figure it out. This is not ideal.
Reproduction
This is an example of one of the errors that can occur with multiple cortex-m-rt versions. This can easily occur after running
cargo-update
where some dependencies have been updated to supportcortex-m-rt
v0.7, and some only support v0.6; for exampledefmt-test
v0.2.3 only supports v0.6, whereas v0.14.0 of the STM32 PACs support v0.6 and v0.7.That might not be so bad if the issue was easily searchable, but none of the first-page results from my search engine had relevant information.
Research
I see that there is a
__ONCE
symbol incortex-m-rt
, but this has never come up when I have run into this issue myself, or when I have helped someone else with this issue.https://github.com/rust-embedded/cortex-m-rt/blob/e48af90b9bb4ce38762b1ee134c9b4991fd605b0/src/lib.rs#L719-L725
As mentioned in the above code the
links
manifest key should resolve this problem; but Cargo seemingly ignores that and allows us to get all the way to calling the linker before any errors appear.https://github.com/rust-embedded/cortex-m-rt/blob/e48af90b9bb4ce38762b1ee134c9b4991fd605b0/Cargo.toml#L17
Solutions
I want multiple versions of
cortex-m-rt
appearing in the dependency tree to result in a clear indication of why the build failed.I can spend time to resolve this problem; but I wanted to bring it up first to see if I am missing any history, or an obvious solution.