This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Static library links differently with gcc ld and armlink

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?

Parents
  • 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.

    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?

    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.

Reply
  • 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.

    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?

    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.

Children
  • 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.

    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!