14

I followed all the steps successfully as mention in the Qt documentation:

But I still couldn't make static Qt application, the executable generated by the above documented steps still needs Qt shared objects on other system.

Any ideas?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Ankit Rawat
  • 321
  • 1
  • 3
  • 17
  • After you've build Qt itself with the `-static` flag, are you sure that you built your own application using the correct Qt version, and that the static libs were linked? – SingerOfTheFall Jan 16 '17 at 11:05
  • i did ldd to see if executable is not link with any system shared object but putting all efforts its stil linked to a system's Qt shared objects, I also tried it to run on other Linux system but it doesn't work – Ankit Rawat Jan 16 '17 at 11:13
  • Are you using QML? – Benp44 Jan 16 '17 at 18:39
  • yes I am using both c++ and qml @Benp44 – Ankit Rawat Jan 17 '17 at 00:09
  • I'm not sure you can completely statically link to the QML libraries and .qml file. I am using static linking to Qt, but I still need to deploy some QML components – Benp44 Jan 17 '17 at 16:13
  • can you tell me the exact steps to deploy Qt only for c++ because i am having problem even for c++, @Benp44 – Ankit Rawat Jan 18 '17 at 02:42
  • Is there a reason you cannot use the system's Qt? – rubenvb Jan 18 '17 at 10:33
  • yes i have to deploy the application and i dont know if ppl using my application have qt installed in there system, @rubenvb – Ankit Rawat Jan 18 '17 at 10:44
  • @Ankit I'm just asking because the normal way to solve this is to make them install Qt. Not knowing if they have it or not is not good enough a reason to statically link Qt, but this is my opinion. It's just not worth the trouble if you know your users are all on distro's with the required Qt version. – rubenvb Jan 18 '17 at 10:53
  • i installed qt-everywhere-opensource with -static flag then compile my application as mentioned on the document, its written in there documents that it wont need any shared library if i compile my application by there way and my executable size will be more.. but its stil linking to the system Qt's library ie /usr/local/Qt-5.5.1/bin @rubenvb – Ankit Rawat Jan 18 '17 at 11:24
  • my question is that is there any other best way or some other documents to generate static qt application @rubenvb – Ankit Rawat Jan 18 '17 at 11:27
  • @Ankit: If it is in /usr/local it was most likely installed by you. And if it is loading >so's from that location, you built against a shared library build of Qt. – rubenvb Jan 18 '17 at 12:53
  • thn what are the right steps to do that @rubenvb – Ankit Rawat Jan 18 '17 at 14:01

2 Answers2

15

You need to deploy the application, for this purpose I use the utility cqtdeployer

This utility itself collects all the necessary dependencies of your application and you do not have to spend your time on it, or you can automate this process.

You can install from github releases (Windows)

or

from snapstore (Linux)

sudo snap install cqtdeployer

You can use as follows:

  • Windows:
%cqtdeployer% -bin myApp -qmake path/to/Qt/5.x.x/build/bin/qmake.exe -qmlDir path/to/my/qml/files/dir
  • Linux:
cqtdeployer -bin myApp -qmake path/to/Qt/5.x.x/build/bin/qmake -qmlDir path/to/my/qml/files/dir
  • path/to/Qt/5.x.x/build/bin/qmake - This is the way qmake is used to build your program.

  • path/to/my/qml/files/dir - this is the path directly to your qml file (which you wrote)

And Run application with sh script (Linux) or exe (Windows)

If you'll use the version from snap then make sure that you have all the permissions. cqtdeployer

If you need use windows version just install application from installer

Updated

If you want create a simple installer for you application just add qif option for command of cqtdeployer. Example :

cqtdeployer -bin myApp -qmake path/to/Qt/5.x.x/build/bin/qmake -qmlDir path/to/my/qml/files/dir qif

Details on all the intricacies of cqtdeployer can be found on the official wiki project.

