rust-embedded / cortex-m-rt

Minimal startup / runtime for Cortex-M microcontrollers
https://rust-embedded.github.io/cortex-m-rt/
Apache License 2.0
357 stars 86 forks source link

Multiple versions of cortex-m-rt result in cryptic error messages #334

Closed newAM closed 2 years ago

newAM commented 2 years ago

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 support cortex-m-rt v0.7, and some only support v0.6; for example defmt-test v0.2.3 only supports v0.6, whereas v0.14.0 of the STM32 PACs support v0.6 and v0.7.

error: linking with `rust-lld` failed: exit status: 1
  |
  = note: "rust-lld" "-flavor" "gnu" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/test-7bb9f543160fc5fc.28o51mcvkezqk1bh.rcgu.o" "--as-needed" "-L" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps" "-L" "/home/alex/git/stm32wl-hal/target/debug/deps" "-L" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/build/cortex-m-rt-7fab41c177d4fb0f/out" "-L" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/build/defmt-e37492638165185b/out" "-L" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/build/cortex-m-56b20a9b0835c0ff/out" "-L" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/build/stm32wl-268b2e40109f6f19/out" "-L" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/build/cortex-m-rt-cf47941bc4772413/out" "-L" "/home/alex/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/thumbv7em-none-eabi/lib" "-Bstatic" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libdefmt_test-9f371f939b139b49.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libcortex_m_rt-7df8bdb1dd11ff88.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libr0-602c7ed723b34751.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libstm32wl_hal-2ae90adfd010dd5a.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libstm32wl-5fec99ee93c356df.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libcortex_m_rt-46297efa72630679.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libcfg_if-05e71c6a35eeb6de.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libchrono-ac8b55667f3c9bcf.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/librand_core-dc07f9dc61de6756.rlib" "--start-group" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libpanic_probe-61a175f21d2c8c99.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libembedded_time-e061ed870c75067c.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libnum-c85645144549749b.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libnum_iter-4a21facd3ab3e331.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libnum_rational-b3d074ec9176569a.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libnum_integer-8a74ce159e1f669d.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libnum_complex-c9f8137f56efb0dd.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libnum_traits-4307b922f9b4b756.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libdefmt_rtt-38bc22b2adffba63.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libcortex_m-40581eb3fc91d2b0.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libcortex_m-23e76122a2f86782.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libembedded_hal-69d52c2a1ee42c23.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libvoid-3ce2cd42bc98cdb6.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libnb-25f3ac2ede577050.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libnb-6365406616716452.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libvolatile_register-a48e15f701df1f57.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libvcell-d827d46a7152656b.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libbare_metal-81f3d5188ce3d3cb.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libaligned-9c8756e84e1f418c.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libas_slice-f7454d2f32cd3256.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libstable_deref_trait-4ea5805194eda68c.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libgeneric_array-12600132a8a8155f.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libgeneric_array-a081ec9aa958f16c.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libgeneric_array-e55f1eb08d4d9917.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libtypenum-645588d57cbff92c.rlib" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libdefmt-6e8c3be752d3f185.rlib" "/home/alex/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/thumbv7em-none-eabi/lib/librustc_std_workspace_core-d6d984acbe5c493d.rlib" "/home/alex/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/thumbv7em-none-eabi/lib/libcore-05b1c0282b74dcd0.rlib" "--end-group" "/home/alex/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/thumbv7em-none-eabi/lib/libcompiler_builtins-795fbc950b6110ce.rlib" "-Bdynamic" "--eh-frame-hdr" "-znoexecstack" "-L" "/home/alex/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/thumbv7em-none-eabi/lib" "-o" "/home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/test-7bb9f543160fc5fc" "--gc-sections" "-O1" "-Tlink.x" "-Tdefmt.x"
  = note: rust-lld: error: duplicate symbol: __INTERRUPTS
          >>> defined at lib.rs:709 (/home/alex/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-rt-0.6.14/src/lib.rs:709)
          >>>            cortex_m_rt-7df8bdb1dd11ff88.cortex_m_rt.7d823d51-cgu.0.rcgu.o:(__INTERRUPTS) in archive /home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libcortex_m_rt-7df8bdb1dd11ff88.rlib
          >>> defined at mod.rs:87 (/home/alex/.cargo/registry/src/github.com-1ecc6299db9ec823/stm32wl-0.14.0/src/stm32wl5x_cm4/mod.rs:87)
          >>>            stm32wl-5fec99ee93c356df.stm32wl.ff5dee21-cgu.0.rcgu.o:(.vector_table.interrupts+0x0) in archive /home/alex/git/stm32wl-hal/target/thumbv7em-none-eabi/debug/deps/libstm32wl-5fec99ee93c356df.rlib

error: could not compile `i2c-testsuite` due to previous error

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 in cortex-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.

