Why does linker fail to resolve dependencies within the same .a file?
I'm using CMake to build a library (as a .a file) and a demo program for that library. My problem is that when I go to link that demo program, I get a linker error that says one file function in the .a file can't find another function in the .a file. Here's what the linker command line and error output look like: Linking CXX executable simpleIO cd /home/cjc/csc583-svn/uriVisionLib/trunk/SDK/Demos/C++/Basic/Simple_IO && /home/cjc/packages/CMake/bin/cmake -P CMakeFiles/simpleIO.dir/cmake_clean_target.cmake cd /home/cjc/csc583-svn/uriVisionLib/trunk/SDK/Demos/C++/Basic/Simple_IO && /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*)' (there are more errors as well, but I figured this was enough to make my point). I thought that perhaps the supposedly missing function wasn't in the .a file, so I check with nm as follows: [EMAIL PROTECTED]:~$ nm --demangle /home/cjc/csc583-svn/uriVisionLib/trunk/Development/Source/C++/liburiVision.a | grep outputFrame 002c T uriMovieEditing::ImageWriter::outputFrame(uriBase::RasterImage*) T uriMovieEditing::ImageWriter::outputFrame(uriBase::RasterImage*, bool) U uriMovieEditing::ImageWriter_gen::outputFrame_(uriBase::RasterImage*, bool) So it appears to be in there. I also thought that maybe this was one of the cases where I needed to list the .a file twice on the linker command line, but the linker invocation / output shown above already reflects my doing that (I think). Does anyone know where I might be going wrong here? Thanks, Christian
Re: Linker problems: dependencies with .a file not resolved?
On 27 Feb 2007 21:11:26 -0800, Ian Lance Taylor <[EMAIL PROTECTED]> wrote: "Christian Convey" <[EMAIL PROTECTED]> writes: > ImageReader.cpp:(.text+0x90): undefined reference to > `uriVideoSources::ImageReader_gen::getFrame_(bool, > uriBase::RasterImage*)' > > (there are more errors as well, but I figured this was enough to make my point). > > I thought that perhaps the supposedly missing function wasn't in the > .a file, so I check with nm as follows: > > [EMAIL PROTECTED]:~$ nm --demangle > /home/cjc/csc583-svn/uriVisionLib/trunk/Development/Source/C++/liburiVision.a > | grep outputFrame > 002c T uriMovieEditing::ImageWriter::outputFrame(uriBase::RasterImage*) > T uriMovieEditing::ImageWriter::outputFrame(uriBase::RasterImage*, > bool) > U uriMovieEditing::ImageWriter_gen::outputFrame_(uriBase::RasterImage*, > bool) The error above refers to uriVideoSources::ImageReader_gen::getFrame_(bool, uriBase::RasterImage*) You didn't show whether the library defines that symbol or not. Ian Sorry, I re-typed the operation to have output for my email and goofed. But the symbol really does appear to be in the archive: [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*)
Why does linker fail to resolve dependencies within the same .a file?
On 2/28/07, Nick Clifton <[EMAIL PROTECTED]> wrote: Hi Christian, > /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++ Note: Placing "-luriVision" twice on the command line next to each other like that will not actually gain you anything. The only reason to include a library more than once on a linker command line is if it contains symbols that are referenced by files that are placed after the first occurrence of the library on the command line. eg: 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? > In function `uriVideoSources::ImageReader::getFrame(bool, > uriBase::RasterImage*)': > ImageReader.cpp:(.text+0x90): undefined reference to > `uriVideoSources::ImageReader_gen::getFrame_(bool, > uriBase::RasterImage*)' > [EMAIL PROTECTED]:~$ nm --demangle > /home/cjc/csc583-svn/uriVisionLib/trunk/Development/Source/C++/liburiVision.a > | grep outputFrame As has already been pointed out you are greping for 'outputFrame' when the error message you have reported was for a missing 'getFrame_' symbol. I assume therefore that you are also getting error messages about a missing reference to 'outputFrame_' ? 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: cd /home/cjc/csc583-svn/uriVisionLib/trunk/SDK/Demos/C++/Basic/Simple_IO && /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*)
Re: Why does linker fail to resolve dependencies within the same .a file?
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