2
votes

I'm trying to link to a static library, libcovis.a. Everything looks fine but I still have

undefined reference to `CoViG_PublicDemo::MoInS::reset()'

I checked that the name exists in the library

$nm libcovis.a | grep reset

...

_ZN16CoViG_PublicDemo5MoInS5resetEv

...

I'm using linking arguments -L/path/to/libcovis.a -lcovis

What am I doing wrong ?

Edit: The error might be something else, if do

gcc main.cpp -I/usr/include/opencv -I/usr/include/cairo -I../../Source -o slam -rdynamic -lGLU -lGL -lSM -lICE -lX11 -lXext -lglut -lXi -lxml2 -lboost_filesystem-mt -llapack -lblas -lcv -lcxcore -lcvaux -lhighgui -lcairo ../../Source/libcovis.a ../../Source/contrib/gnuplot_i/libcovis_contrib_gnuplot_i.a -lgl2ps

It works !

But when I'm in KDevelop using cmake, I doesn't work anymore. I use

CMAKE_EXE_LINKER_FLAGS:STRING=-rdynamic -lGLU -lGL -lSM -lICE -lX11 -lXext -lglut -lXi -lxml2 -lboost_filesystem-mt -llapack -lblas -lcv -lcxcore -lcvaux -lhighgui -lcairo /usr/local/src/CoViS-0.0.0-1/Source/libcovis.a /usr/local/src/CoViS-0.0.0-1/Source/contrib/gnuplot_i/libcovis_contrib_gnuplot_i.a -lgl2ps

CMAKE_CXX_FLAGS:STRING=-I/usr/local/src/CoViS-0.0.0-1/Source -I/usr/include/opencv -I/usr/include/cairo

The only difference I can see is that the paths are absolute and not relative, but if he couldn't find the libs, he would say it...

3
This looks like you are using the gcc toolchain. Compiler and linker options are not the same across different toolchains, so you should tag the question with "gcc" (if that is the case)David Rodríguez - dribeas
You can use CMake to generate regular makefiles and try to compile, if it fails analyze what the exact command line that is being triggered by the CMake generated makefiles is, and how it compares to what you are doing manually.David Rodríguez - dribeas
After documenting a bit about cmake, it seems that I was using it the wrong way (i.e. editing CMakeCache). I added my libraries using CMakeList.txt, and now it works perfectly !Julien

3 Answers

4
votes

There are two different issues there, the first of which is the simplest, you have used the wrong compiler options. The -L option tells the linker to also look in the directory when looking for a library. The -l tells it to link the specific library. To link you would then use:

g++ -o test test.o -L/path/to -lcovis

or

g++ -o test test.o -l/path/to/libcovis.a

To force static linking if the same library is present as a dynamic library in the same directory.

The second potential issue is that the order of static libraries in the linker command line does matter, so that might also be an issue if there is a dependency on different static libs.

g++ -o test tests.o -ldependent -lprovider

The linker will process the libraries in order as they are in the command line, and from each static lib it will only pull those symbols that are required (with as much information as the linker has at that time). In the command line above, the linker will extract from dependent the symbols it needs for test.o, and that might in turn add new undefined symbols to the program (the dependencies of dependent). When it processes provider it will fill in those symbols. If the order was reversed in the command line, the symbols that are required by dependent but not by test.o would not be added to the executable, as the linker does not know that those symbols will be needed when processing provider.

2
votes

Should the arguments be like -L/path/to/ -lcovis?

Besides, object files should be placed before libs, for example

g++ obj1.o obj2.o -L/path/to/ -lcovis.

0
votes

If you see the link succeeding in one context but not another, I suspect the problem may be caused by the order in which the link operation is executed as the linker will discard symbols in a library if they're not needed at the point in which the library is referenced.

Here is a link explaining: http://www.network-theory.co.uk/docs/gccintro/gccintro_18.html

I've run into similar situations in the past the linking order was found to be the cause of the problem.