FreeRTOS+TCP V4.2.2: gcc linker throws error: unrecognized option '--e'

Hi guys,

I have just updated the FreeRTOS+TCP library that I was using from version 2.4.0 to the newest 4.2.2. I am cross-compiling it for the Zynq platform using arm-none-eabi-gcc.

After some minor adjustments in my code, the compiler manages to compile all sources, but the linker immediately throws the following error:

Building target: FreeRTOS_ScanAntenna.elf
Invoking: ARM v7 gcc linker

arm-none-eabi-gcc
-mcpu=cortex-a9
-mfpu=vfpv3
-mfloat-abi=hard
-Wl,-build-id=none
-specs=Xilinx.spec
-Wl,-T
-Wl,../src/lscript.ld
-L"E:\Documents\Projekte\RTC-401_Mira\SOW\RevA\CPP\sw_projects\sdk_workspace\te0715_bsp\ps7_cortexa9_0\lib"
-o "FreeRTOS_Project.elf"
./src/... Placeholder for all the .o files of my code ...
./src/FreeRTOS_TCP_IP/portable/NetworkInterface/Zynq/NetworkInterface.o
./src/FreeRTOS_TCP_IP/portable/NetworkInterface/Zynq/uncached_memory.o
./src/FreeRTOS_TCP_IP/portable/NetworkInterface/Zynq/x_emacpsif_dma.o
./src/FreeRTOS_TCP_IP/portable/NetworkInterface/Zynq/x_emacpsif_hw.o
./src/FreeRTOS_TCP_IP/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.o
./src/FreeRTOS_TCP_IP/portable/BufferManagement/BufferAllocation_1.o
./src/FreeRTOS_TCP_IP/portable/BufferManagement/BufferAllocation_2.o
./src/FreeRTOS_TCP_IP/FreeRTOS_ARP.o
./src/FreeRTOS_TCP_IP/FreeRTOS_BitConfig.o
./src/FreeRTOS_TCP_IP/FreeRTOS_DHCP.o
./src/FreeRTOS_TCP_IP/FreeRTOS_DHCPv6.o
./src/FreeRTOS_TCP_IP/FreeRTOS_DNS.o
./src/FreeRTOS_TCP_IP/FreeRTOS_DNS_Cache.o
./src/FreeRTOS_TCP_IP/FreeRTOS_DNS_Callback.o
./src/FreeRTOS_TCP_IP/FreeRTOS_DNS_Networking.o
./src/FreeRTOS_TCP_IP/FreeRTOS_DNS_Parser.o
./src/FreeRTOS_TCP_IP/FreeRTOS_ICMP.o
./src/FreeRTOS_TCP_IP/FreeRTOS_IP.o
./src/FreeRTOS_TCP_IP/FreeRTOS_IP_Timers.o
./src/FreeRTOS_TCP_IP/FreeRTOS_IP_Utils.o
./src/FreeRTOS_TCP_IP/FreeRTOS_IPv4.o
./src/FreeRTOS_TCP_IP/FreeRTOS_IPv4_Sockets.o
./src/FreeRTOS_TCP_IP/FreeRTOS_IPv4_Utils.o
./src/FreeRTOS_TCP_IP/FreeRTOS_IPv6.o
./src/FreeRTOS_TCP_IP/FreeRTOS_IPv6_Sockets.o
./src/FreeRTOS_TCP_IP/FreeRTOS_IPv6_Utils.o
./src/FreeRTOS_TCP_IP/FreeRTOS_ND.o
./src/FreeRTOS_TCP_IP/FreeRTOS_RA.o
./src/FreeRTOS_TCP_IP/FreeRTOS_Routing.o
./src/FreeRTOS_TCP_IP/FreeRTOS_Sockets.o
./src/FreeRTOS_TCP_IP/FreeRTOS_Stream_Buffer.o
./src/FreeRTOS_TCP_IP/FreeRTOS_TCP_IP.o
./src/FreeRTOS_TCP_IP/FreeRTOS_TCP_IP_IPv4.o
./src/FreeRTOS_TCP_IP/FreeRTOS_TCP_IP_IPv6.o
./src/FreeRTOS_TCP_IP/FreeRTOS_TCP_Reception.o
./src/FreeRTOS_TCP_IP/FreeRTOS_TCP_State_Handling.o
./src/FreeRTOS_TCP_IP/FreeRTOS_TCP_State_Handling_IPv4.o
./src/FreeRTOS_TCP_IP/FreeRTOS_TCP_State_Handling_IPv6.o
./src/FreeRTOS_TCP_IP/FreeRTOS_TCP_Transmission.o
./src/FreeRTOS_TCP_IP/FreeRTOS_TCP_Transmission_IPv4.o
./src/FreeRTOS_TCP_IP/FreeRTOS_TCP_Transmission_IPv6.o
./src/FreeRTOS_TCP_IP/FreeRTOS_TCP_Utils.o
./src/FreeRTOS_TCP_IP/FreeRTOS_TCP_Utils_IPv4.o
./src/FreeRTOS_TCP_IP/FreeRTOS_TCP_Utils_IPv6.o
./src/FreeRTOS_TCP_IP/FreeRTOS_TCP_WIN.o
./src/FreeRTOS_TCP_IP/FreeRTOS_Tiny_TCP.o
./src/FreeRTOS_TCP_IP/FreeRTOS_UDP_IP.o
./src/FreeRTOS_TCP_IP/FreeRTOS_UDP_IPv4.o
./src/FreeRTOS_TCP_IP/FreeRTOS_UDP_IPv6.o
./src/FreeRTOS_Sources/portable/MemMang/heap_4.o
./src/FreeRTOS_Sources/portable/GCC/ARM_CA9/port.o
./src/FreeRTOS_Sources/portable/GCC/ARM_CA9/portASM.o
./src/FreeRTOS_Sources/croutine.o
./src/FreeRTOS_Sources/event_groups.o
./src/FreeRTOS_Sources/list.o
./src/FreeRTOS_Sources/queue.o
./src/FreeRTOS_Sources/stream_buffer.o
./src/FreeRTOS_Sources/tasks.o
./src/FreeRTOS_Sources/timers.o
-lm
-Wl,--start-group,-lxil,-lgcc,-lc,--end-group
-Wl,--start-group,-lxilffs,-lxil,-lgcc,-lc,--end-group
-Wl,--start-group,-lrsa,-lxil,-lgcc,-lc,--end-group

