How to Make Binary Distribution of Qt Application for Linux

How to make binary distribution of Qt application for Linux

You can also distribute Qt shared libraries on Linux. Then, get your software to load those instead of the system default ones. Shared libraries can be over-ridden using the LD_LIBRARY_PATH environment variable. This is probably the simplest solution for you. You can always change this in a wrapper script for your executable.

Alternatively, just specify the minimum library version that your users need to have installed on the system.

Deploy a Qt Application Binary on Linux, compatible with LSB

Your problem here is not the Linux Standard Base, but rather the presence or not of the specific version of Qt you need (or a later one).

Exactly like on a Windows machine, a user may have any of Qt installed, or they may not have it at all. On Windows it is easier to check for the presence of a certain version of Qt than it is on Linux, thus it is easier to write install tools that automate the experience.

To solve your problem there are a few ways:

  1. Inform the user that your program requires a certain version of Qt or higher, and let the user handle the problem
  2. Learn how to create packages for every distribution you want to target and create specific packages
  3. Use a program like 0Install or Elf Statifier to create a package/executable containing all the necessary libraries.

The latter is similar to what many Windows and Mac programs do (they include every library they need within the installer), but it is not the preferred way on Linux, which relies heavily on shared libraries.

How to release a Qt/C++ application on Linux and Windows?

There are several ways to deploy your application

1. Deploy your application with windeployqt/linuxdeployqt

This is the easiest way, windeployqt or linuxdeployqt is an application that will copy all required dependencies to your executable folder. Ready to run on another computer.

The steps are simple:

  1. Compile your binary in release mode
  2. Open the Qt developer console and type windeployqt "C:\folder\of\your\executable" (linuxdeployqt will be very similar)
  3. All libraries required to run the application on another computer are copied to to your application folder. You can create an archive and send it to someone else.

Note: linuxdeployqt is third-party.

2. Static build

Static build will be a single binary at the end that includes all Qt code. You can ship your single binary to someone, no additional libraries are required to run it. The executable is larger since all the Qt code is linked inside your executable.

The steps are as following:

  1. Download the Qt source code
  2. Unzip it to a folder
  3. Open the developer console of your installed compiler (i. e. MingW or MSVC)
  4. Switch to the folder and type

    ./configure -static -static-runtime

  5. When the configuration is done type nmake or make to build Qt statically.
  6. When the build process has finished create a new kit in Qt Creator and select the new qmake.exe or qmake from your source-code folder.
  7. Select in the project settings your kit to build a statically executable that requires not additional libraries.

3. Offline/Online Installer

This step requires some reading and fine tuning. Qt comes with an IFW (Installer Framework) where you can create online and offline installers. The installer will contain a .7z file of your executable and all dependencies. The installer is more comfortable for the user. It can create shortcuts, check available disk space, etc.

IIRC you need build the installer statically for MSVC or you have to ship the runtime libraries. If build with MingW you probably will not need any runtime libraries.

It is up to you which method you choose. If you own the commerical license you can ship all your closed source as static builds, but in general it's better to ship it as a dynamic build especially if you use OpenSSL where users can quickly exchange vulnerable libraries themself if required.

Where is the Qt binary file?

There is no "Qt binary file" per se. Qt is a framework, delivered as a (large) group of libraries and header files.

The Qt installer should provide you with everything you need. I'm not sure this link will work for you, but...
Qt Installer

As an aside, Qt Creator is an IDE for building and testing Qt-based applications. It isn't clear to me why you'd need the sources for that.

Building Qt application for mupltiple linux distributions

I don't think this is viable, there are too many problems with just having your own libraries bundled for everything. Commercial vendors normally have a short list of explicitly supported platforms (distribution + version + architecture combos).

For each platform, use system Qt if such is available and appropriate. For example, on RHEL6/CentOS6, the system Qt is 4.6.2, so you may want to link with your own Qt compiled on CentOS6.

The way it should be done is to have continuous integration system in place, so that you have the target distributions in virtual machines, and an automated script compiles and runs tests on all of them. This doesn't have to be very complex, at a minimum you need a cron script running in each of the VMs, emailing/uploading the results, and a configuration/script to start all the VMs.

