openexr-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Openexr-devel] another undefined symbol link error


From: Tom Dilligan
Subject: Re: [Openexr-devel] another undefined symbol link error
Date: 22 Oct 2003 11:39:26 -0700

>
>On Friday, October 17, 2003, at 05:57 PM, Scott Frankel wrote:
>
>> No way.
>>
>> I placed liblex at the bottom of the Frameworks & Libraries list and 
>> the build succeeded!
>>
>> Thanks for all the help in getting this sussed out.  I'll type up my 
>> notes and send them
>> back out to the group for future reference.
>
>Just out of curiosity, could anyone provide a little explanation of 
>that? Why would the link order matter?
>

When the link phase occurs, all symbols are defined that exist in object
files, but symbols in libraries are only defined on an as-needed basis
(i.e. including a library only gets you the symbols that are currently
un-defined). Here are some examples.

We have a program that has the following symbols (denoted by capital
letters) defined in the following files:

foo.o   : defines A and X, requires B and D
bar.o   : defines B and Y, requires A and D
liba.so : defines C and Z
libb.so : defines D and requires C

Given the link line:
g++ foo.o bar.o -la -lb

Symbols are resolved in approximately the following order:

File processed     defined symbols    undefined symbols
--------------     ---------------    -------------------  
foo.o              A X                B D
bar.o              A X B Y            D
liba.so            A X B Y            D
libb.so            A X B Y D          C

And so the link fails because the symbol C is undefined. It was in one
of our libraries, but it didn't get linked because at the time (when
liba.so was processed) we didn't know that we would need C.

So by simply re-arranging the link line (by refersing the order of the
libraries) we can get this to work correctly.

Given the link line:
g++ foo.o bar.o -lb -la

Symbols are resolved in approximately the following order:

File processed     defined symbols   undefined symbols
--------------     ---------------   -----------------  
foo.o              A X               B D
bar.o              A X B Y           D
libb.so            A X B Y D         C
liba.so            A X B Y D C                 

And everything links OK.

If you're lazy and you don't want to figure out the dependencies, you
can use the following stupid trick (at the cost of link speed): repeat
your libraries in the identical order. For example, going back to the
origional broken example:

Given the link line:
g++ foo.o bar.o -la -lb -la -lb

Symbols are resolved in approximately the following order:

File processed     defined symbols    undefined symbols
--------------     ---------------    -------------------  
foo.o              A X                B D
bar.o              A X B Y            D
liba.so            A X B Y            D
libb.so            A X B Y D          C
liba.so            A X B Y D C                 
libb.so            A X B Y D C

So by re-including liba.so after libb.so we solve the problem of missing
symbol C. The second instance of libb.so is effectively ignored
completely because there are no undefined symbols (but the linker still
gets to parse the file).

You'll note that in the above example, symbol Z never shows up, because
it's in a library and never needed. Symbol X and Y show up, because they
were in an object file (and is therefore always in the final linked
file).

In the above examples, I have shown the libraries as shared libraries.
The same rules apply for static (.a or archive) libraries as well.

Hopefully that answers your question...

If you're really curious, and you want to see what the linker is up to
(i.e. what symbols are getting resolved where),add the following option
to your link line (this is for gcc/g++, similar options exist for other
compilers): -Wl,-M


>>>Tom





reply via email to

[Prev in Thread] Current Thread [Next in Thread]