Andrey Yankovich
  • 868
  • 9
  • 13
  • What kind of package(s) does cqtdeployer produce for linux? – Silicomancer Sep 26 '20 at 21:37
  • 1
    @Silicomancer if you about creating packages with cqtdeployer then it is only [QIF installers and zip arhive](https://github.com/QuasarApp/CQtDeployer/wiki/Packing(en)) (from version 1.5). There are plans to add support for snaps and deb packages. If you about packages of cqtdeployer then the cqtdeployer can be installed from the [snap package and qif installer](https://github.com/QuasarApp/CQtDeployer/wiki/Build-and-Install#installation-without-building). – Andrey Yankovich Sep 27 '20 at 11:59
  • About creating packages. Snap or AppImage would have been what I was looking for. Thank you! – Silicomancer Sep 27 '20 at 12:41
  • @Silicomancer I plan to add support for creating snap packages, but I still did not undertake this task. on the way now is the creation of self-contained [deb packages](https://github.com/QuasarApp/CQtDeployer/pull/434). – Andrey Yankovich Nov 11 '20 at 18:09
  • 1
    Finally found an answer that actually works! Entirely automatic, allows you to distribute a QT project on Ubuntu Linux without violating the GPL license. – Ronen Jul 09 '22 at 17:08
1

The best way to deploy your application is not necessarily to statically link it for the following reasons:

  • LGPL licencing means that your application must now be made public and may not sold (I think) - i.e. since its statically linked and the qt libs are within your executable your executable is now part of the open source.
  • Its a massive pain in the arse... I have gone around this loop and know the pain well.

Installing qt-everywhere is also not so great, I just don't see how you can garantee that the libraries will be the same version as the ones that your program needs.

So what I started to do was create my own script to deploy qt for me. The basic "jist" of this is that you use ldd to find out which qt libraries you need and copy them into a sub folder (./lib) within the same folder as your executable to make an install bundle.

Note: on Windows there is a deployqt application which does somthing similar (can't remember exactly what it is called).

Below I have copied a version of my deploy script. Note that it is quite old now, but I don't see why it should not work (its not written particularly well), but if not it will give you a start place. Also look out for the plugin's. In this script I have added code to copy the audio plugin since I was using that. If you are using other plugins then you will need to copy those (they are usually in sub dir's of the qt libs like .../audio)... I had a todo to try to figure out what plugins are needed from the .pro file but I never got around to that (I would have to pass in the .pro file to this script as well)...

To run, just run this script and pass in the directory that your executable lives in.

#!/bin/bash

# Rememeber start dir
START_DIR=$PWD

# Determine which dir to deploy in and cd to that dir
if [ -d "$1" ]; then
   DEPLOY_DIR=$1
else
   DEPLOY_DIR=$PWD
fi
echo "Deploy dir: $DEPLOY_DIR"
cd $DEPLOY_DIR

# Run ldd on all files in the directory and create a list of required qt libs
flag=false
for entry in `ldd $DEPLOY_DIR/* | grep -i qt`; do
   if $flag; then
      # Only add to the array if it is not already in it
      if ! [[ $libsArray =~ $entry ]]; then
         echo "adding $entry"
         libsArray="$libsArray $entry"
      fi
      flag=false
   fi

   # If we see a "=>" then the next line will be a library
   if [ $entry == "=>" ]; then
      flag=true
   fi
done
echo 
echo

# Create the required folder structure. Note here we are need the qt audio plugin so we are going to manually copy that as well.
mkdir -p lib
mkdir -p lib/audio
# Now copy these files to the deploy directory
for entry in $libsArray; do
   echo "cp -v -f $entry $DEPLOY_DIR/lib"
   cp -v -f $entry $DEPLOY_DIR/lib
done

# Now get the audio lib - this is a plugin that we are using so we need these libs as well.
# Add other plugins here as well.
# TODO: maybe we can read this in from the *.pro file.
cp -v -f `qmake -query QT_INSTALL_BINS`/../plugins/audio/* $DEPLOY_DIR/lib/audio

# Go back to start dir
cd $START_DIR

Once you have all the files you need you should be able to copy the whole lot to another PC and run it. Note: you may have to set the export LD_LIBRARY_PATH=<path-to-libs> so that the libs can be found... or install the libs into somewhere like /usr/lib/your-appplication/.

But installing libs is another question/subject!

code_fodder
  • 15,263
  • 17
  • 90
  • 167
  • 2
    _Your Application must be made public and may not sold_: No such **direct** restrictions in Qt LGPL or LGPLv3. For following: [Can I use the Community open source version to develop my commercial product?](https://www1.qt.io/faq/#_Toc_3_5) And **“work that uses”** comment here : [What are my obligations when using Qt under the LGPL?](https://www1.qt.io/faq/#_Toc_3_7) – Mohammad Kanan Aug 27 '18 at 11:21
  • 1
    @mohammadkanan yes - that is why (one reason) static linking is a less desirable approach. With dynamic linkage it's not a problem – code_fodder Aug 27 '18 at 11:58
  • 1
    Thanks for a nicely semi-automated way to do this without doing the "cut and try" over and over. Other than locally required libraries, the script gets the main Qt libs needed for deployment. – guitarpicva Feb 19 '21 at 13:43
  • @guitarpicva thanks - although it looks like `cqtdeployer` is probably the tool to use - it was not around (that I know of) when I was writing this script - it *looks* like it does a good job, but I have not used it. Still - if you want a lightweight way this worked well enough for me : ) – code_fodder Feb 19 '21 at 19:22