One of Qt’s greatest strength is also one of its major weakness. The code once deploy everywhere motto is nice when coding but once you reach the deployment step, it gets a whole different meaning.
As we are getting ready for the alpha release of Tepee3D (and almost a week late), I thought I’d post about what made us lose time.
Before creating installers for each of the platforms you are targeting, you have to run your application without the whole Qt environment on each of those.
There are two ways two proceed, either by compiling Qt statically against your executable or by delivering the necessary Qt libraries with your application.
Although the first option is the simplest of the two, it has a few caveats. First, you cannot deploy a closed sources application that way as it is against the licenses under which Qt is released.
Additionally the more Qt Modules and Add ons your application depends on, the bigger your executable will be.
We first tried the first option for Tepee3D but as we encountered errors when building statically our Qt3D fork, we switched to the second option.
First of all you need to create a package containing the necessary elements to include for your project to run. In our case this consists of shared libraries, qml and media files as well as the executable itself.
Above is the base packaged used both on Windows and Linux.
The following step is adding the necessary Qt libraries to that package. To find out which libraries you depend on you can use:
On Linux : ldd ./Your_Executable
On Windows : DependencyWalker http://www.dependencywalker.com/
Once you know what are the libraries you need, copy them in a separate folder, in our case Qt_Libraries
If your application uses Qt Declarative / Qt Quick you’ll have to copy the qml directory located at the root of your QtSDK.
In addition, you’ll need to copy the platforms plugins located at QtSDK/plugins/platforms as well.
Here is a listing of our Qt_Libraries directory.
On Windows, you’ll also need to include the C++ windows runtime libraries in Qt_Libraries, (msvcp110.dll and msvcr110.dll) which can be found under Windows/system32.
Now we’re almost done, we just have to set the required path for our executable.
The easiest way to do so is by creating a shell/bat script that will set the proper variables and then call the executable.
On Linux you can use :
#!/bin/sh export LD_LIBRARY_PATH=`pwd`/Qt_Libraries export QML_IMPORT_PATH=`pwd`/Qt_Libraries/qml export QML2_IMPORT_PATH=`pwd`/Qt_Libraries/qml export QT_QPA_PLATFORM_PLUGIN_PATH=`pwd`/Qt_Libraries/plugins/platforms ./Tepee3DEngine
On Windows :
SET PATH=%cd%\Qt_Libraries;%PATH% SET QML_IMPORT_PATH=%cd%\Qt_Libraries\qml SET QML2_IMPORT_PATH=%cd%\Qt_Libraries\qml SET QT_QPA_PLATFORM_PLUGIN_PATH=%cd%\Qt_Libraries\plugins\platforms %cd%\Tepee3DEngine.exe
Now, test that your executable runs as planned and preferably on a clean environment.
You can finally create installers that will bundle properly your application package. We used the Qt Installer Framework and the process was quite straight forward.
Hoping it might help someone someday.