We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi,I've built a static library using arm-none-eabi-gcc and used the -fdata-sections, -ffunction-sections, and --gc-sections to reduce the library memory footprint.
I've used that library successfully within an application sample when building with arm-none-eabi-gcc, but when I try to build the same application with armcc (Keil), I'm getting lots of undefined symbols in the static library.
When I remove the --gc-sections and build using arg-none-eabi-gcc I can see the same undefined symbols as on Keil, I assume --gc-sections got rid of them. But if I add to Keil the --split_sections and --remove options, Keil is still complaining about the undefined symbols.
So three questions:
1- Why the same static libray can be linked with gcc ld and not with armlink?
2- Isn't --gc-sections supposed not to remove undefined symbols as in the ld manual?
3- If I resolve all the undefined symbols by adding the necessary files, will that have considerable impact on library size or will I have only simple references added?
Compiler options:
--c99 -c --cpu Cortex-M4.fp -g -O0 --apcs=interwork --split_sections -I.\inc -I.\STM32F4-Discovery_FW_V1.1.0\Libraries\CMSIS\Include -I.\STM32F4-Discovery_FW_V1.1.0\Libraries\CMSIS\ST\STM32F4xx\Include -I.\STM32F4-Discovery_FW_V1.1.0\Libraries\STM32F4xx_StdPeriph_Driver\inc --littleend --fp16_format=none --thumb --wchar32 -I C:\Keil_v5\ARM\RV31\INC -I C:\Keil_v5\ARM\PACK\ARM\CMSIS\3.20.4\CMSIS\Include
-I C:\Keil_v5\ARM\PACK\Keil\STM32F4xx_DFP\1.0.6\Device\Include -DSTM32F40_41xxx -DUSE_STDPERIPH_DRIVER -D_INT_MIC_ -DSTM32F4XX -o "*.o" --depend "*.d"
Linker Options
--cpu Cortex-M4.fp *.o
--strict --scatter "test.sct"
--cpu=Cortex-M4 --verbose --remove --summary_stderr --info summarysizes --map --xref --callgraph --symbols
--info sizes --info totals --info unused --info veneers
--list ".\test.map"
-o test.axf
Example of errors:
Build target 'test'
linking...
.\test.axf: Warning: L6413W: Disabling merging for mon_target.o(.rodata.str1.4), Section contains misaligned string(s).
.\test.axf: Error: L6218E: Undefined symbol exit (referred from main.o).
.\test.axf: Error: L6218E: Undefined symbol gen (referred from main.o).
.\test.axf: Error: L6218E: Undefined symbol wonder_clear (referred from callmain.o)
Can you show the exact command lines you use to compile and create the static library and an example of one of the error messages? (including the missing symbol name)
Thanks. I only see object files (.o), so I'm not sure I follow what you meant by "static library". If some of the symbols are from a .a file, perhaps you need to add it in the settings.
I expect the linker to find 'exit' in a system library. Are there any linker warnings about not finding libraries?
Which .o file do you expect to define 'gen' and 'wonder_clear'? If they are part of the sources, make sure the file(s) they are in are actually being built. Or maybe they are being skipped by #if, etc. You could use fromelf -s to see what symbols are referenced/defined by a .o file.
Hi Scott,
Thank you for your answer.
The object files you see are from the static library. I've already added the library into my project. If by adding to settings you mean adding the lib to the linker, that will give me:.\evasr.axf: Warning: L6304W: Duplicate input file .\lib\mylib.a ignored.
I removed the exit( ) call from my library, so that's not important, but to answer your question there's no linker warning about missing libs.
The source files that define 'gen' and 'wonder_clear' are not built into my lib. The garbage collector option (--gc-sections) removes them at the linking stage when I build with gcc, the great mystery for me is why Keil isn't doing the same thing even I provided it with the options corresponding to the ones of gcc?
I've also tried building the same example with IAR, and the behavior is the same as gcc, so there's some strange thing happening with armlink!
If you are linking a static library I would expect to see 'mylib.a' on the link line, not the .o files that make up the .a.
Do you mean that 'gen' and 'wonder_clear' are not present at link time but you expect no error because all of the sections referencing them are going to be removed? Unfortunately this is not the way armlink --remove works. Undefined symbols are still an error even if all references to them are going to be removed (later). In this case, you could either use --unresolved=... or define dummy versions (e.g. that assert) which will also get removed or just remove the references.
Me too, but...
Do you mean that 'gen' and 'wonder_clear' are not present at link time but you expect no error because all of the sections referencing them are going to be removed?
Yes Scott, that's exactly the way gcc ld is doing when mapping each function in a different section then garbage collecting, it simply removes them and don't complain about them.
Well, I've added --unresolved=gen --unresolved=wonder_clear to linker options, but I'm still having the same errors.
--unresolved=foo means make all references to unresolved symbols refer to 'foo' instead, so you need foo to be defined; maybe use --unresolved=main
I think I've got all my answers. Thanks a bunch Scott!