g++: In what order should static and dynamic libraries be linked?

Michael picture Michael · Jan 29, 2009 · Viewed 16.5k times · Source

Let's say we got a main executable called "my_app" and it uses several other libraries: 3 libraries are linked statically, and other 3 are linked dynamically. In which order should they be linked against "my_app"?

But in which order should these be linked?

Let's say we got libSA (as in Static A) which depends on libSB, and libSC which depends on libSB:

libSA -> libSB -> libSC

and three dynamic libraries:libDA -> libDB -> libDC (libDA is the basic, libDC is the highest)

in which order should these be linked? the basic one first or last?

g++ ... -g libSA libSB libSC -lDA -lDB -lDC -o my_app

seems like the currect order, but is that so? what if there are dependencies between any dynamic library to a static one, or the other way?

Answer

jpalecek picture jpalecek · Jan 29, 2009

In the static case, it doesn't really matter, because you don't actually link static libraries - all you do is pack some object files together in one archive. All you have to is compile your object files, and you can create static libraries right away.

The situation with dynamic libraries is more convoluted, there are two aspects:

  1. A shared library works exactly the same way as static library (except for shared segments, if they are present), which means, you can just do the same - just link your shared library as soon as you have the object files. This means for example symbols from libDA will appear as undefined in libDB

  2. You can specify the libraries to link to on the command line when linking shared objects. This has the same effect as 1., but, marks libDB as needing libDA.

The difference is that if you use the former way, you have to specify all three libraries (-lDA, -lDB, -lDC) on the command line when linking the executable. If you use the latter, you just specify -lDC and it will pull the others automatically at link time. Note that link time is just before your program runs (which means you can get different versions of symbols, even from different libraries).

This all applies to UNIX; Windows DLL work quite differently.

Edit after clarification of the question:

Quote from the ld info manual.

The linker will search an archive only once, at the location where it is specified on the command line. If the archive defines a symbol which was undefined in some object which appeared before the archive on the command line, the linker will include the appropriate file(s) from the archive. However, an undefined symbol in an object appearing later on the command line will not cause the linker to search the archive again.

See the `-(' option for a way to force the linker to search archives multiple times.

You may list the same archive multiple times on the command line.

This type of archive searching is standard for Unix linkers. However, if you are using `ld' on AIX, note that it is different from the behaviour of the AIX linker.

That means:

Any static library or object that depends on other library should be placed before it in the command line. If static libraries depend on each other circularly, you can eg. use the -( command line option, or place the libraries on the command line twice (-lDA -lDB -lDA). The order of dynamic libraries doesn't matter.