Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Installation and Deployment
  4. [Solved]How can I properly force my Qt Application to loads shared libraries from Certain Directory when it loads?
Forum Updated to NodeBB v4.3 + New Features

[Solved]How can I properly force my Qt Application to loads shared libraries from Certain Directory when it loads?

Scheduled Pinned Locked Moved Installation and Deployment
11 Posts 4 Posters 9.1k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    sunsina
    wrote on last edited by
    #1

    I made my QtApplication (name: QtProjectWork ) in Qt5.2.1 and I compiled the binaries for 64 bit GCC running on LinuxMint.
    In my application I have used number of features such as CommandLineParser that are only avaliable on Qt > 5.2.0

    In my programming environment I have installed the QtCreator and I have no problem in compiling and running the application and the required Qt shared libraries are directly loaded from the Qt5.2.1 installation path directory.

    so running following command returns:
    $ ldd QtProjectWork

        _libQt5Network.so.5 => /opt/Qt/5.2.1/gcc_64/lib/libQt5Network.so.5 (0x00007ff2a78f5000)_
    

    libQt5Core.so.5 => /opt/Qt/5.2.1/gcc_64/lib/libQt5Core.so.5 (0x00007ff2a7227000)

    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ff2a6fe7000)

    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007ff2a6ce4000)
    ....

    The problem that I have is since I am going to deploy the code on other LinuxSystem which has no QtCreator
    installed and the user does not have enough privileges to update or install the libraries so once I hand out the code
    to the user I have to include the shared libraries with the executables.

    So I made a "Qtlibs" directory inside the QtProjectWork binary directory and put all the required libraries inside Qtlibs directory with their respective symbolic links (using ln -s and relative path) , so the Qtlibs contents are as follow:
    lrwxrwxrwx 1 btgarden btgarden 19 apr 1 10:43 libQt5Core.so -> libQt5Core.so.5.2.1
    lrwxrwxrwx 1 btgarden btgarden 19 apr 1 10:55 libQt5Core.so.5 -> libQt5Core.so.5.2.1
    -rwxr-xr-x 1 btgarden btgarden 5030256 mar 31 13:34 libQt5Core.so.5.2.1
    lrwxrwxrwx 1 btgarden btgarden 19 apr 1 10:43 libQt5DBus.so -> libQt5DBus.so.5.2.1
    lrwxrwxrwx 1 btgarden btgarden 19 apr 1 10:56 libQt5DBus.so.5 -> libQt5DBus.so.5.2.1
    -rwxr-xr-x 1 btgarden btgarden 534744 feb 4 15:30 libQt5DBus.so.5.2.1
    lrwxrwxrwx 1 btgarden btgarden 22 apr 1 10:43 libQt5Network.so -> libQt5Network.so.5.2.1
    lrwxrwxrwx 1 btgarden btgarden 22 apr 1 10:56 libQt5Network.so.5 -> libQt5Network.so.5.2.1
    -rwxr-xr-x 1 btgarden btgarden 1391448 feb 4 15:30 libQt5Network.so.5.2.1

    In order to force the application to firstly load the shared libraries from the Qtlib directory I added following lines to very beginning of my application main.cpp:
    [Note:some part of the code is taken from http://stackoverflow.com/questions/20398461/deployment-of-qt-apps-under-linux]

    @int main(int argc, char *argv[])
    {

    setlocale(LC_ALL,"C");
    QCoreApplication a(argc, argv);
    // Fixing LIBRARY PATH in LINUX
    QString appFilePath = QCoreApplication::applicationFilePath();
    QStringList paths = QCoreApplication::libraryPaths();
    QCoreApplication::addLibraryPath(QString("%1/%2").arg(appFilePath).arg("Qtlibs"));
    paths = QCoreApplication::libraryPaths();  // Ensures first path to search is in $APP_PATH/Qtlibs 
    QCoreApplication::setLibraryPaths(paths);// refreshing library paths if needed ! @
    

    But this approach does not work and when I execute the $ ldd QtProjectWork I get same result as before.
    It does not load shared libraries from Qtlibs directory :-( .

    I have read different websites regarding shared libraries workarounds, and on has suggested to use a shell script (in linux) and "export LD_CONFIG_PATH=. " which I rather not to use it (due to my multi-platform approach).

    I do not know if I have to use a.setLibraryPaths(paths) instead of (static method) QCoreApplication::setLibraryPaths(paths) !? or how can I solve the problem.
    Thanks in Advance

    1 Reply Last reply
    0
    • sierdzioS Online
      sierdzioS Online
      sierdzio
      Moderators
      wrote on last edited by
      #2

      setLibraryPaths() will not solve your problem. That method changes default lib paths for libraries loaded after your application starts (plugins, or stuff loaded with QLibrary).

      But Qt libraries (and all other DLLs) are required before the application starts, and are being loaded by your OS. So, that part is handled by the operating system and you have no control over it in your application.

      The solution is indeed to use a shell script with LD_LIBRARY_PATH or similar approaches. I know you would rather not do that, but your other possibility in this case is not to distribute your application at all ;)

      (Z(:^

      1 Reply Last reply
      0
      • S Offline
        S Offline
        sunsina
        wrote on last edited by
        #3

        I even tried following shell script and I took out those lines of code
        which sets the library path.

        Then I made following shell script and I checked it that in fact it did not made any changes.

        @#!/bin/bash
        export LD_LIBRARY_PATH="pwd/Qtlibs"
        echo ${LD_LIBRARY_PATH}
        ldd ./QtProjectWork $*
        @
        So still the libraries are downloaded from the opt/Qt/.... directory.
        I am wondering if I can set any variable in .pro file to solve the problem.

        Otherwise I have to compile the code and use it as static library (that I do not know how?).

        In fact in Linux Mint/Ubunutu LD_LIBRARY_PATH is not defined !?.
        I checked /etc/ld.so.conf.d contents which stores the library paths and I could not find and PATH which points /opt/Qt/5.2.1/..... libraries path that was strange (where the Qt libraries paths are defined ?) and how the system looks for it.
        If none of the solution works I have no other alternatives to compile it as static that I have to figure out how :-(

        1 Reply Last reply
        0
        • sierdzioS Online
          sierdzioS Online
          sierdzio
          Moderators
          wrote on last edited by
          #4

          LD_LIBRARY_PATH is always empty: this is exactly so that you can set it yourself in your scripts :) I definitely use it on Kubuntu and it works. You can also check the bin dir of Qt Creator: they are using the same trick.

          If you want to be sure, rename your Qt folder to /opt/Qt-blahblabhblah and then try to run your application with and without the script.

          (Z(:^

          1 Reply Last reply
          0
          • Q Offline
            Q Offline
            qxoz
            wrote on last edited by
            #5

            "Here":http://www.tripleboot.org/?p=138 you can find great blog about solving this issue from "hskoglund":https://qt-project.org/member/131157 .

            1 Reply Last reply
            0
            • S Offline
              S Offline
              sunsina
              wrote on last edited by
              #6

              Thanks qxoz,
              I think the chrpath command that I have to use does not need to be installed on the user's machine (please note that user can not install anything) but I can apply on the binaries in advance [I guess the chrpath changed the binary contents and I do not need to change LD_LIBRARY_PATH in script file?] but I can not figure out how can I change the $ORIGIN to something like ./Qtlibs since I want the libraries reside in one directory after the executable not the same directory that the executable is.

              1 Reply Last reply
              0
              • Q Offline
                Q Offline
                qxoz
                wrote on last edited by
                #7

                Unfortunately i am more windows user and i am afraid can't give you useful advice :( .
                By the way "Qt SDK":https://qt.gitorious.org/qtsdk installer also do something like that.

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  sunsina
                  wrote on last edited by
                  #8

                  Thanks to qxoz and sierdzio I have followed the [tripleboot.com] guidelines
                  it seems all the problems are solved by using chrpath since it modifies the binaries and change the runtime library path.

                  In fact I have used following command to make it work in linux :
                  $chrpath -r ./Qtlibs QtProjectWork
                  it seems that it has modified the binary (checked with md5sum) and the
                  ldd QtProjectWork could be used as single binary with all the Qt5 libraries installed in [EXEC_PATH]/Qtlibs ---> I got no issues with ldd on missing libraries and the issue is solved. :-)

                  1 Reply Last reply
                  0
                  • sierdzioS Online
                    sierdzioS Online
                    sierdzio
                    Moderators
                    wrote on last edited by
                    #9

                    Thanks for sharing the solution with us, I have learned something too :)

                    (Z(:^

                    1 Reply Last reply
                    0
                    • hskoglundH Online
                      hskoglundH Online
                      hskoglund
                      wrote on last edited by
                      #10

                      Hi, just saw this thread, great that my blog is helping! I am lazy but I promise more blog posts, like, more on deployment, how to fix Qt's ODBC for Linux/Mac and how to write a QtCreator plugin.

                      EDIT: forgot, $chrpath -r ./Qtlibs QtProjectWork is a pretty clever idea, makes for less clutter in the app's main directory. And I should mention in the blog, you can indeed do chrpath in advance on your dev. machine.

                      1 Reply Last reply
                      0
                      • S Offline
                        S Offline
                        sunsina
                        wrote on last edited by
                        #11

                        Thanks hskoglund for your great blog.

                        I would rather to use relative paths instead of absolute due to following reasons:

                        1 - Different versions of an application on a single machine does not crash when there is a version mismatch between their shared libraries (which only happens if their rpath is not relative path).

                        2- Access privileges issues for different machines and type of users, user might not get enough privileges to copy and install shared libraries in certain path on the system.

                        3- Ease and comfort in replacing or upgrading libraries without disturbing other applications that are using the very same shared library, one might imagine the huge differences between libQtCore5.so symbol link if it points to different versions of actual shared libraries such as libQtCore.so.5.0.2 or libQtCore.so.5.2.1 .

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved