Cannot mix incompatible Qt library (version 0x40701) with this library (version 0x40703)
-
I downloaded the latest QtSDK and built the IPC examples. When I attempt to run them, I get the error: Cannot mix incompatible Qt library (version 0x40701) with this library (version 0x40703)
_ldd /home/ngsshatt/QtSDK/Examples/4.7/ipc/localfortuneserver/localfortuneserver _
reveals
*
libQtGui.so.4 => /home/ngsshatt/QtSDK/Desktop/Qt/473/gcc/lib/libQtGui.so.4*&etc;.
The Makefile has the following library settings:
*LFLAGS = -Wl,-O1 -Wl,-rpath,/home/ngsshatt/QtSDK/Desktop/Qt/473/gcc/lib
LIBS = $(SUBLIBS) -L/home/ngsshatt/QtSDK/Desktop/Qt/473/gcc/lib -lQtGui -lQtNetwork -lQtCore -lpthread
*objdump -x localfortuneserver reveals:
- RPATH /home/ngsshatt/QtSDK/Desktop/Qt/473/gcc/lib
RUNPATH /home/ngsshatt/QtSDK/Desktop/Qt/473/gcc/lib
This was built on OS 11.4 with Qt4.7.1 installed. I'm not sure where this library conflict is coming from. Any suggestions?
- RPATH /home/ngsshatt/QtSDK/Desktop/Qt/473/gcc/lib
-
bq. libQtGui.so.4 => /home/ngsshatt/QtSDK/Desktop/Qt/473/gcc/lib/libQtGui.so.4
It looks like the linker want to find libQtGui major version 4.
I am pretty sure that if libQtGui.so.4 is already loaded (let say by another program), it will try to use it instead. To keep both you need to force your Qt program to use a specific minor version.bq. This was built on OS 11.4 with Qt4.7.1 installed
Installed means is it on /usr/lib or inside $LD_LIBRARY_PATH ?
edit: Forgot to propose a solution.
Edit whatever variable or file used for library search path in your system as $LD_LIBRARY_PATH
and prepend the path of Qt SDK library directory. -
I found that adding the path to the Qt4.7.3 libraries to the LD_LIBRARY_PATH allows the application to run. I pretty much expected that. I just don't understand why I needed to do that. I'm guessing it has to do with the /etc/ld.so.cache. This is surprising in that the library files are fully referenced in the executable.
-
From the ld-linux.so man page:
The shared libraries needed by the program are searched for in the following order: o (ELF only) Using the directories specified in the DT_RPATH dynamic section attribute of the binary if present and DT_RUNPATH attribute does not exist. Use of DT_RPATH is deprecated. o Using the environment variable LD_LIBRARY_PATH. Except if the executable is a set-user-ID/set-group-ID binary, in which case it is ignored. o (ELF only) Using the directories specified in the DT_RUNPATH dynamic section attribute of the binary if present. o From the cache file /etc/ld.so.cache which contains a compiled list of can‐ didate libraries previously found in the augmented library path. If, how‐ ever, the binary was linked with the -z nodeflib linker option, libraries in the default library paths are skipped. o In the default path /lib, and then /usr/lib. If the binary was linked with the -z nodeflib linker option, this step is skipped.
There appears to be a way to tell the compiler or linker to set the DT_RUNPATH attribute so the correct libraries are hard-coded in the executable. I'm not sure how that is accomplished.
-
bq. This is surprising in that the library files are fully referenced in the executable.
You are mistaken. The only thing which is in the executable is libQtGui.so.4. The path is added at link time, before the execution of the program. Maybe ldd doesn't take all the step of ld, it will explains why 4.7.1 library is not used.
Now that LD_LIBRARY_FLAGS solved your problem, you may want to specify "QMAKE_LFLAGS_RPATH":http://doc.qt.nokia.com/latest/qmake-variable-reference.html#qmake-lflags in the pro/pri file. I am pretty sure there is a way to enforce using a specific minor version (ie 4.7.3 rather than 4.7.1) but I don't know how to do it.
-
Your program seems to be correctly linked to the QtGui library from the SDK (4.7.3), therefore I guess you're loading a plugin that is linking against some other 4.7.1 module, causing the crash. Are you using any KDE style or something like that?
(Of course this gets fixed once you force the LD_LIBRARY_PATH, because then the plugin will use the corresponding module from the SDK).