I stand corrected on so many points here that I think I'll have
bruises when I wake up tomorrow :)  Thanks for all the help.
To put a happy (though embarrassing) end to the story: I was missing a
few .cpp files when constructing the library.  Not a problem at
compile-time, because the headers were still accessible to those units
that needed them.  Adding those .cpp files to the .a solved all my
link problems.

Thanks a ton for everyone's help.

- Christian

On 2/28/07, Nick Clifton <[EMAIL PROTECTED]> wrote:
Hi Christian,

   [I have restored the CC to gcc@gcc.gnu.org as there may be other
people interested in this discussion].

>>    foo.o -lbar baz.o -lbar
>>
>> The second "-lbar" is only needed if baz.o includes references to
>> symbols that are defined in libbar.a which will not be pulled in when
>> resolving the references made by foo.o.
>
> I'm not so sure that's true, because someone said that putting "bar.a"
> on the linker command line is pretty much identical in effect to
> listing, on the command line, the files that got bundled up into
> bar.a.  So if bar.a is made up of x.o, y.o and z.o, and z.o contains a
> function that depends on a function in x.o, then I really do need to
> list bar.a twice in order to resolve that dependency. No?

No.  :-)

A library is not, quite, the same thing as a bunch of object files.  For
one thing the linker *will* repeatedly search a library until no more
undefined symbols can be resolved.  So in your example x.o will be
pulled into the link because it is needed to resolve a reference in z.o
(which is presumably needed to resolve a reference from an object file
earlier on in the linker command line).

This is all described in the linker documentation as well.  Have a look
at the description of the linker command line option --start-group.


> I pasted an irrelevant example by accident, but I really am seeing the
> problem in question (I think).  Here's the link command and my first
> error message from it:
>
> /usr/bin/c++      -fPIC "CMakeFiles/simpleIO.dir/main_IO.o"   -o
> simpleIO -rdynamic
> -L/home/cjc/csc583-svn/uriVisionLib/trunk/Development/Source/C++ -lGL
> -lglut -Wl,-Bstatic -luriVision -luriVision -Wl,-Bdynamic
> -Wl,-rpath,/home/cjc/csc583-svn/uriVisionLib/trunk/Development/Source/C++

> 
/home/cjc/csc583-svn/uriVisionLib/trunk/Development/Source/C++/liburiVision.a(ImageReader.o):
> In function `uriVideoSources::ImageReader::getFrame(bool,
> uriBase::RasterImage*)':
> ImageReader.cpp:(.text+0x90): undefined reference to
> `uriVideoSources::ImageReader_gen::getFrame_(bool,
> uriBase::RasterImage*)'
>
> and here's the (hopefully) telling nm/grep statement:
>
> [EMAIL PROTECTED]:~$ nm --demangle
> /home/cjc/csc583-svn/uriVisionLib/trunk/Development/Source/C++/liburiVision.a
>
> | grep "uriVideoSources::ImageReader_gen::getFrame"
>         U uriVideoSources::ImageReader_gen::getFrame_(bool)
>         U uriVideoSources::ImageReader_gen::getFrame_(bool,
> uriBase::RasterImage*)

Well this tells me that ...getFrame_(bool.uriBase::RasterImage*) is an
*undefined* symbol referenced from inside liburiVision.a.  (Hence the
'U' attribute as displayed by nm).  Hence the linker is correct in
complaining that it cannot resolve the reference and hence you do need
to tell the linker where to find this symbol.

Where do you think the ...getFrame_(bool.uriBase::RasterImage*) symbol
is defined ?

Cheers
   Nick

Reply via email to