newAM commented 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
cargo tree ``` i2c-testsuite v0.1.0 (/home/alex/git/stm32wl-hal/i2c-testsuite) ├── cortex-m-rt v0.6.14 │ ├── cortex-m-rt-macros v0.1.8 (proc-macro) │ │ ├── proc-macro2 v1.0.29 │ │ │ └── unicode-xid v0.2.2 │ │ ├── quote v1.0.9 │ │ │ └── proc-macro2 v1.0.29 (*) │ │ └── syn v1.0.78 │ │ ├── proc-macro2 v1.0.29 (*) │ │ ├── quote v1.0.9 (*) │ │ └── unicode-xid v0.2.2 │ └── r0 v0.2.2 ├── defmt v0.2.3 │ └── defmt-macros v0.2.3 (proc-macro) │ ├── defmt-parser v0.2.2 │ ├── proc-macro2 v1.0.29 (*) │ ├── quote v1.0.9 (*) │ └── syn v1.0.78 (*) │ [build-dependencies] │ └── semver v1.0.4 ├── defmt-rtt v0.2.0 │ ├── cortex-m v0.6.7 │ │ ├── aligned v0.3.5 │ │ │ └── as-slice v0.1.5 │ │ │ ├── generic-array v0.12.4 │ │ │ │ └── typenum v1.14.0 │ │ │ ├── generic-array v0.13.3 │ │ │ │ └── typenum v1.14.0 │ │ │ ├── generic-array v0.14.4 │ │ │ │ └── typenum v1.14.0 │ │ │ │ [build-dependencies] │ │ │ │ └── version_check v0.9.3 │ │ │ └── stable_deref_trait v1.2.0 │ │ ├── bare-metal v0.2.5 │ │ │ [build-dependencies] │ │ │ └── rustc_version v0.2.3 │ │ │ └── semver v0.9.0 │ │ │ └── semver-parser v0.7.0 │ │ ├── bitfield v0.13.2 │ │ ├── cortex-m v0.7.3 │ │ │ ├── bare-metal v0.2.5 (*) │ │ │ ├── bitfield v0.13.2 │ │ │ ├── embedded-hal v0.2.6 │ │ │ │ ├── nb v0.1.3 │ │ │ │ │ └── nb v1.0.0 │ │ │ │ └── void v1.0.2 │ │ │ └── volatile-register v0.2.1 │ │ │ └── vcell v0.1.3 │ │ └── volatile-register v0.2.1 (*) │ └── defmt v0.2.3 (*) ├── defmt-test v0.2.3 │ ├── cortex-m v0.7.3 (*) │ ├── cortex-m-rt v0.6.14 (*) │ ├── defmt v0.2.3 (*) │ └── defmt-test-macros v0.2.1 (proc-macro) │ ├── proc-macro2 v1.0.29 (*) │ ├── quote v1.0.9 (*) │ └── syn v1.0.78 (*) ├── embedded-time v0.12.1 │ └── num v0.3.1 │ ├── num-complex v0.3.1 │ │ └── num-traits v0.2.14 │ │ [build-dependencies] │ │ └── autocfg v1.0.1 │ ├── num-integer v0.1.44 │ │ └── num-traits v0.2.14 (*) │ │ [build-dependencies] │ │ └── autocfg v1.0.1 │ ├── num-iter v0.1.42 │ │ ├── num-integer v0.1.44 (*) │ │ └── num-traits v0.2.14 (*) │ │ [build-dependencies] │ │ └── autocfg v1.0.1 │ ├── num-rational v0.3.2 │ │ ├── num-integer v0.1.44 (*) │ │ └── num-traits v0.2.14 (*) │ │ [build-dependencies] │ │ └── autocfg v1.0.1 │ └── num-traits v0.2.14 (*) ├── panic-probe v0.2.1 │ ├── cortex-m v0.7.3 (*) │ └── defmt v0.2.3 (*) └── stm32wl-hal v0.1.0-alpha.0 (/home/alex/git/stm32wl-hal/hal) ├── cfg-if v1.0.0 ├── chrono v0.4.19 │ ├── num-integer v0.1.44 (*) │ └── num-traits v0.2.14 (*) ├── cortex-m v0.7.3 (*) ├── defmt v0.2.3 (*) ├── embedded-hal v0.2.6 (*) ├── embedded-time v0.12.1 (*) ├── nb v1.0.0 ├── num-traits v0.2.14 (*) ├── paste v1.0.5 (proc-macro) ├── rand_core v0.6.3 ├── stm32wl v0.14.0 │ ├── bare-metal v1.0.0 │ ├── cortex-m v0.7.3 (*) │ ├── cortex-m-rt v0.7.0 │ │ └── cortex-m-rt-macros v0.7.0 (proc-macro) │ │ ├── proc-macro2 v1.0.29 (*) │ │ ├── quote v1.0.9 (*) │ │ └── syn v1.0.78 (*) │ └── vcell v0.1.3 └── void v1.0.2 ```
adamgreig commented 2 years ago

I think I can offer a couple of explanations for the observed behaviour, at least:

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.

adamgreig commented 2 years ago

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.

newAM commented 2 years ago

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.