- Install Android Studio with SDK and NDK API Level 28.
- Install
strawberry-perl-5.26.2.1-64bit.msi
first (beforemingw-w64-install.exe
) toE:\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
toE:\Qt\Qt5.15.0
and run the following script in QT root directory containingconfigure.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
...
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
Very good tutorial.
I skipped the build part because I installed from offline installer.