papoj
papoj

Reputation: 21

How to cross-compile Qt6 on Linux for Windows?

I'm trying to cross-compile Qt 6.2.1. Target - Windows, my machine OS - Linux (Mint 20.2) (both 64bit). Unfortunately I can't compile it on Windows, so I have to do this cross-compilation.

My configure cmd:

./../qt-everywhere-src-6.2.1/configure -prefix $PWD/. -platform linux-gcc-64 -xplatform win32-g++ -device-option CROSS_COMPILE=/usr/bin/x86_64-w64-mingw32- -opensource -opengl desktop -qt-host-path /home/papoj/Projects/host_qtbuild

At the end of CMake work I'm getting this:

CMake Warning:
  Manually-specified variables were not used by the project:

    QT_QMAKE_DEVICE_OPTIONS

And then, after cmake --build . --parallel:

FAILED: qtbase/src/tools/bootstrap/CMakeFiles/Bootstrap.dir/__/__/corelib/global/qglobal.cpp.o 
/usr/bin/c++ -DHAVE_CONFIG_H -DQT_BOOTSTRAPPED -DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII -DQT_NO_DEBUG -DQT_NO_FOREACH -DQT_USE_QSTRINGBUILDER -DQT_VERSION_MAJOR=6 -DQT_VERSION_MINOR=2 -DQT_VERSION_PATCH=1 -DQT_VERSION_STR=\"6.2.1\" -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -I/home/papoj/Projects/qtbuild/qtbase/src/corelib/Core_autogen/include -I/home/papoj/Projects/qtbuild/qtbase/include -I/home/papoj/Projects/qtbuild/qtbase/include/QtCore -I/home/papoj/Projects/qt-everywhere-src-6.2.1/qtbase/src/corelib -I/home/papoj/Projects/qtbuild/qtbase/src/corelib -I/home/papoj/Projects/qtbuild/qtbase/src/corelib/global -I/home/papoj/Projects/qtbuild/qtbase/src/corelib/kernel -I/home/papoj/Projects/qt-everywhere-src-6.2.1/qtbase/src/corelib/../3rdparty/tinycbor/src -I/home/papoj/Projects/qtbuild/qtbase/include/QtCore/6.2.1 -I/home/papoj/Projects/qtbuild/qtbase/include/QtCore/6.2.1/QtCore -I/home/papoj/Projects/qt-everywhere-src-6.2.1/qtbase/src/corelib/../3rdparty/double-conversion/double-conversion -I/home/papoj/Projects/qt-everywhere-src-6.2.1/qtbase/src/corelib/../3rdparty/double-conversion -I/home/papoj/Projects/qt-everywhere-src-6.2.1/qtbase/src/corelib/../3rdparty/forkfd -I/home/papoj/Projects/qtbuild/qtbase/src/corelib/.rcc -I/home/papoj/Projects/qt-everywhere-src-6.2.1/qtbase/mkspecs/win32-g++ -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/home/papoj/Projects/qtbuild/qtbase/src/xml/Xml_autogen/include -I/home/papoj/Projects/qtbuild/qtbase/include/QtXml -I/home/papoj/Projects/qt-everywhere-src-6.2.1/qtbase/src/xml -I/home/papoj/Projects/qtbuild/qtbase/src/xml -I/home/papoj/Projects/qtbuild/qtbase/include/QtXml/6.2.1 -I/home/papoj/Projects/qtbuild/qtbase/include/QtXml/6.2.1/QtXml -I/home/papoj/Projects/qt-everywhere-src-6.2.1/qtbase/src/tools/bootstrap/.. -I/home/papoj/Projects/qt-everywhere-src-6.2.1/qtbase/src/tools/bootstrap/../../3rdparty/tinycbor/src -DNDEBUG -O2 -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -Wall -Wextra -ffunction-sections -fdata-sections -mshstk -Wsuggest-override -std=gnu++17 -MD -MT qtbase/src/tools/bootstrap/CMakeFiles/Bootstrap.dir/__/__/corelib/global/qglobal.cpp.o -MF qtbase/src/tools/bootstrap/CMakeFiles/Bootstrap.dir/__/__/corelib/global/qglobal.cpp.o.d -o qtbase/src/tools/bootstrap/CMakeFiles/Bootstrap.dir/__/__/corelib/global/qglobal.cpp.o -c /home/papoj/Projects/qt-everywhere-src-6.2.1/qtbase/src/corelib/global/qglobal.cpp
In file included from /home/papoj/Projects/qt-everywhere-src-6.2.1/qtbase/src/corelib/global/qglobal.cpp:41:
/home/papoj/Projects/qt-everywhere-src-6.2.1/qtbase/mkspecs/win32-g++/qplatformdefs.h:55:10: fatal error: tchar.h: No such file or directory
   55 | #include <tchar.h>
      |          ^~~~~~~~~

