Problem linking a foreign static library
Hi, I'm working with Qt-4.6.3 and VTK on Windows (MinGW), Linux and Mac-OSX. My app is working on these platforms, but I am exploring static link possibilities to simplify deployment. I'm starting with the Windows-MinGW platform, and have built the VTK libraries statically. When I try to build my app with QtCreator I get a large number of "undefined reference" errors from the linker. Here is a sample:
./release\myvtk.o:myvtk.cpp:(.text+0x1c3): undefined reference to
_imp___ZN11vtkRenderer11RemoveActorEP7vtkProp' ./release\myvtk.o:myvtk.cpp:(.text+0x238): undefined reference to_imp___ZN8vtkActor3NewEv'
./release\myvtk.o:myvtk.cpp:(.text+0x259): undefined reference to
_imp___ZN8vtkActor11GetPropertyEv' ./release\myvtk.o:myvtk.cpp:(.text+0x292): undefined reference to_imp___ZN11vtkProperty8SetColorEddd'
./release\myvtk.o:myvtk.cpp:(.text+0x46a): undefined reference to
_imp___ZN9vtkProp3D10RotateWXYZEdddd' ./release\myvtk.o:myvtk.cpp:(.text+0x47d): undefined reference to_imp___ZN11vtkRenderer8AddActorEP7vtkProp'
./release\myvtk.o:myvtk.cpp:(.text+0x64c): undefined reference to
_imp___ZN8vtkActor3NewEv' ./release\myvtk.o:myvtk.cpp:(.text+0x66d): undefined reference to_imp___ZN8vtkActor11GetPropertyEv'
./release\myvtk.o:myvtk.cpp:(.text+0x6a6): undefined reference to
_imp___ZN11vtkProperty8SetColorEddd' ./release\myvtk.o:myvtk.cpp:(.text+0x6b9): undefined reference to_imp___ZN11vtkRenderer8AddActorEP7vtkProp'
./release\myvtk.o:myvtk.cpp:(.text+0x799): undefined reference to `_imp___ZN11vtkRenderer11RemoveActorEP7vtkProp'
There are many more (about 75), presumably one for every call to a function in one of the VTK libraries I'm linking (-lvtkCommon -lvtkGraphics -lvtkFiltering -lvtkIO -lvtkImaging -lvtkRendering -lQVTK). Each symbol that isn't found corresponds to a symbol in one of the libraries. For example in libvtkrendering.a there is the symbol __ZN11vtkRenderer11RemoveActorEP7vtkProp.
It looks as if the compiler is being somehow instructed to add the "imp" prefix to all the VTK functions referenced in myvtk.cpp, i.e. all the functions associated with using a QVTKWidget with interactor capabilities, as if the libraries are shared . When I look in myvtk.o I see all those "imp" symbols. Unfortunately I understand only enough of this stuff to be dangerous. I have been in touch with someone who has managed to link static VTK libraries to a shared Qt build, but he uses cmake. There must be a way to tell qmake how to find the VTK functions, but I don't think it's within my unaided capabilities to figure it out - at least not in a reasonable amount of time.
<edit> Note that each occurrence of "imp" has an underscore '_' before and after, but these do not show up online.
I think you are being set up by C++ name mangling: To enable overloading C++ needs to make types part of the name of a function. To do that it "mangles" the name in a certain way to form the names of the symbols in the object files.
If you are using a gcc-based compiler you can use c++filt to unmangle the name again.
Since c++filt from can not unmagle the names you got there my guess is that your libraries were build with MSVC which is not compatible with mingw.
The VTK libraries are built static with cmake and MinGW. The Qt app that tries to link the VTK libraries is built with QtCreator, using MinGW. In case you didn't notice the symbol names in the VTK libraries are exactly those that get compiled into the application object file myvtl.o, except that imp is prepended. Therefore I don't think it is an issue of name mangling. Instead, QtCreator (i.e. qmake/MinGW) thinks that it needs to access symbols in a shared library, and therefore it adds the imp to what would otherwise be the correct names. I need to know how to get qmake to tell g++ that the library functions are static.
I need to repeat that I used 'nm -g' to look at the symbols in the libraries and the object file. Without the imp prefix there will be no problem.
This has been resolved. There were two issues. First, I had an error in the include path that pointed to the wrong vtkConfigure.h, which had
#define VTK_BUILD_SHARED_LIBS in it (this needed to be commented out). This prevented the mangled symbol names from being translated into C++ function references. Second, I had failed to realize that in the case of static libraries, it is necessary to explicitly link all the supporting libraries as well (about 20 of them!). It's all working now.