2

I have a C project using several object files that needs to be linked in a specific order to find all needed symbols.

For example this command works fine (lib2.o depends on lib1.o etc.)

gcc -o my_app main.o lib1.o lib2.o lib3.o -lm

but

gcc -o my_app main.o lib3.o lib2.o lib1.o -lm

ends with undefined reference to `my_variable' errors.

This is a known behavior and can be solved for example by adding these objects to GROUP section in a linker script.

Now I'd like to share these object as a static library with my colleagues. So...

ar -rcs mylib.a lib1.o lib2.o lib3.o
gcc -o my_app main.o mylib.a -lm

Unfortunately this gives the same undefined reference errors like the specifying the objects in incorrect order.

I have not found any linker or archiver options to make it working and also no solution by googling even if I think that this problem should be relatively common.

Do please anybody know a solution?

regards Jan

Honza
  • 1,734
  • 3
  • 16
  • 22

2 Answers2

3

This might be a link order problem. When the GNU linker sees a library, it discards all symbols that it doesn't need. It also does that in the sequential order form left to right.

Recent versions of gcc/ld default to linking with --as-needed flag.

This means if you write -lmylib.a before the C file the library will automatically get excluded (the order matters when testing if things are "needed" like this)

You can fix this with either:

  1. gcc -L. -o example example.c -lmylib.a
  2. gcc -L. -Wl,--no-as-needed -o example example.c -lmylib.a

The latter of which passes --no-as-needed to the linker, which would cause the library to still be linked, even if you didn't call any function external from it.

askmish
  • 6,464
  • 23
  • 42
  • Hi, I'm almost sure that it is a link order problem, but this does not solve it in my case. The problem is that obj files archived in mylib.a depends on another obj files in the same library. I know that circular dependency problems among several libraries solves --start-group option, but this is not the case as the library is only one... – Honza Aug 03 '12 at 10:54
  • Try `ranlib` archiver instead of `ar` . – askmish Aug 03 '12 at 11:01
  • I have already tried that. Also -s parameter for the ar should do the same thing, but no sucess again :( – Honza Aug 03 '12 at 11:30
  • 1
    Thank you, nm solved my issue. I did not noticed that one of the files added to the library was already a .a archive, so its objects were not found by linker. See [http://stackoverflow.com/questions/4318906/ar-on-an-existing-a-file](http://stackoverflow.com/questions/4318906/ar-on-an-existing-a-file) – Honza Aug 06 '12 at 06:26
0

Your error implies that the problem is in one of your lib?.o files [lib{later}.o depends on lib{earlier}.o]
How did you manage to compile them?
Were there any compilation warnings?
It has been a while since I used C, but I think that you will need to include dependent libraries within the library that has the dependency - this may be the reason why you can't find too many references to the problem, because it does not really exist.

Germann Arlington
  • 3,315
  • 2
  • 17
  • 19
  • Hello, unfortunately I do not have the source of the libraries as they were provided by our supplier in binary form only. There is no problem to compile the project by specifying each object file in correct order, but I want to collect them to a static library because one file is easier to maintain than twenty files... – Honza Aug 03 '12 at 10:22
  • 1
    Try http://stackoverflow.com/questions/2980102/combine-two-gcc-compiled-o-object-files-into-a-third-o-file and https://www.google.co.uk/search?q=gcc+combine+multiple+lib+into+one – Germann Arlington Aug 03 '12 at 10:30