I have checked (this is also visible in log above) and CMake, for some reason, ignore my "CROSS_COMPILE" option and uses Linux c++ tool to compile instead of 'x86_64-w64-mingw32-g++', but I dont know how to fix that.

Does anybody cross-compiled Qt6 for Windows on Linux manually? I cannot find any working solution on the Internet.

Upvotes: 0

Views: 4669

Answers (2)

DrAl
DrAl

Reputation: 72716

Another, possibly simpler approach to cross-compiling Qt for Windows on Linux is to use qmake with MXE and mxedeployqt (the latter is the equivalent of windeployqt and collates the required DLLs).

I've got a couple of projects that use MXE and mxedeployqt within Docker to build Qt. The docker container builds MXE from source (because I wanted a recent gcc and it wasn't available in the MXE repositories) which takes a long time, but once that's done, compiling Qt code is very straightforward: docker-compose up.

Once set up, creating a new project that uses the same method is very simple as it uses the same Dockerfile and build script. Two example repositories that use this method are ARPCalc and Digraph. Most of the configuration required to get a working build system is in the dockerfiles/winqt folder: https://github.com/abudden/digraph/blob/master/dockerfiles/winqt

Upvotes: 0

papoj
papoj

Reputation: 21

For those coming here from google with same problem.

In Qt6 you need to specify Cmake toolchain for cross-compilation (I get something similar to toolchain shared here), as 'alone' device-option CROSS_COMPILE (as in cmd from my question) is depreciated/outdated (or smth like that).

In my case I needed to use CMake toolchain and device-option CROSS-COMPILE as well, because in other way qmake was not able to find proper cross-platform compiler (in my case x86_64-w64-mingw32-g++-posix). To use compiler with "posix" at the end I needed to modify qtbase/mkspecs/win32-g++/qmake.conf. This is how it looks like after changes:

#
# qmake configuration for win32-g++
#
# Written for MinGW-w64 / gcc 5.3 or higher
#
# Cross compile example for i686-w64-mingw32-g++:
#   configure -xplatform win32-g++ -device-option CROSS_COMPILE=i686-w64-mingw32-
#

include(../common/g++-win32.conf)
include(../common/windows-desktop.conf)

# modifications to g++-win32.conf

QMAKE_CC                = $${CROSS_COMPILE}gcc-posix
QMAKE_CFLAGS           += -fno-keep-inline-dllexport
QMAKE_CFLAGS_WARN_ON   += -Wextra

QMAKE_CXX               = $${CROSS_COMPILE}g++-posix
QMAKE_CXXFLAGS         += -fno-keep-inline-dllexport
QMAKE_CXXFLAGS_WARN_ON  = $$QMAKE_CFLAGS_WARN_ON
QMAKE_CXXFLAGS_EXCEPTIONS_ON += -mthreads

QMAKE_LINK              = $${CROSS_COMPILE}g++-posix
QMAKE_LINK_C            = $${CROSS_COMPILE}gcc-posix

QMAKE_CFLAGS_LTCG       = -flto
QMAKE_CXXFLAGS_LTCG     = $$QMAKE_CFLAGS_LTCG
QMAKE_LFLAGS_LTCG       = $$QMAKE_CFLAGS_LTCG
QMAKE_LFLAGS_EXCEPTIONS_ON += -mthreads

load(qt_config)

Final ./configure cmd:

./../qt-everywhere-src-6.2.1/configure -prefix $HOME/Projects/testing_qt_builds/qtbuild_with_old_params -platform linux-g++ -xplatform win32-g++ -device-option CROSS_COMPILE=/usr/bin/x86_64-w64-mingw32- -opensource -opengl desktop -qt-host-path $HOME/Qt/6.2.1/gcc_64 -nomake tests -nomake examples -skip qtwebengine -- -DQT_BUILD_TOOLS_WHEN_CROSSCOMPILING=ON -DCMAKE_TOOLCHAIN_FILE=$HOME/Projects/toolchain.cmake

After cmake --build and cmake --install I got host-qmake script in my build path

$HOME/Projects/testing_qt_builds/qtbuild_with_old_params/bin/

Which I had to use to build my Qt project by passing .pro file to it. And then I just copied .exe file to Windows, provided all needed dlls and POOF, app works. :D

My thread on qt forum with same problem where one of moderators helped me a lot to get final solution.

Upvotes: 2

Related Questions