Cross-compilation from Windows to aarch64
-
Hello everyone,
Let me introduce my setup. I have two computers with Qt installed, one on linux (archlinux) and one on Windows 10.
I'm coding alternately on both of them, and use Qt, and I am very happy because it works great.I'm currently trying to develop a new program for a aarch64 architecture (Raspberry Pi 3 B2 - ArchlinuxARM - aarch64).
I could send the sources to my target and let it compile for me but that would be too simple. I'd like to enhance my programming setup (and knowledge) doing the following things :- Cross-compile Qt 5.14.2 for remote deployment from my linux-g++-64 host platform to my linux-aarch64-gnu-g++ target platform
- I cross-compiled and installed Qt sources using the aarch64-linux-gnu-gcc toolchain and following the https://wiki.qt.io/Building_Qt_5_from_Git tutorial
- I successfully cross-compiled a simple program and remote-deployed it using QtCreator (I'm super proud btw).
- Cross-compile Qt 5.14.2 for remote deployment from my win32-g++ host platform to my linux-aarch64-gnu-g++ target platform
- no luck here, and I need some help.
I installed the gcc-arm-9.2-2019.12-mingw-w64-i686-aarch64-none-linux-gnu toolchain.
I am using MinGW 7.3.0 64-bit as host compiler, which I installed with Qt in {Qt_Install_Dir}\Tools\mingw730_64\
I copied mingw32-make.exe to make.exe because Qt would give me an error if no "make" was found in PATH.Perl (Strawberry Perl) and Git (git-scm) are installed and in PATH.
Both compiler bin directories are in PATH.My PATH during compilation is :
D:\Documents\Programmation\Compilation\qt5\qtrepotools\bin; D:\Documents\Programmation\Compilation\qt5\gnuwin32\bin; D:\Documents\Programmation\Compilation\qt5\qtbase\bin; D:\Documents\Programmation\Compilation\gcc-arm-9.2-2019.12-mingw-w64-i686-aarch64-none-linux-gnu\bin; D:\Programmes\Qt\Tools\mingw730_64\bin; D:\Programmes\Git\cmd; D:\Programmes\Perl\perl\bin; D:\Programmes\Git\usr\bin; C:\Windows\System32; C:\Windows;
I thought I should use linux-aarch64-gnu-g++ as xplatform because it is what I used during my linux computer successful cross-compilation.
So I modified {Path_to_qt5}\qtbase\mkspecs\linux-aarch64-gnu-g++\qmake.conf with the following content so that it would use my toolchain (given with the CROSS_COMPILE configure variable) instead of the default linux-aarch64-gnu- :# # qmake configuration for building with $${CROSS_COMPILE}g++ # MAKEFILE_GENERATOR = UNIX CONFIG += incremental QMAKE_INCREMENTAL_STYLE = sublib include(../common/linux.conf) include(../common/gcc-base-unix.conf) include(../common/g++-unix.conf) # modifications to g++.conf QMAKE_CC = $${CROSS_COMPILE}gcc QMAKE_CXX = $${CROSS_COMPILE}g++ QMAKE_LINK = $${CROSS_COMPILE}g++ QMAKE_LINK_SHLIB = $${CROSS_COMPILE}g++ # modifications to linux.conf QMAKE_AR = $${CROSS_COMPILE}ar cqs QMAKE_OBJCOPY = $${CROSS_COMPILE}objcopy QMAKE_NM = $${CROSS_COMPILE}nm -P QMAKE_STRIP = $${CROSS_COMPILE}strip load(qt_config)
My compile batch script is the following :
@echo off set version=5.14.2 set qtName=qt%version:~0,1% set target=linux-aarch64-gnu-g++ set filepath=%~dp0 set toolchainName=gcc-arm-9.2-2019.12-mingw-w64-i686-aarch64-none-linux-gnu set gccName=aarch64-none-linux-gnu set buildDir=%filepath%build set qtDir=%filepath%%qtName% set toolchainDir=%filepath%%toolchainName% set PATH=C:\Windows; set PATH=C:\Windows\System32;%PATH% set PATH=D:\Programmes\Git\usr\bin;%PATH% set PATH=D:\Programmes\Perl\perl\bin;%PATH% set PATH=D:\Programmes\Git\cmd;%PATH% set PATH=D:\Programmes\Qt\Tools\mingw730_64\bin;%PATH% set PATH=%toolchainDir%\bin;%PATH% set PATH=%qtDir%\qtbase\bin;%PATH% set PATH=%qtDir%\gnuwin32\bin;%PATH% set PATH=%qtDir%\qtrepotools\bin;%PATH% set crosscompile=%gccName%- set sysroot=%toolchainDir:\=/%/%gccName%/libc set skip=0 set force=0 for %%i in (%*) do ( if "%%i"=="f" ( echo Forcing reset set force=1 ) else ( if "%%i"=="s" ( echo Skipping set skip=1 ) ) ) if "%skip%"=="0" ( if "%force%"=="1" ( rd /S /Q %qtDir% git clone git://code.qt.io/qt/%qtName%.git cd %qtDir% git checkout %version% perl .\init-repository --module-subset=essential,-qtdoc ) else ( cd %qtDir% git submodule foreach --recursive "git clean -dfx" && git clean -dfx cd qtbase git reset --hard ) copy "%filepath%\qmake.conf" "%qtDir%\qtbase\mkspecs\%target%\" ) cd %filepath% rd /S /Q %buildDir% mkdir %buildDir% cd %buildDir% echo %PATH% "%qtDir%\configure.bat" -v -release -opensource -platform win32-g++ -xplatform %target% -sysroot %sysroot% -device-option CROSS_COMPILE=%crosscompile% -qt-zlib -nomake examples -no-compile-examples -nomake tests -confirm-license mingw32-make
My configure command is the following :
Command line: -v -release -opensource -platform win32-g++ -xplatform linux-aarch64-gnu-g++ -sysroot D:/Documents/Programmation/Compilation/gcc-arm-9.2-2019.12-mingw-w64-i686-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc -device-option "CROSS_COMPILE=aarch64-none-linux-gnu-" -qt-zlib -nomake examples -no-compile-examples -nomake tests -confirm-license
The compilation is OK until :
##### COMPILING OTHER CLASSES ##### g++ -c -o registry.o -DUNICODE -DMINGW_HAS_SECURE_API=1 -std=c++11 -ffunction-sections -g -ID:/Documents/Programmation/Compilation/qt5/qtbase/qmake -ID:/Documents/Programmation/Compilation/qt5/qtbase/qmake/library -ID:/Documents/Programmation/Compilation/qt5/qtbase/qmake/generators -ID:/Documents/Programmation/Compilation/qt5/qtbase/qmake/generators/unix -ID:/Documents/Programmation/Compilation/qt5/qtbase/qmake/generators/win32 -ID:/Documents/Programmation/Compilation/qt5/qtbase/qmake/generators/mac -I../include -I../include/QtCore -I../include/QtCore/5.14.2 -I../include/QtCore/5.14.2/QtCore -I../src/corelib/global -ID:/Documents/Programmation/Compilation/qt5/qtbase/mkspecs/win32-g++ -DQT_VERSION_STR=\"5.14.2\" -DQT_VERSION_MAJOR=5 -DQT_VERSION_MINOR=14 -DQT_VERSION_PATCH=2 -DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED -DPROEVALUATOR_FULL -DQT_NO_FOREACH D:/Documents/Programmation/Compilation/qt5/qtbase/qmake/library/registry.cpp g++ -c -o qlibraryinfo.o -DUNICODE -DMINGW_HAS_SECURE_API=1 -std=c++11 -ffunction-sections -g -ID:/Documents/Programmation/Compilation/qt5/qtbase/qmake -ID:/Documents/Programmation/Compilation/qt5/qtbase/qmake/library -ID:/Documents/Programmation/Compilation/qt5/qtbase/qmake/generators -ID:/Documents/Programmation/Compilation/qt5/qtbase/qmake/generators/unix -ID:/Documents/Programmation/Compilation/qt5/qtbase/qmake/generators/win32 -ID:/Documents/Programmation/Compilation/qt5/qtbase/qmake/generators/mac -I../include -I../include/QtCore -I../include/QtCore/5.14.2 -I../include/QtCore/5.14.2/QtCore -I../src/corelib/global -ID:/Documents/Programmation/Compilation/qt5/qtbase/mkspecs/win32-g++ -DQT_VERSION_STR=\"5.14.2\" -DQT_VERSION_MAJOR=5 -DQT_VERSION_MINOR=14 -DQT_VERSION_PATCH=2 -DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED -DPROEVALUATOR_FULL -DQT_NO_FOREACH -DQT_BUILD_QMAKE_BOOTSTRAP D:/Documents/Programmation/Compilation/qt5/qtbase/src/corelib/global/qlibraryinfo.cpp g++ -o "../bin/qmake.exe" main.o meta.o option.o project.o property.o ioutils.o proitems.o qmakebuiltins.o qmakeevaluator.o qmakeglobals.o qmakeparser.o qmakevfs.o pbuilder_pbx.o makefile.o makefiledeps.o metamakefile.o projectgenerator.o unixmake2.o unixmake.o mingw_make.o msbuild_objectmodel.o msvc_nmake.o msvc_objectmodel.o msvc_vcproj.o msvc_vcxproj.o winmakefile.o xmloutput.o qutfcodec.o qendian.o qglobal.o qlogging.o qmalloc.o qnumeric.o qoperatingsystemversion.o qrandom.o qabstractfileengine.o qbuffer.o qdatastream.o qdebug.o qdir.o qdiriterator.o qfile.o qfiledevice.o qfileinfo.o qfilesystemengine.o qfilesystementry.o qfsfileengine.o qfsfileengine_iterator.o qiodevice.o qsettings.o qtemporaryfile.o qtextstream.o qjsonarray.o qjson.o qjsondocument.o qjsonobject.o qjsonparser.o qjsonvalue.o qmetatype.o qsystemerror.o qvariant.o quuid.o qarraydata.o qbitarray.o qbytearray.o qbytearraylist.o qbytearraymatcher.o qcalendar.o qgregoriancalendar.o qromancalendar.o qcryptographichash.o qdatetime.o qhash.o qlist.o qlocale.o qlocale_tools.o qmap.o qregexp.o qringbuffer.o qstringbuilder.o qstring.o qstringlist.o qversionnumber.o qvsnprintf.o qxmlstream.o qxmlutils.o qfilesystemengine_win.o qfilesystemiterator_win.o qfsfileengine_win.o qlocale_win.o qsettings_win.o qoperatingsystemversion_win.o qsystemlibrary.o registry.o qlibraryinfo.o -static -s -lole32 -luuid -ladvapi32 -lkernel32 -lnetapi32 -Wl,--gc-sections Info: creating super cache file D:\Documents\Programmation\Compilation\build\.qmake.super Info: creating cache file D:\Documents\Programmation\Compilation\build\.qmake.cache Command line: -v -release -opensource -platform win32-g++ -xplatform linux-aarch64-gnu-g++ -sysroot D:/Documents/Programmation/Compilation/gcc-arm-9.2-2019.12-mingw-w64-i686-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc -device-option "CROSS_COMPILE=aarch64-none-linux-gnu-" -qt-zlib -nomake examples -no-compile-examples -nomake tests -confirm-license Info: creating stash file D:\Documents\Programmation\Compilation\build\.qmake.stash This is the Qt Open Source Edition. You have already accepted the terms of the Open Source license. Running configuration tests... Checking for machine tuple... + aarch64-none-linux-gnu-g++ -dumpmachine > aarch64-none-linux-gnu test config.qtbase.tests.machineTuple succeeded Checking for valid makespec... + cd D:\Documents\Programmation\Compilation\build\config.tests\verifyspec && D:\Documents\Programmation\Compilation\build\qtbase\bin\qmake.exe "CONFIG -= qt debug_and_release app_bundle lib_bundle" "CONFIG += shared warn_off console single_arch" "QMAKE_CFLAGS += --sysroot=D:/Documents/Programmation/Compilation/gcc-arm-9.2-2019.12-mingw-w64-i686-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc" "QMAKE_CXXFLAGS += --sysroot=D:/Documents/Programmation/Compilation/gcc-arm-9.2-2019.12-mingw-w64-i686-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc" "QMAKE_LFLAGS += --sysroot=D:/Documents/Programmation/Compilation/gcc-arm-9.2-2019.12-mingw-w64-i686-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc" -early "CONFIG += cross_compile" D:/Documents/Programmation/Compilation/qt5/qtbase/config.tests/verifyspec + cd D:\Documents\Programmation\Compilation\build\config.tests\verifyspec && set MAKEFLAGS=& mingw32-make > g++ -c --sysroot=D:/Documents/Programmation/Compilation/gcc-arm-9.2-2019.12-mingw-w64-i686-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc -O2 -w -fPIC -ID:/Documents/Programmation/Compilation/qt5/qtbase/config.tests/verifyspec -I. -ID:/Documents/Programmation/Compilation/qt5/qtbase/mkspecs/linux-aarch64-gnu-g++ -o verifyspec.obj D:/Documents/Programmation/Compilation/qt5/qtbase/config.tests/verifyspec/verifyspec.cpp > g++ --sysroot=D:/Documents/Programmation/Compilation/gcc-arm-9.2-2019.12-mingw-w64-i686-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc -Wl,-O1 -o verifyspec verifyspec.obj test config.qtbase.tests.verifyspec succeeded Checking for target architecture... + cd D:\Documents\Programmation\Compilation\build\config.tests\arch && D:\Documents\Programmation\Compilation\build\qtbase\bin\qmake.exe "CONFIG -= qt debug_and_release app_bundle lib_bundle" "CONFIG += shared warn_off console single_arch" "QMAKE_CFLAGS += --sysroot=D:/Documents/Programmation/Compilation/gcc-arm-9.2-2019.12-mingw-w64-i686-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc" "QMAKE_CXXFLAGS += --sysroot=D:/Documents/Programmation/Compilation/gcc-arm-9.2-2019.12-mingw-w64-i686-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc" "QMAKE_LFLAGS += --sysroot=D:/Documents/Programmation/Compilation/gcc-arm-9.2-2019.12-mingw-w64-i686-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc" -early "CONFIG += cross_compile" D:/Documents/Programmation/Compilation/qt5/qtbase/config.tests/arch + cd D:\Documents\Programmation\Compilation\build\config.tests\arch && set MAKEFLAGS=& mingw32-make > g++ -c --sysroot=D:/Documents/Programmation/Compilation/gcc-arm-9.2-2019.12-mingw-w64-i686-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc -O2 -w -fPIC -ID:/Documents/Programmation/Compilation/qt5/qtbase/config.tests/arch -I. -ID:/Documents/Programmation/Compilation/qt5/qtbase/mkspecs/linux-aarch64-gnu-g++ -o arch.obj D:/Documents/Programmation/Compilation/qt5/qtbase/config.tests/arch/arch.cpp > g++ --sysroot=D:/Documents/Programmation/Compilation/gcc-arm-9.2-2019.12-mingw-w64-i686-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc -Wl,-O1 -o arch arch.obj Project ERROR: target architecture detection binary not found.
I found no useful information for this error and therefore I think I did somethig wrong.
Do you have any clue why this error pops up ?Thanks a lot for reading,
Alexis T. - Cross-compile Qt 5.14.2 for remote deployment from my linux-g++-64 host platform to my linux-aarch64-gnu-g++ target platform
-
@B3lette said in Cross-compilation from Windows to aarch64:
A couple of side questions please:
I successfully cross-compiled a simple program and remote-deployed it using QtCreator (I'm super proud btw).
- what platform plugin (i.e. EGLFS, LinuxFB, xcb, etc.) do you use to run the app in the target? In particular I'm curious if you're able to run it with EGLFS
aarch64 architecture (Raspberry Pi 3 B2 - ArchlinuxARM - aarch64)
- what ArchlinuxARM OS image did you use?
-
Hello,
- 1 :
(I think we are discussing something that I don't understand fully here)
The qt5-base is installed on my Pi using the aarch64 qt5-base package.
The following PKGBUILD has been used to generate the binary : https://archlinuxarm.org/packages/aarch64/qt5-base/files/PKGBUILD
Therefore, I think it is using xcb ? - 2 :
I installed the OS with the following tutorial : https://archlinuxarm.org/platforms/armv8/broadcom/raspberry-pi-3
and I used the aarch64 image (see at the bottom of my preceding link).
Current kernel infos :
$ uname -a Linux rpi3 5.6.5-1-ARCH #1 SMP Mon Apr 20 18:49:23 MDT 2020 aarch64 GNU/Linux
- 1 :
-
@B3lette said in Cross-compilation from Windows to aarch64:
Thanks for the reply.
The qt5-base is installed on my Pi using the aarch64 qt5-base package
So next question could be why are you cross-compiling Qt if you already installed a pre-built version of Qt for your device?
Please, I'm not questioning your approach, just trying to understand your scenario., I think it is using xcb ?
In that case you should be running X server, are you?
what if you run your Qt app in RPi device like this:
./yourQtApp -platform eglfs
-
So next question could be why are you cross-compiling Qt if you already installed a pre-built version of Qt for your device?
Please, I'm not questioning your approach, just trying to understand your scenario.No problem :)
Really I'm just beggining to learn about cross compilation. So maybe I'm not doing things the way I should.
What I want is to have a Qt-5.14.2-aarch64 version of Qt on both of my hosts computers, used in QtCreator to one-click-remote-deploy my program to my Raspberry Pi.
Are you saying that I could just copy pre-built Qt files from my Pi to my hosts' toolchain's folders and it would work, since I have a cross-compilation toolchain for the correct target installed ? That would be reaaally handy.
I actually thought of doing it but it seemed far too easy, so I didn't even try.
Anyway I was trying to learn new things too, and got my linux crosscompilation to work and just wondered why the "same" process would not work on Windows.In that case you should be running X server, are you?
Huh, I'm using my Pi in command line, so I don't have a X server running. My RPi Qt program will be a server-side console app including a QNetworkAccessManager, some QsslSockets, and some QJsonXX objects (for example).
what if you run your Qt app in RPi device like this:
./yourQtApp -platform eglfs
Actually I deployed another app that took "-p" as a path argument, so this is just giving me my error message for an invalid path ...
Are you interested in me running another program to check if it works ? -
I have solved this issue by explicitly write the compiler toolchain in qmake.conf. It seems that the CROSS_COMPILE variable is not propagated to the config.tests compilation.
I am now having trouble with zlib install prefix management, but that's another story and I'll open a new thread if need be.
I could post a working batch script which cross-compiles Qt to aarch64.