39

Prior to today I had always believed that the order that objects and libraries were passed to g++ during the linking stage was unimportant. Then, today, I tried to link from c++ code to c code. I wrapped all the C headers in an extern "C" block but the linker still had difficulties finding symbols which I knew were in the C object archives.

Perplexed, I created a relatively simple example to isolate the linking error but much to my surprise, the simpler example linked without any problems.

After a little trial and error, I found that by emulating the linking pattern used in the simple example, I could get the main code to link OK. The pattern was object code first, object archives second eg:

g++ -o serverCpp serverCpp.o algoC.o libcrypto.a

Can anyone shed some light on why this might be so?. I've never seen this problem when linking ordinary c++ code.

Gearoid Murphy
  • 11,834
  • 17
  • 68
  • 86
  • For details see: http://stackoverflow.com/questions/1095298/gcc-c-linker-errors-undefined-reference-to-vtable-for-xxx-undefined-referen/1095321#1095321 – Martin York Jul 29 '10 at 17:23

4 Answers4

58

The order you specify object files and libraries is VERY important in GCC - if you haven't been bitten by this before you have lead a charmed life. The linker searches symbols in the order that they appear, so if you have a source file that contains a call to a library function, you need to put it before the library, or the linker won't know that it has to resolve it. Complex use of libraries can mean that you have to specify the library more than once, which is a royal pain to get right.

Community
  • 1
  • 1
  • Believe me, I haven't :-), is there any documentation on this property? – Gearoid Murphy Jul 29 '10 at 14:17
  • 1
    I, too, have always found the link order to be critical; it can be difficult working out why link errors are occurring, too, until you guess that the order is wrong... – PP. Jul 29 '10 at 14:22
  • 1
    @Gearoid In the unlikely event that you are interested in linkers, take a look at http://www.iecc.com/linker. –  Jul 29 '10 at 14:22
  • 7
    @PP There is nothing I dread more than linker error messages. –  Jul 29 '10 at 14:23
  • I remember being puzzled by a complex linking operation I saw in a Makefile last year which referenced certain libraries multiple times, now I understand why :) – Gearoid Murphy Jul 29 '10 at 14:25
  • 3
    +1 for suggesting, "specify the library more than once." Critical, critical, critical! – Andres Jaan Tack Oct 20 '10 at 07:07
  • So, this means that if I have a cross-reference in two libraries - I would never get the build to complete unless I duplicate the `-l` option for one of them... Wow... definitely a pain! – ysap Aug 28 '12 at 22:55
  • ... as mentioned in @caf's comment to Mike's answer. – ysap Aug 28 '12 at 22:57
  • Since the object file containing main() is presumably dependent on the rest of the libraries, shouldn't that be the last argument? I have a case where ld returns nonzero when doing `g++ -L./Foo -lfoo main.o`. However, `g++ main.o -L./Foo -lfoo` works fine. – solstice333 Feb 10 '16 at 02:34
  • Not just libraries either. Order of .o files is important if you do any global variables including static class variables, because you could access the variables before its initialized (functions called before main) – Rahly Aug 01 '17 at 05:44
23

The library order pass to gcc/g++ does actually matter. If A depends on B, A must be listed first. The reason is that it optimizes out symbols that aren't referenced, so if it sees library B first, and no one has referenced it at that point then it won't link in anything from it at all.

Mark B
  • 95,107
  • 10
  • 109
  • 188
7

A static library is a collection of object files grouped into an archive. When linking against it, the linker only chooses the objects it needs to resolve any currently undefined symbols. Since the objects are linked in order given on the command line, objects from the library will only be included if the library comes after all the objects that depend on it.

So the link order is very important; if you're going to use static libraries, then you need to be careful to keep track of dependencies, and don't introduce cyclic dependencies between libraries.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • 1
    Cyclic dependencies are OK - it just means you need to have a link line like "`a.o b.o a.o`". – caf Jul 30 '10 at 11:45
  • 1
    @caf: if the extra objects from the second inclusion of `a` depend on objects in `b` that haven't been included yet, then that's not good enough; you'll need to add `b` again at the end. Which in turn might introduce more dependencies on `a`. So cyclic dependencies aren't really "OK", it's just rare for them to be pathological enough to need more than one repetition. – Mike Seymour Jul 30 '10 at 11:52
3

You can use --start-group archives --end-group and write the 2 dependent libraries instead of archives:

gcc main.o -L. -Wl,--start-group -lobj_A -lobj_b -Wl,--end-group
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
Hani
  • 46
  • 1