Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP


Update makefile for stm32f4 examples so usb_cdcacm example now compiles #65

wants to merge 2 commits into from

6 participants


On three different computers (two Ubuntu and one Fedora), the STM32F4 USB CDC example wouldn't compile; it gave a linker error about VFP registers not being used by libc.a. This is described in Issue #59.

I found that the linker was using arm-none-eabi/lib/libc.a when it should have been using arm-none-eabi/lib/thumb/cortex-m4/float-abi-hard/fpuv4-sp-d16/libc.a for the Cortex M4 hard-float version of the library. I modified the LDFLAGS -L directives to use the hard-float path.

I compiled all of the STM32F4 examples using the modified makefile and ran each one on my STM32F4Discovery board. They all ran as expected (although I don't have UART2 hooked up to check that, the LEDs blinked properly on the UART examples), even the USB CDC example which had previously given me linker errors.


Providing explicit path to the libraries should not be necessary. The compiler should be choosing the right directory based on the -mthumb -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 parameters.

That is what I expected also, but I have three computers where I got that linker error, and the two of them where I explicitly gave the path, it compiled and ran properly.

Could it be that the original makefile gave both /lib and /lib/stm32/f4; could that be overriding the automatic selection? I'll try that when I can; if not, it seems like a bug in the toolchain.


I ran into this issue yesterday and tried your patch just now. With the patch I was unable to compile any of the stm32f4-discovery examples, failing with LD not finding libopencm3_stm32f4.ld. Restoring the flag -L$(TOOLCHAIN_DIR)/lib to LDFLAGS resolved the issue for me.

EDIT: I just tried building again on a fresh clone, without the patch, and it compiles without error. I suspect that my initial problem was in my toolchain as I rolled that by hand. When I then apply the patch, it fails as I mentioned above.


I added -L$(TOOLCHAIN_DIR)/lib after the full path, which still works for me and should resolve technobauble's issue. It still fails to build for me with just that (without the full path), though, which is strange.

The libopencm3 example makefile directs it to use stm32f4_discovery.ld from within the examples directory so the example as grabbed from github shouldn't be using $(TOOLCHAIN_DIR)/lib/libopencm3_stm32f4.ld though.

I tried it again on my system with different variants. With /lib and /lib/stm32/f4 (stock), it fails. With just /lib, it fails. With /lib and /lib/thumb/cortex-m4/float-abi-hard/fpuv4-sp-d16, it fails. With just /lib/thumb/cortex-m4/float-abi-hard/fpuv4-sp-d16, it succeeds. With /lib/thumb/cortex-m4/float-abi-hard/fpuv4-sp-d16 and /lib, it succeeds.

I find it strange that the makefile calls out $TOOLCHAIN_DIR/lib/stm32/f4, which doesn't exist in my toolchain (summon-arm-toolchain most recent version).

It seems like a few people have had the same issue as I have; do we want to add the explicit directory as a workaround for the 5 or 10 people who have this issue even though it shouldn't be required and isn't for most?


When I was looking at this, I added an info statement to the makefile to see what the value of TOOLCHAIN_DIR actually was. It was the default ../../../../.. which pointed to the root of the libopencm3 source tree, not the root of my actual tool chain.

The summon-arm-toolchain script does include libopencm3, but it is the last thing that is built. None of the other programs that are built as part of that script are dependent on libopencm3. Since the examples are built immediately after the library (make with no specific target builds everything), the libopencm3 files haven't been installed in the system yet.

I assumed that that was the point of all of those ifeq, ifneq statements starting at line 32, to detect whether the examples were being built before the library was installed (in which case it needs to grab the files from the local source tree) or after the library was installed (in which case it can get them from the location where the tool chain is installed).


The lookups are to try and work out whether the file is being used inside the libopencm3 build, or whether it has been copied to an external directory.

There's probably still wrinkles, but you never ever want to give -L or -I paths to inside the actual gcc directories. That way is a surefire way to confuse the multilib config and end up with incompatible linking like you're seeing. You're right, it's confusing to talk about TOOLCHAIN_DIR, when it means OPENCM3_DIR.

Have a look at the F1 makefile, it does this more the way you intend.


Another option is to specify float-abi=soft instead of float-abi=hard in examples/stm32/f4/Makefile.include and lib/stm32/f4/Makefile.

Floating point is used in both cases, only the argument transfer is slower with "soft". But if you use threads, context switch doesn't need to care for the FPU registers in the "soft" case to my understanding.


Is this still an issue. Is there a consensus on how to solve this? For me all the examples compile fine with gcc-arm-embedded toolchain 2012q4 and 2013q1.

Is there still action needed?


@nagromo OK no worries. I just wanted to make sure that I am not missing something. Thanks! I am closing this pull request then. :)

@esden esden closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 14, 2012
  1. @nagromo

    Changed STM32F4 makefile so hard-float version of libc.a is used, usb…

    nagromo authored
    …_cdcacm example now successfully compiles.
Commits on Nov 15, 2012
  1. @nagromo
This page is out of date. Refresh to see the latest.
Showing with 3 additions and 3 deletions.
  1. +3 −3 examples/stm32/f4/Makefile.include
6 examples/stm32/f4/Makefile.include
@@ -43,9 +43,9 @@ CFLAGS += -Os -g -Wall -Wextra -I$(TOOLCHAIN_DIR)/include \
-fno-common -mcpu=cortex-m4 -mthumb \
-mfloat-abi=hard -mfpu=fpv4-sp-d16 -MD -DSTM32F4
-LDFLAGS += --static -lc -lnosys -L$(TOOLCHAIN_DIR)/lib \
- -L$(TOOLCHAIN_DIR)/lib/stm32/f4 \
- -T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections \
+LDFLAGS += --static -lc -lnosys \
+ -L$(TOOLCHAIN_DIR)/lib/thumb/cortex-m4/float-abi-hard/fpuv4-sp-d16 \
+ -L$(TOOLCHAIN_DIR)/lib -T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections \
-mthumb -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16
Something went wrong with that request. Please try again.