PDA

View Full Version : Changing Qt Lib Paths



bob2oneil
19th April 2012, 23:18
I performed the standard Qt SDK install, and my binaries produced show
paths to the Qt libraries as /home/QtSDK/etc as revealed by entering the
ldd command under Linux. I am building within Qt Creator using a .pro
file.

As a result, check paths under Linux when building an RPM detects this
absolute path as an error.

For my distribution, I intend to use an RPM to copy two Qt libraries
to /usr/lib64 on a target machine that will not have Qt installed on
it.

While I have changed the LD_LIBRARY_PATH within the QtCreator IDE,
the binaries produced continue to reference my local home SDK install.

I would like this to be the /usr/lib64 pathname where the libraries
are also stored.

Is there a easy way to do this?

ChrisW67
20th April 2012, 01:09
The easy way to do it is to build using the system Qt4 (i.e. use its qmake) rather than the one you are using so that the RPATH/RUNPATH are "correct".

Alternatively, you can force the RPATH using your PRO file:


QMAKE_LFLAGS_RPATH="-Wl,-rpath,/some/other/location"
# or remove it completely
QMAKE_LFLAGS_RPATH=

You can also remove the RPATH/RUNPATH from your executable after it is built using a utility "chrpath".

The rules for locating libraries can can be found in:


$ man ld-linux.so

but you have to temper that with some "What actually happens" information: http://labs.qt.nokia.com/2011/10/28/rpath-and-runpath/

Qt builds executable with both DT_RPATH and DT_RUNPATH set by default. You can see that in the output of:


readelf -d programexe
...

With both set, RPATH is ignored and the dynamic linker will use LD_LIBRARY_PATH, the RUNPATH embedded locations, and the system locations in that order. This is why the Creating the Application Package instructions use a script to ensure that a set of Qt libraries bundled in the application directory are found first. If you don't use LD_LIBRARY_PATH and the RUNPATH does not exist on the target then the system locations will be searched for needed libraries.

You should be aware to writing your application Qt libraries into system location may cripple any system Qt installed on that machine. If you want a system Qt on the machine I suggest you use the system's package manager to install a compatible version.

bob2oneil
20th April 2012, 06:06
Chris, thanks for the detailed response, I will give your suggestions a try.

The motivation for distributing two Qt files (and symlinks) is because for the legacy platforms that I need to support, the latest package manager version of Qt is not very recent, e.g 4.6 rather than say 4.8.1, the current.

I am also considering using static linking to avoid any potential collisions, but am certainly open to ideas on best practices.

The deployment will be for a dedicated platform on say RHEL 6, so the platform itself is not generalized for other use.

However, I do want to be a good workstation citizen, and am open to other ideas.

The platform will not have net access, so the install must be from my installation media, and it is less desirable to install the entire SDK when I only need two shared libraries.

Static linked was the other consideration.

Is there any notion of the Qt libraries being backwards compatible, in the event I replace say a symLink to v4.6 with on to v4.8.1?

Added after 16 minutes:

I should mention that my application is a Linux daemon that is invoked at system boot and run as root and hence some of the solutions that use LD_LIBRARY_PATH may not be applicable.

ChrisW67
20th April 2012, 06:48
For an application running setuid or setgid LD_LIBRARY_PATH will be ignored. A non-setuid application running as root will probably honour it.

There is a magic value, $ORIGIN, you can use on the RPATH/RUNPATH that will cause it to look for libraries in a directory relative to the location of the executable. You can get it this way:


# suppress the default RPATH if you wish
QMAKE_LFLAGS_RPATH=
# add your own with quoting gyrations to make sure $ORIGIN gets to the command line unexpanded
QMAKE_LFLAGS += "-Wl,-rpath,\'\$$ORIGIN\'"
# or for a subdir of your install
QMAKE_LFLAGS += "-Wl,-rpath,\'\$$ORIGIN/libs\'"




$ readelf -d simple example | grep PATH
0x000000000000000f (RPATH) Library rpath: [$ORIGIN]
0x000000000000001d (RUNPATH) Library runpath: [$ORIGIN]


Applications requiring 4.6.1 should run with 4.8.1 libraries, but not the other way around.

bob2oneil
20th April 2012, 16:08
Thanks Chris, this gives me some ideas on the options that are possible. It would seem that the process of installing via an RPM two
Qt libraries does come with some complications, which is why in my case, static linking is a possibility. Currently I am installing via
RPM my daemon to /usr/sbin consistent with Linux conventions for daemons, and I intended to distribute 2 Qt libraries to
/usr/lib64 consistent with the nominal Qt install. The fact that this is not a generalized deployment, but one for a specific
RHEL 6 64-bit platform whose use is for my application alone does give me some latitude. The fact that a 4.8.1 deployment will support
apps using the platform official Qt distro of 4.6, that is 4.8.1 is backwards compatible is very encouraging. It would seem then
by potentially updating the platform and replacing the symbolic links, no damage should be done.

Are you advocating that the 2 Qt libraries, QtCore and QtNetork be placed in /usr/sbin along with my root owned application,
perhaps a different folder for all 3 components, perhaps a static build that eliminates the need for the Qt deployment, or
perhaps just giving me an education on the possibilities?