Linker error with CONFIG_NET_TCP=y

I am using the NUCLEO_F412ZG Board and i want to setup an MQTT-Application with an w5500 mac-phy. Adding step by step my Kconfig-Parameters, i get a linker error after adding CONFIG_NET_TCP.

CONFIG_MAIN_STACK_SIZE=4096

CONFIG_CPLUSPLUS=y
CONFIG_LIB_CPLUSPLUS=y
CONFIG_STD_CPP11=y
CONFIG_NEWLIB_LIBC=y
CONFIG_NEWLIB_LIBC_NANO=n
CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y

CONFIG_SPI=y

CONFIG_ETH_W5500=y

CONFIG_ETHERNET_LOG_LEVEL_DBG=y

CONFIG_NETWORKING=y
CONFIG_NET_SHELL=y
CONFIG_NET_L2_ETHERNET=y

CONFIG_ENTROPY_GENERATOR=y
CONFIG_TEST_RANDOM_GENERATOR=y

# Networking Config:
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_POSIX_NAMES=n
CONFIG_NET_IPV4=y
CONFIG_NET_IPV6=n
CONFIG_NET_TCP=y

# Enable the MQTT Lib
CONFIG_MQTT_LIB=y

# Network address config
CONFIG_NET_CONFIG_SETTINGS=y
# CONFIG_NET_CONFIG_NEED_IPV4=y
CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1"
CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.0.2.2"

CONFIG_MQTT_LIB implicitly sets CONFIG_NET_SOCKETS=y. So far so good. Without CONFIG_NET_TCP build is fine. But after turning this switch to y i get the linker error below.
I build up my Kconfg with the help of the zephyr-samples. So i think CONFIG_NET_TCP is necessary for mqtt comminication.

Building on Zephyr’s ‘west’ is fine.

Logs and console output

Linking .pio/build/my_eval_board/zephyr/firmware-pre.elf
/Project/.piocore/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/8.2.1/../../../../arm-none-eabi/bin/ld.bfd: .piocore/packages/toolchain-gccarmnoneeabi/arm-none-eabi/lib/thumb/v7e-m+fp/hard/libc.a(lib_a-fini.o): in function `__libc_fini_array':
fini.c:(.text.__libc_fini_array+0x26): undefined reference to `_fini'
collect2: error: ld returned 1 exit status
*** [.pio/build/my_eval_board/zephyr/firmware-pre.elf] Error 1

Environment (please complete the following information):

  • OS: Ubuntu Linux 20.04 LTS
  • Toolchain Zephyr 2.6.0 with PlatformIO

