Building QT 5.15.0 (everywhere) for Android on Windows

  • Install Android Studio with SDK and NDK API Level 28.
  • Install strawberry-perl-5.26.2.1-64bit.msi first (before mingw-w64-install.exe) to E:\PFiles
  • Install MinGW with mingw-w64-install.exe online installer. Select POSIX threads in the installer UI combobox, otherwise you will get:
  • Extract the sources from QT archive qt-everywhere-src-5.15.0.zip to E:\Qt\Qt5.15.0 and run the following script in QT root directory containing configure.bat:
rem This script is based on the steps decribed here: https://doc-snapshots.qt.io/qt5-5.15/android-building.html
rem Strawberry Perl and MinGW are already in PATH after install.

set "JDK_ROOT=C:\Program Files\Android\Android Studio\jre\bin"
set "MINGW_ROOT=E:\PFiles\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin"
set "PERL_ROOT=E:\PFiles\Strawberry\perl\bin"

set PATH=;%JDK_ROOT%;%PATH%
set PATH=;%MINGW_ROOT%;%PATH%
set PATH=;%PERL_ROOT%;%PATH%
set PATH=E:\PFiles\Python35;%PATH%
 
rem Check if the tools are in PATH
where gcc
where mingw32-make.exe
where perl.exe
where javac.exe
where python.exe
 
set "ANDROID_SDK_ROOT=C:\Users\D-Ef\AppData\Local\Android\Sdk"
set "ANDROID_NDK_PATH=C:\Users\D-Ef\AppData\Local\Android\Sdk\ndk-bundle"
rem See qtbase\mkspecs\android-clang\qmake.conf
set "ANDROID_NDK_PLATFORM=android-21"
rem see %ANDROID_SDK_ROOT%\build-tools folder
set "ANDROID_BUILD_TOOLS_REVISION=29.0.2"
 
rem QT_NO_EXCEPTIONS disables "try { } catch (...) {}" surrounding the user code in qthread_unix.cpp
configure.bat -prefix E:\Qt\Qt5.15.0\android -DQT_NO_EXCEPTIONS -release -force-debug-info -platform win32-g++ -opengl es2 -xplatform android-clang ^
  -android-ndk %ANDROID_NDK_PATH% -android-sdk %ANDROID_SDK_ROOT% ^
  -opensource -confirm-license -nomake tests -nomake examples ^
  -skip networkauth -skip serialport -skip serialbus -skip activeqt -skip quick3d -skip quicktimeline -skip lottie -skip remoteobjects -skip scxml ^
  -skip websockets -skip webglplugin -skip webchannel -skip gamepad -skip 3d -skip wayland -skip connectivity -skip sensors -skip script ^
  -skip location -skip xmlpatterns -skip speech -skip virtualkeyboard -skip datavis3d -skip charts -skip webengine -skip webview -skip doc ^
  -skip macextras -skip x11extras -skip winextras
 
mingw32-make.exe -j4
 
mingw32-make install

this script uses NDK 21.2.6472646, but Qt Creator 4.12.1 installs NDK 21.1.6352462:

Building QT application

On my machine the above script built QT successfully, but when I tried to build my app in QT Creator I got:

18:49:58: Starting: "C:\Users\D-Ef\AppData\Local\Android\Sdk\ndk\21.1.6352462\prebuilt\windows-x86_64\bin\make.exe" V=1 -j8
E:\Qt\Qt5.15.0\android\bin\rcc.exe -name qml ..\..\examples\src\MyApp\MyAppQt\qml.qrc -o armeabi-v7a\qrc_qml.cpp
E:\Qt\Qt5.15.0\android\bin\rcc.exe -name scene ..\..\examples\src\MyApp\MyAppQt\scene.qrc -o armeabi-v7a\qrc_scene.cpp
make: *** [Makefile:560: armeabi-v7a\qrc_qml.cpp] Error -1073741515
make: *** Waiting for unfinished jobs....
make: *** [Makefile:564: armeabi-v7a\qrc_scene.cpp] Error -1073741515

and when I started rcc.exe manually I got:

