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

Linker error when using a floating point operation #514

Closed
MichalOp opened this issue Mar 6, 2024 · 3 comments
Closed

Linker error when using a floating point operation #514

MichalOp opened this issue Mar 6, 2024 · 3 comments
Labels
compiler-bug Not a bug in avr-hal, but a bug in the rust compiler/LLVM

Comments

@MichalOp
Copy link

MichalOp commented Mar 6, 2024

It seems that I can't use a lot of the floating point functions (when compiling for atmega328p), for example min:

#![no_std]
#![no_main]

use panic_halt as _;

#[arduino_hal::entry]
fn main() -> ! {
    let dp = arduino_hal::Peripherals::take().unwrap();
    let pins = arduino_hal::pins!(dp);
    let mut led = pins.d13.into_output();
    let mut x: f32 = 0.0;
    loop {
        x += 0.1;
        led.toggle();
        arduino_hal::delay_ms(x.min(1000.0) as u16); 
    }
}

This fails to link with the following error:

~/Embedded/min-test$ cargo run
   Compiling min-test v0.1.0 ($HOME/Embedded/min-test)
WARN rustc_codegen_ssa::back::link Linker does not support -no-pie command line option. Retrying without.
error: linking with `avr-gcc` failed: exit status: 1
  |
  = note: LC_ALL="C" PATH="$HOME/.rustup/toolchains/nightly-2023-12-28-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/bin: ........" VSLANG="1033" "avr-gcc" "-mmcu=atmega328p" "/tmp/rustcjNe3pr/symbols.o" "$HOME/Embedded/min-test/target/avr-atmega328p/debug/deps/min_test-5e911a0772a75ebb.arduino_hal-e191b5c45c882469.arduino_hal.bbf3967b75265d73-cgu.0.rcgu.o.rcgu.o" "-Wl,--as-needed" "-L" "$HOME/Embedded/min-test/target/avr-atmega328p/debug/deps" "-L" "$HOME/Embedded/min-test/target/debug/deps" "-L" "$HOME/.rustup/toolchains/nightly-2023-12-28-x86_64-unknown-linux-gnu/lib/rustlib/avr-atmega328p/lib" "-Wl,-Bdynamic" "-lgcc" "-Wl,-z,noexecstack" "-L" "$HOME/.rustup/toolchains/nightly-2023-12-28-x86_64-unknown-linux-gnu/lib/rustlib/avr-atmega328p/lib" "-o" "$HOME/Embedded/min-test/target/avr-atmega328p/debug/deps/min_test-5e911a0772a75ebb.elf" "-Wl,--gc-sections"
  = note: $HOME/Embedded/min-test/target/avr-atmega328p/debug/deps/min_test-5e911a0772a75ebb.arduino_hal-e191b5c45c882469.arduino_hal.bbf3967b75265d73-cgu.0.rcgu.o.rcgu.o: In function `core::f32::_$LT$impl$u20$f32$GT$::min::h6a8fe8903685e749':
          $HOME/.rustup/toolchains/nightly-2023-12-28-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/num/f32.rs:929: undefined reference to `fminf'
          collect2: error: ld returned 1 exit status
          
  = note: some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified
  = note: use the `-l` flag to specify native libraries to link
  = note: use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)

error: could not compile `min-test` (bin "min-test") due to 1 previous error

My understanding is that this function and other float functions should be available in the avr-libc. I tried adding -lm to the linker args in avr-specs, but it didn't help. I also tried the new nightly toolchain and both the newest and mentioned in the readme commits of this repo.

I am on Ubuntu 22.04, and I installed the prerequisites according to the readme, so I have avr-gcc 5.4.0 and avr-libc 2.0.0. If I don't use the floating point functions, the code compiles normally - am I missing something?

@MichalOp MichalOp changed the title Linker failure when using a floating point operation Linker error when using a floating point operation Mar 6, 2024
@Rahix
Copy link
Owner

Rahix commented Mar 7, 2024

Hm, I know that in the past, a lot of the floating point methods didn't exist in libcore so you couldn't call them in the first place. The solution back then was to use the libm crate instead which has replacement implementations. libm::fminf() in your case...

But as your program is failing at the linker stage instead of simply erroring on a missing f32::min() method, it seems something has changed here. Maybe another compiler-builtins topic? @Patryk27, do you have any idea?

@Rahix Rahix added the compiler-bug Not a bug in avr-hal, but a bug in the rust compiler/LLVM label Mar 7, 2024
@Patryk27
Copy link
Contributor

Patryk27 commented Mar 8, 2024

I've just checked and the code compiles correctly on my machine - could you run avr-gcc --version and post the result? Maybe you're using an older avr-gcc which didn't yet have float intrinsics for AVR.

(for comparison, I'm on avr-gcc (Homebrew AVR GCC 9.4.0) 9.4.0)

@MichalOp
Copy link
Author

MichalOp commented Mar 9, 2024

It looks like this was the issue, thank you. I was using avr-gcc 5.4.0 - which is the default one installed via apt for Ubuntu, and I guess it is too old.

After I compiled gcc 13.2.0 from source for avr (I also compiled avr-libc 2.1.0 for good measure), the program compiled and ran without issues.

@MichalOp MichalOp closed this as completed Mar 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler-bug Not a bug in avr-hal, but a bug in the rust compiler/LLVM
Projects
None yet
Development

No branches or pull requests

3 participants