How to deploy Qt5 application on Linux in compliance with LGPL?

I thought that other people with a similar problem would be interested what I ended up doing. So, I experimented some more with the simplest for me dynamic linking of the standard pre-build binary Qt5 shared libraries. It turned out that I could come up with a distribution that worked on the following Linux distros: CentOS 7 64-bit, Ubuntu 12.04 64-bit, and Slackware 14.1 64-bit with KDE desktop. The trick was not to include all the dependencies shown by the ldd command. Instead, my binary distribution contains only the following files:

+-platforms/
| +-libqxcb.so
+-libicudata.so.52
+-libicui18n.so.52
+-libicuuc.so.52
+-libQt5Core.so.5
+-libQt5DBus.so.5
+-libQt5Gui.so.5
+-libQt5PrintSupport.so.5
+-libQt5Widgets.so.5
+-qm
+-qm.sh

Where, qm is the application executable and qm.sh is the bash script for launching the application. The script looks as follows:

#!/bin/sh
dirname=`dirname $0`
tmp="${dirname#?}"

if [ "${dirname%$tmp}" != "/" ]; then
dirname=$PWD/$dirname
fi
LD_LIBRARY_PATH=$dirname
export LD_LIBRARY_PATH
$dirname/qm "$@"

The application (qm) does not have any plugins and uses only the basic Qt widget library.

I should perhaps add that I was using the binary qt-opensource-linux-x64-5.3.1 distribution:

http://download.qt-project.org/official_releases/qt/5.3/5.3.1/qt-opensource-linux-x64-5.3.1.run.mirrorlist

I hope this is helpful.

Can I execute a Linux binary from a Windows application?

If your linux binary depends on a lots of things, I really suggest you use docker for windows. Then, you have chance to pre-build an own docker image which put all dependency software also the linux binary you need to run in it.

Of course, to let your customer to use it, you should put it to dockerhub, register an account for yourself.

Then, the solution is simple: let the QT application to call docker run to setup a container base on your own image, execute it, and also let the linux binary to write the log or others to the bind mount volume among linux container & windows. After it run, the QT application fetch the linux binary output from this shared folder.

Finally, I give a minimal workable example for your reference:

  • Suppose the shared folder between windows & linux container is: C:\\abc\\log_share, it will mapped to linux container as /tmp folder. Of course you need to allow volume share by right click the docker icon in windows tray area & choose settings, like described here

  • Simplify the windows application as bat file, and simplfy the docker image as ubuntu, you should use your own prebuilt docker image with all dependency in it:

    win_app.bat:

    ECHO OFF

    ::New a shared folder with linux container
    RD /s/q C:\\abc\\log_share > NUL 2>&1
    MKDIR C:\\abc\\log_share

    ::From windows call docker to execute linux command like 'echo'
    echo "Start to run linux binary in docker container..."
    docker run -it -v C:\\abc\\log_share:/tmp ubuntu:16.04 bash -c "echo 'helloworld' > /tmp/linux_log_here.txt"

    ::In windows, get the log from shared bind mount from linux
    echo "Linux binary run finish, print the log generated by the container..."
    type C:\\abc\\log_share\linux_log_here.txt
  • Simplify the linux binary just as echo command in linux, the output things should be all write to shared directory:

    echo 'helloworld' > /tmp/linux_log_here.txt

Now, execute the bat file with command win_app.bat:

C:\abc>win_app.bat

C:\abc>ECHO OFF
"Start to run linux binary in docker container..."
"Linux binary run finish, print the log generated by the container..."
helloworld

You can see the windows application already could fetch things(here is helloworld) which generated by linux binary from docker container.

Independent qt application and dependency packing in windows and linux

In Linux you can:

1) static-link the dependencies

or

2) pack dependencies windows-style and set environment variable LD_LIBRARY_PATH pointing to the subdirectory containing the dynamic libraries

[updated]

read man ld, may be you will have to compile static versions of the libraries if they are not compiled by default (look at this tutorial if you can't tell the difference).

Great comment by synthesizerpatel, if the library uses autoconf (a lot of linux software do), it has options like --enable-shared and --enable-static.



Related Topics



Leave a reply



Submit