I am trying to build a trivial Qt application, shown below, for Windows using MSYS2/MinGW.
hello.cpp:
#include <QApplication>
#include <QWidget>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QWidget window;
window.setWindowTitle("Hello world");
window.show();
return app.exec();
}
I can build this with the command below, and it builds and runs successfully:
g++ $(pkg-config Qt5Widgets Qt5Core --cflags) hello.cpp $(pkg-config Qt5Widgets --libs) -o hello
Now I would like to build the application statically so that I can deploy/run it as a standalone executable file. The mingw-w64-x86_64-qt5-static
package appears to exist for exactly this purpose, so I've installed it (version 5.15.1-1) with pacman
.
By default, the pkg-config files for the static Qt build are not in the PKG_CONFIG_PATH, so I've updated PKG_CONFIG_PATH
to search the files in qt5-static first:
PKG_CONFIG_PATH=/mingw64/qt5-static/lib/pkgconfig:$PKG_CONFIG_PATH
I have also updated my build command accordingly to request the static dependencies for the libs. However, this results in a bunch of errors:
$ g++ $(pkg-config Qt5Widgets Qt5Core --cflags) hello.cpp $(pkg-config Qt5Widgets --static --libs) -o hello
g++.exe: error: D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libQt5Gui.a: No such file or directory
g++.exe: error: D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libqtlibpng.a: No such file or directory
g++.exe: error: D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libqtharfbuzz.a: No such file or directory
g++.exe: error: D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libQt5Core.a: No such file or directory
g++.exe: error: D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libqtpcre2.a: No such file or directory
g++.exe: error: D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libQt5Core.a: No such file or directory
g++.exe: error: D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libqtpcre2.a: No such file or directory
g++.exe: error: D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libqtlibpng.a: No such file or directory
g++.exe: error: D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libqtharfbuzz.a: No such file or directory
g++.exe: error: D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libqtpcre2.a: No such file or directory
The offending file paths come directly from the Libs.private
section of the .pc
files from the package. It looks like maybe they're using the package maintainer's machine's paths?
Anyway, since I should have all of these libraries, I tried to work around the issue by piping the pkg-config
output through sed
to replace the absolute paths with their corresponding -l
flags, as shown below (for example, this replaces D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libqtharfbuzz.a
with -lqtharfbuzz
, etc.). This results in a successful build, but when I attempt to run the resulting executable, I get the runtime failure shown:
$ g++ --static -static-libstdc++ $(pkg-config Qt5Widgets Qt5Core --cflags) hello.cpp $(pkg-config Qt5Widgets --static --libs | sed 's/D:\/\S\+\/lib\(\S\+\)\.a\b/-l\1/g') -o hello
$ ./hello
qt.qpa.plugin: Could not find the Qt platform plugin "windows" in ""
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
My question is, then, how do you build a static Qt executable using MSYS2/MinGW
and mingw-w64-x86_64-qt5-static
?
Edit: To provide a little more transparency in case it is useful for understanding/debugging the issue, I've run the same static build commands with set -x
in bash so that you can see how the pkg-config
commands get expanded.
Without the sed
filter:
$ g++ --static -static-libstdc++ $(pkg-config Qt5Widgets Qt5Core --cflags) hello.cpp $(pkg-config Qt5Widgets --static --libs) -o hello
++ pkg-config Qt5Widgets Qt5Core --cflags
++ pkg-config Qt5Widgets --static --libs
+ g++ --static -static-libstdc++ -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -IC:/msys64/mingw64/qt5-static/include/QtWidgets -IC:/msys64/mingw64/qt5-static/include -IC:/msys64/mingw64/qt5-static/include/QtGui -IC:/msys64/mingw64/qt5-static/include -IC:/msys64/mingw64/qt5-static/include/QtCore -IC:/msys64/mingw64/qt5-static/include hello.cpp -LC:/msys64/mingw64/qt5-static/lib -lQt5Widgets D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libQt5Gui.a -ld3d11 -ldxgi -ldxguid D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libqtlibpng.a D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libqtharfbuzz.a -lcomdlg32 -loleaut32 -limm32 -lglu32 -lopengl32 -lgdi32 D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libQt5Core.a -lmpr -luserenv -lversion -lz D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libqtpcre2.a -lzstd -lnetapi32 -lws2_32 -ladvapi32 -lkernel32 -lole32 -lshell32 -luuid -luser32 -lwinmm -luxtheme -ldwmapi -lshell32 -lcomdlg32 -loleaut32 -limm32 -lwinmm -lws2_32 -lole32 -luuid -ladvapi32 -lglu32 -lopengl32 -lgdi32 -luser32 -lQt5Gui -ld3d11 -ldxgi -ldxguid D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libQt5Core.a -lmpr -luserenv -lversion -lz D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libqtpcre2.a -lzstd -lnetapi32 -lws2_32 -ladvapi32 -lkernel32 -lole32 -lshell32 -luuid -luser32 -lwinmm D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libqtlibpng.a D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libqtharfbuzz.a -lz -lcomdlg32 -loleaut32 -limm32 -lwinmm -lws2_32 -lole32 -luuid -ladvapi32 -lglu32 -lopengl32 -lgdi32 -luser32 -lQt5Core -lmpr -luserenv -lversion -lz D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libqtpcre2.a -lzstd -lnetapi32 -lws2_32 -ladvapi32 -lkernel32 -lole32 -lshell32 -luuid -luser32 -lwinmm -o hello
g++.exe: error: D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libQt5Gui.a: No such file or directory
g++.exe: error: D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libqtlibpng.a: No such file or directory
g++.exe: error: D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libqtharfbuzz.a: No such file or directory
g++.exe: error: D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libQt5Core.a: No such file or directory
g++.exe: error: D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libqtpcre2.a: No such file or directory
g++.exe: error: D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libQt5Core.a: No such file or directory
g++.exe: error: D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libqtpcre2.a: No such file or directory
g++.exe: error: D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libqtlibpng.a: No such file or directory
g++.exe: error: D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libqtharfbuzz.a: No such file or directory
g++.exe: error: D:/mingwbuild/mingw-w64-qt5-static/src/x86_64/qtbase/lib/libqtpcre2.a: No such file or directory
With the sed
filter:
$ g++ --static -static-libstdc++ $(pkg-config Qt5Widgets Qt5Core --cflags) hello.cpp $(pkg-config Qt5Widgets --static --libs | sed 's/D:\/\S\+\/lib\(\S\+\)\.a\b/-l\1/g') -o hello
++ pkg-config Qt5Widgets Qt5Core --cflags
++ pkg-config Qt5Widgets --static --libs
++ sed 's/D:\/\S\+\/lib\(\S\+\)\.a\b/-l\1/g'
+ g++ --static -static-libstdc++ -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -IC:/msys64/mingw64/qt5-static/include/QtWidgets -IC:/msys64/mingw64/qt5-static/include -IC:/msys64/mingw64/qt5-static/include/QtGui -IC:/msys64/mingw64/qt5-static/include -IC:/msys64/mingw64/qt5-static/include/QtCore -IC:/msys64/mingw64/qt5-static/include hello.cpp -LC:/msys64/mingw64/qt5-static/lib -lQt5Widgets -lQt5Gui -ld3d11 -ldxgi -ldxguid -lqtlibpng -lqtharfbuzz -lcomdlg32 -loleaut32 -limm32 -lglu32 -lopengl32 -lgdi32 -lQt5Core -lmpr -luserenv -lversion -lz -lqtpcre2 -lzstd -lnetapi32 -lws2_32 -ladvapi32 -lkernel32 -lole32 -lshell32 -luuid -luser32 -lwinmm -luxtheme -ldwmapi -lshell32 -lcomdlg32 -loleaut32 -limm32 -lwinmm -lws2_32 -lole32 -luuid -ladvapi32 -lglu32 -lopengl32 -lgdi32 -luser32 -lQt5Gui -ld3d11 -ldxgi -ldxguid -lQt5Core -lmpr -luserenv -lversion -lz -lqtpcre2 -lzstd -lnetapi32 -lws2_32 -ladvapi32 -lkernel32 -lole32 -lshell32 -luuid -luser32 -lwinmm -lqtlibpng -lqtharfbuzz -lz -lcomdlg32 -loleaut32 -limm32 -lwinmm -lws2_32 -lole32 -luuid -ladvapi32 -lglu32 -lopengl32 -lgdi32 -luser32 -lQt5Core -lmpr -luserenv -lversion -lz -lqtpcre2 -lzstd -lnetapi32 -lws2_32 -ladvapi32 -lkernel32 -lole32 -lshell32 -luuid -luser32 -lwinmm -o hello
Also, at the moment I'm merely interested in understanding how to get this trivial example building from the command line in MSYS2/Mingw using the existing package MSYS2 package. I'm not yet interested in using Qt Creator/QMake/etc. to manage the build.