Skip to main content
daemynnur
Associate II
October 22, 2015
Question

Linker Problem: undefined reference to `__errno'

  • October 22, 2015
  • 11 replies
  • 9938 views
Posted on October 22, 2015 at 18:20

Hi,

I'm trying to get to grips with System Workbench for STM32 & STM32F429i-Disco board.

I'm trying to build the STemWin_SampleDemo project for STM32F429I-Discovery, supplied in STM32Cube_FW_F4_V1.8.0

but it comes up with a linker error :

w_sqrt.c:(.text.sqrt+0xa8): undefined reference to `__errno'

collect2.exe: error: ld returned 1 exit status

I've tried everything I can find suggested here & elsewhere ( mainly revolving around linking the math library with -lm, but this makes no difference.)

I was kinda hoping that a project supplied by ST from their STMcube suite using the ST (supplied?)  IDE would compile without issue so i could use it as a platform to work from.

Other projects, including the 'STM32F429I-Discovery' demonstration project, (also using the STemWin library) build & link without issue.

Linker Script: -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -L..\..\..\..\..\..\..\..\Middlewares\ST\STemWin\Lib -specs=nosys.specs -specs=nano.specs -T''..\STM32F429NIHx_FLASH.ld'' -Wl,-Map=output.map -Wl,--gc-sections -lm

Any ideas on how to resolve this would be welcome

TIA... Daemy

