execute Qt5 program



  • Hi. I am Linux user.
    I installed a new Qt5.5 and uninstall previous installed Qts. I install Qt inside /opt/Qt.
    I have set some environment variables inside "~/.bashrc", so now i can run Qt5 programs from a console (bash),
    but if i want to execute directly a Qt5 program with a double click, it not run. I suppose he not found some library.
    Somebody can help me ? I need to set some environment variables, and where ?
    Daniel



  • Hi, on Linux when you have installed Qt 5.5, you should be able to run Qt programs directly both from Terminal (bash) or by double-clicking them.
    When Qt Creator builds your program, it writes the path to your Qt installation on your PC in your program. It's called the RPATH.

    To check the RPATH, you can download and install a utility:
    sudo apt-get install chrpath

    Then to check your program:
    chrpath myprogram



  • Thanks. But i need to tell you that it not adjust directly my environment variables.
    After doing a chrpath :
    chino/VocabularyMem: RPATH=/home/daniel/Qt5.5/5.5/gcc_64:/home/daniel/Qt5.5/5.5/gcc_64/lib
    But not is
    /home/daniel/Qt5.5/...
    its
    /home/daniel/Qt
    Previously i have installed Qt on path ..Qt5.5, but i uninstall it, and install again on ...Qt (this is default) for have a cleaner system (i have previously directories as Qt5.2, Qt5.3, ...)
    How to set now RPATH permanently ?
    Thanks. Daniel



  • Dynamic linking / shared libraries are a pain. At the end of the day, you'll have to work out a way to determine which shared libraries your executable needs and how to locate them. This will be specific to your system. I've had to deal with this a bit, so I'll post some of my thoughts.

    Determine required shared libraries

    To figure out which shared libraries that your executable needs, you can use readelf:

    $ readelf -d <executable> | grep -i qt
    
    0x00000001 (NEEDED)     Shared library: [libQtGui.so.4]
    0x00000001 (NEEDED)     Shared library: [libQtCore.so.4]
    

    Replace <executable> with the name of your executable...is yours called chino/VocabularyMem?

    Use loader diagnostics (ldd)

    ldd can show you where loader (ld) will find libraries at runtime:

    $ ldd <executable> | grep -i qt
    
    # sample output: the Qt libraries are in /usr/lib64
    libQtGui.so.4 => /usr/lib64/libQtGui.so.4 (0x00007fcac241b000)
    libQtCore.so.4 => /usr/lib64/libQtCore.so.4 (0x00007fcac1f33000)
    

    If a required shared library can't be found, you see something like this:

    liblog4cplus-1.2.so.5 => not found
    

    Many shared libraries use symbolic links

    The loader diagnostics only show part of the story, as the listed libraries might actually reference more specific versions:

    $ /sbin/ldconfig -v 2>/dev/null | egrep -i "libqt(gui|core)"
    
    libQtGui.so.4 -> libQtGui.so.4.8.5
    libQtCore.so.4 -> libQtCore.so.4.8.5
    

    Note: 2>/dev/null gets rid of the annoying "Cannot stat...No such file or directory" messages that often clutter the output.

    In the output above, you'll see that what looks like version 4 is really 4.8.5; so you can tell that in this case, the executable is using Qt 4, specifically Qt 4.8.5.

    Depending on what you're doing, you might be able to use symlinks to help solve your issue.

    System default location for shared libraries

    One way (but not the only way) that the system locates shared libraries is by looking in the paths specified in ld.so.conf:

    $ cat /etc/ld.so.conf
    
    /usr/local/lib64
    /usr/local/lib64
    include /etc/ld.so.conf.d/*.conf
    

    Installing into non-standard locations (like /home) means that the system might not find the shared libraries it needs, in which case you'll have to find another way.

    rpath or runpath in binaries

    When an executable is loaded, it will search the RPATH for shared libraries. You can see what this is:

    chrpath <executable>
    <executable>: no rpath or runpath tag found.
    

    So in the example I gave above, there was no RPATH set. However, you can embed this information into the executable at compile (linking) time. Passing -Wl,-rpath,<paths> to g++ embeds info on where to find the shared library into the executable. For example:

    g++ ... -Wl,-rpath,.:/test/test
    

    This would tell the system to look in these places:

    1. . the current/working directory
    2. test/test a relative path to the current directory

    When I specified RPATH at compile time, this is what chrpath says:

    chrpath <executable>
    <executable>: RPATH=.:test/test
    

    RPATH can be changed after the fact using this option with chrpath:

    -r <path>|--replace <path>
    

    QtCreator: case study

    How does an application find its shared libraries? Let's use QtCreator as an example.

    You'll notice that QtCreator sets RPATH to search relative directories:

    $ chrpath qtcreator
    
    qtcreator: RPATH=$ORIGIN/../lib/qtcreator:$ORIGIN/../lib/qtcreator/plugins
    

    QtCreator is heavily dependent on the specific version of Qt that it was compiled against. As a result, QtCreator ships with the specific libraries it needs to run, which are located in the paths you see above. This has a few consequences:

    1. You can use a different version of Qt than QtCreator was compiled against
    2. You can have multiple versions of QtCreator on the same system

    In my view, these are good properties for a program to have. Here's what I usually do:

    1. Determine the shared libraries that the executable needs.
    2. Copy the libraries into a directory relative to the executable, say lib/.
    3. During the linking phase, set RPATH to lib/.

    Sometimes you will not want to do this, but instead you will indeed want to use the shared libraries on the system--that's a key idea behind shared libraries. However, there are situations where that might not be desired.

    QtCreator is probably different from most Qt applications that most of us write. QtCreator uses private headers and relies on non-public parts of Qt, which are subject to change from one Qt release to the next. You might not need to take the same measures that QtCreator does to locate shared libraries.

    Determine for yourself what is appropriate.

    LD_LIBRARY_PATH

    There is another technique that I see developers use all the time. You can set the LD_LIBRARY_PATH environment variable before the program is run. As a developer I do this often, although the user of an installed program isn't expected to have to do this. Some people will advise against doing this, but before anyone gawks at this method, let's take a look at what QtCreator 3.5.0 does:

    $ cat qtcreator-3.5.0/bin/qtcreator.sh
    ...
    bindir=`dirname "$me"`
    libdir=`cd "$bindir/../lib" ; pwd`
    LD_LIBRARY_PATH=$libdir:$libdir/qtcreator${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
    export LD_LIBRARY_PATH
    exec "$bindir/qtcreator" ${1+"$@"}
    

    I've listed the last few lines of the qtcreator.sh launcher script. I'm using KDE, and this is the script that I run when I want to use QtCreator. I have (at least) three versions of QtCreator installed, and this script tells you exactly what's going on. Notice that LD_LIBRARY_PATH is modified.

    Akin to how qtcreator.sh works, you can write your own "launcher" script that you can run from your desktop, something similar to this:

    #!/bin/bash
    LD_LIBRARY_PATH=/home/daniel/Qt/5.5/gcc_64/lib
    export LD_LIBRARY_PATH
    ./<executable>
    

    Put this in the same directory as the executable. Then run this launcher shell script instead of the executable.



  • Thanks very much.
    I have success using "chrpath ... -r ..."
    Daniel


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.