I have a Linux Qt program. I'd like it to preferentially use the (dynamic) Qt libraries in the executable's directory if they exist, otherwise use the system's Qt libs. RPATH to the rescue.
I add this line to the qmake's .pro file:
QMAKE_LFLAGS += '-Wl,-rpath,\'\$$ORIGIN\''
and looking at the resulting executable with readelf I see:
0x000000000000000f (RPATH) Library rpath: [$ORIGIN:/usr/local/Trolltech/Qt-5.2.0/lib]
0x000000000000001d (RUNPATH) Library runpath: [$ORIGIN:/usr/local/Trolltech/Qt-5.2.0/lib]
Seems right, but ldd shows it's using the system version:
libQt5Core.so.5 => /usr/local/Trolltech/Qt-5.2.0/lib/libQt5Core.so.5 (0x00007f2d2fe09000)
If I manually edit qmake's resulting Makefile to swap the order of the two rpaths, so $ORIGIN comes after /usr/local/..., I get the right behavior:
0x000000000000000f (RPATH) Library rpath: [/usr/local/Trolltech/Qt-5.2.0/lib:$ORIGIN]
0x000000000000001d (RUNPATH) Library runpath: [/usr/local/Trolltech/Qt-5.2.0/lib:$ORIGIN]
libQt5Core.so.5 => ./libQt5Core.so.5 (0x00007fb92aba9000)
My problem is with how qmake constructs the final LFLAGS variable. I can't figure out how to make it put my addition ($ORIGIN) after the system library. Any ideas?
As far as my research can say, you can only add RPATH at the beginning of the list with QMake.
But if you are on Linux and can install
chrpath
, you can hack your way around that.Add this block at the end of your .pro file
I'm taking a bit of a guess at what's happening, but it's based on knowing some of the odd behaviours of ld.
check for the presence of an
LD_LIBRARY_PATH
variable that will come into effect before the processing of a RUNPATH variable. Because of the presence of bothRPATH
andRUNPATH
, theLD_LIBRARY_PATH
rule comes into effect, so if it's set then unset it.Secondly, I'd never expect to see:
in the output of
ldd
, I would always see the expansion of$ORIGIN
to the directory of the binary (maybe you shortened it?), so I would have expected:Which means it sounds like the
LD_LIBRARY_PATH
expansion is.:/usr/local/Trolltech/Qt-5.2.0/lib
, which to me sounds like you've got environmental overrides happening.qmake would always append the
QMAKE_RPATHDIR
with theQT_INSTALL_LIBS
internally defined in$(QT_DIR)/mkspecs/features/qt.prf
file:So to avoid your application using the
QT
library from system path, comment out the lines above which append theQMAKE_RPATHDIR
and addQMAKE_RPATHDIR=$ORIGIN
into your.pro
file.You can add the following to your .pro file to force the dynamic linker to look in the same directory as your Qt application at runtime in Linux :
If you want it to look in a subdirectory of the executable path, you can use :
Note that you should have the .so files with the exact same name in your application directory. For example you should copy
libQt5Core.so.5.2.0
to your application directory with the namelibQt5Core.so.5
. Now the ldd shows the directory of the application.You can also have
libQt5Core.so.5.2.0
and a link to it with the namelibQt5Core.so.5
in the application directory.