P.S. same project compiles without issue on a Keil/Arm compiler [but I don't have easy access to that :( ]

    This topic has been closed for replies.

    11 replies

    AvaTar
    Senior III
    October 22, 2015
    Posted on October 22, 2015 at 19:46

    Not sure about your environment, but on a Linux system, _errno is usually located in libc.a, the C library linked in by default, or explicitly invoked by ''-lc''. And by definition, sqrt() sets the errno variable.

    You might need to check if you are linking against a proper libc.

    Alternatively, you might check if your compiler supports the -fno-math-errno option.

    daemynnur
    daemynnurAuthor
    Associate II
    October 23, 2015
    Posted on October 23, 2015 at 12:17

    Thanks,..

    Environment:

    Win7(32bit)SP1

    System Workbench for STM32 (Eclipse-Ac6 STM MCU GCC)

    MCU: STM32F429

    errno.h is in the include path

    as far as I can tell everything else is as it should be, but I'm kinda new to Eclipse & this MCU (moving up from years spent writing in C for 8051s on Keil C51 compiler) & atm not finding it as easy as I hoped :(

    AvaTar
    Senior III
    October 23, 2015
    Posted on October 23, 2015 at 13:21

    errno.h is in the include path

     

    The errno.h header only declares this variable - if you check, usually as ''external int errno;''.

    You need to link against a library that actually contains this variable. I don't know the System Workbench environment, so I'm not sure how it invokes the standard C libraries.

    I would start with checking the build log. Does the linker call contain a ''-nostdlib'' option ?

    Most toolchain keep several versions of the libraries (M0, M3, M4, soft, softfp, hard, etc.) in different paths. Perhaps there is something not setup correctly in your toolchain, or in your project settings ?

    Is there no ''System Workbench'' help regarding library usage ?

    daemynnur
    daemynnurAuthor
    Associate II
    October 23, 2015
    Posted on October 23, 2015 at 15:08

    Thanks for your help,

    the linker call does not include ''-nostdlib''

    there do appear to be several library versions, (pic attached) but I can find nowhere in the toolchain where the version is specified or any refernce in the help to doing so.

    this is a copy of the build log:

    'Invoking: MCU GCC Linker'

    arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -L..\..\..\..\..\..\..\..\Middlewares\ST\STemWin\Lib -specs=nosys.specs -specs=nano.specs -T''..\STM32F429NIHx_FLASH.ld'' -Wl,-Map=output.map -Wl,--gc-sections -lm -o ''STM32F429I_DISCO_MB1elf''

    ./Middlewares/STemWin/Config/GUIConf.o ./Middlewares/STemWin/Config/GUI_X.o ./Middlewares/STemWin/Config/LCDConf_stm32f429i_disco_MB1o ./Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal.o ./Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_cortex.o ./Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_crc.o ./Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_dma.o ./Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_dma2d.o ./Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_flash.o ./Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_flash_ex.o ./Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_gpio.o ./Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_i2c.o ./Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_i2c_ex.o ./Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_i2s.o ./Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_i2s_ex.o ./Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_ltdc.o ./Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_pwr.o ./Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_pwr_ex.o ./Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_rcc.o ./Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_rcc_ex.o ./Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_rtc.o ./Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_rtc_ex.o ./Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_sdram.o ./Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_spi.o ./Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_tim.o ./Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_tim_ex.o ./Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_uart.o ./Drivers/STM32F4xx_HAL_Driver/stm32f4xx_ll_fmc.o ./Drivers/CMSIS/system_stm32f4xx.o ./Drivers/BSP/STM324x9I_DISCO/stm32f429i_discovery.o ./Drivers/BSP/STM324x9I_DISCO/stm32f429i_discovery_io.o ./Drivers/BSP/STM324x9I_DISCO/stm32f429i_discovery_sdram.o ./Drivers/BSP/STM324x9I_DISCO/stm32f429i_discovery_ts.o ./Drivers/BSP/Components/ili9o ./Drivers/BSP/Components/stmpe8o ./Application/User/calibration.o ./Application/User/main.o ./Application/User/rtc.o ./Application/User/stm32f4xx_it.o ./Application/SW4STM32/startup_stm32f429xx.o ./Application/Demo/GUIDEMO.o ./Application/Demo/GUIDEMO_AntialiasedText.o ./Application/Demo/GUIDEMO_Automotive.o ./Application/Demo/GUIDEMO_BarGraph.o ./Application/Demo/GUIDEMO_Bitmap.o ./Application/Demo/GUIDEMO_ColorBar.o ./Application/Demo/GUIDEMO_Conf.o ./Application/Demo/GUIDEMO_Cursor.o ./Application/Demo/GUIDEMO_Fading.o ./Application/Demo/GUIDEMO_Graph.o ./Application/Demo/GUIDEMO_IconView.o ./Application/Demo/GUIDEMO_ImageFlow.o ./Application/Demo/GUIDEMO_Intro.o ./Application/Demo/GUIDEMO_Listview.o ./Application/Demo/GUIDEMO_RadialMenu.o ./Application/Demo/GUIDEMO_Resource.o ./Application/Demo/GUIDEMO_Skinning.o ./Application/Demo/GUIDEMO_Speed.o ./Application/Demo/GUIDEMO_Speedometer.o ./Application/Demo/GUIDEMO_Start.o ./Application/Demo/GUIDEMO_TransparentDialog.o ./Application/Demo/GUIDEMO_Treeview.o ./Application/Demo/GUIDEMO_VScreen.o ./Application/Demo/GUIDEMO_WashingMachine.o ./Application/Demo/GUIDEMO_ZoomAndRotate.o ./Application/Demo/syscalls.o -l:STemWin528_CM4_GCC.a

    c:/ac6/systemworkbench/plugins/fr.ac6.mcu.externaltools.arm-none.win32_1.3.0.201507241045/tools/compiler/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/

    lib/armv7e-m/fpu\libm.a

    (lib_a-w_sqrt.o): In function `sqrt':

    w_sqrt.c:(.text.sqrt+0x9e): undefined reference to `__errno'

    w_sqrt.c:(.text.sqrt+0xa8): undefined reference to `__errno'

    collect2.exe: error: ld returned 1 exit status

    make: *** [STM32F429I_DISCO_MB1elf] Error 1

    ________________

    Attachments :

    GCC_Libs.png : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006Htav&d=%2Fa%2F0X0000000aS2%2F1fIcSILBHmiQFYsHpFCflhCqnJHzgHFcQqvEDD7a3So&asPdf=false
    AvaTar
    Senior III
    October 23, 2015
    Posted on October 23, 2015 at 15:20

    Honestly, I don't know.

    Just for curiosity, I installed the system workbench (the 64-Bit version failed on a 64-Bit system, only the 32-Bit version works ...), and test-build a simple application for the F3.

    Using the SPL, I had no linking issues, even when using sqrt().

    The final linker stage call looks like :

    'Invoking: MCU GCC Linker'

    arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=softfp -L''E:\Tools\Ac6\workspace\stm32f3discovery_stdperiph_lib\Debug'' -T''E:\Tools\Ac6\workspace\F3_test\LinkerScript.ld'' -Wl,-Map=output.map -Wl,--gc-sections -lm -o ''F3_test.elf'' @''objects.list''  -lstm32f3discovery_stdperiph_lib

    so the actual errno variable might reside in stm32f3discovery_stdperiph_lib.a.

    You could of course add a global ''errno'' variable to your project, but that might break something else ...

    I rather stick to Crossworks, and avoid the Cube firmware at all costs ...

    daemynnur
    daemynnurAuthor
    Associate II
    October 23, 2015
    Posted on October 23, 2015 at 15:44

    Well thanks for trying anyway

    Intestingly, my own project throws the same error if I include the sqrt function, but not with other maths functions (sin() etc.)

    but the demo project still throws the error, referencing sqrt, even if I delete all use of sqrt from the project...???

    I'll keep working at it for now. I was hoping to get away with a 'free' IDE, but may end up having to persuede my boss to splash out on a pukka Keil ARM-SDK :(

    Cheers,... Daemy

    AvaTar
    Senior III
    October 23, 2015
    Posted on October 23, 2015 at 17:27

    I was hoping to get away with a 'free' IDE, ...

     

    Then have a look at Em:Blocks (http://www.emblocks.org/web/), which is free as well, and worked out-of-the-box (at least for me).

    And, it includes the clib (which contains _errno) by default.

    Not sure about that ''System Workbench'' - it seems to work with the same reliability as french cars ...

    Tesla DeLorean
    Guru
    October 23, 2015
    Posted on October 23, 2015 at 18:13

    __errno is a function that returns a pointer, look to sys/errno.h and sys/reent.h, so not usually a global variable.

    I've been building GNU/GCC code with makefiles, and not had this issue, I #include <math.h>, and have the following command line

    Compiling file: main.c
    arm-none-eabi-gcc -c -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16
    -Os -ffunction-sections -fdata-sections -Wall -Wstrict-prototypes -Wextra -std=gnu89 -g -ggdb3 -fverbose-asm -Wa,-ahlms=out/main.lst -DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DUSE_STM32F4_DISCOVERY -DUSE_USB_OTG_FS -DHSE_VALUE=8000000 -D__FPU_PRESENT=1 -MD -MP -MF out/main.d -I. -Iinc main.c -o out/main.o

    Also got a chuckle there as my first car was a 2-cylinder Citroen with a gear shift in the dash...
    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    AvaTar
    Senior III
    October 23, 2015
    Posted on October 23, 2015 at 20:18

    __errno is a function that returns a pointer, look to sys/errno.h and sys/reent.h, so not usually a global variable.

     

    Under Linux, it usually is:

    http://linux.die.net/man/3/errno

    But since it is here (MCU world) basically an emulation of an OS feature, the actual kind of implementation depends on the toolchain or library.

    Also got a chuckle there as my first car was a 2-cylinder Citroen with a gear shift in the dash...

     

    That was probably before the massive invasion of electronics into automobiles ...

    Dominic S
    Visitor II
    December 13, 2016
    Posted on December 13, 2016 at 13:04

    I had the same issue with SystemWorkbench. The solution that worked for me was simply to edit the project properties under C/C++ Build > Settings > Tool Settings > MCU GCC Linker > Libraries as follows:

    - Uncheck 'Use C math library (-lm)'

    - Add the math library manually to the libraries list by simply adding 'm'

    This way the '-lm' part is moved to end of the make file instruction and it should compile properly.

    Min-Kyoung Kim
    Associate III
    February 9, 2017
    Posted on February 09, 2017 at 21:59

    Best Solution