linking problems and order

826 views
Skip to first unread message

Robert Kraus

unread,
Oct 21, 2001, 6:29:57 PM10/21/01
to
Hello,

I often have linking problems, when I build a project with multiple static
libraries.

Sometimes these problems can get resolved by changing the order of the
linked libraries.

What causes these errors ? Why can it be resolved by rearranging -
does this mean, that all includes, definitions, declarations etc.
are correct ?

Or what am I doing possibly wrong ?

Thank you very much for your answer.

robert

Gunnar Andersson

unread,
Oct 22, 2001, 4:04:45 AM10/22/01
to

On Sun, 21 Oct 2001, Robert Kraus wrote:

> I often have linking problems, when I build a project with
> multiple static libraries.
>
> Sometimes these problems can get resolved by changing the order of the
> linked libraries.
>
> What causes these errors ? Why can it be resolved by rearranging -
> does this mean, that all includes, definitions, declarations etc.
> are correct ?

Suppose you're linking with -lfoobar. Then all uses of symbols
defined in foobar must precede -lfoobar on the command-line. If
you're linking against several static libraries, you must therefore
make sure that they are in the right order.

/ Gunnar

Paul Pluzhnikov

unread,
Oct 23, 2001, 1:44:54 AM10/23/01
to
"Robert Kraus" <rob...@gmx.net> wrote in message
news:F%HA7.11606$PV1.3...@news.chello.at...

> I often have linking problems, when I build a project with multiple static
> libraries.

You are not alone: I see many people who do

gcc -lfoo main.o

>
> Sometimes these problems can get resolved by changing the order of the
> linked libraries.
>
> What causes these errors ? Why can it be resolved by rearranging -
> does this mean, that all includes, definitions, declarations etc.
> are correct ?

I find the following analogy most useful when explaining
how the linker works with archive libraries:

- think of an archive library as a bookshelf, with
some books on it (the separate .o files).
- some books may refer you to other books
(via unresolved symbols), which may be on the
same, or on a different bookshelf.

A librarian comes to the first bookshelf (the first archive
library on your link line) with two lists -- a list of things
she still needs (unresolved symbols), and a list of things
she already has (symbols already defined).

Usually, she will already have crt0.o (added to the link
line by the compiler driver), which refers to main.
So her "need" list contains main. Often she will
have main.o as well, which means she no longer needs
main, but probably needs malloc, free, printf, etc.

Now she starts to scan one bookshelf at a time looking for books
that define symbols she needs. If a book defines one of
the symbols on the "need" list, she takes that book from
the shelf, scratches off all symbols defined in that book
from the "need" list, adds all defined symbols to the "have" list,
and adds all symbols used by that book and not already in the
"have" list to the "need" list.

If a book does not define any symbols currently in the "need"
list, she does not take it (even though this book may come in
handy later).

If a book she just took defines a symbol she already has, there
is "multiply-defined symbol" problem.

Once she is done with a bookshelf, she does not return
to it (unless the library corresponding to it is listed
on the command line several times).

If, after searching all the bookshelves listed on command
line (as well as libc which is added by the compiler driver),
she still has entries in the "need" list, there is an
"undefined symbol" error.

Clearly, if many of your biology books refer to chemistry
books, and you've got a biology paper to write, you better
start searching the biology bookshelf before the chemistry one.

Sometimes, two archive libraries are inter-dependent:
objects from one depend on objects from the other, and
vice versa.

This means, that there is no correct order of linking
such libraries, that both libraries are poorly structured,
and that in order to successfully link an executable, you may
need to list both of these libraries several times, as in:

gcc main.o -lfoo -lbar -lfoo -lbar -lfoo

Finally, there is no reason a linker could not pass over
all the objects and libraries twice: first to build the
two lists, then to actually pull all the needed .o files
from their libraries.

This is certainly user-friendly (you never get the types
of errors that could be solved by rearranging library order).

I believe 2-pass linkers were common some 10-20 years ago.
I believe the reasons they are not used much anymore are:

- they consume twice the amount of I/O and significant
additional amounts of memory, and
- they force users with well-structured libraries
(who can and do arrange them properly on the link line)
to pay this price so that users with poorly-structured
libraries can still link successfully.


Jane Anderson

unread,
Oct 25, 2001, 11:37:38 AM10/25/01
to
"Paul Pluzhnikov" <ppluz...@earthlink.net> wrote in message news:<qt7B7.4096$AQ6.3...@newsread2.prod.itd.earthlink.net>...

You may also want to try one of the special purpose linker options that is
documented in the "ld Command Line Options":
-(archives-)
--start-group archives
--end group
The documentation states that the archives may be a list of
archive file names or '-l' options.
This causes the archives in the group to be searched multiple times until all
references have been resolved.

Reply all
Reply to author
Forward
0 new messages