Some code in the project is calling into exit() which requires _fini (finish) (see here, but the function is either not implemented or not auto-included by the compiler under the current compiler settings.

Per undefined reference to `_fini' · Issue #4 · micro-ROS/micro_ros_zephyr_module · GitHub that is causing the issue and should be rather

CONFIG_NEWLIB_LIBC=n
CONFIG_NEWLIB_LIBC_NANO=y
CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y

…but that was alter then corrected to not work after a rebuild. You should still give it a try.

If you’re not using C++ in the project, the “solution” at the end, which disables C++.

I see you’ve cross-posted this to Linker error with CONFIG_NET_TCP=y · Issue #39655 · zephyrproject-rtos/zephyr · GitHub. Please link existing issues directly when creating the post so that it’s easier to find.

I need CONFIG_NEWLIB_LIBC=y because i am using C++. When i change to

CONFIG_NEWLIB_LIBC=n
CONFIG_NEWLIB_LIBC_NANO=y
CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y

i get another errors.

I did a diff between the Kconfig of West-build and PlatformIO-Build. So both use:

  #
  # C Library
  #
  # CONFIG_MINIMAL_LIBC is not set
  CONFIG_NEWLIB_LIBC=y
  # CONFIG_EXTERNAL_LIBC is not set
  CONFIG_HAS_NEWLIB_LIBC_NANO=y
  # CONFIG_NEWLIB_LIBC_NANO is not set
  CONFIG_NEWLIB_LIBC_MIN_REQUIRED_HEAP_SIZE=8192
  CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y
  # CONFIG_NEWLIB_LIBC_FLOAT_SCANF is not set
  CONFIG_STDOUT_CONSOLE=y
  # end of C Library

Differences are:

CONFIG_TOOLCHAIN_GNUARMEMB=y
vs.
CONFIG_TOOLCHAIN_ZEPHYR_0_13=y

The difference in used toolchain could make the difference, but I don’t know whether that config is user-controllable.

Thought differently: There is a Zephyr example which uses the TCP stack at platform-ststm32/examples/zephyr-net-https-client at develop · platformio/platform-ststm32 · GitHub. And there are also lots of calls into exit() in there. However, the example builds perfectly fine for me in the given configuration (F7 Discovery board) – so maybe we missed something in the config after all? platform-ststm32/examples/zephyr-net-https-client/zephyr/prj.conf at develop · platformio/platform-ststm32 · GitHub

These Parameters are not user controllable.

I tried to change the libc.a. So i copied it from Zephyr-Sdk to Platformio-Toolchain. Then the Build works. So i think something is suitable concerning the Toolchain platformio uses.

There must be something else to this. When I take the above-mentioned example and exchange

board = disco_f769ni

with

board = nucleo_f429zi

I get

RAM:   [=======   ]  67.0% (used 131781 bytes from 196608 bytes)
Flash: [=         ]  10.0% (used 208852 bytes from 2097152 bytes)
================= [SUCCESS] Took 23.95 seconds ==================

So PlatformIO is well-capable of building a Zephyr example with CONFIG_NET_TCP=y for a STM32F4 board.

i think you meen disco_f469ni.
On this Profile i got same error. I am using Zephyr 2.6. Which version do you use?

No the original line says

that’s what I changed it from, to nucleo_f429zi, and it still worked.

Even if I rename src\main.c to src\main.cpp (with some (void*) cast fixes) and the appropriate change in zephyr\CMakeLists.txt it still builds.

I then added CONFIG_CPLUSPLUS=y and the build still went through.

Added CONFIG_LIB_CPLUSPLUS=y and CONFIG_STD_CPP11=y and it stell went through.

Added CONFIG_NEWLIB_LIBC=y and it still went through.

Add CONFIG_NEWLIB_LIBC_NANO=n and it broke the build.

c:/users/max/.platformio/packages/toolchain-gccarmnoneeabi@1.80201.190214/bin/../lib/gcc/arm-none-eabi/8.2.1/../../../../arm-none-eabi/bin/ld.exe: C:\Users\Max\.platformio\packages\toolchain-gccarmnoneeabi@1.80201.190214\arm-none-eabi\lib\thumb\v7e-m\nofp\libc.a(lib_a-fini.o): in function `__libc_fini_array':
fini.c:(.text.__libc_fini_array+0x26): undefined reference to `_fini'
collect2.exe: error: ld returned 1 exit status

Changed to CONFIG_NEWLIB_LIBC_NANO=y, cleaned & rebuilt and compilation goes through again.

So for me at least the error is only if CONFIG_NEWLIB_LIBC_NANO=n.

See GitHub - maxgerhardt/pio-zephyr-net-test.

Hi,
i just tested out your project and building is fine.
After adding CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y linker errors are back:

myProject/.piocore/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/8.2.1/../../../../arm-none-eabi/bin/ld.bfd: .pio/build/test_nucleo/zephyr/lib/libc/newlib/liblib__libc__newlib.a(libc-hooks.c.o): in function `__malloc_lock':

myProject/.piocore/packages/framework-zephyr/lib/libc/newlib/libc-hooks.c:304: multiple definition of `__malloc_lock'; .piocore/packages/toolchain-gccarmnoneeabi/arm-none-eabi/lib/thumb/v7e-m/nofp/libc_nano.a(lib_a-mlock.o):mlock.c:(.text.__malloc_lock+0x0): first defined here

myProject/.piocore/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/8.2.1/../../../../arm-none-eabi/bin/ld.bfd: .pio/build/test_nucleo/zephyr/lib/libc/newlib/liblib__libc__newlib.a(libc-hooks.c.o): in function `__malloc_unlock':

myProject/.piocore/packages/framework-zephyr/lib/libc/newlib/libc-hooks.c:309: multiple definition of `__malloc_unlock'; .piocore/packages/toolchain-gccarmnoneeabi/arm-none-eabi/lib/thumb/v7e-m/nofp/libc_nano.a(lib_a-mlock.o):mlock.c:(.text.__malloc_unlock+0x0): first defined here

collect2: error: ld returned 1 exit status

*** [.pio/build/test_nucleo/zephyr/firmware-pre.elf] Error 1

Yes this option auto-includes back NEWLIB_LIBC (source) and not NEWLIB_LIBC_NANO which I think is the source of the problems. Two different C libraries being included. Try including the float-printf from newlib-nano in a different way, as seen in e.g. Sprintf not working on bluepill (build_flags = -Wl,--undefined,_printf_float).

Since Zephyr Version 2.7.1 the probleme has gone.
As far as i can see it was caused by PlatformIO Build skripts

1 Like