---------------------------
rcc.exe - System Error
---------------------------
The code execution cannot proceed because libgcc_s_seh-1.dll was not found. Reinstalling the program may fix this problem. 
---------------------------
OK   
---------------------------

Obviously, it requires MinGW to be in PATH:

set PATH=E:\PFiles\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin;%PATH%

So I updated Path environment variable in QT Creator:

and the build succeeded and the application started successfully.

Also a possible solution is to copy MinGW dlls:

libgcc_s_seh-1.dll
libstdc++-6.dll
libwinpthread-1.dll

to QT binary directory.

Testing the app

I tested the app with Android 10 x86 emulators and it seems it is OK, but it is not clear how to test it on ARM because I have ARM images till API 25 only:

Uploading the app to Google Play

When I published the app in Google Play for internal testing it passed the monkey test on all the devices except Android 5.0 armeabi-v7a, see Prelaunch Report:

This crash stably repeated in 3 releases, see below for more information on it:

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'Huawei/ALE-L23/hwALE-H:5.0.1/HuaweiALE-L23/C605B150:user/release-keys'
Revision: '0'
ABI: 'arm64'
pid: 20596, tid: 20703, name: qtMainLoopThrea  >>> com.domain.MyApp <<<
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
Abort message: 'art/runtime/mirror/art_method.cc:377] Check failed: !IsFastNative() int java.lang.Character.digitImpl!(int, int)'
    x0   0000000000000000  x1   00000000000050df  x2   0000000000000006  x3   00000055a9bb4c00
    x4   00000055a9bb4c00  x5   0000000000000005  x6   0000000000000001  x7   0000000000000020
    x8   0000000000000083  x9   0000007f9795de18  x10  0000000000000003  x11  0000000000000001
    x12  0000000000000001  x13  00000055a963f000  x14  e673a3bab54834e2  x15  0000000000000005
    x16  0000007f97956798  x17  0000007f9791b1bc  x18  0000000000000000  x19  00000055a9bb4c00
    x20  0000007f7e89ebb0  x21  0000007f9795c000  x22  0000000000000002  x23  0000000000000006
    x24  0000007f7e89d420  x25  00000055a9bb41e0  x26  0000000000000000  x27  00000055a9c2c950
    x28  0000000070f128c8  x29  0000007f7e89d2a0  x30  0000007f978d8ee0
    sp   0000007f7e89d2a0  pc   0000007f9791b1c4  pstate 0000000060000000
backtrace:
    #00 pc 00000000000601c4  /system/lib64/libc.so (tgkill+8)
    #01 pc 000000000001dedc  /system/lib64/libc.so (pthread_kill+160)
    #02 pc 000000000001f410  /system/lib64/libc.so (raise+28)
    #03 pc 0000000000018ebc  /system/lib64/libc.so (abort+60)
    #04 pc 00000000002eafac  /system/lib64/libart.so (art::Runtime::Abort()+300)
    #05 pc 00000000000cdd38  /system/lib64/libart.so (art::LogMessage::~LogMessage()+2684)
    #06 pc 000000000027f2e8  /system/lib64/libart.so (art::mirror::ArtMethod::RegisterNative(art::Thread*, void const*, bool)+452)
    #07 pc 0000000000270e94  /system/lib64/libart.so (art::JNI::RegisterNativeMethods(_JNIEnv*, _jclass*, JNINativeMethod const*, int, bool)+616)
    #08 pc 000000000000242c  /system/lib64/libnativehelper.so (jniRegisterNativeMethods+124)
    #09 pc 000000000001ac2c  /system/lib64/libjavacore.so (JNI_OnLoad+100)
    #10 pc 00000000001e2534  /data/app/com.domain.MyApp-1/lib/arm64/libQt5Core_arm64-v8a.so
    #11 pc 00000000001df86c  /data/app/com.domain.MyApp-1/lib/arm64/libQt5Core_arm64-v8a.so
    #12 pc 00000000001df764  /data/app/com.domain.MyApp-1/lib/arm64/libQt5Core_arm64-v8a.so
    #13 pc 00000000001df670  /data/app/com.domain.MyApp-1/lib/arm64/libQt5Core_arm64-v8a.so
    #14 pc 00000000001dcacc  /data/app/com.domain.MyApp-1/lib/arm64/libQt5Core_arm64-v8a.so (QFactoryLoader::instance(int) const+108)
    #15 pc 0000000000123fb0  /data/app/com.domain.MyApp-1/lib/arm64/libQt5Gui_arm64-v8a.so

