En
Ar
Bg
De
El
Es
Fa
Fi
Fr
Hi
Hu
It
Ja
Kn
Ko
Ms
Nl
Pl
Pt
Ru
Sq
Th
Tr
Uk
Zh
Contents
- 1 WARNING
- 1.1 Why a static Qt?
- 1.2 MinGW vs. MSVC
- 1.3 Target environment
- 1.4 Restrictions in a static environment
- 2 Prerequisites
- 2.1 Dynamic pre-built Qt environment
- 2.2 Windows PowerShell
- 2.3 7-Zip
- 2.4 Qt build dependancies
- 3 Building the Qt static environment
- 3.1 Using the Windows Powershell script
- 3.2 Command line syntax
- 3.3 Command line parameters
- 4 Using the Qt static environment
- 4.1 Using the Qt static environment with Qt Creator (recommended)
- 4.2 Command line
- 4.3 When to use a Static Qt build
WARNING
The information on this page is outdated!
Please refer to the official documentation for instructions how to build Qt on Windows: https://doc.qt.io/qt-6/windows-building.html
Also, the rationale why to use a static build is questionable. See https://doc.qt.io/qt-6/windows-deployment.html for how to deploy a Qt application on Windows.
If you still want a static build, add -static
to the configure
arguments.
Why a static Qt?
On Windows, the pre-built environments from qt.io are dynamically linked. This means that your Qt application dynamically references the Qt DLL’s which are installed with the pre-built environment.
This is probably 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 deploy with the application. Even using the classical DLL Dependency Walker tool, 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.
This article describes an automated way of downloading, building and installing a static Qt development environment using a Windows PowerShell script.
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 this article takes advantage of that.
MinGW vs. MSVC
On Windows, two pre-built environments can be downloaded: one using MinGW and one using Microsoft Visual Studio. The two environments are incompatible and cannot be mixed. You have to choose one.
This article describes how to build a static version of Qt in a MinGW environment. If you need a static Qt for MSVC, you may probably find some ideas here but there is definitely some extra work.
Target environment
When you develop Qt applications on Windows and need to deploy them later on «general purpose» Windows machines, the recommended Qt environment contains two distinct builds of the same version of Qt:
- A dynamic version, installed in C:\Qt from a pre-built package.
- A static version, installed in C:\Qt\Static using the procedure which is described in this article.
The pre-built dynamic environment shall be used for development and debugging. In addition to the Qt command line tools (qmake, moc, uic, lupdate, lrelease, etc.), it contains the high-level GUI tools such as Qt Creator, Assistant, Linguist, etc. The installation is straightforward, everything is here, well integrated, working like a charm.
The static environment should only be used to release the deployment version of the application, after it has been fully developed and debugged using the dynamic environment. The static environment should only be compiled to contain the Qt command line tools. There are at least two reasons for not building static versions of the GUI tools. First, releasing a new version of an application is typically a task that you automate using a script and there is no need for GUI tools at this stage. Second, it is probably impossible to build a static version of Qt Creator because of the lack of support for plugins in a static environment.
Restrictions in a static environment
Although building a static version of your application makes it easier to deploy, there are some restrictions in a static environment. Be sure to check that your application complies with these constraints before going further.
- There are licensing issues in distributing applications embedding Qt code in a static link. See here and here for more details. While you are probably safe if your application is distributed according to the terms of a recognized free and open-source license, you should definitely check the licensing issue for proprietary or closed-source applications.
- The application cannot use a dynamic modular approach using plugins. But you cannot both ask for a static environment and for a dynamic loading of your own DLL’s.
Also note the following points:
- The static executable file of the application is bigger than the dynamic one since all used Qt code is copied into the executable. However, if your application has only one executable, the total deployed size is smaller since only the Qt code which is actually used is linked. When deploying a dynamic version of the application, you have to install all required Qt DLL’s with the application and the overall size of all these DLL’s is larger than the static application.
- A Qt static build means that no Qt or MinGW DLL’s are used. However, the static executable file of the application still references the Windows DLL’s such as kernel32.dll or user32.dll. These DLL’s, however, are installed with Windows and do not need to be deployed with the application.
Prerequisites
Dynamic pre-built Qt environment
You must have a pre-built Qt environment installed before you attempt to build a static version of the library with the Qt source code.
- Obtain the Qt Installer from qt.io and install the relevant pre-build Qt environment. For example, «Qt 5.15.2 MinGw 8.1.0 32-bit»
- Preferably plan the installation of the same version of Qt for the dynamic and static builds. This is not a strict requirement but it is a safe configuration.
- During installation, select the default installation location (C:\). Be sure to add the MinGW environment in the installation (selectable in the «Tools» branch of the installation options).
If you have a separated MinGW environment that you prefer to use and do not install the one from the Qt package installer, be sure to specify the option -MingwDir in the static build script (see below).
Example image of the Qt Installer with what was selected to write this guide.
Windows PowerShell
The script which builds the static Qt environment is a PowerShell script. PowerShell version 3.0 or higher is required. It is recommended to use Windows 10 which comes with PowerShell version 5 and onwards.
7-Zip
The build script also requires 7-Zip to uncompress the downloaded Qt source code. Be sure to install it first.
Qt build dependancies
As per the README that is packaged with the qt-everywhere-* zip package, it is noted that for windows the following also need to be available (as at Qt version 5.15.2):
- Perl version 5.12 or later (http://www.activestate.com/activeperl/)
- Python version 2.7 or later (http://www.activestate.com/activepython/)
- Ruby version 1.9.3 or later (http://rubyinstaller.org/)
Building the Qt static environment
Using the Windows Powershell script
The PowerShell script aims to assist with the install of the qt source code and the compilation of Qt as a static binary. For the purposes of the below instructions, Qt version 5.15.2 is used with Windows 10.
1. Take a copy of the following PowerShell script on github: qt-windows-static-build.ps1
2. Edit the script as required to change the variables which define the Qt version and directory location of the Qt pre-built environment already installed. Specifically the lines:
[CmdletBinding()] param( $QtSrcUrl = "https://download.qt.io/official_releases/qt/5.15/5.15.2/single/qt-everywhere-src-5.15.2.zip", $QtStaticDir = "C:\Qt\Static", # NO TRAILING SLASH $QtVersion = "5.15.2", #If you change this, you'll need to change the URL above to download as well... $MingwDir = "", [switch]$NoPause = $false )
The script contains flags to ‘configure’ what to include in the Qt static build. By default it removes a lot of modules that probably are not required for most applications. However, if your requirements differ — modify this line of the script accordingly.
cmd /c "configure.bat -static -release -platform win32-g++ -opensource -confirm-license -prefix $QtDir -qt-zlib -qt-libpng -qt-webp -qt-libjpeg -qt-freetype -no-opengl -skip qt3d -skip qtactiveqt -skip qtandroidextras -skip qtcharts -skip qtconnectivity -skip qtdatavis3d -skip qtdeclarative -skip qtdoc -skip qtgamepad -skip qtlocation -skip qtlottie -skip qtmacextras -skip qtmultimedia -skip qtnetworkauth -skip qtpurchasing -skip qtquick3d -skip qtquickcontrols -skip qtquickcontrols2 -skip qtquicktimeline -skip qtremoteobjects -skip qtscript -skip qtsensors -skip qtspeech -skip qtsvg -skip qtwayland -skip qtwebglplugin -skip qtwebview -skip webengine -make libs -nomake tools -nomake examples -nomake tests"
3. Execute the script in Windows PowerShell as a non-administrator user:
.\qt-windows-static-build.ps1
The PowerShell script will check to see if your path variable is configured correctly such that ‘powershell’, ‘ruby’, ‘python’ and ‘perl’ commands are avaialble. If not, you will need to double check what you installed as covered in ‘Qt build dependancies’. The PowerShell will now perform the following steps:
- Download the Qt everything source code.
- Build a static version of Qt using the MinGW compiler in the pre-built dynamic environment. It builds the libraries and the command line tools (qmake, moc, uic, lupdate, lrelease, etc.)
- Install the static version of Qt in C:\Qt\Static by default.
The execution of this script may take a couple of hours to complete, depending on your processing power. So you have to be patient. Qt is a complex framework with a very large amount of code.
Command line syntax
Alternatively, you can invoke the script from the PowerShell prompt using the following syntax:
windows-build-qt-static.ps1 [-QtSrcUrl url] [-QtStaticDir directory] [-QtVersion string] [-MingwDir directory] [-NoPause]
Command line parameters
-QtSrcUrl url
Specify the URL of the Qt source file archive.
-QtStaticDir directory
Specify the root directory where the static versions of Qt are installed. By default: C:.
-QtVersion string
Specify the Qt version. By default, the script tries to extract the version number from the Qt source file name. Usually, this is sufficient, the script will find «5.15.2» or «5.0.0-rc1» for instance. If the naming scheme of the Qt source file changes one day, you may need to specify an explicit value to this parameter.
-MingwDir directory
Specify the root directory of the MinGW environment. By default, use the version which was installed by the prebuilt Qt environment.
When the prebuilt environment for Qt 5.15.2 is installed for instance, the script locates MinGW in C:\Qt\5.15.2\Tools\mingw492_32. If you chose not to install MinGW as part of the prebuilt environment for Qt, you have to specify the root directory of your MinGW installation.
-NoPause
Do not wait for the user to press enter at the end of execution. By default, the scripts executes a pause instruction at the end of execution, which is useful when the script was run from the Windows Explorer.
Using the Qt static environment
Using the Qt static environment with Qt Creator (recommended)
This section describes how to use the static Qt environment from Qt Creator.
Please note: Qt Creator is provided as part of the dynamic pre-built environment. By default, it builds the applications for this dynamic environment, but it is possible to configure projects to use the static Qt environment when required.
The following instructions are based on a standard Qt 5.15.2 / Qt Creator 4.14.2 installation. Change the version numbers to adapt to your configuration.
Qt Creator Configuration
- Open the Qt Creator
- Tools (menu) -> Option
- Select ‘Qt Versions’ tab. In the «qmake location» table, there must be an «Auto-detected» part and a «Manual» part. In the «Auto-detected» part, there should be one line named «Qt 5.15.2 MinGW 32bit C:\Qt\Qt5.15.2\5.5\mingw492_32\bin\qmake.exe» (or whatever version of Qt you are working with). The «Manual» part is initially empty.
- Click «Add», browse to C:\Qt\Static\<your static build version>\bin and select «qmake.exe». The version name is automatically set to «Qt 5.15.2 (5.15.2)». You should set a more meaningful name such as «Qt 5.15.2 MinGW Static 32bit»
- Then go to tab «Kits». Again, there must be an «Auto-detected» part and an initially empty «Manual» part.
- Click «Add».
- Set a meaningful name such as «Desktop Qt 5.15.2 MinGW Static 32bit». In the «Qt version» field towards the bottom, select your static environment, named «Qt 5.15.2 MinGW Static 32bit» if you followed the above advice. Qt Creator should auto populate the Compiler details.
Then click «OK» to terminate the options setup.
Your Project Configuration
- In each project you want to deploy with a static build, edit the project setup (select «Projects» in the left vertical pane).
- Click «Add Kit» in the upper left corner and select your static kit, named «Desktop Qt 5.15.2 MinGW Static 32bit» if you followed the above advice.
- The new kit for your project is configured. Note that, by default, there are distinct build directories for the dynamic and static versions of your project.
- Now you can build your application in any combination of static vs. dynamic and release vs. debug. In the bottom part of the left pane, the project selector (the computer icon with the name of your project and either «Release» or «Debug») lets you select the combination you want.
Command line
This section describes how to use the static Qt environment from the command line, either the traditional Windows command shell (cmd.exe) or the Windows PowerShell.
Simply add the bin subdirectory of the static Qt environment in front of the Path environment variable. For Qt 5.15.2, this is C:\Qt\Static\5.15.2\bin.
Do not forget to also include the MinGW environment in the path. With the dynamic pre-built Qt environment, you may want to add Qt Creator also.
The following commands summarize the command line setups for the various environments.
Dynamic pre-built Qt with the traditional Windows command shell:
set Path=C:\Qt\5.15.2\mingw81_32\bin;C:\Qt\Tools\mingw810_32\bin;C:\Qt\Tools\QtCreator\bin;C:\Perl64\bin;C:\Ruby27-x64\bin;C:\ActivePython3;
Dynamic pre-built Qt with the Windows PowerShell:
$env:Path=C:\Qt\5.15.2\mingw81_32\bin;C:\Qt\Tools\mingw810_32\bin;C:\Qt\Tools\QtCreator\bin;C:\Perl64\bin;C:\Ruby27-x64\bin;C:\ActivePython3;
Static Qt build with the traditional Windows command shell:
set Path=C:\Qt\Static\5.15.2\bin;C:\Qt\5.15.2\mingw81_32\bin;C:\Qt\Tools\mingw810_32\bin;
Static Qt build with the Windows PowerShell:
$env:Path=C:\Qt\Static\5.15.2\bin;C:\Qt\5.15.2\mingw81_32\bin;C:\Qt\Tools\mingw810_32\bin;
When to use a Static Qt build
It is recommended to only build release versions of the application with at static Qt environment. Avoid building a debug version of the application with the static Qt environment. There are several reasons for this:
- The recommended environment for the development, debug and test phase is the pre-built dynamic environment, not the static one.
- The size of a static application in debug mode is insanely huge. For a given application, the following sizes have been observed for the application executable file:
- Dynamic + Release: 1 MB
- Dynamic + Debug: 33 MB
- Static + Release: 16 MB
- Static + Debug: 297 MB
Время на прочтение
3 мин
Количество просмотров 15K
Доброго времени суток, хабравчане!
Я уверен, что все заметили, когда делали деплой своей программы через windeployqt.exe, программа зависит от разных динамических и qt’шных библиотек. Вследствие чего, развертка на других компьютерах становится неудобной. Почему? Приходится держать сам exe’шник в папке с нужными библиотеками. Разумеется, можно умудриться и без статической линковки решить эту проблему. Согласитесь, неудобно, да и каждый раз нужно лишние телодвижения делать. Проще один раз запариться и потом не делать лишних движений. Еще один плюс статической линковки — размер файла. При динамической линковке сам exe’шник весит примерно от 1 МБ до 7-8 МБ, а с окружением до 70 МБ может спокойно дойти, даже если проект небольшой. При статической линковке есть только exe’шник, который весит примерно в 2 раза меньше, чем окружение при динамической линковке.
Для сборки необходимы:
- Qt 5.x.x с включенными компонентами (если Qt уже был установлен, нужные компоненты можно установить с помощью Qt Maintenance Tool):
- Qt — Qt 5.x — MinGW x.x.x 32 bit
- Qt — Qt 5.x — Sources
- Qt — Tools — MinGW
- Perl (Strawberry Perl, к примеру). Я использую strawberry-perl-5.30.2.1-32bit.
Проверить, что путь к исполняемому файлу Perl прописан в переменной окружения PATH. Этот пункт можно пропустить, но лучше проверить. - Python 3.8
Путь установки Qt неважен, у меня он установлен на диске D. Убедитесь, что объем доступной памяти вам хватит. Нужно как минимум 30 ГБ свободного места.
Сам алгоритм:
- Переходите в директорию, где папка Src (D:\Qt\5.x.x\Src);
- Там создайте папку static (D:\Qt\5.х.х\static);
- Папку Src копируйте в папку static. Получится D:\Qt\5.x.x\static\Src. Дальнейшие действия будут там, в Папке Src;
- Создайте папку mingwXX_32 (у меня, например, mingw73_32). Получится D:\Qt\5.x.x\static\mingwXX_32;
- Редактируйте файл qmake.conf, который находится в D:\Qt\5.х.х\static\Src\qtbase\mkspecs\win32-g++.
В самый конец файла, после строки
load(qt_config)
допишите с новой строки эти команды:QMAKE_LFLAGS += -static -static-libgcc QMAKE_CFLAGS_RELEASE -= O2 DEFINES += UNICODE QT_STATIC_BUILD
- Сохраниите файл qmake.conf;
- Откройте (ВНИМАНИЕ! НЕ CMD! НЕ CMD! НЕ CMD!) командную строку MinGW. В поисковике компьютера (на панели задач) пишите mingw.
Командная строка MinGW будет выдана как Qt 5.x.x (MinGW x.x.x 32-bit) - Введите в командную строку MinGW поочередно следующие команды:
(именно такая строка без изменений)set LANG=en
set QT_INSTALL_PREFIX="C:\Qt\5.8-static\mingw53_32"
cd /d %QT_INSTALL_PREFIX%\..\Src
configure.bat -static -debug-and-release -platform win32-g++ -prefix %QT_INSTALL_PREFIX% -qt-zlib -qt-pcre -qt-libpng -qt-libjpeg -qt-freetype -opengl desktop -opensource -confirm-license -make libs -nomake tools -nomake examples -nomake tests -qt-sqlite -no-ssl
Тут стоит обратить внимание на опцию -no-ssl — это значит что Qt будет собран без поддержки SSL.
Если никаких ошибок нету, можно продолжать:
- Введите
mingw32-make -k -j4
Нереально длительный процесс, можете смело забыть про него на 4 часа ориентировачно, от скорости чтения/записи диска не зависит, а зависит от процессора. Там где -j4 вместо 4 поставьте число ядер вашего процессора. - Введите
mingw32-make -k install
В результате получаем статическое окружение в D:\Qt\5.x.x\statiс\mingwXX_32; - Настройка Qt Creator:
- В верхнем меню Инструменты -> Параметры -> Профили Qt
- Добавить -> D:\Qt\5.х.х\static\mingw73_32\bin\qmake.exe -> Применить
- Комплекты -> Добавить
- Название: Qt static x32 (или какое угодно)
- Тип Устройства: Desktop
- Устройство: Локальный ПК
- Корень образа: D:\Qt\5.х.х\static
- Компилятор:
a) для С: MinGW x.x.x 32-bit for C
b) для С++: MinGW x.x.x 32-bit for C++ - Профиль Qt: Qt static x32 (название профиля, которое вы указали при добавлении профиля)
- Применить -> Ок
- Остается только пересобрать свой проект с новым комплектом.
Дополнительная информация. У меня:
- Qt 5.14.1
- MinGW 7.3.0 32-bit (mingw73_32)
- Python 3.8 x32
- strawberry-perl-5.30.2.1-32bi
- Windows 10 Pro x64
Полет нормальный.
Брал информацию отсюда:
- vladsol.tk/2017/05/qt-5-8-0-static-build
- www.pvsm.ru/pesochnitsa/73256
En
Ar
Bg
De
El
Es
Fa
Fi
Fr
Hi
Hu
It
Ja
Kn
Ko
Ms
Nl
Pl
Pt
Ru
Sq
Th
Tr
Uk
Zh
WARNING
The information on this page is outdated!
Please refer to the official documentation for instructions how to build Qt on Windows: https://doc.qt.io/qt-6/windows-building.html
Also, the rationale why to use a static build is questionable. See https://doc.qt.io/qt-6/windows-deployment.html for how to deploy a Qt application on Windows.
If you still want a static build, add
to the
arguments.
Why a static Qt?
On Windows, the pre-built environments from qt.io are dynamically linked. This means that your Qt application dynamically references the Qt DLL’s which are installed with the pre-built environment.
This is probably 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 deploy with the application. Even using the classical DLL Dependency Walker tool, 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.
This article describes an automated way of downloading, building and installing a static Qt development environment using a Windows PowerShell script.
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 this article takes advantage of that.
MinGW vs. MSVC
On Windows, two pre-built environments can be downloaded: one using MinGW and one using Microsoft Visual Studio. The two environments are incompatible and cannot be mixed. You have to choose one.
This article describes how to build a static version of Qt in a MinGW environment. If you need a static Qt for MSVC, you may probably find some ideas here but there is definitely some extra work.
Target environment
When you develop Qt applications on Windows and need to deploy them later on «general purpose» Windows machines, the recommended Qt environment contains two distinct builds of the same version of Qt:
- A dynamic version, installed in C:\Qt from a pre-built package.
- A static version, installed in C:\Qt\Static using the procedure which is described in this article.
The pre-built dynamic environment shall be used for development and debugging. In addition to the Qt command line tools (qmake, moc, uic, lupdate, lrelease, etc.), it contains the high-level GUI tools such as Qt Creator, Assistant, Linguist, etc. The installation is straightforward, everything is here, well integrated, working like a charm.
The static environment should only be used to release the deployment version of the application, after it has been fully developed and debugged using the dynamic environment. The static environment should only be compiled to contain the Qt command line tools. There are at least two reasons for not building static versions of the GUI tools. First, releasing a new version of an application is typically a task that you automate using a script and there is no need for GUI tools at this stage. Second, it is probably impossible to build a static version of Qt Creator because of the lack of support for plugins in a static environment.
Restrictions in a static environment
Although building a static version of your application makes it easier to deploy, there are some restrictions in a static environment. Be sure to check that your application complies with these constraints before going further.
- There are licensing issues in distributing applications embedding Qt code in a static link. See here and here for more details. While you are probably safe if your application is distributed according to the terms of a recognized free and open-source license, you should definitely check the licensing issue for proprietary or closed-source applications.
- The application cannot use a dynamic modular approach using plugins. But you cannot both ask for a static environment and for a dynamic loading of your own DLL’s.
Also note the following points:
- The static executable file of the application is bigger than the dynamic one since all used Qt code is copied into the executable. However, if your application has only one executable, the total deployed size is smaller since only the Qt code which is actually used is linked. When deploying a dynamic version of the application, you have to install all required Qt DLL’s with the application and the overall size of all these DLL’s is larger than the static application.
- A Qt static build means that no Qt or MinGW DLL’s are used. However, the static executable file of the application still references the Windows DLL’s such as kernel32.dll or user32.dll. These DLL’s, however, are installed with Windows and do not need to be deployed with the application.
Prerequisites
Dynamic pre-built Qt environment
You must have a pre-built Qt environment installed before you attempt to build a static version of the library with the Qt source code.
- Obtain the Qt Installer from qt.io and install the relevant pre-build Qt environment. For example, «Qt 5.15.2 MinGw 8.1.0 32-bit»
- Preferably plan the installation of the same version of Qt for the dynamic and static builds. This is not a strict requirement but it is a safe configuration.
- During installation, select the default installation location (C:\). Be sure to add the MinGW environment in the installation (selectable in the «Tools» branch of the installation options).
If you have a separated MinGW environment that you prefer to use and do not install the one from the Qt package installer, be sure to specify the option -MingwDir in the static build script (see below).
Example image of the Qt Installer with what was selected to write this guide.
Windows PowerShell
The script which builds the static Qt environment is a PowerShell script. PowerShell version 3.0 or higher is required. It is recommended to use Windows 10 which comes with PowerShell version 5 and onwards.
7-Zip
The build script also requires 7-Zip to uncompress the downloaded Qt source code. Be sure to install it first.
Qt build dependancies
As per the README that is packaged with the qt-everywhere-* zip package, it is noted that for windows the following also need to be available (as at Qt version 5.15.2):
- Perl version 5.12 or later (http://www.activestate.com/activeperl/)
- Python version 2.7 or later (http://www.activestate.com/activepython/)
- Ruby version 1.9.3 or later (http://rubyinstaller.org/)
Building the Qt static environment
Using the Windows Powershell script
The PowerShell script aims to assist with the install of the qt source code and the compilation of Qt as a static binary. For the purposes of the below instructions, Qt version 5.15.2 is used with Windows 10.
1. Take a copy of the following PowerShell script on github: qt-windows-static-build.ps1
2. Edit the script as required to change the variables which define the Qt version and directory location of the Qt pre-built environment already installed. Specifically the lines:
[CmdletBinding()] param( $QtSrcUrl = "https://download.qt.io/official_releases/qt/5.15/5.15.2/single/qt-everywhere-src-5.15.2.zip", $QtStaticDir = "C:\Qt\Static", # NO TRAILING SLASH $QtVersion = "5.15.2", #If you change this, you'll need to change the URL above to download as well... $MingwDir = "", [switch]$NoPause = $false )
The script contains flags to ‘configure’ what to include in the Qt static build. By default it removes a lot of modules that probably are not required for most applications. However, if your requirements differ — modify this line of the script accordingly.
cmd /c "configure.bat -static -release -platform win32-g++ -opensource -confirm-license -prefix $QtDir -qt-zlib -qt-libpng -qt-webp -qt-libjpeg -qt-freetype -no-opengl -skip qt3d -skip qtactiveqt -skip qtandroidextras -skip qtcharts -skip qtconnectivity -skip qtdatavis3d -skip qtdeclarative -skip qtdoc -skip qtgamepad -skip qtlocation -skip qtlottie -skip qtmacextras -skip qtmultimedia -skip qtnetworkauth -skip qtpurchasing -skip qtquick3d -skip qtquickcontrols -skip qtquickcontrols2 -skip qtquicktimeline -skip qtremoteobjects -skip qtscript -skip qtsensors -skip qtspeech -skip qtsvg -skip qtwayland -skip qtwebglplugin -skip qtwebview -skip webengine -make libs -nomake tools -nomake examples -nomake tests"
3. Execute the script in Windows PowerShell as a non-administrator user:
.\qt-windows-static-build.ps1
The PowerShell script will check to see if your path variable is configured correctly such that ‘powershell’, ‘ruby’, ‘python’ and ‘perl’ commands are avaialble. If not, you will need to double check what you installed as covered in ‘Qt build dependancies’. The PowerShell will now perform the following steps:
- Download the Qt everything source code.
- Build a static version of Qt using the MinGW compiler in the pre-built dynamic environment. It builds the libraries and the command line tools (qmake, moc, uic, lupdate, lrelease, etc.)
- Install the static version of Qt in C:\Qt\Static by default.
The execution of this script may take a couple of hours to complete, depending on your processing power. So you have to be patient. Qt is a complex framework with a very large amount of code.
Command line syntax
Alternatively, you can invoke the script from the PowerShell prompt using the following syntax:
windows-build-qt-static.ps1 [-QtSrcUrl url] [-QtStaticDir directory] [-QtVersion string] [-MingwDir directory] [-NoPause]
Command line parameters
-QtSrcUrl url
Specify the URL of the Qt source file archive.
-QtStaticDir directory
Specify the root directory where the static versions of Qt are installed. By default: C:.
-QtVersion string
Specify the Qt version. By default, the script tries to extract the version number from the Qt source file name. Usually, this is sufficient, the script will find «5.15.2» or «5.0.0-rc1» for instance. If the naming scheme of the Qt source file changes one day, you may need to specify an explicit value to this parameter.
-MingwDir directory
Specify the root directory of the MinGW environment. By default, use the version which was installed by the prebuilt Qt environment.
When the prebuilt environment for Qt 5.15.2 is installed for instance, the script locates MinGW in C:\Qt\5.15.2\Tools\mingw492_32. If you chose not to install MinGW as part of the prebuilt environment for Qt, you have to specify the root directory of your MinGW installation.
-NoPause
Do not wait for the user to press enter at the end of execution. By default, the scripts executes a pause instruction at the end of execution, which is useful when the script was run from the Windows Explorer.
Using the Qt static environment
Using the Qt static environment with Qt Creator (recommended)
This section describes how to use the static Qt environment from Qt Creator.
Please note: Qt Creator is provided as part of the dynamic pre-built environment. By default, it builds the applications for this dynamic environment, but it is possible to configure projects to use the static Qt environment when required.
The following instructions are based on a standard Qt 5.15.2 / Qt Creator 4.14.2 installation. Change the version numbers to adapt to your configuration.
Qt Creator Configuration
- Open the Qt Creator
- Tools (menu) -> Option
- Select ‘Qt Versions’ tab. In the «qmake location» table, there must be an «Auto-detected» part and a «Manual» part. In the «Auto-detected» part, there should be one line named «Qt 5.15.2 MinGW 32bit C:\Qt\Qt5.15.2\5.5\mingw492_32\bin\qmake.exe» (or whatever version of Qt you are working with). The «Manual» part is initially empty.
- Click «Add», browse to C:\Qt\Static\<your static build version>\bin and select «qmake.exe». The version name is automatically set to «Qt 5.15.2 (5.15.2)». You should set a more meaningful name such as «Qt 5.15.2 MinGW Static 32bit»
- Then go to tab «Kits». Again, there must be an «Auto-detected» part and an initially empty «Manual» part.
- Click «Add».
- Set a meaningful name such as «Desktop Qt 5.15.2 MinGW Static 32bit». In the «Qt version» field towards the bottom, select your static environment, named «Qt 5.15.2 MinGW Static 32bit» if you followed the above advice. Qt Creator should auto populate the Compiler details.
Then click «OK» to terminate the options setup.
Your Project Configuration
- In each project you want to deploy with a static build, edit the project setup (select «Projects» in the left vertical pane).
- Click «Add Kit» in the upper left corner and select your static kit, named «Desktop Qt 5.15.2 MinGW Static 32bit» if you followed the above advice.
- The new kit for your project is configured. Note that, by default, there are distinct build directories for the dynamic and static versions of your project.
- Now you can build your application in any combination of static vs. dynamic and release vs. debug. In the bottom part of the left pane, the project selector (the computer icon with the name of your project and either «Release» or «Debug») lets you select the combination you want.
Command line
This section describes how to use the static Qt environment from the command line, either the traditional Windows command shell (cmd.exe) or the Windows PowerShell.
Simply add the bin subdirectory of the static Qt environment in front of the Path environment variable. For Qt 5.15.2, this is C:\Qt\Static\5.15.2\bin.
Do not forget to also include the MinGW environment in the path. With the dynamic pre-built Qt environment, you may want to add Qt Creator also.
The following commands summarize the command line setups for the various environments.
Dynamic pre-built Qt with the traditional Windows command shell:
set Path=C:\Qt\5.15.2\mingw81_32\bin;C:\Qt\Tools\mingw810_32\bin;C:\Qt\Tools\QtCreator\bin;C:\Perl64\bin;C:\Ruby27-x64\bin;C:\ActivePython3;
Dynamic pre-built Qt with the Windows PowerShell:
$env:Path=C:\Qt\5.15.2\mingw81_32\bin;C:\Qt\Tools\mingw810_32\bin;C:\Qt\Tools\QtCreator\bin;C:\Perl64\bin;C:\Ruby27-x64\bin;C:\ActivePython3;
Static Qt build with the traditional Windows command shell:
set Path=C:\Qt\Static\5.15.2\bin;C:\Qt\5.15.2\mingw81_32\bin;C:\Qt\Tools\mingw810_32\bin;
Static Qt build with the Windows PowerShell:
$env:Path=C:\Qt\Static\5.15.2\bin;C:\Qt\5.15.2\mingw81_32\bin;C:\Qt\Tools\mingw810_32\bin;
When to use a Static Qt build
It is recommended to only build release versions of the application with at static Qt environment. Avoid building a debug version of the application with the static Qt environment. There are several reasons for this:
- The recommended environment for the development, debug and test phase is the pre-built dynamic environment, not the static one.
- The size of a static application in debug mode is insanely huge. For a given application, the following sizes have been observed for the application executable file:
- Dynamic + Release: 1 MB
- Dynamic + Debug: 33 MB
- Static + Release: 16 MB
- Static + Debug: 297 MB
For quite a long time statically built Qt was kind of a mystery to me. I always used dynamic builds and had lots of involuntary sexual intercourses with macdeployqt
/windeployqt
(perhaps I should write about this too).
But not anymore, because I finally overcame my fears/stupidity/laziness, RTFMed and managed to build Qt statically.
Although the article is about making a static build, it also covers the task of building Qt from sources in general.
TLDR
The article has really exploded in volume over the years, so here are some general commands for configuration and building static Qt.
On Windows:
> cd d:\path\to\qt\src
> mkdir build
> cd build
> ..\configure.bat -static -release -no-pch -prefix "d:\path\to\qt\5.15.2-static" -skip qtwebengine -nomake tests -nomake examples
> jom -j8
> jom -j8 install
On GNU/Linux:
$ cd /path/to/qt/src
$ mkdir build && cd $_
$ ../configure -static -release -no-pch -prefix "/path/to/qt/5.15.2-static" -skip qtwebengine -nomake tests -nomake examples -fontconfig
$ make -j8
$ make -j8 install
On Mac OS:
$ cd /path/to/qt/src
$ mkdir build && cd $_
$ ../configure -static -release -no-pch -prefix "/path/to/qt/5.15.2-static" -skip qtwebengine -nomake tests -nomake examples
$ make -j8
$ make -j8 install
Also note that this article was written when Qt 5.x was the latest version available, so it doesn’t account for all the peculiarities of building Qt 6.x or newer (although the process is mostly the same). But here is a more recent partly related article about installing Qt without official installer, which covers Qt 6.x too.
There are 3 main reasons:
- Easier deployment;
- Smaller binaries size;
- Better security.
Deployment of dynamically linked Qt applications always was (is) not a trivial task. While everything works on your development machine, being deployed on another machine your applications most likely will complain about all sorts of missing libraries.
What I did in the past — I just copied the entire set of Qt libraries to the application directory and then application started working. But, first of all, copying just Qt libraries is not enough, there are some other libraries that need to be deployed along, and secondly, the final size of the deployed application can easily exceed a couple of hundreds of megabytes, which is not really okay even for desktop targets, not to say about embedded devices with quite a limited space available.
Having built your application statically linked, you get everything all-in-one — a single executable file which is very easy to deploy and it will have a smaller size comparing with its dynamically linked equivalent.
However, if your deployment target has several Qt-based applications, then static linking is not that attractive in terms of saving space, because in case of dynamic linking every Qt-based application can use the same set of shared Qt libraries, which you need to deploy only once. Here’s a simplified picture about it:
As you can see, even though 1 statically linked application takes less space than 1 dynamically linked, but when you have 4 applications, then you can save more space on your disk by using dynamic linking: 620 — 220 = 400 MB of space saved. Not bad indeed, but again — this is just a simplified example, and real numbers probably won’t be that exciting.
Speaking about security — that one usually refers to the fact that application relying on shared libraries is easier to hack (because you can replace libraries with the modified ones). But I am not sure if it’s really the case, because if shared libraries are exposed for hacking then it probably means that the whole OS is compromised, so there is no much point to fight the fire in the ashtray when entire building is in flames. And also as far as I know it is possible to sign shared libraries and perform checks before actually loading them.
About Open Source licenses compliance
Be aware, that if you are using Qt under LGPL, then using static linking might make it harder for you to comply with the license terms and keep your code private at the same time.
But if you are using Qt under GPL, then it doesn’t matter to you anyway as your code already belongs to community.
Please note, that I am not a lawyer, and this is just my interpretation of the license text, so don’t make business decisions based only on my comments — consult with a proper legal specialist.
How to build Qt statically
Configuration
It is actually embarrassingly easy. You only need to run the configure
utility with the right set of parameters.
I’ll describe the process for Mac OS (works like a charm), Linux (there are some tiny problems) and Windows (doesn’t fucking work lots of problems).
The first step is the same for all platforms: create a folder for shadow build and run configure
command from there:
$ cd /path/to/qt/sources
$ mkdir build && cd $_
$ ../configure -static -release -no-pch -prefix "/path/to/qt/510-static" -skip webengine -nomake tools -nomake tests -nomake examples
Note how configure
doesn’t care about short/long options and just has a single -
for everything.
Here’s a description for the options I used:
-static
— this one tells to build exactly a static version;-release
— because I need static build only for publishing my apps, therefore there is no need in static debug build, so it can be skipped. For debugging/profiling I’ll keep using dynamic build;-no-pch
— no precompiled headers, meaning that all the header files (.h
) will not be precompiled, so you’ll get all the benefits from#ifdef
. Moreover, for some platforms Qt won’t even build with precompiled headers turned on;-prefix "/path/to/qt/510-static"
— where to put the result;-skip webengine
— I don’t need WebEngine;-nomake tools
— I don’t need static tools (Qt Creator, Designer, etc);-nomake tests
— I don’t need tests;-nomake examples
— I don’t need examples.
The set of options can differ from platform to platform. In my case it was the same for Mac and Linux, but for Windows I had to add two additional ones.
Full list of all possible options you can find in the documentation. Or you can get it from configure
itself. Here’s an output from Qt 5.11.1 on Mac OS:
$ /path/to/qt/5.11.1/Src/configure -h
+ cd qtbase
+ /path/to/qt/5.11.1/Src/qtbase/configure -top-level -h
Usage: configure [options] [assignments]
Configure understands variable assignments like VAR=value on the command line.
Each uppercased library name (obtainable with -list-libraries) supports the
suffixes _INCDIR, _LIBDIR, _PREFIX (INCDIR=PREFIX/include, LIBDIR=PREFIX/lib),
_LIBS, and - on Windows and Darwin - _LIBS_DEBUG and _LIBS_RELEASE. E.g.,
ICU_PREFIX=/opt/icu42 ICU_LIBS="-licui18n -licuuc -licudata".
It is also possible to manipulate any QMAKE_* variable, to amend the values
from the mkspec for the build of Qt itself, e.g., QMAKE_CXXFLAGS+=-g3.
Note that the *_LIBS* and QMAKE_* assignments manipulate lists, so items
containing meta characters (spaces in particular) need to be quoted according
to qmake rules. On top of that, the assignments as a whole need to be quoted
according to shell rules. It is recommended to use single quotes for the inner
quoting and double quotes for the outer quoting.
Top-level installation directories:
-prefix <dir> ...... The deployment directory, as seen on the target device.
[/usr/local/Qt-$QT_VERSION, $PWD if -developer-build]
-extprefix <dir> ... The installation directory, as seen on the host machine.
[SYSROOT/PREFIX]
-hostprefix [dir] .. The installation directory for build tools running on
the host machine. If [dir] is not given, the current
build directory will be used. [EXTPREFIX]
-external-hostbindir <path> ... Path to Qt tools built for this machine.
Use this when -platform does not match the current
system, i.e., to make a Canadian Cross Build.
Fine tuning of installation directory layout. Note that all directories
except -sysconfdir should be located under -prefix/-hostprefix:
-bindir <dir> ......... Executables [PREFIX/bin]
-headerdir <dir> ...... Header files [PREFIX/include]
-libdir <dir> ......... Libraries [PREFIX/lib]
-archdatadir <dir> .... Arch-dependent data [PREFIX]
-plugindir <dir> ...... Plugins [ARCHDATADIR/plugins]
-libexecdir <dir> ..... Helper programs [ARCHDATADIR/bin on Windows,
ARCHDATADIR/libexec otherwise]
-importdir <dir> ...... QML1 imports [ARCHDATADIR/imports]
-qmldir <dir> ......... QML2 imports [ARCHDATADIR/qml]
-datadir <dir> ........ Arch-independent data [PREFIX]
-docdir <dir> ......... Documentation [DATADIR/doc]
-translationdir <dir> . Translations [DATADIR/translations]
-sysconfdir <dir> ..... Settings used by Qt programs [PREFIX/etc/xdg]
-examplesdir <dir> .... Examples [PREFIX/examples]
-testsdir <dir> ....... Tests [PREFIX/tests]
-hostbindir <dir> ..... Host executables [HOSTPREFIX/bin]
-hostlibdir <dir> ..... Host libraries [HOSTPREFIX/lib]
-hostdatadir <dir> .... Data used by qmake [HOSTPREFIX]
Conventions for the remaining options: When an option's description is
followed by a list of values in brackets, the interpretation is as follows:
'yes' represents the bare option; all other values are possible prefixes to
the option, e.g., -no-gui. Alternatively, the value can be assigned, e.g.,
--gui=yes. Values are listed in the order they are tried if not specified;
'auto' is a shorthand for 'yes/no'. Solitary 'yes' and 'no' represent binary
options without auto-detection.
Configure meta:
-help, -h ............ Display this help screen
-verbose, -v ......... Print verbose messages during configuration
-continue ............ Continue configure despite errors
-redo ................ Re-configure with previously used options.
Additional options may be passed, but will not be
saved for later use by -redo.
-recheck [test,...] .. Discard cached negative configure test results.
Use this after installing missing dependencies.
Alternatively, if tests are specified, only their
results are discarded.
-recheck-all ......... Discard all cached configure test results.
-feature-<feature> ... Enable <feature>
-no-feature-<feature> Disable <feature> [none]
-list-features ....... List available features. Note that some features
have dedicated command line options as well.
-list-libraries ...... List possible external dependencies.
Build options:
-opensource .......... Build the Open-Source Edition of Qt
-commercial .......... Build the Commercial Edition of Qt
-confirm-license ..... Automatically acknowledge the license
-release ............. Build Qt with debugging turned off [yes]
-debug ............... Build Qt with debugging turned on [no]
-debug-and-release ... Build two versions of Qt, with and without
debugging turned on [yes] (Apple and Windows only)
-optimize-debug ...... Enable debug-friendly optimizations in debug builds
[auto] (Not supported with MSVC or Clang toolchains)
-optimize-size ....... Optimize release builds for size instead of speed [no]
-optimized-tools ..... Build optimized host tools even in debug build [no]
-force-debug-info .... Create symbol files for release builds [no]
-separate-debug-info . Split off debug information to separate files [no]
-gdb-index ........... Index the debug info to speed up GDB
[no; auto if -developer-build with debug info]
-strip ............... Strip release binaries of unneeded symbols [yes]
-force-asserts ....... Enable Q_ASSERT even in release builds [no]
-developer-build ..... Compile and link Qt for developing Qt itself
(exports for auto-tests, extra checks, etc.) [no]
-shared .............. Build shared Qt libraries [yes] (no for UIKit)
-static .............. Build static Qt libraries [no] (yes for UIKit)
-framework ........... Build Qt framework bundles [yes] (Apple only)
-platform <target> ... Select host mkspec [detected]
-xplatform <target> .. Select target mkspec when cross-compiling [PLATFORM]
-device <name> ....... Cross-compile for device <name>
-device-option <key=value> ... Add option for the device mkspec
-appstore-compliant .. Disable code that is not allowed in platform app stores.
This is on by default for platforms which require distribution
through an app store by default, in particular Android,
iOS, tvOS, watchOS, and Universal Windows Platform. [auto]
-qtnamespace <name> .. Wrap all Qt library code in 'namespace <name> {...}'.
-qtlibinfix <infix> .. Rename all libQt5*.so to libQt5*<infix>.so.
-testcocoon .......... Instrument with the TestCocoon code coverage tool [no]
-gcov ................ Instrument with the GCov code coverage tool [no]
-trace [backend] ..... Enable instrumentation with tracepoints.
Currently supported backends are 'etw' (Windows) and
'lttng' (Linux), or 'yes' for auto-detection. [no]
-sanitize {address|thread|memory|undefined}
Instrument with the specified compiler sanitizer.
Note that some sanitizers cannot be combined;
for example, -sanitize address cannot be combined with
-sanitize thread.
-c++std <edition> .... Select C++ standard <edition> [c++1z/c++14/c++11]
(Not supported with MSVC)
-sse2 ................ Use SSE2 instructions [auto]
-sse3/-ssse3/-sse4.1/-sse4.2/-avx/-avx2/-avx512
Enable use of particular x86 instructions [auto]
Enabled ones are still subject to runtime detection.
-mips_dsp/-mips_dspr2 Use MIPS DSP/rev2 instructions [auto]
-qreal <type> ........ typedef qreal to the specified type. [double]
Note: this affects binary compatibility.
-R <string> .......... Add an explicit runtime library path to the Qt
libraries. Supports paths relative to LIBDIR.
-rpath ............... Link Qt libraries and executables using the library
install path as a runtime library path. Similar to
-R LIBDIR. On Apple platforms, disabling this implies
using absolute install names (based in LIBDIR) for
dynamic libraries and frameworks. [auto]
-reduce-exports ...... Reduce amount of exported symbols [auto]
-reduce-relocations .. Reduce amount of relocations [auto] (Unix only)
-plugin-manifests .... Embed manifests into plugins [no] (Windows only)
-static-runtime ...... With -static, use static runtime [no] (Windows only)
-pch ................. Use precompiled headers [auto]
-ltcg ................ Use Link Time Code Generation [no]
-use-gold-linker ..... Use the GNU gold linker [auto]
-incredibuild-xge .... Use the IncrediBuild XGE [no] (Windows only)
-ccache .............. Use the ccache compiler cache [no] (Unix only)
-make-tool <tool> .... Use <tool> to build qmake [nmake] (Windows only)
-mp .................. Use multiple processors for compilation (MSVC only)
-warnings-are-errors . Treat warnings as errors [no; yes if -developer-build]
-silent .............. Reduce the build output so that warnings and errors
can be seen more easily
Build environment:
-sysroot <dir> ....... Set <dir> as the target sysroot
-gcc-sysroot ......... With -sysroot, pass --sysroot to the compiler [yes]
-pkg-config .......... Use pkg-config [auto] (Unix only)
-D <string> .......... Pass additional preprocessor define
-I <string> .......... Pass additional include path
-L <string> .......... Pass additional library path
-F <string> .......... Pass additional framework path (Apple only)
-sdk <sdk> ........... Build Qt using Apple provided SDK <sdk>. The argument
should be one of the available SDKs as listed by
'xcodebuild -showsdks'.
Note that the argument applies only to Qt libraries
and applications built using the target mkspec - not
host tools such as qmake, moc, rcc, etc.
-android-sdk path .... Set Android SDK root path [$ANDROID_SDK_ROOT]
-android-ndk path .... Set Android NDK root path [$ANDROID_NDK_ROOT]
-android-ndk-platform Set Android platform
-android-ndk-host .... Set Android NDK host (linux-x86, linux-x86_64, etc.)
[$ANDROID_NDK_HOST]
-android-arch ........ Set Android architecture (armeabi, armeabi-v7a,
arm64-v8a, x86, x86_64, mips, mips64)
-android-toolchain-version ... Set Android toolchain version
-android-style-assets Automatically extract style assets from the device at
run time. This option makes the Android style behave
correctly, but also makes the Android platform plugin
incompatible with the LGPL2.1. [yes]
Component selection:
-skip <repo> ......... Exclude an entire repository from the build.
-make <part> ......... Add <part> to the list of parts to be built.
Specifying this option clears the default list first.
[libs and examples, also tools if not cross-building,
also tests if -developer-build]
-nomake <part> ....... Exclude <part> from the list of parts to be built.
-compile-examples .... When unset, install only the sources of examples [yes]
-gui ................. Build the Qt GUI module and dependencies [yes]
-widgets ............. Build the Qt Widgets module and dependencies [yes]
-no-dbus ............. Do not build the Qt D-Bus module
[default on Android and Windows]
-dbus-linked ......... Build Qt D-Bus and link to libdbus-1 [auto]
-dbus-runtime ........ Build Qt D-Bus and dynamically load libdbus-1 [no]
-accessibility ....... Enable accessibility support [yes]
Note: Disabling accessibility is not recommended.
Qt comes with bundled copies of some 3rd party libraries. These are used
by default if auto-detection of the respective system library fails.
Core options:
-doubleconversion .... Select used double conversion library [system/qt/no]
No implies use of sscanf_l and snprintf_l (imprecise).
-glib ................ Enable Glib support [no; auto on Unix]
-eventfd ............. Enable eventfd support
-inotify ............. Enable inotify support
-iconv ............... Enable iconv(3) support [posix/sun/gnu/no] (Unix only)
-icu ................. Enable ICU support [auto]
-pcre ................ Select used libpcre2 [system/qt]
-pps ................. Enable PPS support [auto] (QNX only)
-zlib ................ Select used zlib [system/qt]
Logging backends:
-journald .......... Enable journald support [no] (Unix only)
-syslog ............ Enable syslog support [no] (Unix only)
-slog2 ............. Enable slog2 support [auto] (QNX only)
Network options:
-ssl ................. Enable either SSL support method [auto]
-no-openssl .......... Do not use OpenSSL [default on Apple and WinRT]
-openssl-linked ...... Use OpenSSL and link to libssl [no]
-openssl-runtime ..... Use OpenSSL and dynamically load libssl [auto]
-securetransport ..... Use SecureTransport [auto] (Apple only)
-sctp ................ Enable SCTP support [no]
-libproxy ............ Enable use of libproxy [no]
-system-proxies ...... Use system network proxies by default [yes]
Gui, printing, widget options:
-cups ................ Enable CUPS support [auto] (Unix only)
-fontconfig .......... Enable Fontconfig support [auto] (Unix only)
-freetype ............ Select used FreeType [system/qt/no]
-harfbuzz ............ Select used HarfBuzz-NG [system/qt/no]
(Not auto-detected on Apple and Windows)
-gtk ................. Enable GTK platform theme support [auto]
-lgmon ............... Enable lgmon support [auto] (QNX only)
-no-opengl ........... Disable OpenGL support
-opengl <api> ........ Enable OpenGL support. Supported APIs:
es2 (default on Windows), desktop (default on Unix),
dynamic (Windows only)
-opengles3 ........... Enable OpenGL ES 3.x support instead of ES 2.x [auto]
-angle ............... Use bundled ANGLE to support OpenGL ES 2.0 [auto]
(Windows only)
-combined-angle-lib .. Merge LibEGL and LibGLESv2 into LibANGLE (Windows only)
-qpa <name> .......... Select default QPA backend(s) (e.g., xcb, cocoa, windows)
A prioritized list separated by semi-colons.
-xcb-xlib............. Enable Xcb-Xlib support [auto]
Platform backends:
-direct2d .......... Enable Direct2D support [auto] (Windows only)
-directfb .......... Enable DirectFB support [no] (Unix only)
-eglfs ............. Enable EGLFS support [auto; no on Android and Windows]
-gbm ............... Enable backends for GBM [auto] (Linux only)
-kms ............... Enable backends for KMS [auto] (Linux only)
-linuxfb ........... Enable Linux Framebuffer support [auto] (Linux only)
-mirclient ......... Enable Mir client support [no] (Linux only)
-xcb ............... Select used xcb-* libraries [system/qt/no]
(-qt-xcb still uses system version of libxcb itself)
Input backends:
-libudev............ Enable udev support [auto]
-evdev ............. Enable evdev support [auto]
-imf ............... Enable IMF support [auto] (QNX only)
-libinput .......... Enable libinput support [auto]
-mtdev ............. Enable mtdev support [auto]
-tslib ............. Enable tslib support [auto]
-xinput2 ........... Enable XInput2 support [auto]
-xkbcommon-x11 ..... Select xkbcommon used in combination with xcb
[system/qt/no]
-xkbcommon-evdev ... Enable X-less xkbcommon in combination with libinput
[auto]
Image formats:
-gif ............... Enable reading support for GIF [auto]
-ico ............... Enable support for ICO [yes]
-libpng ............ Select used libpng [system/qt/no]
-libjpeg ........... Select used libjpeg [system/qt/no]
Database options:
-sql-<driver> ........ Enable SQL <driver> plugin. Supported drivers:
db2 ibase mysql oci odbc psql sqlite2 sqlite tds
[all auto]
-sqlite .............. Select used sqlite3 [system/qt]
Qt3D options:
-assimp .............. Select used assimp library [system/qt/no]
-qt3d-profile-jobs ... Enable jobs profiling [no]
-qt3d-profile-gl ..... Enable OpenGL profiling [no]
-qt3d-simd ........... Select level of SIMD support [no/sse2/avx2]
-qt3d-render ......... Enable the Qt3D Render aspect [yes]
-qt3d-input .......... Enable the Qt3D Input aspect [yes]
-qt3d-logic .......... Enable the Qt3D Logic aspect [yes]
-qt3d-extras ......... Enable the Qt3D Extras aspect [yes]
-qt3d-animation....... Enable the Qt3D Animation aspect [yes]
Multimedia options:
-pulseaudio .......... Enable PulseAudio support [auto] (Unix only)
-alsa ................ Enable ALSA support [auto] (Unix only)
-no-gstreamer ........ Disable support for GStreamer
-gstreamer [version] . Enable GStreamer support [auto]
With no parameter, 1.0 is tried first, then 0.10.
-mediaplayer-backend <name> ... Select media player backend (Windows only)
Supported backends: directshow (default), wmf
Webengine options:
-webengine-alsa ................ Enable ALSA support [auto] (Linux only)
-webengine-pulseaudio .......... Enable PulseAudio support [auto]
(Linux only)
-webengine-embedded-build ...... Enable Linux embedded build [auto]
(Linux only)
-webengine-icu ................. Use system ICU libraries [system/qt]
(Linux only)
-webengine-ffmpeg .............. Use system FFmpeg libraries [system/qt]
(Linux only)
-webengine-opus ................ Use system Opus libraries [system/qt]
(Linux only)
-webengine-webp ................ Use system WebP libraries [system/qt]
(Linux only)
-webengine-pepper-plugins ...... Enable use of Pepper Flash and Widevine
plugins [auto]
-webengine-printing-and-pdf .... Enable use of printing and output to PDF
[auto]
-webengine-proprietary-codecs .. Enable support for proprietary codecs [no]
-webengine-spellchecker ........ Enable support for spellchecker [yes]
-webengine-native-spellchecker . Enable support for native spellchecker [no]
(macOS only)
-webengine-webrtc .............. Enable support for WebRTC [auto]
Core options section refers to 3rd-party libraries, and quite often I see in different places people putting options like -qt-zlib
, -qt-libpng
and so on for configure
. Although, if you won’t set them, it doesn’t mean that you won’t have those libraries in your build — they just will be included with default values: some with Qt implementations and some with system ones. You can check which ones exactly are set in the configure
summary output (after you run it).
Optimization options
Qt build can be configured with so-called optimization options:
-ltcg
— Link-Time Code Generation, optimizes something. I took it from here-optimize-size
— seems to be optimizing release builds in terms of resulting binaries size (by sacrificing build time)
To see the actual effect of such optimization, I built Qt 5.12.3 on Mac OS twice, first time with these options:
$ ../configure -static -release -ltcg -optimize-size -no-pch -prefix "/path/to/qt/5123-static" -skip webengine -nomake tools -nomake tests -nomake examples
and second time without them:
$ ../configure -static -release -no-pch -prefix "/path/to/qt/5123-static" -skip webengine -nomake tools -nomake tests -nomake examples
Results are here:
Qt build time |
Qt build size |
Qt installation size |
Application build time |
Application size |
|
---|---|---|---|---|---|
With optimisation options | 00:31:53 | 1.15 GB | 519.3 MB | 00:03:28 | 27.0 MB |
Without optimisation options | 00:21:35 | 835.7 MB | 381.5 MB | 00:00:04 | 31.2 MB |
So, indeed, -optimize-size
does provide smaller application binaries, but at the same time you lose in Qt build time, its size and also applications build time.
What -ltcg
actually does — that I still don’t know and have no idea how to measure it.
I had these options enabled for most of the builds described below, and on Windows it caused certain problems, so perhaps I would recommend not to set those in your builds.
Cleaning the build directory
Note, that if you were building Qt before, then you should clean out the old build first (and the folder you’ve set with -prefix
):
or:
$ rm -r ./*; rm .config.notes; rm .qmake.*
Platforms
Mac OS
So, you ran configure
and now it asks you which edition you would like to build and also if you accept the license (these two are also available as options for configure
):
Creating qmake...
.Done.
Selecting Qt Edition.
Type 'c' if you want to use the Commercial Edition.
Type 'o' if you want to use the Open Source Edition.
Which edition of Qt do you want to use? c
This is the Qt Enterprise Edition.
You are licensed to use this software under the terms of following license(s):
Qt Enterprise License Agreement
Type '?' to view the license offer.
Type 'y' to accept this license offer.
Type 'n' to decline this license offer.
Do you accept the terms of the license(s)?
y
After that it will generate configuration summary and perform some checks:
Running configuration tests...
Done running configuration tests.
Configure summary:
Build type: macx-clang (x86_64, CPU features: cx16 mmx sse sse2 sse3 ssse3)
Configuration: sse2 aesni sse3 ssse3 sse4_1 sse4_2 avx avx2 avx512f avx512bw avx512cd avx512dq avx512er avx512ifma avx512pf avx512vbmi avx512vl compile_examples f16c largefile ltcg optimize_size rdrnd shani release c++11 c++14 c++1z concurrent dbus no-pkg-config reduce_exports static stl
Build options:
Mode ................................... release
Optimize release build for size ........ yes
Building shared libraries .............. no
Using C++ standard ..................... C++1z
Using ccache ........................... no
Using gold linker ...................... no
Using precompiled headers .............. no
Using LTCG ............................. yes
Target compiler supports:
SSE .................................. SSE2 SSE3 SSSE3 SSE4.1 SSE4.2
AVX .................................. AVX AVX2
AVX512 ............................... F ER CD PF DQ BW VL IFMA VBMI
Other x86 ............................ AES F16C RDRAND SHA
Build parts ............................ libs
App store compliance ................... no
Qt modules and options:
Qt Concurrent .......................... yes
Qt D-Bus ............................... yes
Qt D-Bus directly linked to libdbus .... no
Qt Gui ................................. yes
Qt Network ............................. yes
Qt Sql ................................. yes
Qt Testlib ............................. yes
Qt Widgets ............................. yes
Qt Xml ................................. yes
Support enabled for:
Using pkg-config ....................... no
QML debugging .......................... yes
udev ................................... no
Using system zlib ...................... yes
Qt Core:
DoubleConversion ....................... yes
Using system DoubleConversion ........ no
GLib ................................... no
iconv .................................. no
ICU .................................... no
Logging backends:
journald ............................. no
syslog ............................... no
slog2 ................................ no
Using system PCRE2 ..................... no
Qt Network:
CoreWLan ............................... yes
getifaddrs() ........................... yes
IPv6 ifname ............................ yes
libproxy ............................... no
SecureTransport ........................ yes
OpenSSL ................................ no
Qt directly linked to OpenSSL ........ no
SCTP ................................... no
Use system proxies ..................... yes
Qt Gui:
Accessibility .......................... yes
FreeType ............................... yes
Using system FreeType ................ no
HarfBuzz ............................... yes
Using system HarfBuzz ................ no
Fontconfig ............................. no
Image formats:
GIF .................................. yes
ICO .................................. yes
JPEG ................................. yes
Using system libjpeg ............... no
PNG .................................. yes
Using system libpng ................ no
EGL .................................... no
OpenVG ................................. no
OpenGL:
Desktop OpenGL ....................... yes
OpenGL ES 2.0 ........................ no
OpenGL ES 3.0 ........................ no
OpenGL ES 3.1 ........................ no
OpenGL ES 3.2 ........................ no
Vulkan ................................. no
Session Management ..................... yes
Features used by QPA backends:
evdev .................................. no
libinput ............................... no
INTEGRITY HID .......................... no
mtdev .................................. no
tslib .................................. no
xkbcommon-evdev ........................ no
QPA backends:
DirectFB ............................... no
EGLFS .................................. no
LinuxFB ................................ no
VNC .................................... no
Mir client ............................. no
Qt Widgets:
GTK+ ................................... no
Styles ................................. Fusion macOS Windows
Qt PrintSupport:
CUPS ................................... yes
Qt Sql:
DB2 (IBM) .............................. no
InterBase .............................. no
MySql .................................. no
OCI (Oracle) ........................... no
ODBC ................................... no
PostgreSQL ............................. no
SQLite2 ................................ no
SQLite ................................. yes
Using system provided SQLite ......... no
TDS (Sybase) ........................... no
Qt SerialBus:
Socket CAN ............................. no
Socket CAN FD .......................... no
QtXmlPatterns:
XML schema support ..................... yes
Qt QML:
QML interpreter ........................ yes
QML network support .................... yes
Qt Quick:
Direct3D 12 ............................ no
AnimatedImage item ..................... yes
Canvas item ............................ yes
Support for Qt Quick Designer .......... yes
Flipable item .......................... yes
GridView item .......................... yes
ListView item .......................... yes
Path support ........................... yes
PathView item .......................... yes
Positioner items ....................... yes
ShaderEffect item ...................... yes
Sprite item ............................ yes
Qt Gamepad:
SDL2 ................................... no
Qt 3D:
Assimp ................................. yes
System Assimp .......................... no
Output Qt3D Job traces ................. no
Output Qt3D GL traces .................. no
Use SSE2 instructions .................. yes
Use AVX2 instructions .................. no
Aspects:
Render aspect ........................ yes
Input aspect ......................... yes
Logic aspect ......................... yes
Animation aspect ..................... yes
Extras aspect ........................ yes
Qt 3D GeometryLoaders:
Autodesk FBX ........................... no
Qt Wayland Client ........................ no
Qt Wayland Compositor .................... no
Qt Bluetooth:
BlueZ .................................. no
BlueZ Low Energy ....................... no
Linux Crypto API ....................... no
WinRT Bluetooth API (desktop & UWP) .... no
Qt Sensors:
sensorfw ............................... no
Qt Quick Controls 2:
Styles ................................. Default Fusion Imagine Material Universal
Qt Quick Templates 2:
Hover support .......................... yes
Multi-touch support .................... yes
Qt Positioning:
Gypsy GPS Daemon ....................... no
WinRT Geolocation API .................. no
Qt Location:
Geoservice plugins:
OpenStreetMap ........................ yes
HERE ................................. yes
Esri ................................. yes
Mapbox ............................... yes
MapboxGL ............................. yes
Itemsoverlay ......................... yes
Qt Multimedia:
ALSA ................................... no
GStreamer 1.0 .......................... no
GStreamer 0.10 ......................... no
Video for Linux ........................ no
OpenAL ................................. yes
PulseAudio ............................. no
Resource Policy (libresourceqt5) ....... no
AVFoundation ........................... yes
Windows Audio Services ................. no
DirectShow ............................. no
Windows Media Foundation ............... no
Note: Using static linking will disable the use of dynamically
loaded plugins. Make sure to import all needed static plugins,
or compile needed modules into the library.
Note: No wayland-egl support detected. Cross-toolkit compatibility disabled.
Qt is now configured for building. Just run 'make'.
Once everything is built, you must run 'make install'.
Qt will be installed into '/path/to/qt/510-static'.
Prior to reconfiguration, make sure you remove any leftovers from
the previous build.
Now you need to actually build it. It is done by running make
command, and it is important to note that it will be doing it for ages, because by default it doesn’t parallelize the process. So, if you, like me, have 8 cores in your CPU (4 physical and 4 logical), you can run it like that:
With -j8
provided, it took 32 minutes to build Qt statically on my MacBookPro with 2.8 GHz Intel Core i7.
However, if there will be any error, the only output you’ll get will be:
make[1]: *** [sub-src-make_first] Error 2
make: *** [module-qtbase-make_first] Error 2
And to see the errors you’ll have to run make
without -j8
.
Last step is to “install” your new static Qt:
That should take a couple of minutes (usually less than a minute), and then you can go to /path/to/qt/510-static
to see the result. If installation runs for more than 5 minutes, than it likely means that something is wrong and it might actually fail. This concerns not only Mac OS but other platforms too.
Linux
All the same as for Mac OS, but I encountered 2 problems.
First one was missing g++
, which is fixed by installing build tools:
$ sudo apt install build-essential
Second one was this:
ERROR The OpenGL functionality tests failed
Which is fixed by installing Mesa libraries:
$ sudo apt install libgl1-mesa-dev
And actually documentation says about that, but I didn’t notice at first.
Note here, that even after you install the missing stuff, configure
won’t know about it, because it performs all the checks only once, and after that it relies on the generated config.cache
, so every time you change something — delete config.cache
before launching configure
again.
I have Linux on Lenovo T540p laptop with 2.5 GHz Intel Core i7, and there it takes 43 minutes (with make -j8
) to built Qt statically.
After executing the last step (make -j8 install
) you will get your static Qt in the folder specified with -prefix
parameter.
Windows
I was trying to build Qt on Windows from time to time, and usually it fails, but sometimes it actually does build.
Qt 5.10.1, Windows 10 and MinGW x32
I have Windows 10 running on the same Lenovo laptop, and there I use Qt (d:\Programs\Qt
) with MinGW (you should have \path\to\Qt\Tools\mingw530_32\bin
in your PATH
).
First I tried to do it with Qt 5.10, but it failed with some error about dummy platforms. I wanted to investigate that, but then suddenly Qt 5.10.1 was released, so I tried with this version and this time it didn’t give me that error.
But I got another error anyway, and it was about OpenGL:
WARNING: Using OpenGL ES 2.0 on Windows without ANGLE.
The build will most likely fail.
Specify -opengl desktop to use regular OpenGL.
So I added -opengl desktop
to the list of configure
options. In addition to that, in some article I read about the option -platform win32-g++
, which apparently would have fixed the dummy platform error. So, the final command line now looks like this:
configure.bat -release -static -ltcg -no-pch -optimize-size -opengl desktop -platform win32-g++ -prefix "\path\to\Qt\510-static" -skip webengine -nomake tools -nomake tests -nomake examples
I executed it and after a while (like, 10 times slower than on Linux) I got the following output:
Running configuration tests...
Checking for valid makespec... yes
Checking for target architecture... i386
Checking for SSE2 instructions... yes
Checking for AES new instructions... yes
Checking for alloca() in alloca.h... no
Checking for alloca() in malloc.h... yes
Checking for SSE3 instructions... yes
Checking for SSSE3 instructions... yes
Checking for SSE4.1 instructions... yes
Checking for SSE4.2 instructions... yes
Checking for AVX instructions... yes
Checking for AVX2 instructions... yes
Checking for AVX512 F instructions... yes
Checking for AVX512 BW instructions... yes
Checking for AVX512 CD instructions... yes
Checking for AVX512 DQ instructions... yes
Checking for AVX512 ER instructions... yes
Checking for AVX512 IFMA instructions... yes
Checking for AVX512 PF instructions... yes
Checking for AVX512 VBMI instructions... yes
Checking for AVX512 VL instructions... yes
Checking for C++14 support... yes
Checking for C++1z support... yes
Checking for D-Bus >= 1.2... no
Checking for F16C instructions... yes
Checking for D-Bus >= 1.2 (host)... yes
Checking for IncrediBuild... no
Checking for udev... no
Checking for POSIX fallocate()... no
Checking for RDRAND instruction... yes
Checking for SHA new instructions... yes
Checking for STL compatibility... yes
Checking for zlib... yes
Checking for C++11 <future>... yes
Checking for eventfd... no
Checking for inotify... no
Checking for slog2... no
Checking for 64 bit atomics... yes
Checking for DoubleConversion... no
Checking for PCRE2... no
Checking for O_CLOEXEC... no
Checking for C++11 <random>... yes
Checking for working std::atomic for function pointers... yes
Checking for getifaddrs()... no
Checking for IPv6 ifname... no
Checking for OpenSSL Headers... no
Checking for OpenSSL v. 1.1 support... no
Checking for XCB >= 1.5 (core)... no
Checking for Direct 2D... no
Checking for DirectWrite... yes
Checking for DirectWrite 2... no
Checking for Desktop OpenGL... yes
Checking for EGL... no
Checking for evdev... no
Checking for GBM... no
Checking for KMS... no
Checking for LinuxFB... no
Checking for mtdev... no
Checking for OpenVG... no
Checking for default QPA platform... windows
Checking for libjpeg... no
Checking for libpng... no
Checking for tslib... no
Checking for Vulkan... no
Checking for xkbcommon... no
Checking for XLib... no
Checking for uxtheme.h... yes
Checking for CUPS... no
Checking for DB2 (IBM)... no
Checking for InterBase... no
Checking for MySQL... no
Checking for OCI (Oracle)... no
Checking for ODBC... yes
Checking for PostgreSQL... no
Checking for SQLite (version 2)... no
Checking for TDS (Sybase)... no
Checking for Direct3D 12... no
Checking for SDL2... no
Checking for Assimp... no
Checking for Autodesk FBX... no
Checking for Wayland EGL library... no
Checking for BlueZ... no
Checking for WinRT Bluetooth API... no
Checking for sensorfw... no
Checking for Gypsy... no
Checking for WinRT Geolocation API... no
Checking for DirectShow... yes
Checking for evr.h... yes
Checking for GStreamer 1.0... no
Checking for GStreamer 0.10... no
Checking for OpenAL... no
Checking for libresourceqt5... no
Checking for Windows Audio Services... no
Checking for WMF... no
Checking for wmsdk.h... no
Checking for WShellItem... yes
Done running configuration tests.
Configure summary:
Build type: win32-g++ (i386, CPU features: <none>)
Configuration: sse2 aesni sse3 ssse3 sse4_1 sse4_2 avx avx2 avx512f avx512bw avx512cd avx512dq avx512er avx512ifma avx512pf avx512vbmi avx512vl compile_examples f16c largefile ltcg optimize_size rdrnd shani release c++11 c++14 c++1z concurrent dbus no-pkg-config static stl
Build options:
Mode ................................... release
Optimize release build for size ........ yes
Building shared libraries .............. no
Using C++ standard ..................... C++1z
Using gold linker ...................... no
Using precompiled headers .............. no
Using LTCG ............................. yes
Target compiler supports:
SSE .................................. SSE2 SSE3 SSSE3 SSE4.1 SSE4.2
AVX .................................. AVX AVX2
AVX512 ............................... F ER CD PF DQ BW VL IFMA VBMI
Other x86 ............................ AES F16C RDRAND SHA
Build parts ............................ libs
App store compliance ................... no
Qt modules and options:
Qt Concurrent .......................... yes
Qt D-Bus ............................... yes
Qt D-Bus directly linked to libdbus .... no
Qt Gui ................................. yes
Qt Network ............................. yes
Qt Sql ................................. yes
Qt Testlib ............................. yes
Qt Widgets ............................. yes
Qt Xml ................................. yes
Support enabled for:
Using pkg-config ....................... no
QML debugging .......................... yes
udev ................................... no
Using system zlib ...................... yes
Qt Core:
DoubleConversion ....................... yes
Using system DoubleConversion ........ no
GLib ................................... no
iconv .................................. no
ICU .................................... no
Logging backends:
journald ............................. no
syslog ............................... no
slog2 ................................ no
Using system PCRE2 ..................... no
Qt Network:
getifaddrs() ........................... no
IPv6 ifname ............................ no
libproxy ............................... no
OpenSSL ................................ no
Qt directly linked to OpenSSL ........ no
SCTP ................................... no
Use system proxies ..................... yes
Qt Gui:
Accessibility .......................... yes
FreeType ............................... yes
Using system FreeType ................ no
HarfBuzz ............................... yes
Using system HarfBuzz ................ no
Fontconfig ............................. no
Image formats:
GIF .................................. yes
ICO .................................. yes
JPEG ................................. yes
Using system libjpeg ............... no
PNG .................................. yes
Using system libpng ................ no
EGL .................................... no
OpenVG ................................. no
OpenGL:
ANGLE ................................ no
Desktop OpenGL ....................... yes
Dynamic OpenGL ....................... no
OpenGL ES 2.0 ........................ no
OpenGL ES 3.0 ........................ no
OpenGL ES 3.1 ........................ no
OpenGL ES 3.2 ........................ no
Vulkan ................................. no
Session Management ..................... yes
Features used by QPA backends:
evdev .................................. no
libinput ............................... no
INTEGRITY HID .......................... no
mtdev .................................. no
tslib .................................. no
xkbcommon-evdev ........................ no
QPA backends:
DirectFB ............................... no
EGLFS .................................. no
LinuxFB ................................ no
VNC .................................... no
Mir client ............................. no
Windows:
Direct 2D ............................ no
DirectWrite .......................... yes
DirectWrite 2 ........................ no
Qt Widgets:
GTK+ ................................... no
Styles ................................. Fusion Windows WindowsVista
Qt PrintSupport:
CUPS ................................... no
Qt Sql:
DB2 (IBM) .............................. no
InterBase .............................. no
MySql .................................. no
OCI (Oracle) ........................... no
ODBC ................................... yes
PostgreSQL ............................. no
SQLite2 ................................ no
SQLite ................................. yes
Using system provided SQLite ......... no
TDS (Sybase) ........................... no
Qt SerialBus:
Socket CAN ............................. no
Socket CAN FD .......................... no
QtXmlPatterns:
XML schema support ..................... yes
Qt QML:
QML interpreter ........................ yes
QML network support .................... yes
Qt Quick:
Direct3D 12 ............................ no
AnimatedImage item ..................... yes
Canvas item ............................ yes
Support for Qt Quick Designer .......... yes
Flipable item .......................... yes
GridView item .......................... yes
ListView item .......................... yes
Path support ........................... yes
PathView item .......................... yes
Positioner items ....................... yes
ShaderEffect item ...................... yes
Sprite item ............................ yes
Qt Gamepad:
SDL2 ................................... no
Qt 3D:
Assimp ................................. yes
System Assimp .......................... no
Output Qt3D Job traces ................. no
Output Qt3D GL traces .................. no
Use SSE2 instructions .................. no
Use AVX2 instructions .................. no
Aspects:
Render aspect ........................ yes
Input aspect ......................... yes
Logic aspect ......................... yes
Animation aspect ..................... yes
Extras aspect ........................ yes
Qt 3D GeometryLoaders:
Autodesk FBX ........................... no
Qt Wayland Client ........................ no
Qt Wayland Compositor .................... no
Qt Bluetooth:
BlueZ .................................. no
BlueZ Low Energy ....................... no
Linux Crypto API ....................... no
WinRT Bluetooth API (desktop & UWP) .... no
Qt Sensors:
sensorfw ............................... no
Qt Quick Controls 2:
Styles ................................. Default Fusion Imagine Material Universal
Qt Quick Templates 2:
Hover support .......................... yes
Multi-touch support .................... yes
Qt Positioning:
Gypsy GPS Daemon ....................... no
WinRT Geolocation API .................. no
Qt Location:
Geoservice plugins:
OpenStreetMap ........................ yes
HERE ................................. yes
Esri ................................. yes
Mapbox ............................... yes
MapboxGL ............................. yes
Itemsoverlay ......................... yes
Qt Multimedia:
ALSA ................................... no
GStreamer 1.0 .......................... no
GStreamer 0.10 ......................... no
Video for Linux ........................ no
OpenAL ................................. no
PulseAudio ............................. no
Resource Policy (libresourceqt5) ....... no
Windows Audio Services ................. no
DirectShow ............................. yes
Windows Media Foundation ............... no
Media player backend ................... DirectShow
Note: Using static linking will disable the use of dynamically
loaded plugins. Make sure to import all needed static plugins,
or compile needed modules into the library.
Note: No wayland-egl support detected. Cross-toolkit compatibility disabled.
Qt is now configured for building. Just run 'mingw32-make'.
Once everything is built, you must run 'mingw32-make install'.
Qt will be installed into 'D:\programs\Qt\510-static'.
Prior to reconfiguration, make sure you remove any leftovers from
the previous build.
Next step was to run make
:
But it failed:
...
\ccUClyLX.ltrans22.ltrans.o:<artificial>:(.text+0x20d): undefined reference to `QByteArray::QByteArray(int, Qt::Initialization)'
\ccUClyLX.ltrans22.ltrans.o:<artificial>:(.text+0x244): undefined reference to `QByteArray::resize(int)'
collect2.exe: error: ld returned 1 exit status
Makefile.Release:86: recipe for target '..\..\..\bin\moc.exe' failed
mingw32-make[4]: *** [..\..\..\bin\moc.exe] Error 1
mingw32-make[4]: Leaving directory 'd:/programs/Qt/5.10.1/Src/qtbase/src/tools/moc'
Makefile:36: recipe for target 'release' failed
mingw32-make[3]: *** [release] Error 2
mingw32-make[3]: Leaving directory 'd:/programs/Qt/5.10.1/Src/qtbase/src/tools/moc'
Makefile:93: recipe for target 'sub-moc-make_first' failed
mingw32-make[2]: *** [sub-moc-make_first] Error 2
mingw32-make[2]: Leaving directory 'd:/programs/Qt/5.10.1/Src/qtbase/src'
Makefile:44: recipe for target 'sub-src-make_first' failed
mingw32-make[1]: *** [sub-src-make_first] Error 2
mingw32-make[1]: Leaving directory 'd:/programs/Qt/5.10.1/Src/qtbase'
Makefile:78: recipe for target 'module-qtbase-make_first' failed
mingw32-make: *** [module-qtbase-make_first] Error 2
I tried setting flags in qmake.conf
like it is said here, but that didn’t help (I found the actual reason later).
Okay then, let’s try another computer — who knows, maybe my environment is messed up somehow. So I installed Qt to another machine with Windows and tried to perform configure
. There it gave me a different type of error:
Cannot detect host toolchain. Please use -platform. Aborting.
Okay, I provided -platform win32-g++
(and -opengl desktop
) and relaunched configure
. It asked me about edition, I chose commercial, and…
Which edition of Qt do you want to use? c
Error: Insufficient command line arguments for licheck (configure)
ERROR: You are not licensed to use this software.
But I do have a commercial license! And the license file is where it should be. But okay, let’s try Open Source option:
Which edition of Qt do you want to use? o
Running configuration tests...
Checking for valid makespec... ERROR: Cannot compile a minimal program. The toolchain or QMakeSpec is broken.
Yeah, fuck this shit.
Qt 5.11.1, Windows 7 and MSVC2015 x64
After quite a while I gave it another shot as I needed to build static Qt for Windows 7 with MSVC2015.
So, here are the steps.
Install DirectX and DirectX SDK. Most likely it is not required, but I would do it just in case;
Install Python (I took 3.7), Perl and make sure that both are added to PATH. Thank you, Qt documentation, for not mentioning Python and Perl at all, because I discovered it by getting the following error:
Makefile [module-qtdeclarative-install_subtargets] Error 3
Which does not explain anything, but having googled it, I found out that it’s exactly due to the missing Python and Perl.
Install .NET 4.6, which is needed for Visual Studio installer. Choose the following components from VS:
Yes, even though you’re on Windows 7, install Windows 8.1 SDK. Although, it could be that only UCRT component is needed.
Now install Qt:
It is actually not required to install pre-built MSVC Qt (you only need Sources
), but I wanted to compare dynamic with static, so I installed it.
Get jom and add it to PATH. If you won’t do this, Qt will be built with nmake
, which will take ages as it cannot use more than one CPU core (no -j
option).
Create a folder for shadow build, launch VS2015 x64 Native Tools Command Prompt
from your Start menu and go to this folder. Then build Qt from there:
configure.bat -release -static -no-pch -optimize-size -opengl desktop -platform win32-msvc -prefix "C:\Qt\511-static" -skip webengine -nomake tools -nomake tests -nomake examples
time /t >> time.txt & jom -j8 & time /t >> time.txt
jom -j8 install
It took 35 minutes (on the same Lenovo laptop) to build 487 MB of binaries, and then it took a 1 hour and 40 minutes to perform install
, which resulted in 560 MB. I don’t know why it takes so long to perform install
, but what’s more amusing is that sometimes it takes just a couple of minutes as it should — no idea what Windows “magic” is behind that.
Note that I don’t have -ltcg
option this time. I actually had it, but it resulted in something ridiculous: the build itself occupied fucking 46 GB of space, and after install
command I got another 22 GB. What is the actual fuck. Apparently, it has something to do with the compiler (hello, Microsoft), because the .lib
files were matching the .obj
folder (someone told me that, I’ve no idea what it means).
During both build and install phases I got several occasional freezes of my PC when it became totally unresponsive so I had to hard-reset the machine and start over. Windows is definitely my favorite development platform.
But okay, most importantly thing is that it has successfully built and that it works.
Also note, that I haven’t set any special flags which you can find being mentioned all over the internet (QMAKE_CFLAGS_X
and others) and didn’t edit any configs — everything just builds as it is with out-of-the-box configuration.
Qt 5.11.1, Windows 10 and MSVC2017 x64
Just in case I decided to try Windows 10 and MSVC2017.
Again, it’s all the same: Python and Perl in your PATH, Visual Studio installed but this time with MSVC2017, you launched VS2017 x64 Native Tools Command Prompt
.
configure.bat -release -static -no-pch -optimize-size -opengl desktop -platform win32-msvc -prefix "\path\to\Qt\511-static" -skip webengine -nomake tools -nomake tests -nomake examples
time /t >> time.txt & jom -j8 & time /t >> time.txt
jom -j8 install
And again, with -ltcg
option it produced 14.5 GB after build, then increased that to 52.6 GB, having installed 25.7 GB of static Qt. Compilation took 18 minutes, and installation was going for 59 minutes.
Without -ltcg
it produced 480 MB after build, increased that to 1.34 GB and installed 606 MB of static Qt. Compilation took 15 minutes, and installation was going for 44 minutes.
Qt 5.11.2, Windows 10 and MinGW x32
After I succeeded building Qt with MSVC, I decided to try MinGW again with just released Qt 5.11.2.
It’s all the same as for Windows 7, except for installed Python and Perl.
Configuration went okay, but mingw32-make
failed literally within a couple of minutes:
C:\Users\vasya\AppData\Local\Temp\ccj6NtVh.ltrans2.ltrans.o:<artificial>:(.text+0x232a): undefined reference to
`QMapDataBase::recalcMostLeftNode()'
C:\Users\vasya\AppData\Local\Temp\ccj6NtVh.ltrans2.ltrans.o:<artificial>:(.text.unlikely+0x21): undefined refer
ence to `QAbstractConcatenable::appendLatin1To(char const*, int, QChar*)'
C:\Users\vasya\AppData\Local\Temp\ccj6NtVh.ltrans2.ltrans.o:<artificial>:(.text$_ZN8SubArrayC4EPKc.lto_priv.53.
lto_priv.106[_ZN8SubArrayC4EPKc.lto_priv.53.lto_priv.106]+0xd): undefined reference to `QByteArray::QByteArray(
char const*, int)'
C:\Users\vasya\AppData\Local\Temp\ccj6NtVh.ltrans2.ltrans.o:<artificial>:(.text$_ZN11FunctionDefC4ERKS_.lto_pri
v.67.lto_priv.128[_ZN11FunctionDefC4ERKS_.lto_priv.67.lto_priv.128]+0xbb): undefined reference to `QArrayData::
allocate(unsigned long long, unsigned long long, unsigned long long, QFlags<QArrayData::AllocationOption>)'
C:\Users\vasya\AppData\Local\Temp\ccj6NtVh.ltrans2.ltrans.o:<artificial>:(.text$_ZN11FunctionDefC4ERKS_.lto_pri
v.67.lto_priv.128[_ZN11FunctionDefC4ERKS_.lto_priv.67.lto_priv.128]+0xdb): undefined reference to `QArrayData::
allocate(unsigned long long, unsigned long long, unsigned long long, QFlags<QArrayData::AllocationOption>)'
C:\Users\vasya\AppData\Local\Temp\ccj6NtVh.ltrans2.ltrans.o:<artificial>:(.text$_ZN7QVectorI11FunctionDefEC4ERK
S1_.lto_priv.65.lto_priv.132[_ZN7QVectorI11FunctionDefEC4ERKS1_.lto_priv.65.lto_priv.132]+0x46): undefined refe
rence to `QArrayData::allocate(unsigned long long, unsigned long long, unsigned long long, QFlags<QArrayData::A
llocationOption>)'
C:\Users\vasya\AppData\Local\Temp\ccj6NtVh.ltrans2.ltrans.o:<artificial>:(.text$_ZN7QVectorI11FunctionDefEC4ERK
S1_.lto_priv.65.lto_priv.132[_ZN7QVectorI11FunctionDefEC4ERKS1_.lto_priv.65.lto_priv.132]+0x65): undefined refe
rence to `QArrayData::allocate(unsigned long long, unsigned long long, unsigned long long, QFlags<QArrayData::A
llocationOption>)'
collect2.exe: error: ld returned 1 exit status
Makefile.Release:86: recipe for target '..\..\..\bin\moc.exe' failed
mingw32-make[4]: *** [..\..\..\bin\moc.exe] Error 1
mingw32-make[4]: Leaving directory 'c:/Qt/5.11.1/5111/qtbase/src/tools/moc'
Makefile:36: recipe for target 'release' failed
mingw32-make[3]: *** [release] Error 2
mingw32-make[3]: Leaving directory 'c:/Qt/5.11.1/5111/qtbase/src/tools/moc'
Makefile:92: recipe for target 'sub-moc-make_first' failed
mingw32-make[2]: *** [sub-moc-make_first] Error 2
mingw32-make[2]: Leaving directory 'c:/Qt/5.11.1/5111/qtbase/src'
Makefile:44: recipe for target 'sub-src-make_first' failed
mingw32-make[1]: *** [sub-src-make_first] Error 2
mingw32-make[1]: Leaving directory 'c:/Qt/5.11.1/5111/qtbase'
Makefile:78: recipe for target 'module-qtbase-make_first' failed
mingw32-make: *** [module-qtbase-make_first] Error 2
I almost cursed everything forever, but then suddenly I decided to… try without -ltcg
option. And it fucking worked! Hallelujah.
Although, in case of MinGW there is one more thing you should know about — its runtime doesn’t link statically by default. Surprise! So having deployed your statically linked Qt application to some other computer, you can get the following error:
In order to link MinGW runtime too, you need to set yet another option: -static-runtime
.
So, the final configure
options for building static Qt with MinGW on Windows is the following:
configure.bat -release -static -static-runtime -no-pch -optimize-size -opengl desktop -platform win32-g++ -prefix "\path\to\qt\511-static" -skip webengine -nomake tools -nomake tests -nomake examples
Building took 1 hour and 14 minutes and 1.02 GB. Installing took 8 minutes and resulted in 460 MB.
Now I can finally state that MinGW static builds of Qt do actually work. By the way, contrary to many manuals from the internet, I haven’t used any additional scripts or MSYS environment — everything just works within regular cmd
.
How to use static Qt
You need to add static Qt in your Qt Creator settings:
After that you just need to add this kit to your existing project and build with it:
How exactly static build is different
Let’s see how to use static Qt in your projects and also let’s compare some metrics between dynamic and static builds. I took Cinematic Experience demo for experiments.
You can see for yourself that dynamically linked applications have dependency on Qt shared libraries and statically linked ones do not.
Mac OS
Dynamic:
otool -L cinematic-demo.app/Contents/MacOS/cinematic-demo
cinematic-demo.app/Contents/MacOS/cinematic-demo:
@rpath/QtQuick.framework/Versions/5/QtQuick (compatibility version 5.10.0, current version 5.10.1)
@rpath/QtQml.framework/Versions/5/QtQml (compatibility version 5.10.0, current version 5.10.1)
@rpath/QtNetwork.framework/Versions/5/QtNetwork (compatibility version 5.10.0, current version 5.10.1)
@rpath/QtCore.framework/Versions/5/QtCore (compatibility version 5.10.0, current version 5.10.1)
/System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0)
@rpath/QtGui.framework/Versions/5/QtGui (compatibility version 5.10.0, current version 5.10.1)
/System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/AGL.framework/Versions/A/AGL (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.0.0)
Static:
otool -L cinematic-demo.app/Contents/MacOS/cinematic-demo
cinematic-demo.app/Contents/MacOS/cinematic-demo:
/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 1561.20.106)
/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon (compatibility version 2.0.0, current version 158.0.0)
/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0)
/System/Library/Frameworks/QuartzCore.framework/Versions/A/QuartzCore (compatibility version 1.2.0, current version 1.11.0)
/usr/lib/libcups.2.dylib (compatibility version 2.0.0, current version 2.12.0)
/System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 1450.15.0)
/System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices (compatibility version 1.0.0, current version 822.19.0)
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices (compatibility version 1.0.0, current version 50.0.0)
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1450.15.0)
/System/Library/Frameworks/CoreGraphics.framework/Versions/A/CoreGraphics (compatibility version 64.0.0, current version 1129.5.0)
/System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/AGL.framework/Versions/A/AGL (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/CoreText.framework/Versions/A/CoreText (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/Security.framework/Versions/A/Security (compatibility version 1.0.0, current version 58286.31.2)
/System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration (compatibility version 1.0.0, current version 963.30.1)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.0.0)
/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.0)
/System/Library/Frameworks/CFNetwork.framework/Versions/A/CFNetwork (compatibility version 1.0.0, current version 893.13.1)
/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
I’ve no idea why why it has a much longer list of some other stuff.
Linux
On Linux it makes more sense.
Dynamic:
ldd cinematic-demo
linux-vdso.so.1 => (0x00007ffff63e3000)
libQt5Gui.so.5 => /path/to/qt/5.10.1/gcc_64/lib/libQt5Gui.so.5 (0x00007f54fbd1f000)
libQt5Qml.so.5 => /path/to/qt/5.10.1/gcc_64/lib/libQt5Qml.so.5 (0x00007f54fb6ee000)
libQt5Core.so.5 => /path/to/qt/5.10.1/gcc_64/lib/libQt5Core.so.5 (0x00007f54faf9e000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f54fabff000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f54fa9e9000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f54fa61f000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f54fa401000)
libGL.so.1 => /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1 (0x00007f54fa18e000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f54f9f74000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f54f9c6a000)
libQt5Network.so.5 => /path/to/qt/5.10.1/gcc_64/lib/libQt5Network.so.5 (0x00007f54f98d4000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f54f96cc000)
libicui18n.so.56 => /path/to/qt/5.10.1/gcc_64/lib/libicui18n.so.56 (0x00007f54f9232000)
libicuuc.so.56 => /path/to/qt/5.10.1/gcc_64/lib/libicuuc.so.56 (0x00007f54f8e7a000)
libicudata.so.56 => /path/to/qt/5.10.1/gcc_64/lib/libicudata.so.56 (0x00007f54f7496000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f54f7292000)
libgthread-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgthread-2.0.so.0 (0x00007f54f7090000)
libglib-2.0.so.0 => /lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007f54f6d7f000)
/lib64/ld-linux-x86-64.so.2 (0x0000562cf8cce000)
libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007f54f6b55000)
libxcb-dri3.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-dri3.so.0 (0x00007f54f6952000)
libxcb-present.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-present.so.0 (0x00007f54f674e000)
libxcb-sync.so.1 => /usr/lib/x86_64-linux-gnu/libxcb-sync.so.1 (0x00007f54f6547000)
libxshmfence.so.1 => /usr/lib/x86_64-linux-gnu/libxshmfence.so.1 (0x00007f54f6344000)
libglapi.so.0 => /usr/lib/x86_64-linux-gnu/libglapi.so.0 (0x00007f54f6113000)
libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007f54f5f01000)
libXdamage.so.1 => /usr/lib/x86_64-linux-gnu/libXdamage.so.1 (0x00007f54f5cfe000)
libXfixes.so.3 => /usr/lib/x86_64-linux-gnu/libXfixes.so.3 (0x00007f54f5af7000)
libX11-xcb.so.1 => /usr/lib/x86_64-linux-gnu/libX11-xcb.so.1 (0x00007f54f58f5000)
libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007f54f55bb000)
libxcb-glx.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-glx.so.0 (0x00007f54f53a1000)
libxcb-dri2.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-dri2.so.0 (0x00007f54f519c000)
libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f54f4f7a000)
libXxf86vm.so.1 => /usr/lib/x86_64-linux-gnu/libXxf86vm.so.1 (0x00007f54f4d73000)
libdrm.so.2 => /usr/lib/x86_64-linux-gnu/libdrm.so.2 (0x00007f54f4b62000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f54f48f1000)
libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f54f46ed000)
libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f54f44e6000)
Static:
ldd cinematic-demo
linux-vdso.so.1 => (0x00007ffda1b9f000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f9b02744000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f9b0252e000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9b02164000)
libxcb-glx.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-glx.so.0 (0x00007f9b01f4a000)
libX11-xcb.so.1 => /usr/lib/x86_64-linux-gnu/libX11-xcb.so.1 (0x00007f9b01d48000)
libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007f9b01a0e000)
libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f9b017eb000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f9b015e7000)
libGL.so.1 => /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1 (0x00007f9b01374000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f9b01156000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f9b00e4d000)
/lib64/ld-linux-x86-64.so.2 (0x00005583c34ae000)
libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f9b00c49000)
libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f9b00a42000)
libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007f9b00819000)
libxcb-dri3.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-dri3.so.0 (0x00007f9b00616000)
libxcb-present.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-present.so.0 (0x00007f9b00412000)
libxcb-sync.so.1 => /usr/lib/x86_64-linux-gnu/libxcb-sync.so.1 (0x00007f9b0020b000)
libxshmfence.so.1 => /usr/lib/x86_64-linux-gnu/libxshmfence.so.1 (0x00007f9b00008000)
libglapi.so.0 => /usr/lib/x86_64-linux-gnu/libglapi.so.0 (0x00007f9affdd7000)
libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007f9affbc5000)
libXdamage.so.1 => /usr/lib/x86_64-linux-gnu/libXdamage.so.1 (0x00007f9aff9c2000)
libXfixes.so.3 => /usr/lib/x86_64-linux-gnu/libXfixes.so.3 (0x00007f9aff7bb000)
libxcb-dri2.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-dri2.so.0 (0x00007f9aff5b6000)
libXxf86vm.so.1 => /usr/lib/x86_64-linux-gnu/libXxf86vm.so.1 (0x00007f9aff3b0000)
libdrm.so.2 => /usr/lib/x86_64-linux-gnu/libdrm.so.2 (0x00007f9aff19e000)
Windows
On Windows there is no out of the box tool to track dependencies, so I used Dependency Walker.
And it’s worth to mention that MSVC and MinGW builds have different set of dependencies.
MSVC
Dynamic MSVC:
Static MSVC:
MinGW
Dynamic MinGW:
Oh, by the way, in case of dynamic linking it’s not a trivial task to gather all the required Qt libraries based on what Dependency Walker shows you. For instance, here we can see that only 3 Qt libraries are required, but after I deployed those, my application complained about one more, and when I added that one, it stopped complaining, however having launched it I never saw its window, even though application was present among the running processes at Task Manager. And only after a set of tests and trials I’ve managed to collect the full pack:
release
├── Qt5Core.dll
├── Qt5Gui.dll
├── Qt5Network.dll
├── Qt5Qml.dll
├── Qt5Quick.dll
├── Qt5QuickControls2.dll
├── Qt5QuickParticles.dll
├── Qt5QuickTemplates2.dll
├── Qt5QuickWidgets.dll
├── cinematic-demo.exe
├── libgcc_s_dw2-1.dll
├── libstdc++-6.dll
└── libwinpthread-1.dll
From that perspective MinGW static linking on Windows is really a savior:
If you are confused by longer list for static builds — this whole bunch of system libraries is actually from the SHELL32.DLL
tree, and you can find them in dynamic build too by expanding its node. What matters is that there are no Qt libraries (and no MinGW runtime) among dependencies anymore.
Smaller builds
Naturally, static build gives you smaller size for your application binary.
On Mac OS:
- dynamic (with all required Qt libraries): 33.4 MB;
- static: 26.1 MB.
On Windows (MinGW):
- dynamic (with all required Qt libraries and MinGW runtime): 28.2 MB;
- static: 19.9 MB.
Less RAM
I saw people claiming that RAM consumption is different too. On Mac it’s not really the case:
- dynamic: 118.7 MB;
- static: 116.8 MB.
Windows (MinGW) has some difference, but not that big:
- dynamic: 168.9 MB;
- static: 160.7 MB.
And there is some notable difference on Linux:
- dynamic: 141.0 MB;
- static: 115.2 MB.
Slower building
But there is also a trade-off in terms of compilation time (measured on Mac OS):
- dynamic: 5 seconds;
- static: 210 seconds.
Possible problems
There could be all sorts of problems along the road. And those are not necessarily your fault — on the contrary, in most cases it will be Qt bugs, which you should definitely report at Qt’s bug-tracker. Seriously, do that, because they give highest priority to that kind of issues (especially if it’s reported against a pre-release version) and fix those pretty fast.
Now about the problems I’ve encountered myself.
Shadow builds not working
Sometimes, shadow builds just get broken, meaning that it is impossible to built a particular Qt version using shadow build, whatever the reason might be, and so you’ll have to do it right in the Src
directory.
Trailing backslash in prefix
Having a trailing \
in prefix on Windows can cause the following problem:
Running configuration tests...
Checking for valid makespec... ERROR: Cannot compile a minimal program. The toolchain or QMakeSpec is broken.
Check config.log for details.
Remove the trailing \
and try again. So:
-prefix "d:\programs\qt\5122-static\"
— fails;-prefix "d:\programs\qt\5122-static"
— works.
Text is not visible, because there are no fonts
One of the issues you might encounter with your applications built with static Qt is the absence of fonts for your GUI. Literally, all the text controls will have no text at all. Also, your application will print the following to the console:
QFontDatabase: Cannot find font directory /path/to/qt/5.15.2-static/lib/fonts.
Note that Qt no longer ships fonts. Deploy some (from https://dejavu-fonts.github.io/ for example) or switch to fontconfig.
As I understood, that happens on GNU/Linux only.
There are several ways of fixing this. First, obviously, it might be enough to just deploy some fonts to /path/to/qt/5.15.2-static/lib/fonts
folder.
Second option would be to “embed” a font into your application — add a font file to resources and “activate” it in main.cpp
:
...
#include <QFontDatabase>
#include <QFont>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
int id = QFontDatabase::addApplicationFont(":/fonts/TitilliumWeb-Regular.ttf");
app.setFont(QFont(QFontDatabase::applicationFontFamilies(id).at(0)));
...
}
Finally, you can re-configure (and rebuild) Qt with -fontconfig
option. First, install these packages just in case:
$ sudo apt install libfreetype6 libfreetype6-dev libfreetype-dev
$ sudo apt install libfontconfig1 libfontconfig1-dev
and then configure Qt (having deleted the old build and cache files):
$ ../configure -static -release -no-pch -prefix "/path/to/qt/5.15.2-static" \
-fontconfig -skip qtwebengine -nomake tests -nomake examples
You should see the following in the configuration output:
Qt Gui:
Accessibility .......................... yes
FreeType ............................... yes
Using system FreeType ................ yes
HarfBuzz ............................... yes
Using system HarfBuzz ................ no
Fontconfig ............................. yes
Non-existent module or unknown command line option
Sometimes you might get this error trying to run configure
:
Project ERROR: -skip command line argument used with non-existent module 'qtwebengine'.
or even this one:
ERROR: Unknown command line option '-release'.
I’ve got both after unpacking Qt sources from a snapshot archive with default Archive Manager application on Elementary OS. I figured it did something wrong during unpacking, and so I unpacked the archive using tar
from command line instead, and then the exactly same configure
command ran without problems.
QQmlApplicationEngine failed to load component, qtquick2plugin not found
At some point, having built Qt 5.15.2, I got this error, trying to launch my application:
QQmlApplicationEngine failed to load component
qrc:/main.qml:1:1: module "QtQuick" plugin "qtquick2plugin" not found
So the application builds fine, but throws this error on launch.
At first I did not find a solution for this, so I just re-built Qt dynamically (without -static
configuration option), and then my application was able to launch.
But then I did some digging and discovered that some Qt plugins/modules (including qtquick2plugin
, apparently) require some additional massaging if Qt is built statically, and actually Qt warns about this in the end of the configuration output:
Note: Using static linking will disable the use of dynamically
loaded plugins. Make sure to import all needed static plugins,
or compile needed modules into the library.
Why cannot it just take care of this on its own, so one could get a working build out of the box — I don’t know, apparently one just can not. Well, actually, if you are using qmake, then it will work out of the box (but here’s also some documentation on the matter, just in case), and you won’t need to change anything in your project file, but with CMake that is not the case.
When using Qt static build and CMake, one needs to call qt5_import_qml_plugins function in his project:
get_target_property(QT_TARGET_TYPE Qt5::Core TYPE)
if(${QT_TARGET_TYPE} STREQUAL "STATIC_LIBRARY")
find_package(Qt5QmlImportScanner REQUIRED)
qt5_import_qml_plugins(${CMAKE_PROJECT_NAME})
endif()
Hopefully, there is also qt6_import_qml_plugins
in Qt 6, at least it is mentioned in QTBUG-86827.
This function is available only from Qt 5.14, but for versions older than 5.14 there seems to be nothing for that in the official resources, but fortunately there is this external CMake module. I did some modifications to it, and here’s how I used it in my project:
get_target_property(QT_TARGET_TYPE Qt${QT_VERSION_MAJOR}::Core TYPE)
if(${QT_TARGET_TYPE} STREQUAL "STATIC_LIBRARY")
message(STATUS "This Qt is static")
# from 5.14 there is a standard function for this
set(QT_VERSION_WITH_QML_IMPORTS 5.14)
if(${QT_VERSION} VERSION_EQUAL ${QT_VERSION_WITH_QML_IMPORTS}
OR ${QT_VERSION} VERSION_GREATER ${QT_VERSION_WITH_QML_IMPORTS}
)
message(STATUS "This Qt version (${QT_VERSION}) is newer than ${QT_VERSION_WITH_QML_IMPORTS}")
find_package(Qt5QmlImportScanner REQUIRED)
qt5_import_qml_plugins(${CMAKE_PROJECT_NAME})
else() # use a custom module
message(STATUS "This Qt version (${QT_VERSION}) is older than ${QT_VERSION_WITH_QML_IMPORTS}")
include(QtStaticPlugins)
# this adds lots of unused modules and actually is not needed at all, as it seems
#qt_generate_plugin_import(${CMAKE_PROJECT_NAME}
# OUTPUT "${CMAKE_PROJECT_NAME}_plugin_import.cpp"
# OUTPUT_DIR "${PROJECT_BINARY_DIR}"
# #VERBOSE
#)
qt_generate_qml_plugin_import(${CMAKE_PROJECT_NAME}
QML_DIR "${QT_HOME}/qml"
QML_SRC "${CMAKE_CURRENT_SOURCE_DIR}"
OUTPUT "${CMAKE_PROJECT_NAME}_qml_plugin_import.cpp"
OUTPUT_DIR "${PROJECT_BINARY_DIR}"
#VERBOSE
)
endif()
if(TARGET Qt${QT_VERSION_MAJOR}::QmlWorkerScript)
target_link_libraries(${CMAKE_PROJECT_NAME}
PRIVATE
Qt${QT_VERSION_MAJOR}::QmlWorkerScript
)
endif()
endif()
The last bit about linking to QmlWorkerScript
is a required crutch, otherwise you’ll get the following error on linking:
Undefined symbols for architecture x86_64:
"qml_register_types_QtQml_WorkerScript()", referenced from:
qt_plugin_instance_QtQmlWorkerScriptPlugin() in libworkerscriptplugin.a(plugin.o)
"QQmlWorkerScriptModule::registerQuickTypes()", referenced from:
QtQuick2Plugin::registerTypes(char const*) in libqtquick2plugin.a(plugin.o)
non-virtual thunk to QtQuick2Plugin::registerTypes(char const*) in libqtquick2plugin.a(plugin.o)
With my glorious Color Corners application as an example, both the standard function and this module produced identical .cpp
files in the build directory:
#include <QtPlugin>
Q_IMPORT_PLUGIN(QtQuick2Plugin)
Q_IMPORT_PLUGIN(QtQuick2WindowPlugin)
Q_IMPORT_PLUGIN(QtQuickLayoutsPlugin)
Q_IMPORT_PLUGIN(QtQmlPlugin)
Q_IMPORT_PLUGIN(QtQmlModelsPlugin)
Q_IMPORT_PLUGIN(QtQmlWorkerScriptPlugin)
Plus certain linking instructions were added.
If you are curious to see where this list of plugins originates from, you can inspect your application imports with qmlimportscanner
tool yourself:
$ /path/to/qt/5.15.2-static/bin/qmlimportscanner \
-rootPath /path/to/your/project/qml/sources \
-importPath /path/to/qt/5.15.2-static/qml
For me it was the following:
[
{
"classname": "QtQuick2Plugin",
"name": "QtQuick",
"path": "/path/to/qt/5.15.2-static/qml/QtQuick.2",
"plugin": "qtquick2plugin",
"relativePath": "QtQuick.2",
"type": "module",
"version": "2.15"
},
{
"classname": "QtQuick2WindowPlugin",
"name": "QtQuick.Window",
"path": "/path/to/qt/5.15.2-static/qml/QtQuick/Window.2",
"plugin": "windowplugin",
"relativePath": "QtQuick/Window.2",
"type": "module",
"version": "2.15"
},
{
"classname": "QtQuickLayoutsPlugin",
"name": "QtQuick.Layouts",
"path": "/path/to/qt/5.15.2-static/qml/QtQuick/Layouts",
"plugin": "qquicklayoutsplugin",
"relativePath": "QtQuick/Layouts",
"type": "module",
"version": "1.15"
},
{
"classname": "QtQmlPlugin",
"name": "QtQml",
"path": "/path/to/qt/5.15.2-static/qml/QtQml",
"plugin": "qmlplugin",
"relativePath": "QtQml",
"type": "module",
"version": "2.15"
},
{
"classname": "QtQmlModelsPlugin",
"name": "QtQml.Models",
"path": "/path/to/qt/5.15.2-static/qml/QtQml/Models.2",
"plugin": "modelsplugin",
"relativePath": "QtQml/Models.2",
"type": "module",
"version": "2.15"
},
{
"classname": "QtQmlWorkerScriptPlugin",
"name": "QtQml.WorkerScript",
"path": "/path/to/qt/5.15.2-static/qml/QtQml/WorkerScript.2",
"plugin": "workerscriptplugin",
"relativePath": "QtQml/WorkerScript.2",
"type": "module",
"version": "2.15"
}
]
Which matches the generated list of imports.
Could not find the Qt platform plugin XCB
On Linux, even though the Qt builds fine, and even your applications build fine, you might get the following error, trying to launch them:
qt.qpa.plugin: Could not find the Qt platform plugin "xcb" in ""
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
Available platform plugins are: eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, webgl.
There is a one kilometer long thread on Qt’s forum, where you might find an absolutely retarded advice (что за уебан догадался такое посоветовать) to remove libqt5gui5
from the system — don’t do that, not only it won’t help, but it will actually pretty much ruin your system.
Some replies there and also here say that installing/reinstalling libxcb-xinerama0
resolved the problem for them, but it didn’t for me.
There is also a shorter thread on a similar topic here, and this one did point to this comment, which finally got me to the right place — Qt wiki, which had the full list of packets that you need to install:
$ sudo apt install '^libxcb.*-dev' libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev
Qt’s documentation also provides a list of those, but it’s not as full as the one from wiki, and installing only the ones listed in documentation was not enough in my case.
Anyway, here’s how your Qt configuration output might look like without required XCB packages installed:
...
Features used by QPA backends:
evdev .................................. yes
libinput ............................... no
INTEGRITY HID .......................... no
mtdev .................................. no
tslib .................................. no
xkbcommon .............................. no
X11 specific:
XLib ................................. no
XCB Xlib ............................. no
EGL on X11 ........................... no
xkbcommon-x11 ........................ no
QPA backends:
DirectFB ............................... no
EGLFS .................................. yes
EGLFS details:
EGLFS OpenWFD ........................ no
EGLFS i.Mx6 .......................... no
EGLFS i.Mx6 Wayland .................. no
EGLFS RCAR ........................... no
EGLFS EGLDevice ...................... no
EGLFS GBM ............................ no
EGLFS VSP2 ........................... no
EGLFS Mali ........................... no
EGLFS Raspberry Pi ................... no
EGLFS X11 ............................ no
LinuxFB ................................ yes
VNC .................................... yes
...
here’s the resulting platform plugins folder contents:
$ ls -L1 ~/programs/qt/5152-static/plugins/platforms
libqeglfs.a
libqeglfs.prl
libqlinuxfb.a
libqlinuxfb.prl
libqminimal.a
libqminimal.prl
libqminimalegl.a
libqminimalegl.prl
libqoffscreen.a
libqoffscreen.prl
libqvnc.a
libqvnc.prl
libqwebgl.a
libqwebgl.prl
That’s how you know that your applications will build but will not launch. Pretty amazing how you can get get a Qt build, which did not complain about anything neither during configuration nor during the build, succeeded without errors, and yet it ended up being actually useless for you.
And here’s a Qt configuration output when all the required XCB packages are installed:
...
Features used by QPA backends:
evdev .................................. yes
libinput ............................... no
INTEGRITY HID .......................... no
mtdev .................................. no
tslib .................................. no
xkbcommon .............................. yes
X11 specific:
XLib ................................. yes
XCB Xlib ............................. yes
EGL on X11 ........................... yes
xkbcommon-x11 ........................ yes
QPA backends:
DirectFB ............................... no
EGLFS .................................. yes
EGLFS details:
EGLFS OpenWFD ........................ no
EGLFS i.Mx6 .......................... no
EGLFS i.Mx6 Wayland .................. no
EGLFS RCAR ........................... no
EGLFS EGLDevice ...................... no
EGLFS GBM ............................ no
EGLFS VSP2 ........................... no
EGLFS Mali ........................... no
EGLFS Raspberry Pi ................... no
EGLFS X11 ............................ yes
LinuxFB ................................ yes
VNC .................................... yes
XCB:
Using system-provided xcb-xinput ..... yes
Native painting (experimental) ....... no
GL integrations:
GLX Plugin ......................... yes
XCB GLX .......................... yes
EGL-X11 Plugin ..................... yes
...
and resulting platform plugins folder contents:
$ ls -L1 ~/programs/qt/5152-static/plugins/platforms
libqeglfs.a
libqeglfs.prl
libqlinuxfb.a
libqlinuxfb.prl
libqminimal.a
libqminimal.prl
libqminimalegl.a
libqminimalegl.prl
libqoffscreen.a
libqoffscreen.prl
libqvnc.a
libqvnc.prl
libqwebgl.a
libqwebgl.prl
libqxcb.a
libqxcb.prl
So now libqxcb
plugin is in place, and your applications will not only build but also actually work.
d3d12.dll is missing
Having built your application with static Qt, you can get this error trying to launch the application on a different computer:
Запуск программы невозможен, так как на компьютере отсутствует d3d12.dll. Попробуйте переустановить программу.
The program can't start because d3d12.dll is missing from your computer. Try reinstalling the program to fix this problem.
That could be because you might have built Qt on a system with DirectX 12, but this other computer might not have it. To avoid this problem you’ll need to re-configure Qt with -no-feature-d3d12
and re-build it.
Cannot open compiler generated file
That one I got trying to build Qt 5.15.2 on Windows 10, and this problem seems to be specific to Windows only, as it cannot handle paths longer than certain length. The error message is not very descriptive, though:
D:\path\to\qt-everywhere-src-5.15.2\qtbase\src\3rdparty\angle\src\libANGLE\renderer\d3d\d3d11\texture_format_table_autogen.cpp : fatal error C1083: Cannot open compiler generated file: '': Invalid argument
The solution for this is to have sources and build folder somewhere closer to the disk root, such as d:\qt\build
.
Variable has incomplete type struct stat64
I got this one trying to build Qt 5.15.2 on Mac OS 11.2 with Apple silicon processor (so my configuration command had QMAKE_APPLE_DEVICE_ARCHS=arm64
):
In file included from /path/to/qt-everywhere-src-5.15.2/qt3d/src/3rdparty/assimp/contrib/zip/src/zip.c:12:
/path/to/qt-everywhere-src-5.15.2/qt3d/src/3rdparty/assimp/contrib/zip/src/miniz.h:3075:30: error: variable has incomplete type 'struct stat64'
struct MZ_FILE_STAT_STRUCT file_stat;
^
I did not find a solution for this, so I just disabled 3D stuff with -skip qt3d -skip qtquick3d
(I don’t use it anyway). Probably later Qt versions already have a fix for this, but for now I only found this bugreport, and it is still open.
Cannot open input file qwebp.lib
I got this one trying to build Qt 5.15.6 on Windows 11 with MSVC 143 (VS 2022). But I think I also had this problem with 5.15.2 on Windows 10 with MSVC 142 (VS 2019):
fatal error LNK1181: cannot open input file 'D:\path\to\qt\src\5.15.6\build\qtimageformats\plugins\imageformats\qwebp.lib'
I don’t know why it happens and how to resolve it, so I just disabled WebP (yeah, fuck WebP anyway) with -no-webp
configuration option.
Unknown type name CGColorSpaceRef
Got this one trying to build Qt 6.2.0:
In file included from /path/to/qt/src/6.2.0/qtbase/src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.mm:40:
/path/to/qt/src/6.2.0/qtbase/src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.h:56:32: error: unknown type name 'CGColorSpaceRef'; did you mean 'QColorSpace'?
void setColorSpace(QCFType<CGColorSpaceRef> colorSpace);
^~~~~~~~~~~~~~~
QColorSpace
The fix is to edit /path/to/qt/src/6.2.0/qtbase/src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.h
and add missing header CoreGraphics/CGColorSpace.h
:
diff --git a/src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.h b/src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.h
index 5d4b6d6a71..cc7193d8b7 100644
--- a/src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.h
+++ b/src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.h
@@ -43,6 +43,7 @@
#include <qpa/qplatformgraphicsbuffer.h>
#include <private/qcore_mac_p.h>
+#include <CoreGraphics/CGColorSpace.h>
#include <IOSurface/IOSurface.h>
QT_BEGIN_NAMESPACE
Undefined symbols GSSAPI
Started to get this one all of the sudden even with versions that were for sure building fine before:
Undefined symbols for architecture x86_64:
"___gss_c_nt_hostbased_service_oid_desc", referenced from:
qGSsapiGetServiceName(QStringView) in libQt6Network.a(qauthenticator.cpp.o)
That turned out to be caused by vcpkg that I had installed at some point. Apparently, something collides or overlaps somewhere with the things found in VCPKG_ROOT
path. So the workaround is to unset this variable before building Qt (and do a clean build, if you have remains from the previous build):
$ pwd
/path/to/qt/src/6.4.2/build
$ rm -r ./*; rm -r .qt; rm .ninja_*; ls -lah
$ echo $VCPKG_ROOT
/path/to/programs/vcpkg
$ unset VCPKG_ROOT
$ echo $VCPKG_ROOT
$ ../configure -static -release AND-SO-ON
Updates
2021-11-12 | Некоторый итог
Ну что сказать. Я просто труба тех шатал, кто писал документацию на тему. Ни хера нормально не расписано, пердолься сам до посинения, собирай инфу по кусочкам со всего интернета, может чего и получится, но скорее всего нет. Понятно, что Шиндошс не в почёте, и реальные пацаны сидят на Линупсе, но это же документация продукта, который (помимо GPL/LGPL) продаётся за (немаленькие) деньги, так что можно наверное ради такого дела написать на пару строчек побольше?
Да ладно Шиндошс, там и на других платформах полно неочевидных проблем, особенно на ЖМУ/Пинусе. Пытаться собрать статический Qt я начал ну наверное году в 2012, к 2018 у меня это стало в основном получаться и я написал эту статью, но сейчас 2021 год, а я до сих натыкаюсь на проблемы, решение которых надо выискивать по всем интернетам, потому что документация о них скромно умалчивает. Ну и конечно с появлением новых версий Qt появляются новые проблемы со сборкой.
Пиздец нахуй блядь!
2023-09-19 | Qt 5.15.2, Windows 10/11, MinGW x32 from MSYS2
All of a sudden today I needed to do something horrible: I needed to build static Qt 5.15.2 on Windows 10 (and then on Windows 11) x64 host using MinGW x32 toolchain. The Qt version, MinGW and x32 target were strict requirements, so I had to make it work with exactly those.
MSVC x32
First I tried to build static Qt 5.15.2 with MSVC 143 (VS 2022) x32, just to check that it does build at all:
> call "E:\tools\vs\vs2022\VC\Auxiliary\Build\vcvars32.bat"
**********************************************************************
** Visual Studio 2022 Developer Command Prompt v17.5.5
** Copyright (c) 2022 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x86'
> cd e:\tools\qt
> mkdir 5.15.2-static-x32
> cd e:\tools\qt\src\5.15.2
> rmdir /Q /S build
> mkdir build
> cd build
> ..\configure.bat -static -release -no-pch -prefix "e:\tools\qt\5.15.2-static-x32" -skip qtwebengine -nomake tests -nomake examples
> jom
> jom install
> dumpbin ..\..\..\5.15.2-static-x32\lib\Qt5Core.lib /headers | findstr machine
14C machine (x86)
The build went just fine out of the box, I didn’t need to touch the original sources at all.
MinGW x32
And then I started my in-and-out-twenty-minutes-adventure of building static Qt with MinGW.
The very first issue I’ve stumbled upon is: where does one get the MinGW from? Before I was getting it from Qt installer, but I stopped using that anal probe some years ago, so this isn’t an option anymore.
Long story short, I didn’t find a MinGW that would work, as apparently just MinGW alone is not enough, because I was getting errors like:
error: 'KEY_WOW64_32KEY' was not declared in this scope
error: '_popen' was not declared in this scope
error: '_pclose' was not declared in this scope
And so apparently one needs to have some environment for it to run in, and one such environment is MSYS2. I do have Git BASH too, but there was something still missing there.
So, download MSYS2 installer, install it and, as we are targeting x32 build, launch /path/to/msys2/mingw32.exe
. Then, based on these instructions, update the system packages:
Yes, to my surprise, it uses a proper package manager (that being pacman), which certainly helps with getting the right stuff.
That command will eventually close the MSYS2 terminal during the update, so launch it again (/path/to/msys2/mingw32.exe
) and repeat the last command to finish the update.
Then install MinGW x32 toolchain (if you’ll later need x64 toolchain, that one is available as mingw-w64-x86_64-toolchain
):
$ pacman -S mingw-w64-i686-toolchain
:: There are 19 members in group mingw-w64-i686-toolchain:
:: Repository mingw32
1) mingw-w64-i686-binutils 2) mingw-w64-i686-crt-git 3) mingw-w64-i686-gcc 4) mingw-w64-i686-gcc-ada 5) mingw-w64-i686-gcc-fortran 6) mingw-w64-i686-gcc-libgfortran 7) mingw-w64-i686-gcc-libs
8) mingw-w64-i686-gcc-objc 9) mingw-w64-i686-gdb 10) mingw-w64-i686-gdb-multiarch 11) mingw-w64-i686-headers-git 12) mingw-w64-i686-libgccjit 13) mingw-w64-i686-libmangle-git
14) mingw-w64-i686-libwinpthread-git 15) mingw-w64-i686-make 16) mingw-w64-i686-pkgconf 17) mingw-w64-i686-tools-git 18) mingw-w64-i686-winpthreads-git 19) mingw-w64-i686-winstorecompat-git
I got the following versions after the installation was done:
$ pacman -Qe
base 2022.06-1
filesystem 2023.02.07-1
mingw-w64-i686-binutils 2.41-2
mingw-w64-i686-crt-git 11.0.0.r159.g0605217f5-1
mingw-w64-i686-gcc 13.2.0-2
mingw-w64-i686-gcc-ada 13.2.0-2
mingw-w64-i686-gcc-fortran 13.2.0-2
mingw-w64-i686-gcc-libgfortran 13.2.0-2
mingw-w64-i686-gcc-libs 13.2.0-2
mingw-w64-i686-gcc-objc 13.2.0-2
mingw-w64-i686-gdb 13.2-3
mingw-w64-i686-gdb-multiarch 13.2-3
mingw-w64-i686-headers-git 11.0.0.r159.g0605217f5-1
mingw-w64-i686-libgccjit 13.2.0-2
mingw-w64-i686-libmangle-git 11.0.0.r159.g0605217f5-1
mingw-w64-i686-libwinpthread-git 11.0.0.r159.g0605217f5-1
mingw-w64-i686-make 4.4-2
mingw-w64-i686-pkgconf 1~2.0.3-1
mingw-w64-i686-tools-git 11.0.0.r159.g0605217f5-1
mingw-w64-i686-winpthreads-git 11.0.0.r159.g0605217f5-1
mingw-w64-i686-winstorecompat-git 11.0.0.r159.g0605217f5-1
msys2-runtime 3.4.9-2
Check that the tools are available:
$ gcc --version
gcc.exe (Rev2, Built by MSYS2 project) 13.2.0
Copyright (C) 2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ g++ --version
g++.exe (Rev2, Built by MSYS2 project) 13.2.0
Copyright (C) 2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ mingw32-make.exe --version
GNU Make 4.4
Built for Windows32
Copyright (C) 1988-2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Set an “alias” for make
:
$ export MAKE="mingw32-make"
…otherwise it will fail complaining that there is no make
available:
You don't seem to have 'make' or 'gmake' in your PATH.
Cannot proceed.
Configure Qt:
$ cd /e/tools/qt
$ mkdir 5.15.2-static-x32-mingw
$ cd /e/tools/qt/src/5.15.2
$ rm -r ./build
$ mkdir build && cd $_
$ ../configure -static -release -no-pch -prefix "e:/tools/qt/5.15.2-static-x32-mingw" \
-platform win32-g++ -skip qtwebengine -nomake tests -nomake examples
The -platform win32-g++
is important, otherwise you’ll get:
The build script does not currently recognize all
platforms supported by Qt.
Rerun this script with a -platform option listed to
set the system/compiler combination you use.
Anyway, the configuration will fail like this:
In file included from E:/tools/qt/src/5.15.2/qtbase/include/QtCore/qfloat16.h:1,
from E:/tools/qt/src/5.15.2/qtbase/src/corelib/global/qendian.h:44,
from E:/tools/qt/src/5.15.2/qtbase/include/QtCore/qendian.h:1,
from E:/tools/qt/src/5.15.2/qtbase/src/corelib/codecs/qutfcodec.cpp:43:
E:/tools/qt/src/5.15.2/qtbase/src/corelib/global/qfloat16.h:300:7: error: 'numeric_limits' is not a class template
300 | class numeric_limits<QT_PREPEND_NAMESPACE(qfloat16)> : public numeric_limits<float>
To fix that, add #include <limits>
to e:/tools/qt/src/5.15.2/qtbase/src/corelib/global/qfloat16.h
and e:/tools/qt/src/5.15.2/qtbase/src/corelib/text/qbytearraymatcher.h
and run configuration again. Then it should configure, but there will likely be a warning about OpenGL:
WARNING: Using OpenGL ES 2.0 on Windows without ANGLE.
The build will most likely fail.
Specify -opengl desktop to use regular OpenGL.
So add that option (-opengl desktop
) to the configure command and run it again. Then it should succeed for good. Here’s my configuration output, just in case:
Build type: win32-g++ (i386, CPU features: mmx sse sse2)
Compiler: gcc 13.2.0
Configuration: sse2 aesni sse3 ssse3 sse4_1 sse4_2 avx avx2 avx512f avx512bw avx512cd avx512dq avx512er avx512ifma avx512pf avx512vbmi avx512vl compile_examples f16c largefile rdrnd rdseed shani x86SimdAlways release c++11 c++14 c++17 c++1z concurrent dbus no-pkg-config static stl
Build options:
Mode ................................... release
Optimize release build for size ........ no
Building shared libraries .............. no
Using C standard ....................... C11
Using C++ standard ..................... C++17
Relocatable ............................ no
Using precompiled headers .............. no
Using LTCG ............................. no
Target compiler supports:
SSE .................................. SSE2 SSE3 SSSE3 SSE4.1 SSE4.2
AVX .................................. AVX AVX2
AVX512 ............................... F ER CD PF DQ BW VL IFMA VBMI
Other x86 ............................ AES F16C RDRAND SHA
Intrinsics without -mXXX option ...... yes
Build parts ............................ libs tools
App store compliance ................... no
Qt modules and options:
Qt Concurrent .......................... yes
Qt D-Bus ............................... yes
Qt D-Bus directly linked to libdbus .... no
Qt Gui ................................. yes
Qt Network ............................. yes
Qt Sql ................................. yes
Qt Testlib ............................. yes
Qt Widgets ............................. yes
Qt Xml ................................. yes
Support enabled for:
Using pkg-config ....................... no
udev ................................... no
Using system zlib ...................... yes
Zstandard support ...................... yes
Qt Core:
DoubleConversion ....................... yes
Using system DoubleConversion ........ no
GLib ................................... no
iconv .................................. no
ICU .................................... no
Built-in copy of the MIME database ..... yes
Tracing backend ........................ <none>
Logging backends:
journald ............................. no
syslog ............................... no
slog2 ................................ no
PCRE2 .................................. yes
Using system PCRE2 ................... no
Qt Network:
getifaddrs() ........................... no
IPv6 ifname ............................ no
libproxy ............................... no
Schannel ............................... no
OpenSSL ................................ yes
Qt directly linked to OpenSSL ........ no
OpenSSL 1.1 ............................ yes
DTLS ................................... yes
OCSP-stapling .......................... yes
SCTP ................................... no
Use system proxies ..................... yes
GSSAPI ................................. no
Qt Gui:
Accessibility .......................... yes
FreeType ............................... yes
Using system FreeType ................ no
HarfBuzz ............................... yes
Using system HarfBuzz ................ no
Fontconfig ............................. no
Image formats:
GIF .................................. yes
ICO .................................. yes
JPEG ................................. yes
Using system libjpeg ............... no
PNG .................................. yes
Using system libpng ................ no
Text formats:
HtmlParser ........................... yes
CssParser ............................ yes
OdfWriter ............................ yes
MarkdownReader ....................... yes
Using system libmd4c ............... no
MarkdownWriter ....................... yes
EGL .................................... no
OpenVG ................................. no
OpenGL:
ANGLE ................................ no
Desktop OpenGL ....................... yes
Dynamic OpenGL ....................... no
OpenGL ES 2.0 ........................ no
OpenGL ES 3.0 ........................ no
OpenGL ES 3.1 ........................ no
OpenGL ES 3.2 ........................ no
Vulkan ................................. yes
Session Management ..................... yes
Features used by QPA backends:
evdev .................................. no
libinput ............................... no
INTEGRITY HID .......................... no
mtdev .................................. no
tslib .................................. no
xkbcommon .............................. no
X11 specific:
XLib ................................. no
XCB Xlib ............................. no
EGL on X11 ........................... no
xkbcommon-x11 ........................ no
QPA backends:
DirectFB ............................... no
EGLFS .................................. no
LinuxFB ................................ no
VNC .................................... no
Windows:
Direct 2D ............................ yes
DirectWrite .......................... yes
DirectWrite 2 ........................ yes
Qt Sql:
SQL item models ........................ yes
Qt Widgets:
GTK+ ................................... no
Styles ................................. Fusion Windows WindowsVista
Qt PrintSupport:
CUPS ................................... no
Qt Sql Drivers:
DB2 (IBM) .............................. no
InterBase .............................. no
MySql .................................. no
OCI (Oracle) ........................... no
ODBC ................................... yes
PostgreSQL ............................. no
SQLite2 ................................ no
SQLite ................................. yes
Using system provided SQLite ......... no
TDS (Sybase) ........................... no
Qt Testlib:
Tester for item models ................. yes
Serial Port:
ntddmodm ............................... yes
Qt SerialBus:
Socket CAN ............................. no
Socket CAN FD .......................... no
SerialPort Support ..................... yes
Further Image Formats:
JasPer ................................. no
MNG .................................... no
TIFF ................................... yes
Using system libtiff ................. no
WEBP ................................... yes
Using system libwebp ................. no
Qt QML:
QML network support .................... yes
QML debugging and profiling support .... yes
QML just-in-time compiler .............. yes
QML sequence object .................... yes
QML XML http request ................... yes
QML Locale ............................. yes
Qt QML Models:
QML list model ......................... yes
QML delegate model ..................... yes
Qt Quick:
Direct3D 12 ............................ yes
AnimatedImage item ..................... yes
Canvas item ............................ yes
Support for Qt Quick Designer .......... yes
Flipable item .......................... yes
GridView item .......................... yes
ListView item .......................... yes
TableView item ......................... yes
Path support ........................... yes
PathView item .......................... yes
Positioner items ....................... yes
Repeater item .......................... yes
ShaderEffect item ...................... yes
Sprite item ............................ yes
QtQuick3D:
Assimp ................................. yes
System Assimp .......................... no
Qt Scxml:
ECMAScript data model for QtScxml ...... yes
Qt Gamepad:
SDL2 ................................... no
Qt 3D:
Assimp ................................. yes
System Assimp .......................... no
Output Qt3D GL traces .................. no
Use SSE2 instructions .................. no
Use AVX2 instructions .................. no
Aspects:
Render aspect ........................ yes
Input aspect ......................... yes
Logic aspect ......................... yes
Animation aspect ..................... yes
Extras aspect ........................ yes
Qt 3D Renderers:
OpenGL Renderer ........................ yes
RHI Renderer ........................... no
Qt 3D GeometryLoaders:
Autodesk FBX ........................... no
Qt Wayland Client ........................ no
Qt Wayland Compositor .................... no
Qt Bluetooth:
BlueZ .................................. no
BlueZ Low Energy ....................... no
Linux Crypto API ....................... no
Native Win32 Bluetooth ................. no
WinRT Bluetooth API (desktop & UWP) .... no
WinRT advanced bluetooth low energy API (desktop & UWP) . no
Qt Sensors:
sensorfw ............................... no
Qt Quick Controls 2:
Styles ................................. Default Fusion Imagine Material Universal
Qt Quick Templates 2:
Hover support .......................... yes
Multi-touch support .................... yes
Qt Positioning:
Gypsy GPS Daemon ....................... no
WinRT Geolocation API .................. no
Qt Location:
Qt.labs.location experimental QML plugin . yes
Geoservice plugins:
OpenStreetMap ........................ yes
HERE ................................. yes
Esri ................................. yes
Mapbox ............................... yes
MapboxGL ............................. yes
Itemsoverlay ......................... yes
QtXmlPatterns:
XML schema support ..................... yes
Qt Multimedia:
ALSA ................................... no
GStreamer 1.0 .......................... no
GStreamer 0.10 ......................... no
Video for Linux ........................ no
OpenAL ................................. no
PulseAudio ............................. no
Resource Policy (libresourceqt5) ....... no
Windows Audio Services ................. no
DirectShow ............................. yes
Windows Media Foundation ............... yes
Qt TextToSpeech:
Flite .................................. no
Flite with ALSA ........................ no
Speech Dispatcher ...................... no
Qt Tools:
Qt Assistant ........................... yes
Qt Designer ............................ yes
Qt Distance Field Generator ............ yes
kmap2qmap .............................. yes
Qt Linguist ............................ yes
Mac Deployment Tool .................... no
makeqpf ................................ yes
pixeltool .............................. yes
qdbus .................................. yes
qev .................................... yes
Qt Attributions Scanner ................ yes
qtdiag ................................. yes
qtpaths ................................ yes
qtplugininfo ........................... yes
Windows deployment tool ................ yes
WinRT Runner Tool ...................... no
Qt Tools:
QDoc ................................... no
Note: Using static linking will disable the use of dynamically
loaded plugins. Make sure to import all needed static plugins,
or compile needed modules into the library.
Note: No wayland-egl support detected. Cross-toolkit compatibility disabled.
WARNING: QDoc will not be compiled, probably because libclang could not be located. This means that you cannot build the Qt documentation.
Either ensure that llvm-config is in your PATH environment variable, or set LLVM_INSTALL_DIR to the location of your llvm installation.
On Linux systems, you may be able to install libclang by installing the libclang-dev or libclang-devel package, depending on your distribution.
On macOS, you can use Homebrew's llvm package.
On Windows, you must set LLVM_INSTALL_DIR to the installation path.
Qt is now configured for building. Just run 'mingw32-make'.
Once everything is built, you must run 'mingw32-make install'.
Qt will be installed into 'e:\tools\qt\5.15.2-static-x32-mingw'.
Prior to reconfiguration, make sure you remove any leftovers from
the previous build.
You can now try to build it:
But soon enough it will fail with this:
E:/tools/qt/src/5.15.2/qtactiveqt/src/activeqt/control/qaxfactory.h:85:32:E:/tools/qt/src/5.15.2/qtdeclarative/src/3rdparty/masm/yarr/Yarr.h:46:44: note: error: by ''virtual const QMetaObject* QAxFactory::numeric_limitsmetaObject' is not a member of '(const QString&) conststd'
85 | virtual const QMetaObject *'
46 | static const unsigned offsetNoMatch = std::metaObjectnumeric_limits(const QString &key) const = 0;
| <unsigned>::max();
| ^~~~~~~~~~^~~~~~~~~~~~~~
E:/tools/qt/src/5.15.2/qtdeclarative/src/3rdparty/masm/yarr/Yarr.h:46:59: error: expected primary-expression before 'unsigned'
46 | static const unsigned offsetNoMatch = std::numeric_limits<unsigned>::max();
| ^~~~~~~~
You can try to reconfigure Qt with -c++std c++11
(and check that it now has C++11
in the configuration summary) and try building again. I’d actually recommend to use exactly C++11 standard, since it’s a rather old Qt version, and probably it is to be expected to encounter more errors trying to compile with C++17.
With C++11 standard the error will still be there, but a little bit different:
E:/tools/qt/src/5.15.2/qtdeclarative/src/3rdparty/masm/yarr/Yarr.h:46:44: error: 'numeric_limits' is not a member of 'std'
46 | static const unsigned offsetNoMatch = std::numeric_limits<unsigned>::max();
| ^~~~~~~~~~~~~~
E:/tools/qt/src/5.15.2/qtdeclarative/src/3rdparty/masm/yarr/Yarr.h:46:59: error: expected primary-expression before 'unsigned'
46 | static const unsigned offsetNoMatch = std::numeric_limits<unsigned>::max();
| ^~~~~~~~
…which is actually the same error that we already saw during configuration, so add #include <limits>
to /e/tools/qt/src/5.15.2/qtdeclarative/src/3rdparty/masm/yarr/Yarr.h
too and… except that it is already there. But actually it’s not, because it’s wrong: you need to replace #include <limits.h>
with #include <limits>
. Then try building again.
It will proceed, but will fail with a different error later:
mingw32-make[6]: Entering directory 'E:/tools/qt/src/5.15.2/build/qtdeclarative/src/plugins/scenegraph/d3d12'
fxc.exe /nologo /E VS_VertexColor /T vs_5_0 /Fh vs_vertexcolor.hlslh E:/tools/qt/src/5.15.2/qtdeclarative/src/plugins/scenegraph/d3d12/shaders/vertexcolor.hlsl
process_begin: CreateProcess(NULL, fxc.exe /nologo /E VS_VertexColor /T vs_5_0 /Fh vs_vertexcolor.hlslh E:/tools/qt/src/5.15.2/qtdeclarative/src/plugins/scenegraph/d3d12/shaders/vertexcolor.hlsl, ...) failed.
make (e=2): The system cannot find the file specified.
This one is about not finding fxc.exe
, as it seems, which you should have somewhere in your variant of e:\Windows Kits\10\bin\10.0.20348.0\x86\fxc.exe
(use the x86 version, since we are in x32). So add it to PATH
and try again:
$ export PATH=/e/Windows\ Kits/10/bin/10.0.20348.0/x86:$PATH
$ mingw32-make -j 16
And indeed, that helps it to proceed further. But then I got this weird error on Windows 11:
E:/tools/qt/src/5.15.2/build/qtdeclarative/src/imports/testlib/qmltyperegistrar_wrapper.sh: line 6: E:\tools\qt\src\5.15.2\build\qtdeclarative\bin\qmltyperegistrar.exe: Bad address
E:/tools/qt/src/5.15.2/build/qtdeclarative/src/imports/testlib/qmltyperegistrar_wrapper.sh: line 6: E:\tools\qt\src\5.15.2\build\qtdeclarative\bin\qmltyperegistrar.exe: No error
mingw32-make[5]: *** [Makefile.Release:145: qmltestplugin_qmltyperegistrations.cpp] Error 126
What the fuck is this shit. And I didn’t get it on Windows 10, by the way. I googled for that one and found the following workaround:
$ export MSYS2_ARG_CONV_EXCL='*'
Then the build continues. But! When I needed to build the whole thing again after cleaning the build
folder, the configuration suddenly failed like this:
Preparing build tree...
Creating qmake....................................................................................................Done.
Cannot find file: \e\tools\qt\src\5.15.2.
Good thing I remembered exporting this variable, so I unset it:
$ unset MSYS2_ARG_CONV_EXCL
and re-run the configuration, and then it succeeded. And then I exported that variable again, since it does resolve the qmltyperegistrar
error.
Anyway, coming back to the build at hand, after that it failed with several other errors:
E:/tools/qt/src/5.15.2/qtdeclarative/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp:241:60: error: '_uuidof' was not declared in this scope
241 | if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), fl, _uuidof(ID3D12Device), nullptr))) {
| ^~~~~~~
E:/tools/qt/src/5.15.2/qtdeclarative/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp: In member function 'virtual void QSGD3D12ShaderCompileTask::run()':
E:/tools/qt/src/5.15.2/qtdeclarative/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp:785:54: warning: format '%x' expects argument of type 'unsigned int', but argument 3 has type 'HRESULT' {aka 'long int'} [-Wformat=]
785 | qWarning("HLSL shader compilation failed: 0x%x", hr);
| ~^ ~~
| | |
| | HRESULT {aka long int}
| unsigned int
| %lx
E:/tools/qt/src/5.15.2/qtdeclarative/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp: In member function 'bool QSGD3D12GuiThreadShaderEffectManager::reflect(QSGGuiThreadShaderEffectManager::ShaderInfo*)':
E:/tools/qt/src/5.15.2/qtdeclarative/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp:857:52: warning: format '%x' expects argument of type 'unsigned int', but argument 3 has type 'HRESULT' {aka 'long int'} [-Wformat=]
857 | qWarning("D3D shader reflection failed: 0x%x", hr);
| ~^ ~~
| | |
| | HRESULT {aka long int}
| unsigned int
| %lx
E:/tools/qt/src/5.15.2/qtdeclarative/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp: In member function 'void QSGD3D12EnginePrivate::initialize(WId, const QSize&, float, int, bool)':
E:/tools/qt/src/5.15.2/qtdeclarative/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp:758:16: error: 'ID3D12Debug' was not declared in this scope; did you mean 'ID3D10Debug'?
758 | ComPtr<ID3D12Debug> debugController;
| ^~~~~~~~~~~
| ID3D10Debug
E:/tools/qt/src/5.15.2/qtdeclarative/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp:758:27: error: template argument 1 is invalid
758 | ComPtr<ID3D12Debug> debugController;
| ^
E:/tools/qt/src/5.15.2/qtdeclarative/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp:759:46: error: invalid type argument of unary '*' (have 'int')
759 | if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController))))
| ^~~~~~~~~~~~
E:/tools/qt/src/5.15.2/qtdeclarative/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp:759:46: error: no matching function for call to '__mingw_uuidof<<expression error> >()'
759 | if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController))))
| ^~~~~~~~~~~~
To fix those edit e:\tools\qt\src\5.15.2\qtdeclarative\src\plugins\scenegraph\d3d12\qsgd3d12engine.cpp
:
// ...
#include <d3d12sdklayers.h>
// ...
//HRESULT hr = D3D12CreateDevice(adapter.Get(), fl, _uuidof(ID3D12Device), nullptr);
HRESULT hr = D3D12CreateDevice(adapter.Get(), fl, __uuidof(ID3D12Device), nullptr);
//if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), fl, _uuidof(ID3D12Device), nullptr))) {
if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), fl, __uuidof(ID3D12Device), nullptr))) {
// ...
…or you could probably just reconfigure Qt with -no-feature-d3d12
, especially if you or/and your users will be building applications for running on machines without DirectX 12.
Trying to continue the build, you’ll get this one again:
E:/tools/qt/src/5.15.2/qtdeclarative/src/qmldebug/qqmlprofilerevent_p.h:314:65: error: 'numeric_limits' is not a member of std
Add #include <limits>
to e:/tools/qt/src/5.15.2/qtdeclarative/src/qmldebug/qqmlprofilerevent_p.h
too.
Then it will proceed, but will fail with something else later:
E:/tools/qt/src/5.15.2/qtconnectivity/src/bluetooth/qbluetoothservicediscoveryagent_win.cpp:276:43: error: invalid conversion from 'BOOL (*)(ULONG, LPBYTE, ULONG, LPVOID)' {aka 'int (*)(long unsigned int, unsigned char*, long unsigned in
{aka 'int (__attribute__((stdcall)) *)(long unsigned int, unsigned char*, long unsigned int, void*)'} [-fpermissive]
276 | bluetoothSdpCallback,
| ^~~~~~~~~~~~~~~~~~~~
| |
| BOOL (*)(ULONG, LPBYTE, ULONG, LPVOID) {aka int (*)(long unsigned int, unsigned char*, long unsigned int, void*)}
Patch for that problem is here. I would have never figured it out on my own. Apply the changes and continue the build.
Next error will be this:
E:/tools/qt/src/5.15.2/qtmultimedia/src/plugins/wmf/player/mfvideorenderercontrol.cpp:2334:68: error: 'virtual void {anonymous}::MediaStream::customEvent(QEvent*)' is protected within this context
2334 | static_cast<MediaStream*>(childEvent->child())->customEvent(event);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~
Patch for this problem is here. Again, it is very unlikely that I would ever be able to figure it out myself. Apply the changes and continue.
And then it fucking finally builds to the end! To make sure that it did in fact succeed, check the exit code:
If it is non-zero but the build has finished without printing any errors in the end, run the build again, first with -j
and check the exit code, and if it is still non-zero, then try yet again but this time without -j
, so it would stop on the first error without spamming the output with other jobs leftovers.
Anyway, mine has succeeded, but at some point later I realized that I forgot to add configuration option for the static runtime, so I needed to reconfigure and rebuild again. And so the final configure command with all the additions is now this:
$ ../configure -static -release -no-pch -prefix "e:/tools/qt/5.15.2-static-x32-mingw" \
-platform win32-g++ -skip qtwebengine -nomake tests -nomake examples \
-opengl desktop -c++std c++11 -static-runtime -no-feature-d3d12
And also just in case here’s a diff
output for all the changes to the original Qt sources that I had to make in order to build static Qt 5.15.2 with MinGW.
If you are curious, the build time on Intel Core i9-9900K CPU with 8/16 cores was about 31 minute (30:47).
Using the MinGW build in Qt Creator
Let’s now add this build to Qt Creator and try to use it.
First add C and C++ compilers (note the ABI value, it should auto-detect when you’ll browse for gcc
and g++
executables):
Then debugger:
Then the Qt version that you’ve just built:
And finally the kit:
As for the application to be built with this kit, of course we’ll take Color Corners.
With qmake
First I tried to build it with qmake (by the way, just look at how big that project file is (4 lines) in comparison with CMake (bloody 157 lines)).
Configuration and build output:
15:06:27: Running steps for project color-corners...
15:06:27: Starting: "E:\tools\qt\5.15.2-static-x32-mingw\bin\qmake.exe" E:\code\color-corners\color-corners.pro -spec win32-g++ "CONFIG+=qtquickcompiler"
Info: creating stash file E:\code\color-corners\build\color-corners-Qt_5_15_2_x32_MinGW-Release\.qmake.stash
15:06:28: The process "E:\tools\qt\5.15.2-static-x32-mingw\bin\qmake.exe" exited normally.
15:06:28: Starting: "E:\tools\msys2\mingw32\bin\mingw32-make.exe" -f E:/code/color-corners/build/color-corners-Qt_5_15_2_x32_MinGW-Release/Makefile qmake_all
mingw32-make: Nothing to be done for 'qmake_all'.
15:06:28: The process "E:\tools\msys2\mingw32\bin\mingw32-make.exe" exited normally.
15:06:28: Starting: "E:\tools\msys2\mingw32\bin\mingw32-make.exe" -j16
E:/tools/msys2/mingw32/bin/mingw32-make.exe -f Makefile.Release
mingw32-make[1]: Entering directory 'E:/code/color-corners/build/color-corners-Qt_5_15_2_x32_MinGW-Release'
g++ -c -fno-keep-inline-dllexport -O2 -Wall -Wextra -Wextra -ffunction-sections -fdata-sections -fexceptions -mthreads -DUNICODE -D_UNICODE -DWIN32 -DMINGW_HAS_SECURE_API=1 -DQT_NO_DEBUG -DQT_QUICK_LIB -DQT_GUI_LIB -DQT_QMLMODELS_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN -I../../../color-corners -I. -I../../../../tools/qt/5.15.2-static-x32-mingw/include -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtQuick -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtGui -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtQmlModels -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtQml -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtNetwork -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtCore -Irelease -IE:/tools/vulkan-sdk/include -I../../../../tools/qt/5.15.2-static-x32-mingw/mkspecs/win32-g++ -o release/main.o ../../main.cpp
g++ -c -fno-keep-inline-dllexport -O2 -Wall -Wextra -Wextra -ffunction-sections -fdata-sections -fexceptions -mthreads -DUNICODE -D_UNICODE -DWIN32 -DMINGW_HAS_SECURE_API=1 -DQT_NO_DEBUG -DQT_QUICK_LIB -DQT_GUI_LIB -DQT_QMLMODELS_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN -I../../../color-corners -I. -I../../../../tools/qt/5.15.2-static-x32-mingw/include -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtQuick -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtGui -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtQmlModels -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtQml -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtNetwork -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtCore -Irelease -IE:/tools/vulkan-sdk/include -I../../../../tools/qt/5.15.2-static-x32-mingw/mkspecs/win32-g++ -o release/color-corners_plugin_import.o E:/code/color-corners/build/color-corners-Qt_5_15_2_x32_MinGW-Release/color-corners_plugin_import.cpp
g++ -c -fno-keep-inline-dllexport -O2 -Wall -Wextra -Wextra -ffunction-sections -fdata-sections -fexceptions -mthreads -DUNICODE -D_UNICODE -DWIN32 -DMINGW_HAS_SECURE_API=1 -DQT_NO_DEBUG -DQT_QUICK_LIB -DQT_GUI_LIB -DQT_QMLMODELS_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN -I../../../color-corners -I. -I../../../../tools/qt/5.15.2-static-x32-mingw/include -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtQuick -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtGui -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtQmlModels -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtQml -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtNetwork -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtCore -Irelease -IE:/tools/vulkan-sdk/include -I../../../../tools/qt/5.15.2-static-x32-mingw/mkspecs/win32-g++ -o release/color-corners_qml_plugin_import.o E:/code/color-corners/build/color-corners-Qt_5_15_2_x32_MinGW-Release/color-corners_qml_plugin_import.cpp
'E:\tools\qt\5.15.2-static-x32-mingw\bin\qmlcachegen.exe' --resource=E:/code/color-corners/qml.qrc -o release/main_qml.cpp ../../main.qml
'E:\tools\qt\5.15.2-static-x32-mingw\bin\qmlcachegen.exe' --resource-file-mapping=E:/code/color-corners/qml.qrc=E:/code/color-corners/build/color-corners-Qt_5_15_2_x32_MinGW-Release/qml_qmlcache.qrc -o release/qmlcache_loader.cpp ../../qml.qrc
'E:\tools\qt\5.15.2-static-x32-mingw\bin\rcc.exe' -name qml_qmlcache qml_qmlcache.qrc -o release/qrc_qml_qmlcache.cpp
g++ -c -fno-keep-inline-dllexport -O2 -Wall -Wextra -Wextra -ffunction-sections -fdata-sections -fexceptions -mthreads -DUNICODE -D_UNICODE -DWIN32 -DMINGW_HAS_SECURE_API=1 -DQT_NO_DEBUG -DQT_QUICK_LIB -DQT_GUI_LIB -DQT_QMLMODELS_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN -I../../../color-corners -I. -I../../../../tools/qt/5.15.2-static-x32-mingw/include -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtQuick -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtGui -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtQmlModels -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtQml -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtNetwork -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtCore -Irelease -IE:/tools/vulkan-sdk/include -I../../../../tools/qt/5.15.2-static-x32-mingw/mkspecs/win32-g++ -o release/main_qml.o release/main_qml.cpp
g++ -c -fno-keep-inline-dllexport -O2 -Wall -Wextra -Wextra -ffunction-sections -fdata-sections -fexceptions -mthreads -DUNICODE -D_UNICODE -DWIN32 -DMINGW_HAS_SECURE_API=1 -DQT_NO_DEBUG -DQT_QUICK_LIB -DQT_GUI_LIB -DQT_QMLMODELS_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN -I../../../color-corners -I. -I../../../../tools/qt/5.15.2-static-x32-mingw/include -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtQuick -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtGui -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtQmlModels -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtQml -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtNetwork -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtCore -Irelease -IE:/tools/vulkan-sdk/include -I../../../../tools/qt/5.15.2-static-x32-mingw/mkspecs/win32-g++ -o release/qmlcache_loader.o release/qmlcache_loader.cpp
g++ -c -fno-keep-inline-dllexport -O2 -Wall -Wextra -Wextra -ffunction-sections -fdata-sections -fexceptions -mthreads -DUNICODE -D_UNICODE -DWIN32 -DMINGW_HAS_SECURE_API=1 -DQT_NO_DEBUG -DQT_QUICK_LIB -DQT_GUI_LIB -DQT_QMLMODELS_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN -I../../../color-corners -I. -I../../../../tools/qt/5.15.2-static-x32-mingw/include -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtQuick -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtGui -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtQmlModels -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtQml -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtNetwork -I../../../../tools/qt/5.15.2-static-x32-mingw/include/QtCore -Irelease -IE:/tools/vulkan-sdk/include -I../../../../tools/qt/5.15.2-static-x32-mingw/mkspecs/win32-g++ -o release/qrc_qml_qmlcache.o release/qrc_qml_qmlcache.cpp
g++ -Wl,-s -static -Wl,--gc-sections -Wl,-subsystem,windows -mthreads -o release/color-corners.exe release/main.o release/color-corners_plugin_import.o release/color-corners_qml_plugin_import.o release/main_qml.o release/qmlcache_loader.o release/qrc_qml_qmlcache.o E:/tools/qt/5.15.2-static-x32-mingw/plugins/platforms/libqwindows.a -ldwmapi -lwinspool -lshlwapi -lwtsapi32 E:/tools/qt/5.15.2-static-x32-mingw/lib/libQt5EventDispatcherSupport.a E:/tools/qt/5.15.2-static-x32-mingw/lib/libQt5FontDatabaseSupport.a E:/tools/qt/5.15.2-static-x32-mingw/lib/libqtfreetype.a -ldwrite -ld2d1 E:/tools/qt/5.15.2-static-x32-mingw/lib/libQt5ThemeSupport.a E:/tools/qt/5.15.2-static-x32-mingw/lib/libQt5AccessibilitySupport.a E:/tools/qt/5.15.2-static-x32-mingw/lib/libQt5VulkanSupport.a E:/tools/qt/5.15.2-static-x32-mingw/lib/libQt5WindowsUIAutomationSupport.a E:/tools/qt/5.15.2-static-x32-mingw/plugins/imageformats/libqgif.a E:/tools/qt/5.15.2-static-x32-mingw/plugins/imageformats/libqicns.a E:/tools/qt/5.15.2-static-x32-mingw/plugins/imageformats/libqico.a E:/tools/qt/5.15.2-static-x32-mingw/plugins/imageformats/libqjpeg.a E:/tools/qt/5.15.2-static-x32-mingw/plugins/imageformats/libqtga.a E:/tools/qt/5.15.2-static-x32-mingw/plugins/imageformats/libqtiff.a E:/tools/qt/5.15.2-static-x32-mingw/plugins/imageformats/libqwbmp.a E:/tools/qt/5.15.2-static-x32-mingw/plugins/imageformats/libqwebp.a E:/tools/qt/5.15.2-static-x32-mingw/plugins/qmltooling/libqmldbg_debugger.a E:/tools/qt/5.15.2-static-x32-mingw/plugins/qmltooling/libqmldbg_inspector.a E:/tools/qt/5.15.2-static-x32-mingw/plugins/qmltooling/libqmldbg_local.a E:/tools/qt/5.15.2-static-x32-mingw/plugins/qmltooling/libqmldbg_messages.a E:/tools/qt/5.15.2-static-x32-mingw/plugins/qmltooling/libqmldbg_native.a E:/tools/qt/5.15.2-static-x32-mingw/plugins/qmltooling/libqmldbg_nativedebugger.a E:/tools/qt/5.15.2-static-x32-mingw/plugins/qmltooling/libqmldbg_preview.a E:/tools/qt/5.15.2-static-x32-mingw/plugins/qmltooling/libqmldbg_profiler.a E:/tools/qt/5.15.2-static-x32-mingw/plugins/qmltooling/libqmldbg_quickprofiler.a E:/tools/qt/5.15.2-static-x32-mingw/plugins/qmltooling/libqmldbg_server.a E:/tools/qt/5.15.2-static-x32-mingw/lib/libQt5PacketProtocol.a E:/tools/qt/5.15.2-static-x32-mingw/plugins/qmltooling/libqmldbg_tcp.a E:/tools/qt/5.15.2-static-x32-mingw/plugins/bearer/libqgenericbearer.a E:/tools/qt/5.15.2-static-x32-mingw/qml/QtQuick.2/libqtquick2plugin.a E:/tools/qt/5.15.2-static-x32-mingw/qml/QtQuick/Window.2/libwindowplugin.a E:/tools/qt/5.15.2-static-x32-mingw/qml/QtQuick/Layouts/libqquicklayoutsplugin.a E:/tools/qt/5.15.2-static-x32-mingw/lib/libQt5Quick.a E:/tools/qt/5.15.2-static-x32-mingw/lib/libQt5Gui.a -ld3d11 -ldxgi -ldxguid E:/tools/qt/5.15.2-static-x32-mingw/lib/libqtlibpng.a E:/tools/qt/5.15.2-static-x32-mingw/lib/libqtharfbuzz.a -lcomdlg32 -loleaut32 -limm32 -lglu32 -lopengl32 -lgdi32 E:/tools/qt/5.15.2-static-x32-mingw/qml/QtQml/libqmlplugin.a E:/tools/qt/5.15.2-static-x32-mingw/qml/QtQml/Models.2/libmodelsplugin.a E:/tools/qt/5.15.2-static-x32-mingw/lib/libQt5QmlModels.a E:/tools/qt/5.15.2-static-x32-mingw/qml/QtQml/WorkerScript.2/libworkerscriptplugin.a E:/tools/qt/5.15.2-static-x32-mingw/lib/libQt5QmlWorkerScript.a E:/tools/qt/5.15.2-static-x32-mingw/lib/libQt5Qml.a E:/tools/qt/5.15.2-static-x32-mingw/lib/libQt5Network.a -ldnsapi -liphlpapi -lcrypt32 E:/tools/qt/5.15.2-static-x32-mingw/lib/libQt5Core.a -lmpr -luserenv -lversion -lz E:/tools/qt/5.15.2-static-x32-mingw/lib/libqtpcre2.a -lzstd -lnetapi32 -lws2_32 -ladvapi32 -lkernel32 -lole32 -lshell32 -luuid -luser32 -lwinmm -lglu32 -lopengl32 -lgdi32 -luser32 -lmingw32 E:/tools/qt/5.15.2-static-x32-mingw/lib/libqtmain.a -lshell32
mingw32-make[1]: Leaving directory 'E:/code/color-corners/build/color-corners-Qt_5_15_2_x32_MinGW-Release'
15:06:32: The process "E:\tools\msys2\mingw32\bin\mingw32-make.exe" exited normally.
15:06:32: Elapsed time: 00:05.
Resulting application launched fine both from Qt Creator environment and without Qt Creator, and it didn’t require any DLLs. Everything as expected.
Here’s a Dependency Walker report:
With CMake
Then I tried to build it with CMake.
Configuration output:
Running E:\tools\cmake\bin\cmake.exe -S E:/code/color-corners -B E:/code/color-corners/build/color-corners-Qt_5_15_2_x32_MinGW-Release "-DCMAKE_GENERATOR:STRING=Ninja" "-DCMAKE_BUILD_TYPE:STRING=Release" "-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=E:\code\color-corners\build\color-corners-Qt_5_15_2_x32_MinGW-Release/.qtc/package-manager/auto-setup.cmake" "-DQT_QMAKE_EXECUTABLE:FILEPATH=E:/tools/qt/5.15.2-static-x32-mingw/bin/qmake.exe" "-DCMAKE_PREFIX_PATH:PATH=E:/tools/qt/5.15.2-static-x32-mingw" "-DCMAKE_C_COMPILER:FILEPATH=E:/tools/msys2/mingw32/bin/gcc.exe" "-DCMAKE_CXX_COMPILER:FILEPATH=E:/tools/msys2/mingw32/bin/g++.exe" "-DCMAKE_CXX_FLAGS_INIT:STRING=" in E:\code\color-corners\build\color-corners-Qt_5_15_2_x32_MinGW-Release.
-- The CXX compiler identification is GNU 13.2.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: E:/tools/msys2/mingw32/bin/g++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found Qt 5.15.2: E:/tools/qt/5.15.2-static-x32-mingw
-- This Qt is static
-- This Qt version (5.15.2) is newer than 5.14
-- Running qmlimportscanner to find used QML plugins.
-- Configuring done
-- Generating done
-- Build files have been written to: E:/code/color-corners/build/color-corners-Qt_5_15_2_x32_MinGW-Release
Build output:
13:36:40: Running steps for project color-corners...
13:36:40: Starting: "E:\tools\cmake\bin\cmake.exe" --build E:/code/color-corners/build/color-corners-Qt_5_15_2_x32_MinGW-Release --target all
[1/28 10.2/sec] Automatic MOC for target color-corners
[2/28 17.4/sec] Generating qrc_qml.cpp
[3/28 16.6/sec] Building CXX object CMakeFiles/color-corners.dir/color-corners_autogen/mocs_compilation.cpp.obj
[4/28 17.8/sec] Building CXX object CMakeFiles/color-corners.dir/qrc_qml.cpp.obj
[5/28 2.7/sec] Building CXX object CMakeFiles/color-corners.dir/Qt5_QmlPlugins_Imports_color-corners.cpp.obj
[6/28 3.2/sec] Building CXX object CMakeFiles/color-corners.dir/E_/tools/qt/5.15.2-static-x32-mingw/lib/cmake/Qt5Network/Qt5Network_QGenericEnginePlugin_Import.cpp.obj
[7/28 3.8/sec] Building CXX object CMakeFiles/color-corners.dir/E_/tools/qt/5.15.2-static-x32-mingw/lib/cmake/Qt5Qml/Qt5Qml_QQmlDebugServerFactory_Import.cpp.obj
[8/28 4.3/sec] Building CXX object CMakeFiles/color-corners.dir/E_/tools/qt/5.15.2-static-x32-mingw/lib/cmake/Qt5Qml/Qt5Qml_QLocalClientConnectionFactory_Import.cpp.obj
[9/28 4.8/sec] Building CXX object CMakeFiles/color-corners.dir/E_/tools/qt/5.15.2-static-x32-mingw/lib/cmake/Qt5Qml/Qt5Qml_QDebugMessageServiceFactory_Import.cpp.obj
[10/28 5.3/sec] Building CXX object CMakeFiles/color-corners.dir/E_/tools/qt/5.15.2-static-x32-mingw/lib/cmake/Qt5Gui/Qt5Gui_QTgaPlugin_Import.cpp.obj
[11/28 5.8/sec] Building CXX object CMakeFiles/color-corners.dir/main.cpp.obj
[12/28 6.4/sec] Building CXX object CMakeFiles/color-corners.dir/E_/tools/qt/5.15.2-static-x32-mingw/lib/cmake/Qt5Gui/Qt5Gui_QTiffPlugin_Import.cpp.obj
[13/28 6.9/sec] Building CXX object CMakeFiles/color-corners.dir/E_/tools/qt/5.15.2-static-x32-mingw/lib/cmake/Qt5Gui/Qt5Gui_QJpegPlugin_Import.cpp.obj
[14/28 7.4/sec] Building CXX object CMakeFiles/color-corners.dir/E_/tools/qt/5.15.2-static-x32-mingw/lib/cmake/Qt5Qml/Qt5Qml_QQmlInspectorServiceFactory_Import.cpp.obj
[15/28 7.9/sec] Building CXX object CMakeFiles/color-corners.dir/E_/tools/qt/5.15.2-static-x32-mingw/lib/cmake/Qt5Gui/Qt5Gui_QGifPlugin_Import.cpp.obj
[16/28 8.4/sec] Building CXX object CMakeFiles/color-corners.dir/E_/tools/qt/5.15.2-static-x32-mingw/lib/cmake/Qt5Gui/Qt5Gui_QICNSPlugin_Import.cpp.obj
[17/28 7.7/sec] Building CXX object CMakeFiles/color-corners.dir/E_/tools/qt/5.15.2-static-x32-mingw/lib/cmake/Qt5Gui/Qt5Gui_QICOPlugin_Import.cpp.obj
[18/28 8.2/sec] Building CXX object CMakeFiles/color-corners.dir/E_/tools/qt/5.15.2-static-x32-mingw/lib/cmake/Qt5Gui/Qt5Gui_QWebpPlugin_Import.cpp.obj
[19/28 8.6/sec] Building CXX object CMakeFiles/color-corners.dir/E_/tools/qt/5.15.2-static-x32-mingw/lib/cmake/Qt5Qml/Qt5Qml_QQmlDebuggerServiceFactory_Import.cpp.obj
[20/28 8.9/sec] Building CXX object CMakeFiles/color-corners.dir/E_/tools/qt/5.15.2-static-x32-mingw/lib/cmake/Qt5Gui/Qt5Gui_QWbmpPlugin_Import.cpp.obj
[21/28 9.3/sec] Building CXX object CMakeFiles/color-corners.dir/E_/tools/qt/5.15.2-static-x32-mingw/lib/cmake/Qt5Gui/Qt5Gui_QWindowsIntegrationPlugin_Import.cpp.obj
[22/28 9.6/sec] Building CXX object CMakeFiles/color-corners.dir/E_/tools/qt/5.15.2-static-x32-mingw/lib/cmake/Qt5Qml/Qt5Qml_QQmlNativeDebugConnectorFactory_Import.cpp.obj
[23/28 7.7/sec] Building CXX object CMakeFiles/color-corners.dir/E_/tools/qt/5.15.2-static-x32-mingw/lib/cmake/Qt5Qml/Qt5Qml_QQuickProfilerAdapterFactory_Import.cpp.obj
[24/28 8.1/sec] Building CXX object CMakeFiles/color-corners.dir/E_/tools/qt/5.15.2-static-x32-mingw/lib/cmake/Qt5Qml/Qt5Qml_QQmlPreviewServiceFactory_Import.cpp.obj
[25/28 8.3/sec] Building CXX object CMakeFiles/color-corners.dir/E_/tools/qt/5.15.2-static-x32-mingw/lib/cmake/Qt5Qml/Qt5Qml_QQmlNativeDebugServiceFactory_Import.cpp.obj
[26/28 8.6/sec] Building CXX object CMakeFiles/color-corners.dir/E_/tools/qt/5.15.2-static-x32-mingw/lib/cmake/Qt5Qml/Qt5Qml_QQmlProfilerServiceFactory_Import.cpp.obj
[27/28 8.9/sec] Building CXX object CMakeFiles/color-corners.dir/E_/tools/qt/5.15.2-static-x32-mingw/lib/cmake/Qt5Qml/Qt5Qml_QTcpServerConnectionFactory_Import.cpp.obj
[28/28 5.5/sec] Linking CXX executable color-corners.exe
13:36:45: The process "E:\tools\cmake\bin\cmake.exe" exited normally.
And I could launch the application from Qt Creator, but surprisingly, trying to launch the executable without Qt Creator, I got an error about missing MinGW runtime DLL, even though Qt was built with -static-runtime
:
Then I got an error about missing zstd DLL:
And looks like it will also complain about missing zlib DLL, because here’s what Dependency Walker reports:
To highlight the imports difference between executables produced by qmake and CMake:
Well, what the fuck.
There is also a big difference in executables sizes:
$ du -s /path/to/qmake-build/color-corners.exe
27404
$ du -s /path/to/cmake-build/color-corners.exe
40520
So CMake-produced executable is so much bigger and yet it is the one failing to launch due to missing DLLs? What is the actual f…
Okay, the MinGW runtime issue can be fixed like this:
set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -static")
but what about zstd and zlib, where did they come from? And why they are shared libraries in CMake build, while qmake got static variants?
I couldn’t find answers on the internets, so I just inspected the qmake output and I saw that it links to a lot of stuff, out of which the following seemed to be the most relevant: E:/tools/qt/5.15.2-static-x32-mingw/lib/libQt5Core.a
, -lzstd
and -lz
. So I added those to CMake project:
# if you remove QtCore from linking, it will still complain about missing zstd,
# even though -lzstd is present here
target_link_libraries(${CMAKE_PROJECT_NAME}
PRIVATE
Qt${QT_VERSION_MAJOR}::Core
-lz
-lzstd
)
and then resulting executable was able to launch without Qt Creator environment, as it didn’t require those DLLs anymore.
Just in case, here’s a comparison of imports between executable created with qmake and this new executable from fixed CMake build:
One other change is that executable size got even bigger:
$ du -s /path/to/cmake-build/color-corners.exe
42408
but that’s a minor detail.
So yeah, it is definitely possible to build static Qt with MinGW, but I didn’t fucking enjoy it at all.
2023-10-01 | Qt 6.5.1, Mac OS 13.6, Apple M2 Pro
I got the latest MacBook Pro with Apple M2 Pro processor, and of course I wanted to check how fast it can build Qt and that Qt does build there at all.
My environment:
$ sw_vers -productVersion
13.6
$ sysctl -n machdep.cpu.brand_string
Apple M2 Pro
$ system_profiler SPHardwareDataType | grep Cores:
Total Number of Cores: 12 (8 performance and 4 efficiency)
$ nproc --all
12
$ clang --version
Apple clang version 15.0.0 (clang-1500.0.40.1)
Target: arm64-apple-darwin22.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
$ cmake --version
cmake version 3.27.6
If you have vcpkg installed, unset VCPKG_ROOT
environment variable (as it will probably cause troubles with GSSAPI):
And then configure and try building Qt as usual:
$ ../configure -static -release -no-pch -prefix "/Users/vasya/programs/qt/6.5.1-static" \
-skip qtwebengine -nomake tests -nomake examples
$ cmake --build . --parallel
The build will fail with the following:
[1172/10531] Automatic MOC for target Core
FAILED: qtbase/src/corelib/Core_autogen/timestamp qtbase/src/corelib/Core_autogen/mocs_compilation.cpp /Users/vasya/programs/qt/src/6.5.1/build/qtbase/src/corelib/Core_autogen/timestamp /Users/vasya/programs/qt/src/6.5.1/build/qtbase/src/corelib/Core_autogen/mocs_compilation.cpp
cd /Users/vasya/programs/qt/src/6.5.1/build/qtbase/src/corelib && /opt/homebrew/Cellar/cmake/3.27.6/bin/cmake -E cmake_autogen /Users/vasya/programs/qt/src/6.5.1/build/qtbase/src/corelib/CMakeFiles/Core_autogen.dir/AutogenInfo.json Release && /opt/homebrew/Cellar/cmake/3.27.6/bin/cmake -E touch /Users/vasya/programs/qt/src/6.5.1/build/qtbase/src/corelib/Core_autogen/timestamp && /opt/homebrew/Cellar/cmake/3.27.6/bin/cmake -E cmake_transform_depfile Ninja gccdepfile /Users/vasya/programs/qt/src/6.5.1 /Users/vasya/programs/qt/src/6.5.1/qtbase/src/corelib /Users/vasya/programs/qt/src/6.5.1/build /Users/vasya/programs/qt/src/6.5.1/build/qtbase/src/corelib /Users/vasya/programs/qt/src/6.5.1/build/qtbase/src/corelib/Core_autogen/deps /Users/vasya/programs/qt/src/6.5.1/build/CMakeFiles/d/606731a3a0f1e503548aa7c710455eaf53992e00a8ae745add67869bd2ab1236.d
AutoMoc subprocess error
------------------------
The moc process failed to compile
"SRC:/qtbase/src/corelib/io/qfiledevice.h"
into
"SRC:/build/qtbase/src/corelib/Core_autogen/include/moc_qfiledevice.cpp"
included by
"SRC:/qtbase/src/corelib/io/qfiledevice.cpp"
Process was terminated by signal 6
Output
------
dyld[53461]: Symbol not found: __ZTVNSt3__13pmr25monotonic_buffer_resourceE
Referenced from: <844A2EB8-F282-3594-8EC0-4E52F289E557> /Users/vasya/programs/qt/src/6.5.1/build/qtbase/libexec/moc
Expected in: <3EE92404-8FC3-374B-A598-D5C9A8CD64B5> /usr/lib/libc++.1.dylib
[1185/10531] Building CXX object qtbase/src/3rdparty/harfbuzz-ng/CMakeFiles/BundledHarfbuzz.dir/src/hb-subset.cc.o
ninja: build stopped: subcommand failed.
$ c++filt -n _ZTVNSt3__13pmr25monotonic_buffer_resourceE
vtable for std::__1::pmr::monotonic_buffer_resource
This one is likely because of missing LLVM. There are probably other ways of fixing this, but I know only one — install LLVM with Homebrew and use that one. And since Homebrew has come up, I noticed that some features were disabled in the configuration output, for instance FFmpeg backend for Multimedia, so yes, let’s try with Homebrew prefix:
$ ../configure -static -release -no-pch -prefix "/Users/vasya/programs/qt/6.5.1-static" \
-skip qtwebengine -nomake tests -nomake examples \
-- -DCMAKE_PREFIX_PATH="/opt/homebrew"
That will fail already on configure:
CMake Error at /opt/homebrew/lib/cmake/zstd/zstdTargets.cmake:42 (message):
Some (but not all) targets in this export set were already defined.
Targets Defined: zstd::libzstd_static
Targets not yet defined: zstd::libzstd_shared
Call Stack (most recent call first):
/opt/homebrew/lib/cmake/zstd/zstdConfig.cmake:1 (include)
qtbase/cmake/FindWrapZSTD.cmake:24 (find_package)
/opt/homebrew/Cellar/cmake/3.27.6/share/cmake/Modules/CMakeFindDependencyMacro.cmake:76 (find_package)
build/qtbase/lib/cmake/Qt6/QtPublicDependencyHelpers.cmake:36 (find_dependency)
build/qtbase/lib/cmake/Qt6Core/Qt6CoreDependencies.cmake:30 (_qt_internal_find_third_party_dependencies)
build/qtbase/lib/cmake/Qt6Core/Qt6CoreConfig.cmake:40 (include)
build/qtbase/lib/cmake/Qt6/Qt6Config.cmake:157 (find_package)
qtimageformats/CMakeLists.txt:14 (find_package)
I’ve already encountered this one when I was building Qt on Steam Deck, the workaround is to remove zstd::libzstd_shared
from /opt/homebrew/lib/cmake/zstd/zstdTargets.cmake
. Don’t forget to return it back afterwards.
Try to configure the build again. There will be another error in the end of configure:
CMake Error at qtbase/cmake/QtTargetHelpers.cmake:146 (target_link_libraries):
Target "QGstreamerMediaPlugin" links to:
EGL::EGL
but the target was not found. Possible reasons include:
* There is a typo in the target name.
* A find_package call is missing for an IMPORTED target.
* An ALIAS target is missing.
Call Stack (most recent call first):
qtmultimedia/src/plugins/multimedia/gstreamer/CMakeLists.txt:59 (qt_internal_extend_target)
I tried to install Mesa packages:
$ brew install mesa mesa-glu
but that didn’t help. Then I realized that this problem originates in GStreamer backend, so it probably can be just disabled, because FFmpeg is now the default backend anyway:
$ ../configure -static -release -no-pch -prefix "/Users/vasya/programs/qt/6.5.1-static" \
-skip qtwebengine -nomake tests -nomake examples -no-gstreamer \
-- -DCMAKE_PREFIX_PATH="/opt/homebrew"
That helped, and Qt has successfully configured. I started building it and got this error:
[680/10313] Building CXX object qtgrpc/src/tools/qtprotoccommon/CMakeFiles/QtProtocCommon.dir/generatorbase.cpp.o
FAILED: qtgrpc/src/tools/qtprotoccommon/CMakeFiles/QtProtocCommon.dir/generatorbase.cpp.o
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -DPROTOBUF_USE_DLLS -I/Users/vasya/programs/qt/src/6.5.1/qtgrpc/src/tools/qtprotoccommon -isystem /opt/homebrew/include -DNDEBUG -O2 -std=gnu++17 -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk -mmacosx-version-min=11.0 -fPIC -Wall -Wextra -MD -MT qtgrpc/src/tools/qtprotoccommon/CMakeFiles/QtProtocCommon.dir/generatorbase.cpp.o -MF qtgrpc/src/tools/qtprotoccommon/CMakeFiles/QtProtocCommon.dir/generatorbase.cpp.o.d -o qtgrpc/src/tools/qtprotoccommon/CMakeFiles/QtProtocCommon.dir/generatorbase.cpp.o -c /Users/vasya/programs/qt/src/6.5.1/qtgrpc/src/tools/qtprotoccommon/generatorbase.cpp
/Users/vasya/programs/qt/src/6.5.1/qtgrpc/src/tools/qtprotoccommon/generatorbase.cpp:8:10: fatal error: 'google/protobuf/stubs/logging.h' file not found
#include <google/protobuf/stubs/logging.h>
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I thought this is because I don’t have protobuf installed:
but no, I did have it. Then I checked what headers it has in /opt/homebrew/include/google/protobuf/stubs/
, and logging.h
wasn’t there. As it turned out, protobof migrated to a different logger, so I needed to downgrade my protobuf to version 21.12:
$ brew uninstall --ignore-dependencies protobuf
$ brew install protobuf@21
$ brew link protobuf@21
Hopefully, later versions of Qt will switch to newer versions of protobuf. Meanwhile, do keep in mind that you might brake other packages in your environment by force-downgrading with --ignore-dependencies
, because they might require exactly the latest protobuf.
Then the build proceeded, and I got that same error about monotonic_buffer_resource
:
Output
------
dyld[80989]: Symbol not found: __ZTVNSt3__13pmr25monotonic_buffer_resourceE
Referenced from: <1F874DB3-B6FE-325D-8E18-58B83A377595> /Users/vasya/programs/qt/src/6.5.1/build/qtbase/libexec/moc
Expected in: <3EE92404-8FC3-374B-A598-D5C9A8CD64B5> /usr/lib/libc++.1.dylib
So first I checked that I actually have LLVM installed:
But I did, and then I realized that it is not linked anywhere (it’s a new Mac, I didn’t have time to set it up properly). But probably don’t link it to the main prefix, instead add the following to your ~/.bash_profile
(or whichever shell you are using):
export PATH="/opt/homebrew/opt/llvm/bin:$PATH"
export LDFLAGS="-L/opt/homebrew/opt/llvm/lib/c++ -Wl,-rpath,/opt/homebrew/opt/llvm/lib/c++ $LDFLAGS"
export CPPFLAGS="-I/opt/homebrew/opt/llvm/include $CPPFLAGS"
I re-configured Qt again, and it still warns about not finding LLVM for QDoc, so probably you can try adding -DLLVM_INSTALL_DIR="/opt/homebrew/opt/llvm"
after -DCMAKE_PREFIX_PATH="..."
(or export LLVM_INSTALL_DIR="/opt/homebrew/opt/llvm"
in ~/.bash_profile
), but it doesn’t matter for the main build.
Just in case, here’s the final configure command:
$ ../configure -static -release -no-pch \
-prefix "/Users/vasya/programs/qt/6.5.1-static" \
-skip qtwebengine -nomake tests -nomake examples -no-gstreamer \
-- -DCMAKE_PREFIX_PATH="/opt/homebrew"
and configuration summary:
-- Configure summary:
Building for: macx-clang (arm64, CPU features: neon crc32 crypto)
Compiler: clang (Apple) 15.0.0.15000040
Build options:
Mode ................................... release
Optimize release build for size ........ no
Fully optimize release builds (-O3) .... no
Building shared libraries .............. no
Using C standard ....................... C11
Using C++ standard ..................... C++17
Using ccache ........................... no
Relocatable ............................ no
Using precompiled headers .............. no
Using Link Time Optimization (LTCG) .... no
Using Intel CET ........................ no
Target compiler supports:
ARM Extensions ....................... NEON CRC32 AES
Sanitizers:
Addresses ............................ no
Threads .............................. no
Memory ............................... no
Fuzzer (instrumentation only) ........ no
Undefined ............................ no
Build parts ............................ libs tools
App store compliance ................... no
Qt modules and options:
Qt Concurrent .......................... yes
Qt D-Bus ............................... yes
Qt D-Bus directly linked to libdbus .... no
Qt Gui ................................. yes
Qt Network ............................. yes
Qt PrintSupport ........................ yes
Qt Sql ................................. yes
Qt Testlib ............................. yes
Qt Widgets ............................. yes
Qt Xml ................................. yes
Support enabled for:
Using pkg-config ....................... no
udev ................................... no
OpenSSL ................................ yes
Qt directly linked to OpenSSL ........ no
OpenSSL 1.1 ............................ no
OpenSSL 3.0 ............................ yes
Using system zlib ...................... yes
Zstandard support ...................... yes
Thread support ......................... yes
Common build options:
Linker can resolve circular dependencies yes
Qt Core:
backtrace .............................. yes
DoubleConversion ....................... yes
Using system DoubleConversion ........ no
GLib ................................... yes
ICU .................................... no
Using system libb2 ..................... yes
Built-in copy of the MIME database ..... yes
cpp/winrt base ......................... no
Tracing backend ........................ <none>
Logging backends:
journald ............................. no
syslog ............................... no
slog2 ................................ no
PCRE2 .................................. yes
Using system PCRE2 ................... yes
Application permissions ................ yes
Qt Sql:
SQL item models ........................ yes
Qt Network:
getifaddrs() ........................... yes
IPv6 ifname ............................ yes
libproxy ............................... no
SecureTransport ........................ yes
DTLS ................................... yes
OCSP-stapling .......................... yes
SCTP ................................... no
Use system proxies ..................... yes
GSSAPI ................................. yes
Brotli Decompression Support ........... yes
qIsEffectiveTLD() ...................... yes
Built-in publicsuffix database ....... yes
System publicsuffix database ......... no
Core tools:
Android deployment tool ................ yes
macOS deployment tool .................. yes
Windows deployment tool ................ no
qmake .................................. yes
Qt Gui:
Accessibility .......................... yes
FreeType ............................... yes
Using system FreeType ................ yes
HarfBuzz ............................... yes
Using system HarfBuzz ................ no
Fontconfig ............................. no
Image formats:
GIF .................................. yes
ICO .................................. yes
JPEG ................................. yes
Using system libjpeg ............... yes
PNG .................................. yes
Using system libpng ................ yes
Text formats:
HtmlParser ........................... yes
CssParser ............................ yes
OdfWriter ............................ yes
MarkdownReader ....................... yes
Using system libmd4c ............... no
MarkdownWriter ....................... yes
EGL .................................... no
OpenVG ................................. no
OpenGL:
Desktop OpenGL ....................... yes
OpenGL ES 2.0 ........................ no
OpenGL ES 3.0 ........................ no
OpenGL ES 3.1 ........................ no
OpenGL ES 3.2 ........................ no
Vulkan ................................. no
Session Management ..................... yes
Features used by QPA backends:
evdev .................................. no
libinput ............................... no
HiRes wheel support in libinput ........ no
INTEGRITY HID .......................... no
mtdev .................................. no
tslib .................................. no
xkbcommon .............................. no
X11 specific:
XLib ................................. no
XCB Xlib ............................. no
EGL on X11 ........................... no
xkbcommon-x11 ........................ no
xcb-sm ............................... no
QPA backends:
DirectFB ............................... no
EGLFS .................................. no
EGLFS details:
EGLFS OpenWFD ........................ no
EGLFS i.Mx6 .......................... no
EGLFS i.Mx6 Wayland .................. no
EGLFS RCAR ........................... no
EGLFS EGLDevice ...................... no
EGLFS GBM ............................ no
EGLFS VSP2 ........................... no
EGLFS Mali ........................... no
EGLFS Raspberry Pi ................... no
EGLFS X11 ............................ no
LinuxFB ................................ no
VNC .................................... no
VK_KHR_display ......................... no
QNX:
lgmon ................................ no
IMF .................................. no
XCB:
Using system-provided xcb-xinput ..... no
GL integrations:
GLX Plugin ......................... no
XCB GLX .......................... no
EGL-X11 Plugin ..................... no
Windows:
Direct 2D ............................ no
Direct 2D 1.1 ........................ no
DirectWrite .......................... no
DirectWrite 3 ........................ no
Qt Widgets:
GTK+ ................................... no
Styles ................................. Fusion macOS Windows
Qt Testlib:
Tester for item models ................. yes
Batch tests ............................ no
Qt PrintSupport:
CUPS ................................... yes
Qt Sql Drivers:
DB2 (IBM) .............................. no
InterBase .............................. no
MySql .................................. yes
OCI (Oracle) ........................... no
ODBC ................................... no
PostgreSQL ............................. yes
SQLite ................................. yes
Using system provided SQLite ......... no
Further Image Formats:
JasPer ................................. yes
MNG .................................... no
TIFF ................................... yes
Using system libtiff ................. yes
WEBP ................................... yes
Using system libwebp ................. yes
Qt QML:
QML network support .................... yes
QML debugging and profiling support .... yes
QML just-in-time compiler .............. no
QML XML http request ................... yes
QML Locale ............................. yes
Qt QML Models:
QML list model ......................... yes
QML delegate model ..................... yes
Qt Quick:
AnimatedImage item ..................... yes
Canvas item ............................ yes
Support for Qt Quick Designer .......... yes
Flipable item .......................... yes
GridView item .......................... yes
ListView item .......................... yes
TableView item ......................... yes
TreeView item .......................... yes
Path support ........................... yes
PathView item .......................... yes
Positioner items ....................... yes
Repeater item .......................... yes
ShaderEffect item ...................... yes
Sprite item ............................ yes
Qt Quick Templates 2:
Hover support .......................... yes
Multi-touch support .................... yes
Calendar support ....................... yes
Qt Quick Controls 2:
Styles ................................. Basic Fusion Imagine iOS Material Universal macOS Windows
QtQuick3D:
Assimp ................................. yes
System Assimp .......................... no
Qt Multimedia:
Spatial Audio .......................... yes
Spatial Audio (Quick3D) ................ yes
Low level Audio Backend:
ALSA (experimental) .................. no
PulseAudio ........................... no
MMRenderer ........................... no
CoreAudio ............................ yes
Windows Media SDK .................... no
Open SLES (Android) .................. no
Web Assembly ......................... no
Plugin:
GStreamer 1.0 ........................ no
FFmpeg ............................... yes
MMRenderer ........................... no
AVFoundation ......................... yes
Windows Media Foundation ............. no
Hardware acceleration and features:
Video for Linux ...................... no
VAAPI support ........................ no
Linux DMA buffer support ............. no
VideoToolbox ......................... yes
Qt 3D:
Assimp ................................. yes
System Assimp .......................... no
Use SSE2 instructions .................. no
Use AVX2 instructions .................. no
Aspects:
Render aspect ........................ yes
Input aspect ......................... yes
Logic aspect ......................... yes
Animation aspect ..................... yes
Extras aspect ........................ yes
Qt 3D APIs:
Vulkan ................................. no
Qt 3D Renderers:
OpenGL Renderer ........................ yes
RHI Renderer ........................... yes
Qt3D Geometry Loaders:
Autodesk FBX ........................... no
Qt 5 Compatibility Libraries:
iconv .................................. no
Qt Charts Types:
Area Chart ............................. yes
Line Chart ............................. yes
Spline Chart ........................... yes
Scatter Chart .......................... yes
Bar Chart .............................. yes
Pie Chart .............................. yes
Boxplot Chart .......................... yes
Candlestick Chart ...................... yes
Qt Axis Types:
DateTime Axis .......................... yes
Qt Bluetooth:
BlueZ .................................. no
BlueZ Low Energy ....................... no
Linux Crypto API ....................... no
WinRT Bluetooth API .................... no
Qt Tools:
Qt Assistant ........................... yes
QDoc ................................... no
Clang-based lupdate parser ............. no
Qt Designer ............................ yes
Qt Distance Field Generator ............ yes
Qt Linguist ............................ yes
pixeltool .............................. yes
qdbus .................................. yes
Qt Attributions Scanner ................ yes
qtdiag ................................. yes
qtplugininfo ........................... yes
Serial Port:
ntddmodm ............................... no
Qt Protobuf tools:
Qt Protobuf generator .................. yes
Qt GRPC:
gRPC support ........................... yes
Native gRPC support .................... no
Qt GRPC tools:
Qt GRPC generator ...................... yes
Qt Opcua:
Open62541 .............................. yes
Unified Automation C++ SDK ............. no
Support for namespace 0 NodeId names ... yes
Namespace 0 NodeIds generator .......... no
Open62541 security support ............. yes
Support for global discovery server .... yes
Qt Remote Objects:
High Availability Manager (ham) ........ no
Qt Scxml:
ECMAScript data model for QtScxml ...... yes
Qt Sensors:
Qt SerialBus:
Socket CAN ............................. no
Socket CAN FD .......................... no
SerialPort Support ..................... yes
Qt TextToSpeech:
Flite .................................. no
Flite with ALSA ........................ no
Speech Dispatcher ...................... no
Qt Virtualkeyboard:
Desktop integration .................... yes
Built-in layouts ....................... yes
Key navigation ......................... no
Retro style as default ................. no
Sensitive Debug ........................ no
Cerence ................................ no
Static Linking ....................... no
Handwriting .......................... no
Alphabetic ......................... no
CJK ................................ no
XT9 .................................. no
XT9 Debug .......................... no
XT9 9-key layouts .................. no
Bundle resources ..................... no
Handwriting ........................ no
XT9 ................................ no
Hunspell ............................... no
Using Hunspell copy from 3rdparty/ ... no
OpenWnn ................................ yes
MyScript ............................... no
Language support enabled for:
Arabic ............................... yes
Bulgarian ............................ yes
Czech ................................ yes
Danish ............................... yes
German ............................... yes
Greek ................................ yes
English GB ........................... yes
English US ........................... yes
Spanish .............................. yes
Spanish Mexico ....................... yes
Estonian ............................. yes
Farsi ................................ yes
Finnish .............................. yes
French Canada ........................ yes
French France ........................ yes
Hebrew ............................... yes
Hindi ................................ yes
Croatian ............................. yes
Hungarian ............................ yes
Indonesian ........................... yes
Italian .............................. yes
Japanese ............................. yes
Korean ............................... yes
Malay ................................ yes
Norwegian ............................ yes
Dutch ................................ yes
Polish ............................... yes
Portuguese Brazil .................... yes
Portuguese Portugal .................. yes
Romanian ............................. yes
Russian .............................. yes
Slovak ............................... yes
Slovenian ............................ yes
Albanian ............................. yes
Serbian .............................. yes
Swedish .............................. yes
Thai ................................. yes
Turkish .............................. yes
Ukrainian ............................ yes
Vietnamese ........................... yes
Simplified Chinese ................... yes
Traditional Chinese .................. yes
HongKong Chinese ..................... no
Traditional chinese input methods:
Zhuyin ............................... yes
Cangjie .............................. yes
So, configuration succeeded, and I started the build again. It passed that problem with monotonic_buffer_resource
, but failed later with something different:
/Users/vasya/programs/qt/src/6.5.1/qtmultimedia/src/plugins/multimedia/darwin/camera/avfcamerautility.mm:72:35: error: no template named 'unary_function' in namespace 'std'; did you mean '__unary_function'?
struct FormatHasNoFPSRange : std::unary_function<AVCaptureDeviceFormat *, bool>
~~~~~^~~~~~~~~~~~~~
__unary_function
Apparently, this function was removed from C++17, which means that Qt 6.5.1 doesn’t support C++17? Or at least that is how it is with Xcode 15. I found a seemingly relevant workaround about setting _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION
preprocessor definition. I tried to do that in /path/to/qt/qtmultimedia/src/plugins/multimedia/darwin/CMakeLists.txt
:
qt_internal_add_plugin(QDarwinMediaPlugin
OUTPUT_NAME darwinmediaplugin
PLUGIN_TYPE multimedia
SOURCES
# ...
INCLUDE_DIRECTORIES
# ...
LIBRARIES
# ...
DEFINES
"_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION"
)
it didn’t help. Then I tried this:
qt_internal_extend_target(QDarwinMediaPlugin CONDITION NOT TVOS
SOURCES
# ...
DEFINES
"_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION"
)
it didn’t help either. Then I tried this:
target_compile_definitions(QDarwinMediaPlugin
PRIVATE
"_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION"
)
but that didn’t help either. Then I just edited /path/to/qt/qtmultimedia/src/plugins/multimedia/darwin/camera/avfcamerautility.mm
:
-struct FormatHasNoFPSRange : std::unary_function<AVCaptureDeviceFormat *, bool>
+struct FormatHasNoFPSRange : std::__unary_function<AVCaptureDeviceFormat *, bool>
And that did help, the build continued and then succeeded. Installation too:
The entire build (measured from scratch, after all the problems were solved) and installation took… 12 minutes (12:15)!
Fuck me sideways, it sure is nice to live in the future. For comparison, here are the build times of the same static Qt 6.5.1 on other machines that I have.
The installation size is 851 MB (according to du
). Binaries are arm64
:
$ lipo -info /Users/vasya/programs/qt/6.5.1-static/lib/libQt6Core.a
Non-fat file: /Users/vasya/programs/qt/6.5.1-static/lib/libQt6Core.a is architecture: arm64
By the way, I didn’t need to provide -DCMAKE_OSX_ARCHITECTURES="arm64"
to the configure, as I assumed that it should be the default one. If I wanted to build universal binaries, then yes, I would’ve provided -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64"
(some say the order should be exactly x86_64;arm64
, because it might be important for Qt somehow).
Right, so let’s add this build to Qt Creator then. The procedure is the same as always, but with one little surprise:
No compiler can produce code for this Qt version. Please define one or more compilers for:
arm-darwin-generic-mach_o-64bit
So for some reasons it couldn’t auto-detect system compilers, and you’ll need to set them manually.
Here’s C compiler:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc
And here’s C++ compiler:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++
The rest goes fine:
Building the greatest application in the world succeeds:
19:31:56: Starting: "/opt/homebrew/Cellar/cmake/3.27.6/bin/cmake" --build /Users/vasya/code/qt/color-corners/build/Qt_6_5_1_static/Release --target all
[1/6 6.2/sec] Automatic MOC for target color-corners
[2/6 10.6/sec] Generating qrc_qml.cpp
[3/6 12.7/sec] Building CXX object CMakeFiles/color-corners.dir/color-corners_autogen/mocs_compilation.cpp.o
[4/6 15.9/sec] Building CXX object CMakeFiles/color-corners.dir/qrc_qml.cpp.o
[5/6 6.6/sec] Building CXX object CMakeFiles/color-corners.dir/main.cpp.o
[6/6 6.5/sec] Linking CXX executable color-corners.app/Contents/MacOS/color-corners
ld: warning: ignoring duplicate libraries: '/Users/vasya/programs/qt/6.5.1-static/./qml/QtQml/Base/libqmlplugin.a', '/Users/vasya/programs/qt/6.5.1-static/./qml/QtQml/Models/libmodelsplugin.a', '/Users/vasya/programs/qt/6.5.1-static/./qml/QtQml/WorkerScript/libworkerscriptplugin.a', '/Users/vasya/programs/qt/6.5.1-static/./qml/QtQml/libqmlmetaplugin.a', '/Users/vasya/programs/qt/6.5.1-static/./qml/QtQuick/libqtquick2plugin.a', '/Users/vasya/programs/qt/6.5.1-static/lib/libQt6Core.a', '/Users/vasya/programs/qt/6.5.1-static/lib/libQt6Qml.a', '/Users/vasya/programs/qt/6.5.1-static/lib/libQt6QmlWorkerScript.a', '/Users/vasya/programs/qt/6.5.1-static/lib/libQt6Quick.a'
19:31:56: The process "/opt/homebrew/Cellar/cmake/3.27.6/bin/cmake" exited normally.
19:31:56: Elapsed time: 00:01.
Not sure what this warning with duplicate libraries is about.
The executable is arm64
:
$ cd ~/code/qt/color-corners/build/Qt_6_5_1_static/Release/color-corners.app/Contents/MacOS/
$ lipo -info ./color-corners
Non-fat file: ./color-corners is architecture: arm64
Checking its dependencies shows that there are no Qt libraries:
$ otool -L ./color-corners
./color-corners:
/System/Library/Frameworks/CoreVideo.framework/Versions/A/CoreVideo (compatibility version 1.2.0, current version 1.5.0)
/System/Library/Frameworks/IOSurface.framework/Versions/A/IOSurface (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/QuartzCore.framework/Versions/A/QuartzCore (compatibility version 1.2.0, current version 1.11.0)
/opt/homebrew/opt/jasper/lib/libjasper.7.dylib (compatibility version 7.0.0, current version 7.0.0)
/opt/homebrew/opt/jpeg-turbo/lib/libjpeg.8.dylib (compatibility version 8.0.0, current version 8.3.2)
/opt/homebrew/opt/libtiff/lib/libtiff.6.dylib (compatibility version 7.0.0, current version 7.2.0)
/opt/homebrew/opt/webp/lib/libwebpdemux.2.dylib (compatibility version 3.0.0, current version 3.14.0)
/opt/homebrew/opt/webp/lib/libwebpmux.3.dylib (compatibility version 4.0.0, current version 4.13.0)
/opt/homebrew/opt/webp/lib/libwebp.7.dylib (compatibility version 9.0.0, current version 9.8.0)
/opt/homebrew/opt/webp/lib/libsharpyuv.0.dylib (compatibility version 1.0.0, current version 1.1.0)
/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon (compatibility version 2.0.0, current version 170.0.0)
/System/Library/Frameworks/CoreGraphics.framework/Versions/A/CoreGraphics (compatibility version 64.0.0, current version 1774.0.4)
/System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/AGL.framework/Versions/A/AGL (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/CoreText.framework/Versions/A/CoreText (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/Metal.framework/Versions/A/Metal (compatibility version 1.0.0, current version 341.16.0)
/opt/homebrew/opt/libpng/lib/libpng16.16.dylib (compatibility version 57.0.0, current version 57.0.0)
/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.12)
/opt/homebrew/opt/freetype/lib/libfreetype.6.dylib (compatibility version 27.0.0, current version 27.1.0)
/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0)
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 2048.1.255)
/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 2048.1.255)
/System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 2483.0.0)
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices (compatibility version 1.0.0, current version 64.0.0)
/System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices (compatibility version 1.0.0, current version 1226.0.0)
/System/Library/Frameworks/Security.framework/Versions/A/Security (compatibility version 1.0.0, current version 61040.1.3)
/opt/homebrew/opt/libb2/lib/libb2.1.dylib (compatibility version 2.0.0, current version 2.4.0)
/opt/homebrew/opt/pcre2/lib/libpcre2-16.0.dylib (compatibility version 12.0.0, current version 12.2.0)
/opt/homebrew/opt/glib/lib/libglib-2.0.0.dylib (compatibility version 7801.0.0, current version 7801.0.0)
/opt/homebrew/opt/glib/lib/libgthread-2.0.0.dylib (compatibility version 7801.0.0, current version 7801.0.0)
/System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration (compatibility version 1.0.0, current version 1296.0.1)
/opt/homebrew/opt/brotli/lib/libbrotlidec.1.dylib (compatibility version 1.0.0, current version 1.1.0)
/System/Library/Frameworks/GSS.framework/Versions/A/GSS (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 1600.151.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1336.0.0)
/System/Library/Frameworks/CFNetwork.framework/Versions/A/CFNetwork (compatibility version 1.0.0, current version 1474.0.0)
/System/Library/Frameworks/ColorSync.framework/Versions/A/ColorSync (compatibility version 1.0.0, current version 3730.0.0)
/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
However, there is one other surprising dependency, because trying to launch the application fails:
$ ./color-corners
dyld[95470]: Symbol not found: __ZNSt3__13pmr15memory_resourceD2Ev
Referenced from: <15D1042B-EDEF-3DD0-831C-DB3B35972406> /Users/vasya/code/qt/color-corners/build/Qt_6_5_1_static/Release/color-corners.app/Contents/MacOS/color-corners
Expected in: <3EE92404-8FC3-374B-A598-D5C9A8CD64B5> /usr/lib/libc++.1.dylib
Abort trap: 6
So all of a sudden it cannot find C++/LLVM runtime library. I don’t know yet, how to link to it statically or how to set the right path to it, but the “workaround” is well known:
$ DYLD_LIBRARY_PATH=/opt/homebrew/opt/llvm/lib/c++ ./color-corners
And then it launches fine.
At the same time, building without Qt Creator produces a different result. Here’s a build from bare CLI:
$ cd ~/code/qt/color-corners/color-corners
$ mkdir build && cd $_
$ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="/Users/vasya/programs/qt/6.5.1-static" ..
$ cmake --build .
$ ./color-corners.app/Contents/MacOS/color-corners
And it launches just fine without setting DYLD_LIBRARY_PATH
. Huh.
I compared otool
output for both executables (left one is produced by Qt Creator, right one is built from CLI), and they are the same except for that exact C++ library:
As we can see, basic CMake/Ninja build from CLI is capable of setting the dependencies paths correctly, but Qt Creator build is not. Not to mention Qt Creator’s inability to auto-detect default system C/C++ compilers. Hah, by the way, it still requires manually setting CMAKE_MAKE_PROGRAM
to Ninja path for every project, despite it being available in system’s PATH
.
Yeah, so much progress has happened in Qt Creator from its last 4.x
version in 2021 till the current 11.0.3
version in 2023 — fucking seven major versions in just two years. Not every IDE is developed so rapidly and with so many great new features! Too bad I can’t recall a single such feature that would be worth increasing the major version number.
Qt is a cross-platform software development framework for C++ used to build software across all major industries. If you work at company that uses Qt you may have wondered how you can pack all dependencies of your application in a single executable. Yes, that is possible but only with static builds. Let me show you how to do it.
Disclaimer: According to the Qt license you may not deploy static builds with the open-source license. Deploying static builds is only allowed for companies who purchase Qt.
Does this image look familiar to you?
Yeah Qt has so many dependencies… with static builds Qt can generate a single executable file so, no more missing dependencies and no need to use external tools such as Qt’s windeployqt
or Dependency Walker.
Unfortunately the only way to do static builds is to compile Qt itself statically first. I’ll show you how to do it and how to setup Qt Creator to do both shared and static builds:
Requirements
- A computer to develop Qt applications with Qt and Qt Creator already installed;
- A Windows 10 (64 bit) virtual machine to build a static version of Qt;
- Qt source code: https://www.qt.io/offline-installers > Offline Installers > Source packages > For Windows users as a single zip file.
- mingw-w64: https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/installer/mingw-w64-install.exe/download
- Perl (64 bit): http://strawberryperl.com/
- Ruby (64 bit): https://rubyinstaller.org/downloads/
- Python 2.7: https://www.python.org/downloads/
Setup
In your virtual machine start by unpacking the Qt Source code to the root of the system, for instance C:\qt-everywhere-src-5.14.2
. Now install Perl, Python, Ruby and then MinGW with the following settings:
- Architecture:
x86_64
- Threads:
win32
- Installation path:
C:\Qt-Static\mingw-w64
Make sure Perl, Python, Ruby and MinGW are in your system path and MinGW is the first one. This will avoid issues with the build in C compiler of Strawberry Perl. Example:
Compiling Qt Statically
Now that we have all dependencies open command prompt as admin and:
cd C:\qt-everywhere-src-5.14.2
configure -debug-and-release -static -opengl desktop -qt-zlib -qt-pcre -qt-libpng -qt-libjpeg -qt-freetype -nomake examples -nomake tests
This will configure the source code for a static build capable of debug and release configurations. I’ve added OpenGL for desktop applications and most of the commonly used libraries. I’ve also excluded examples and tests – those are already available in our development machine. Now build and install Qt with:
mingw32-make
mingw32-make install
Qt will be installed to C:\Qt\Qt-5.14.2
, now you may copy that directory over to our final destination C:\Qt-Static\Qt-5.14.2
.
Configure Your Development Machine
Start by copying the static build folder C:\Qt-Static
from the virtual machine to the same path in your development machine. Open Qt Creator and go to Tools > Options > Kits
.
Now under Compilers add the following:
- C Compiler:
- Name:
MinGW Static
- Path:
C:\Qt-Static\mingw-w64\mingw64\bin\gcc.exe
- Name:
- C++ Compiler:
- Name:
MinGW++ Static
- Path:
C:\Qt-Static\mingw-w64\mingw64\bin\g++.exe
- Name:
Under Qt Versions add a new version as:
- Version name:
Qt-Static %{Qt:Version} (Qt-5.14.2)
- qmake location:
C:\Qt-Static\Qt-5.14.2\bin\qmake.exe
Now go to Kits and add a Kit that uses the static Qt version and the compiler we’ve added before:
Project Configuration
In order to do static builds you still need to add the following to your project’s .pro
file:
# Static Builds
QTPREFIX=$$[QT_INSTALL_PREFIX]
equals(QTPREFIX, "C:/Qt-Static/Qt-5.14.2"){
message("--STATIC BUILD--")
CONFIG += qt static
QMAKE_LFLAGS += -static-libgcc -static-libstdc++
} else {
message("--NON-STATIC BUILD--")
}
This configuration will detect whenever you’re building with the static Qt and make sure the proper flags are added.
Congratulations, you’re ready for your first static build.