How to build a static Qt on Windows / MinGW using a PowerShell script



  • Hello,

    There is a number of requests and answers in many forums about the way to compile a static version of Qt. When I was looking for a method to do so on Windows, I found many clues but no complete off-the-shelf script to do this. Since I prefer automated processes for administrative tasks, I wrote a script to do so and I share it using this post.

    Why a static Qt?

    On Windows, the pre-built environments from qt-project.org are dynamically linked. IMHO, this remains the preferred environment for developing and debugging since everything is there and ready to use. However, when it comes to deploying an application on systems without pre-installed Qt environments, it becomes complicated. There are several DLL's to install. Even using the classical "DLL Dependency Walker", you cannot find all required DLL's since some of them are dynamically loaded at execution. So, when the application is ready to deploy, it is easier to build a static version of it. But building a static version of the application requires a static version of the Qt environment in addition to the pre-built dynamic Qt environment.

    Building script

    I had this requirement in a small personal open-source project named "QtlMovie":http://qtlmovie.sourceforge.net/ and, as part of this project, I wrote a script which downloads, builds and installs a static version of Qt.

    Note that building and installing a static version of Qt on Windows was somewhat problematic up to Qt 4. But Qt 5 has now a much better support for static builds on Windows and the script takes advantage of that.

    The script is available in the git repository of QtlMovie at "https://sourceforge.net/p/qtlmovie/code/ci/master/tree/build/windows-build-qt-static.ps1":https://sourceforge.net/p/qtlmovie/code/ci/master/tree/build/windows-build-qt-static.ps1?format=raw

    Note that I use MinGW for both the pre-built and static environment. I have not used MS Visual Studio and I have not written a corresponding version of the script for this environment.

    If you have similar needs as mine, you may want to try it or review it. Any feedback is welcome.

    Requirements

    First, a pre-built Qt environment for MinGW must be installed. Preferably use the same version for both dynamic and static versions of Qt.

    This script uses Windows PowerShell. The version 3.0 or higher is required. PowerShell 3.0 comes with Windows 8 but it can be installed on Windows 7 as well from Microsoft "download":http://www.microsoft.com/en-us/download/details.aspx?id=34595

    This script also requires "7-Zip":http://www.7-zip.org/ to uncompress the downloaded Qt source code.

    Invocation

    The PowerShell script can be directly invoked from the Windows Explorer if you are ok with the default parameter values (see below).

    Alternatively, you can invoke it from the PowerShell prompt using the following syntax;

    windows-build-qt-static.ps1 [[-QtSrcUrl] <Object>] [[-QtStaticDir] <Object>] [[-QtVersion] <Object>] [[-MingwDir] <Object>] [-NoPause]

    Description

    This scripts downloads Qt source code, compiles and installs a static version of Qt. It assumes that a prebuilt Qt / MinGW environment is already installed, typically in C:\Qt. This prebuilt environment uses shared libraries. It is supposed to remain the main development environment for Qt. This script adds a static version of the Qt libraries in order to allow the construction of standalone and self-sufficient executable.

    This script is typically run from the Windows Explorer.

    Parameters

    -QtSrcUrl <Object>

    URL of the Qt source file archive. By default, use the latest identified version (Qt 5.2.0-rc1 at the time of this post). You may want to modify the script using another URL / version.

    -QtStaticDir <Object>

    Root directory where the static versions of Qt are installed. By default, use C:\Qt\Static.

    -QtVersion <Object>

    The Qt version. By default, this script tries to extract the version number from the Qt source file name.

    -MingwDir <Object>

    Root directory of the MinGW prebuilt environment. By default, use the version which was installed by the prebuilt Qt environment.

    -NoPause [<SwitchParameter>]

    Do not wait for the user to press <enter> at end of execution. By default, execute a "pause" instruction at the end of execution, which is useful when the script was run from Windows Explorer.

    Using the Qt static environment

    To build your static applications, set up the environment variables to the static environment. For instance, using Qt 5.2.0-rc1, wherever you use C:\Qt\Qt5.2.0\5.2.0-rc1\mingw48_32 for the dynamic environment, use C:\Qt\Static\5.2.0-rc1 for the static environment.

    Also add CONFIG+=static to all your qmake command lines.

    Note that the static environment contains all libraries and command line tools (qmake, lupdate, lrelease, etc) but not the GUI tools (designer, assistant, creator, linguist, etc). The GUI tools are essentially used in the development process and the pre-built dynamic environment remains the preferred one. On the other hand, the command line tools are required in scripts to build the final static application.


  • Moderators

    Thanks for sharing this. I skimmed through quickly, but it looks really impressive and you have invested quite a bit.
    I think it is worthwhile to make a "wiki entry":http://qt-project.org/wiki out of it. Or may be try to get it into the "blogs".
    Here it might be forgotten over time.


  • Lifetime Qt Champion

    Hi,

    I agree with koahnig, a more lasting support would be good. The guide however misses just one thing: the licensing issues that comes with static linking.



  • Thanks for your support.

    I will consider putting this in the wiki when I have some time. I think it would need more details and background info in a good wiki entry.

    @SGaist: This is only a script describing "how to build", nothing more. And yes, there are both licensing and technical implications / restrictions in the use of a static build, like the inability to use dynamic plugins in the applications. This is why using Qt in a static environment would deserve a very long and detailed article.

    Generally speaking, I prefer to avoid writing about licensing because there is no "truth" in this matter, only an aggregation of contradictory opinions (even though everyone is firmly convinced to hold the truth).

    In "this post":https://blog.qt.digia.com/blog/2009/11/30/qt-making-the-right-licensing-decision/, Cristy Hamley says "There is debate in the legal and open source communities as to whether static linking is permissible under the LGPL version 2.1. The uncertainty is caused by an inconsistency in the LGPL license itself [...]" A good summary for "nobody knows but everyone pretend to".

    My position is that the GPL family of licenses creates more problems than it solves. This is why I use the BSD license for the small project I mentioned. I just hope to never be sued for having used the LGPL static Qt libraries with my BSD code in an open-source project :-) But who knows, I have read so many silly ukases about GPL licensing...


  • Lifetime Qt Champion

    I understand your point but I was just thinking about a warning directing to Digia for further information. Nothing more fancy, we are not lawyers :-)



  • You saved my day man. You are a hero!



  • @koahnig Following your advice, I have adapted this post for a "wiki entry":http://qt-project.org/wiki/How-to-build-a-static-Qt-for-Windows-MinGW.

    The explanations are a bit more detailed. Information has been added on building static applications using Qt Creator.

    @SGaist The wiki entry mentions the licensing issue and links to Digia for more details.


  • Lifetime Qt Champion

    Very nice, thank you


  • Moderators

    Thank you very much for sharing this!



  • Newbie here getting the following error. Any help would be greatly appreciated.

    Building static Qt version 5.3.0
    Using MinGW from C:\Qt\Qt5.3.0\Tools\mingw482_32

    • cd qtbase
    • C:\Qt\Static\src\qt-everywhere-opensource-src-5.3.0\qtbase\configure.bat -top-level -static -debug-and-release -platform win32-g++ -prefix C:\Qt\Static\5.3.0 -qt-zlib -qt-pcre -qt-libpng -qt-libjpeg -qt-freetype -opengl desktop -qt-sql-sqlite -no-openssl -opensource -confirm-license -make libs -nomake tools -nomake examples -nomake tests

    This is the Qt for Windows Open Source Edition.

    You have already accepted the terms of the license.

    Creating qmake...
    mingw32-make: Nothing to be done for 'first'.
    Running configuration tests...
    In file included from arch.cpp:45:0:
    C:\Program Files (x86)\Microsoft Visual Studio\VC98\include/stdio.h:77:24: error: redeclaration of C++ built-in type 'wchar_t' [-fpermissive]
    typedef unsigned short wchar_t;
    ^
    mingw32-make: *** [arch.o] Error 1
    Could not find output file: No such file or directory
    mingw32-make: *** No targets specified and no makefile found. Stop.
    mingw32-make: *** No rule to make target 'install'.



  • The path to stdio.h in the error message contains Microsoft Visual Studio\VC98, which seems to indicate that an old Visual C++ 6.0 interferes with the MinGW compiler.

    The stdio.h file for MinGW is expected to be found in C:\Qt\Qt5.3.0\Tools\mingw482_32\i686-w64-mingw32\include.

    Did you install first the dynamic version of Qt 5.3 with the MinGW toolset? See the full "wiki entry":http://qt-project.org/wiki/How-to-build-a-static-Qt-for-Windows-MinGW for this article for details.

    Did you define environment variables which could lead MinGW to search the include files in the VC++ 6.0 tree?



  • Thanks thiel; It did finally work after I un-installed VS6.0. I can't quite explain why even after removing \Microsoft Visual Studio and adding the MinGW path to stdio.h to my environment path it still tried to go to \Microsoft Visual Studio. But I didn't care much about VS6.0 so it worked out fine to just un-install it.


Log in to reply
 

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