esden / summon-arm-toolchain

This project is not under active development any more. Consider using https://launchpad.net/gcc-arm-embedded instead! A very simple build script for bare metal arm toolchain. NO LINUX!
http://summon-arm-toolchain.org/
213 stars 92 forks source link

Can't use hard-float with libc? (VFP register linker error) #40

Closed mlamoore closed 11 years ago

mlamoore commented 11 years ago

I'm trying to build the stm32f4 usb_cdcacm example at https://github.com/libopencm3/libopencm3 using summon-arm-toolchain, but I'm getting a linker error when I use memcpy as it looks like gcc is trying to link to a libc.a library that doesn't have floating point support. I made a stripped down test.c to reproduce the issue as simply as possible:

test.c:

#include <string.h>

#define arrayLen 6
static char src[arrayLen] = "hello";
static char dest[arrayLen] = "world";

int main(void)
{
    float scale = 0.25f;

    /* If this memcpy is commented out, the file compiles and links fine */
    memcpy( dest, src, arrayLen );

    while (1) {
        scale   *= 0.875f;
    }

    return 0;
}

I grabbed the commands and arguments that make was using and ran gcc directly from the command line.

Compile (no errors):

arm-none-eabi-gcc -Os -g -Wall -Wextra -I/home/morgan/sat/bin/../arm-none-eabi/include -fno-common -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -MD -DSTM32F4 -o test.o -c test.c

Link:

arm-none-eabi-gcc -o test.elf test.o -lopencm3_stm32f4 --static -lc -lnosys -L/home/morgan/sat/bin/../arm-none-eabi/lib -L/home/morgan/sat/bin/../arm-none-eabi/lib/stm32/f4 -T./stm32f4-discovery.ld -nostartfiles -Wl,--gc-sections -mthumb -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--print-gc-sections

Here's the errors I got:

/home/morgan/sat/lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/bin/ld: error: test.elf uses VFP register arguments, /home/morgan/sat/bin/../arm-none-eabi/lib/libc.a(lib_a-memcpy.o) does not
/home/morgan/sat/lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/bin/ld: failed to merge target specific data of file /home/morgan/sat/bin/../arm-none-eabi/lib/libc.a(lib_a-memcpy.o)
collect2: ld returned 1 exit status

If I try to remove -lopencm3_stm32f4 and -nostartfiles, I get a ridiculously long list of errors that make me think I'd need to dig into the linker script to figure them out.

Am I (or the libopencm3 Makefile) doing something wrong here? All of the other libopencm3 stm32f4 examples compiled, linked, and ran just fine, but they just use libopencm3 functions, no memcpy or other libc functions.

mlamoore commented 11 years ago

I found the problem (with some help from a friend). It stems from me not understanding gcc multi-lib properly; I thought it would select which library to use based on compiler flags, but it turns out you still need to direct it to the correct version of the library in the linker flags.

It's an error in the makefile that ships with libopencm3; because the makefile linked with -L to both arm-none-eabi/lib and arm-none-eabi/lib/thumb/cortex-m4/float-abi-hard/fpuv4-sp-d16 with the plain /lib first, it was using the libc.a from /lib instead of the floating-point specific subdirectory.

I'll look into how to push a fixed version to libopencm3.