[Qt-interest] Linux Deployment using rpath and $ORIGIN
Oliver.Knoll at comit.ch
Oliver.Knoll at comit.ch
Mon Dec 13 11:23:34 CET 2010
On 2010-12-11 Joshua Joshua Grauman wrote:
> .... I just read that rpath can take $ORIGIN as an
> option which looks for libraries in the directory of the executable.
Yes, I can confirm that the following works (at least on Kubuntu 10.10):
In the *.pro file for an executable/library: (1)
QMAKE_LFLAGS += -Wl,--rpath=\'\$\$ORIGIN\'
Then when copying the *.so files into the same directory as the executable the executable will find them (regardless of the CURRENT WORKING DIRECTORY, which is good).
(1) Not sure whether it would be sufficient to have this line only set for the executable. I also have it set for the libraries, because they depend on each other. But maybe that would also work with that line only for the executable.
This page helped me, too: http://paulf.free.fr/undocumented_qmake.html
This page was also helpful: http://newsgroup.xnview.com/viewtopic.php?f=14&t=5557
(with regards of the danger of using '.' instead of $ORIGIN)
And while we're at it:
I tried several combinations, e.g.
QMAKE_LFLAGS_RPATH += \'\$\$ORIGIN\'
or
QMAKE_RPATHDIR += \'\$\$ORIGIN\'
but that did not work, at least not with the combination of '$ORIGIN': the generated Makefile syntax would not recognize/accept the value for $ORIGIN, or the libraries would still not be found by the executable.
Also refer to http://bugreports.qt.nokia.com/browse/QTBUG-8110
And for the record, this is how I managed to create an application bundle on Mac, using shared libraries (*.dynlib, dynamic libraries on Mac):
For a given library:
macx {
QMAKE_LFLAGS_SONAME = -Wl,-install_name, at executable_path/../Frameworks/
DESTDIR = $$PWD/../bin/$${APP_NAME}.app/Contents/Frameworks
}
!macx {
CONFIG += plugin
}
where APP_NAME is the name of the application (my own defined variable) respective the <APP_NAME>.app bundle. That is @executable_path../Frameworks is set as the "library identifier" and the library is copied into
<APP_NAME>.app/Contents/Framework
subfolder. Also refer to http://doc.trolltech.com/4.7/mac-differences.html#bundle-based-libraries
Note that I usually set CONFIG += plugin for ALL my shared libraries. This is so that on Linux/Windows I don't get the symbolic links (Linux) and the version number in the file name (Linux, Windows), e.g.
libFoo.1.0.0.so
libFoo.1.0.so -> libFoo.1.0.0.so
libFoo.1.so -> libFoo.1.0.0.so
Instead I prefer to simply have:
libFoo.so
which in my case is enough. The only way so far I figured out is to set the above CONFIG += plugin - or is there a better way to prevent qmake from generating symbolic links/version numbers?.
But on Mac one must NOT set config += plugin, because it seems that in this case the install_name_tool is NOT applied to the generated plugin/library and the line
QMAKE_LFLAGS_SONAME = -Wl,-install_name, at executable_path/../Frameworks/
Has NO effect! But since the libraries are copied into the app bundle anyway (and hence "not visible" to the user and the application can easily be copied/deployed) this is okay to have the symbolic links/version numbers inside the app bundle).
And to complete the story, on Windows it is usually enough to copy the DLLs into the application directory, where the *.exe is located, without any other qmake settings required. On Windows the executable path is also included, refer to http://msdn.microsoft.com/en-us/library/7d83bc18%28v=vs.80%29.aspx
Note that since the "current directory" is ALSO (by default) included in the "DLL search path" this can be a security risk if the application dynamically loads DLLs with relative file paths! Also refer to http://www.securityfocus.com/bid/1699/discuss and other resources on the internet on how to tweak the "DLL search path" (basically always use *absolute* file paths, e.g. when loading plugins etc.).
Cheers, Oliver
--
Oliver Knoll
Dipl. Informatik-Ing. ETH
COMIT AG - ++41 79 520 95 22
More information about the Qt-interest-old
mailing list