The list of the modules we build

Modules we build (see generated Makefile at QT root directory):

base
androidextras
imageformats - not sure we need it
svg
declarative - QML
purchasing
graphicaleffects
quickcontrols2
quickcontrols
multimedia
tools - command line tools like 'lrelease.exe'
translations

Notes

I have an impression that using

mingw32-make -j4 install

instead of

mingw32-make install

results in unstable behavior of the build script.

The content of qtbase\mkspecs\android-clang\qmake.conf:

# qmake configuration for building with android-clang
MAKEFILE_GENERATOR      = UNIX
QMAKE_PLATFORM          = android
QMAKE_COMPILER          = gcc clang llvm
 
CONFIG                 += android_install unversioned_soname unversioned_libname plugin_with_soname android_deployment_settings
 
include(../common/linux.conf)
include(../common/gcc-base-unix.conf)
include(../common/clang.conf)
 
load(device_config)
 
# In early configure setup; nothing useful to be done here.
isEmpty(DEFAULT_ANDROID_NDK_ROOT): return()
 
NDK_ROOT = $$(ANDROID_NDK_ROOT)
isEmpty(NDK_ROOT): NDK_ROOT = $$DEFAULT_ANDROID_NDK_ROOT
 
!exists($$NDK_ROOT): error("You need to set the ANDROID_NDK_ROOT environment variable to point to your Android NDK.")
 
NDK_HOST = $$(ANDROID_NDK_HOST)
isEmpty(NDK_HOST): NDK_HOST = $$DEFAULT_ANDROID_NDK_HOST
 
ANDROID_PLATFORM = $$(ANDROID_NDK_PLATFORM)
isEmpty(ANDROID_PLATFORM): ANDROID_PLATFORM = $$DEFAULT_ANDROID_PLATFORM
 
ANDROID_SDK_ROOT = $$(ANDROID_SDK_ROOT)
isEmpty(ANDROID_SDK_ROOT): ANDROID_SDK_ROOT = $$DEFAULT_ANDROID_SDK_ROOT
 
ANDROID_SDK_BUILD_TOOLS_REVISION = $$(ANDROID_BUILD_TOOLS_REVISION)
isEmpty(ANDROID_SDK_BUILD_TOOLS_REVISION) {
    SDK_BUILD_TOOLS_REVISIONS = $$files($$ANDROID_SDK_ROOT/build-tools/*)
    for (REVISION, SDK_BUILD_TOOLS_REVISIONS) {
        BASENAME = $$basename(REVISION)
        greaterThan(BASENAME, $$ANDROID_SDK_BUILD_TOOLS_REVISION): ANDROID_SDK_BUILD_TOOLS_REVISION = $$BASENAME
    }
}
 
ALL_ANDROID_ABIS = $$(ALL_ANDROID_ABIS)
isEmpty(ALL_ANDROID_ABIS): ALL_ANDROID_ABIS = $$DEFAULT_ANDROID_ABIS
isEmpty(ALL_ANDROID_ABIS): ALL_ANDROID_ABIS = arm64-v8a armeabi-v7a x86_64 x86
 
CONFIG += $$ANDROID_PLATFORM
 
ANDROID_MIN_SDK_VERSION = $$replace(ANDROID_PLATFORM, "android-", "")
ANDROID_TARGET_SDK_VERSION = 28
 
...

Links

2 Responses to Building QT 5.15.0 (everywhere) for Android on Windows

  1. dmitriano says:

    There is
    ANDROID_TARGET_SDK_VERSION = 28
    in
    E:\repos\qt-everywhere-src-5.15.2\qtbase\mkspecs\android-clang\qmake.conf
    so probably I need to add
    ANDROID_TARGET_SDK_VERSION = 29
    for example

  2. Marius says:

    Very good tutorial.

    I skipped the build part because I installed from offline installer.

Leave a Reply

Your email address will not be published. Required fields are marked *