c:/xilinx/sdk/2019.1/gnu/aarch32/nt/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/8.2.0/../../../../arm-none-eabi/bin/ld.exe: unrecognized option '--e'

:information_source: In order to make the listing above more readable I replaced the blanks with newlines.

I am sure that the problem lies somwhere within the FreeRTOS+TCP directory, because the error only appeared since I switched to the newer library version and switching the library back to its ā€œoldā€ version compiles & links flawlessly.

I removed all non-Zynq related ports from within the portable folder, so there is just code that should be compatible with the environment.

On a side note, I am still using an older version of the FreeRTOS kernel itself (10.2.1). This might not be advisble when using the up-to-date version of the FreeRTOS+TCP stack and I will update the kernel also soon, but I donā€™t think that it might be the cause for this linker error in this scenario (please correct me if Iā€™m wrong).

Any help would be very appreciated, thank you.

@Stonebull

It seems like your linker is receiving an invalid option, in this case --e, which might be an unintended or a space mistakenly added to an existing command-line argument to the linker.

I would re-examine the build system or makefile.

@tony-josi-aws Thanks for your quick reply. Yeah, I checked the build system and the make file (which is auto-generated in Eclipse) and could not find any option that may adds --e to the linker invocation.

Strangely, the command invoked itself does not contain the --e option either, as you can see in the listing I posted above.

