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

Update Rust toolchain to nightly-2025-03-03 #634

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

tones111
Copy link
Contributor

This change bumps the toolchain to a recent nightly that incorporates LLVM codegen improvements and avr-none target.

Much thanks to @Patryk27 for all your hard work

closes #537

@tones111 tones111 force-pushed the toolchain branch 5 times, most recently from 1a0f125 to d4538ec Compare February 23, 2025 00:10
@tones111
Copy link
Contributor Author

I'd like to phone a friend (@Patryk27)

When I build locally I get an error like
/usr/bin/avr-ld: avr architecture of input file `/tmp/rustcyPlIoS/symbols.o' is incompatible with avr:51 output
which led me here and suggests a -mavr51 flag needs to be passed to the linker.

I'm not sure where symbols.o comes from. Maybe we need to (somehow) pass extra flags when building the core library?

It appears the avr-gcc on the CI system doesn't understand that flag

my versions

$ avr-gcc --version
avr-gcc (GCC) 14.2.0
$ avr-ld --version
GNU ld (GNU Binutils) 2.43

@Patryk27
Copy link
Contributor

[...] suggests a -mavr51 flag needs to be passed to the linker.

Yes, this is supposed to be done automatically by rustc:

https://github.com/rust-lang/rust/blob/bb2cc59a2172d6e35c89b409a4e6b5058d9039d7/compiler/rustc_codegen_ssa/src/back/linker.rs#L580

I'll take a look later at what's going on here!

@tones111 tones111 changed the title update toolchain to 2025-02-22 update toolchain to 2025-03-03 Mar 3, 2025
@tones111
Copy link
Contributor Author

tones111 commented Mar 5, 2025

Pinging @Rahix for another look now that the CI is passing.

@Rahix
Copy link
Owner

Rahix commented Mar 7, 2025

At last! Thanks everyone, especially @Patryk27, for the effort! I just smoke tested the uno examples to make sure we're not masking any obvious regressions - see below for documentation.

  • uno-16chan-servo-driver
  • uno-74hc595
  • uno-adc
  • uno-blink
  • uno-blink-embedded-hal
  • uno-eeprom
  • uno-ext-interrupt
  • uno-hc-sr04
  • uno-i2cdetect (1)
  • uno-infrared
  • uno-manual-servo
  • uno-millis
  • uno-panic (only builds in release now!)
  • uno-pin-change-interrupt
  • uno-println
  • uno-simple-pwm
  • uno-simple-pwm-embedded-hal
  • uno-spi-feedback
  • uno-timer
  • uno-usart
  • uno-watchdog

If someone is willing and able to run some of the ATtiny examples to gather a few more data points, that would not hurt.

Footnotes

  1. was not verified with actual devices on the bus

Comment on lines +110 to +113
run: cd "examples/${{ matrix.m.name }}" && cargo build --release --bins
- name: Compile board crate (without examples)
if: "${{ matrix.m.type == 'board' && !matrix.m.examples }}"
run: cd "arduino-hal/" && cargo build --features "${{ matrix.m.name }}"
run: cd "arduino-hal/" && cargo build --release --features "${{ matrix.m.name }}"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume you added --release here because some of the examples no longer build without release-mode, right?

From what I noticed, it is mainly the usual problem of panic bloat that gets cut down a bit more in release builds where less panicking code-paths remain.

Copy link
Contributor Author

@tones111 tones111 Mar 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, some of the example builds were running out of space so building for release feels like a better default. This is consistent with the AVR platform notes.

Note that since AVRs have rather small amounts of registers, ROM and RAM, it's
recommended to always use --release to avoid running out of space.

I'm not familiar with any workflows that would make use of debug info so documenting --release as the default way to build seems ok. If there's a way to remotely gdb that would be great to document.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The meaning of --release is entirely dependent on the profile-configuration. We're advertising a recommended set of profiles here in avr-hal and in the template repository. Currently, they look like this:

avr-hal/Cargo.toml

Lines 1 to 11 in 1d158e0

[profile.dev]
panic = "abort"
lto = true
opt-level = "s"
[profile.release]
panic = "abort"
codegen-units = 1
debug = true
lto = true
opt-level = "s"

(and imagine those being merged with the default profiles from cargo).

I do want to keep the situation where both dev and release profiles are usable for most applications. So I guess we'll have to dig in a bit why this is happening now. As mentioned, the smoking gun is panic bloat. The main remaining difference between dev and release is this:

[profile.dev]
debug-assertions = true
overflow-checks = true

[profile.release]
debug-assertions = false
overflow-checks = false

Both settings lead to a number of additional panicking code paths being introduced. If they cannot be optimized out, they quickly fill up RAM with useless formatting info.

I really don't think we should disable either of them in the dev profile because that would really degrade the Rust experience in my eyes. But maybe we can tweak dependency profiles or the like to work around the regression.

Copy link
Contributor Author

@tones111 tones111 Mar 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uno-panic is one of the problematic binaries (see #639). I agree changing those dev profile flags would be surprising to users as it essentially turns dev into a release build. At that point I think telling users to explicitly build with --release is the better option.

Baseline sizes for a couple binaries are

   text	   data	    bss	    dec	    hex	filename
    892	      0	      1	    893	    37d	../../target/avr-none/debug/uno-timer.elf
   1016	      0	      1	   1017	    3f9	../../target/avr-none/release/uno-timer.elf
   1504	      0	      1	   1505	    5e1	../../target/avr-none/release/uno-panic.elf

Turning off debug-assertions

   text	   data	    bss	    dec	    hex	filename
    908	      0	      1	    909	    38d	../../target/avr-none/debug/uno-timer.elf
   4336	      0	      1	   4337	   10f1	../../target/avr-none/debug/uno-panic.elf

Turning off debug-assertions and overflow-checks

   text	   data	    bss	    dec	    hex	filename
   1016	      0	      1	   1017	    3f9	../../target/avr-none/debug/uno-timer.elf
   3062	      0	      1	   3063	    bf7	../../target/avr-none/debug/uno-panic.elf

Only if we also set codegen-units=1 does the size of uno-panic come down.

For these devices which have a reputation for being extremely space limited I fail to understand the value in trying to support the debug profile. However, tracking code size regressions for release builds seems like a worthwhile endeavor. Panic bloat will become increasingly problematic as application complexity scales beyond the small examples here.

EDIT:
For comparison the sizes when building with the 2024-03-22 toolchain (main branch) are:

   text	   data	    bss	    dec	    hex	filename
    936	      0	      1	    937	    3a9	../../target/avr-atmega328p/debug/uno-timer.elf
    838	      0	      1	    839	    347	../../target/avr-atmega328p/release/uno-timer.elf
   5512	      0	      1	   5513	   1589	../../target/avr-atmega328p/debug/uno-panic.elf
   3164	      0	      1	   3165	    c5d	../../target/avr-atmega328p/release/uno-panic.elf

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After more investigation I've narrowed the debug bloat down to printing the panic information. Debug binary size is small when commented out, but as soon as we try to format anything from the PanicInfo (even just the line number) we get the linker error.

@@ -47,7 +47,7 @@ Go into `./examples/arduino-uno` (or the directory for whatever board you want),
cd examples/arduino-uno

# Build and run it on a connected board
cargo run --bin uno-blink
cargo run --release --bin uno-blink
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We really shouldn't require release builds. If panic bloat is more of a problem now, we'll have to be more explicit about this topic or, worst-case, adjust the dev-profile even further.

@Rahix Rahix changed the title update toolchain to 2025-03-03 Update Rust toolchain to nightly-2025-03-03 Mar 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

cargo build - error[E0658] - proc_macro::Literal::byte_character(byte)
3 participants