How to determine inter-library dependencies?

Charly picture Charly · Jan 24, 2011 · Viewed 7k times · Source

My project consists of a couple of static libraries, which are linked together in a final step. Now I have the problem, that the link order of the library is important (otherwise I get an undefined symbol linker error). Sometimes I run into the problem, that I have to re-sort the linked libraries (-lcommon -lsetup -lcontrol etc). At the moment it's a stupid trial and error: re-sort, compile, check error, re-sort, compile and so on.

So I wrote a small program to show me the inter-library-dependencies and generates me the order of libraries to link. It reads in the defined ('T', 'B', etc) and undefined symbols ('U') from nm and removes the weak symbols ('w', 'W', 'v' and 'V') from the 'undefined symbol list'. Now it determines for every undefined symbol the library which resolves it.

But my program shows me circular dependencies... what's my mistake?

If they really exist, I could not link at all... so what did I miss, when analyzing the nm output? Or is analyzing the nm output not the way, to get these dependencies?

libcommon.a:
         U _ZN15HardwareUnit23GetHardwareSerialNumberEv
libhardware.a:
00000484 T _ZN15HardwareUnit23GetHardwareSerialNumberEv
libsecurityaccess.a:
         U _ZN15HardwareUnit23GetHardwareSerialNumberEv
---
libhardware.a:
         U _ZN21ApplicationProfile26GetApplicationSettingsPathERK7QString
libsecurityaccess.a:
00004020 T _ZN21ApplicationProfile26GetApplicationSettingsPathERK7QString
         U _ZN21ApplicationProfile26GetApplicationSettingsPathERK7QString

Answer

Maxim Egorushkin picture Maxim Egorushkin · Jan 24, 2011

Another option to link libraries with circular dependencies is to use a special linker option for that. Man ld:

   -( archives -)
   --start-group archives --end-group
       The archives should be a list of archive files.  They may be either
       explicit file names, or -l options.

       The specified archives are searched repeatedly until no new
       undefined references are created.  Normally, an archive is searched
       only once in the order that it is specified on the command line.
       If a symbol in that archive is needed to resolve an undefined
       symbol referred to by an object in an archive that appears later on
       the command line, the linker would not be able to resolve that
       reference.  By grouping the archives, they all be searched
       repeatedly until all possible references are resolved.

       Using this option has a significant performance cost.  It is best
       to use it only when there are unavoidable circular references
       between two or more archives.

It is always cleaner to eliminate the circular dependencies though.