Additionally, when switching the library versions I literally do not touch anything within either the build system and the makefile. However, the error appears when trying to link the V4.2.2 version of the FreeRTOS+TCP library, but not with the V2.4.0.

Very strange.

From v2.4.0 to v4.2.2, the folder structure of FreeRTOS+TCP changes, so I believe you might be making some path-specific changes at least.

Can you share the generated makefile?

@tony-josi-aws

You are right about the folder structure, but my include paths do not change, as I just added all sub directories of the FreeRTOS+TCP library. Those directories are still the same in V4.2.2, although they contain more files. The auto-generated makefiles then do contain all the files within thoes include directories.

These are the toplevel makefile & the makefiles related to the FreeRTOS+TCP library
makefiles.zip (7.1 KB)

Not sure the following is the right syntax as per gcc documentation [-Wl,option]:

arm-none-eabi-gcc -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -Wl,-build-id=none -specs=Xilinx.spec -Wl,-T -Wl,../src/lscript.ld -L"E:\Documents\Projekte\RTC-401_Mira\SOW\RevA\CPP\sw_projects\sdk_workspace\te0715_bsp\ps7_cortexa9_0\lib" -o "FreeRTOS_Project.elf" $(OBJS) $(USER_OBJS) $(LIBS)

In this part : -Wl,-T -Wl, I believe -T should be followed by the path to the linker script.

I found the problem. The culprit is not FreeRTOS or its libraries, although the new file structure of the FreeRTOS+TCP library triggered the problem.

Apparently the Xilinx SDK, which is Eclipse based, uses the Windows cmd.exe for itā€™s internal build console, which is the one that executes make and subsequently calls the compiler and the linker. And Windowā€™s cmd.exe apparently has a pretty limited input buffer which cuts off chars from the linker command string if it gets too long.

I noticed this when manually pasting the linker invocation command into the cmd.exe, as the command got trunkated and I also could not add any more chars manually.

Apparently the new file structure of the FreeRTOS+TCP library, which contains many more files than before somehow reaches the limit of the consoleā€™s input buffer.
I confirmed this suspicion by shortening some paths of the object files and now it links successfully.

I am aware that it is possible to rearrange the FreeRTOS+TCP library in order to return it to the ā€œoldā€ structure, but I am not satisfied with this solution, as this just delays the problem from happening again, if more sources are added in the future.

Unfortunately, it seems to be impossible to either change the Xilinx SDKā€™s internal build console, as well as increasing the cmd.exeā€™s input buffer size.

If somebody has a solution regarding these approaches or the overall problem Iā€™d greatly appreciate that.
Otherwise no worries, this mess is not caused by FreeRTOS or its libraries so I may post the problem somewhere else.

Try converting the command to sub commands that are chained (^) or using a batch file.

Hello, I managed to solve the problem within the Eclipse SDK by redirecting the linker output to a file.

LINKER_CMD_FILE := linker_cmd.txt

@echo ā€˜Writing linker command parameters to file: $(LINKER_CMD_FILE)ā€™
@echo -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -Wl,-build-id=none -specs=Xilinx.spec -Wl,-T -Wl,ā€¦/src/lscript.ld -L"ā€œE:/Documents/Projekte/bsp/ps7_cortexa9_0/libā€" -o "Project.elf" > $(LINKER_CMD_FILE)
@echo $(OBJS) >> $(LINKER_CMD_FILE)
@echo $(USER_OBJS) >> $(LINKER_CMD_FILE)
@echo $(LIBS) >> $(LINKER_CMD_FILE)

And subsequently I execute the linker, using the same file as input for the linker parameters.

arm-none-eabi-gcc @linker_options.txt

All these changes can be automated by writing them into a file called makefile.targets which gets included into the auto-generated makefile and then redefines the makefile rule for the linking process.

Hope this helps somebody with the same problem, as it took me quit some time to figure it out.

2 Likes

Thanks for reporting back.