Subversion Repositories tpanel

Rev

Rev 381 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
357 andreas 1
# Build Android APK
2
 
363 andreas 3
There are 2 possibilities to create an Android APK file. You can use the ready script on the command line to build it, or use _QtCreator_. Both methods are based on _cmake_. The following description shows both methods and explain what you need and how to put the things together.
357 andreas 4
 
5
Developing for another platform means to _cross compile_ code. This is necessary because there is no way (not that I know) to create the program directly on the target platform. And even if it would be a nightmere to develop a complex program like **TPanel** directly on an Android phone.
6
 
7
> This documentation assumes that you're creating **TPanel** on a Linux system.
8
 
359 andreas 9
## Prerequisites
357 andreas 10
 
359 andreas 11
We need the [Android SDK](https://developer.android.com/). In case you've not installed it, do it now. I recommend to install the SDK into your home directory. Usually this is installed in the directory `<home directory>/Android/Sdk`. Additionally you need the following libraries compiled for Android:
357 andreas 12
 
13
- [Skia](https://skia.org)
363 andreas 14
- [Qt 6.5.x](https://doc.qt.io/qt-6/) or newer
357 andreas 15
- openssl (can easily be installed out of QtCreator)
16
- [pjsip](https://www.pjsip.org)
17
 
18
> _Hint_: For Qt version less then 6.5.0 you need openssl 1.1, while for newer versions of Qt you need openssl 3!
19
 
20
I made an archive file containing _Skia_ and _PjSIP_ as precompiled versions for all 4 possible Android architectures (arm64-v8a, armeabi-v7a, x86_64, x86) You can download it from my [server](https://www.theosys.at/download/android_dist.tar.bz2) (~ 1Gb!). After you've downloaded this hugh file, unpack it into any directory. The file details are:
21
 
22
- [`android_dist.tar.bz2`](https://www.theosys.at/download/android_dist.tar.bz2)
365 andreas 23
- SHA256: `a79b313d03aa630f9574e5d9652fa1c28ef8d766a7cbb270d406838260c8c2b2`
357 andreas 24
 
363 andreas 25
> The package does **not** include the Qt framework!
357 andreas 26
 
27
## Build with script `build_android.sh`
28
 
29
This is a shell script to create an Android APK file. Such files can be deployed to any Android device running Android 11 or newer. This is API level 30.
30
 
381 andreas 31
First copy the file `build_android.sh` to another name e.g.:
357 andreas 32
 
381 andreas 33
    cp build_android.sh buildAndroid.sh
34
 
35
Now open the copy with a text editor. The first lines defining some paths. Adapt the settings to the paths of your installation. Then simply start the script on the command line. If everything was installed and all paths were set correct, it should compile the code and produce an APK file. The last line will give you the path and name of the produced file.
36
 
357 andreas 37
The script contains a help function (`build_android.sh --help`). It shows the possible parameters and their meaning:
38
```
39
build_android.sh [clean] [debug] [deploy] [sign] [list-avds] [help|--help|-h]
40
   clean     Delete old build, if there is one, and start a new clean build.
41
   debug     Create a binary with debugging enabled.
42
   deploy    Deploy the binary to an Android emulator.
43
   sign      Sign the resulting APK file. This requires a file named
44
             "$HOME/.keypass" containing the password and has read
45
             permissions for the owner only (0400 or 0600). If this file
46
             is missing, the script asks for the password.
47
   verbose | --verbose | -v
48
             Prints the commands used to create the target file.
49
   list-avds List all available AVDs and exit.
50
 
51
   help | --help | -h   Displays this help screen and exit.
52
 
53
Without parameters the source is compiled, if there were changes, and then
54
an Android package is created. This package will be an unsigned release APK.
55
```
56
 
57
## Build with _QtCreator_
58
 
59
There are some reasons why it is better to use [QtCreator](https://www.qt.io/product/development-tools) then using the command line. The most important reason is if you want to be able to flexible deploy the application to different Android devices. And if you want to participate in developing you should use this IDE also.
60
 
381 andreas 61
After starting _QtCreator_ click on `Open project` and open the file `CMakeLists.txt` in the source folder of **TPanel**. When the project is open, click on `Projects` on left panel. Select `Android Qt 6.x.x CLang x86_64` from the list and click on `Build` (hammer symbol). Now you see the _Build Settings_. Under `CMake` set in the _Initial Configuration_ the value of `ANDROID_PLATFORM` to `android-30`. Make sure the NDK version `25.2.9519653` is set. If not, hit `Manage Kits...` and make this version the default or install it and make it then the default. I will not explain how to install the Android SDK or an NDK, which is part of the Android SDK. This is subject to the Google documentation of Android Studio.
357 andreas 62
 
63
Click now on `Re-configure with Initial Parameters` (on the bottom of the `Cmake` box.). If everything went well, the tab should jump to `Current Configuration`. If you want to build Android for all ABIs you must set `QT_ANDROID_BUILD_ALL_ABIS` to `ON`. Leave the rest as it is.
64
 
65
> _Hint_: If you want to compile sources in parallel (much faster) you can add the parameter `-j<#cpus>` (replace `<#cpus>` with the number of CPUs your system offers) to `Additional CMake options:`.
66
 
67
At the block called `Build Android APK` set under `Application` the `Android build platform SDK:` to `android-30`. This very important because with an SDK version less it may not even compile. You can, if you like, use any newer version.
68
 
69
Expand the block `Build Environment` and set the variable `ANDROID_NDK_PLATFORM` to `android-30`. _Do not check the `Clear system environment` check box!_
70
 
71
Before you can start compiling, click on the Android symbol in the left bottom corner and select `tpanel` under _Run_. Now you can compile the program by clicking on the hammer symbol.
72
 
73
# Problems
74
 
75
With Qt 6.5.2 and older versions it is very likely that you can't compile the code. You will see errors like this:
76
```
77
Changing into build directory "tpanel-6-build" ...
78
Compiling the source ...
79
[1/72] Performing tpanel_build step for 'qt_internal_android_x86'
363 andreas 80
FAILED: qt_internal_android_x86-prefix/src/qt_internal_android_x86-stamp/qt_internal_android_x86-tpanel_build /home/<user>/tpanel/tpanel-6-build/qt_internal_android_x86-prefix/src/qt_internal_android_x86-stamp/qt_internal_android_x86-tpanel_build
359 andreas 81
cd /home/<user>/tpanel/tpanel-6-build && /opt/Qt/Tools/CMake/bin/cmake --build /home/<user>/tpanel/tpanel-6-build/android_abi_builds/x86 --config Release --target tpanel
357 andreas 82
[1/58] Building CXX object CMakeFiles/tpanel.dir/tnameformat.cpp.o
363 andreas 83
FAILED: CMakeFiles/tpanel.dir/tnameformat.cpp.o
359 andreas 84
/home/<user>/Android/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --target=i686-none-linux-android23 --sysroot=/home/<user>/Android/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/sysroot -DPJ_AUTOCONF -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIAWIDGETS_LIB -DQT_MULTIMEDIA_LIB -DQT_NETWORK_LIB -DQT_NO_DEBUG -DQT_POSITIONING_LIB -DQT_WIDGETS_LIB -D_GNU_SOURCE -D_OPAQUE_SKIA_ -D_REENTRANT -Dtpanel_EXPORTS -I/home/<user>/tpanel/tpanel-6-build/android_abi_builds/x86/tpanel_autogen/include -I/home/<user>/Android/extras/expat/include -I/home/<user>/Android/distribution/skia/include -I/home/<user>/Android/distribution/pjsip/include -I/home/<user>/Android/android_openssl/ssl_3/include -isystem /opt/Qt/6.5.2/android_x86/include/QtCore -isystem /opt/Qt/6.5.2/android_x86/include -isystem /opt/Qt/6.5.2/android_x86/mkspecs/android-clang -isystem /opt/Qt/6.5.2/android_x86/include/QtWidgets -isystem /opt/Qt/6.5.2/android_x86/include/QtGui -isystem /opt/Qt/6.5.2/android_x86/include/QtMultimedia -isystem /opt/Qt/6.5.2/android_x86/include/QtNetwork -isystem /opt/Qt/6.5.2/android_x86/include/QtMultimediaWidgets -isystem /opt/Qt/6.5.2/android_x86/include/QtPositioning -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -mstackrealign -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security   -O3 -DNDEBUG  -fPIC -fvisibility=default   -pedantic -fexceptions -Wextra -Wno-attributes -Wno-nested-anon-types -Wno-gnu-anonymous-struct -Wno-gnu-zero-variadic-macro-arguments -fPIC -pthread -std=gnu++17 -MD -MT CMakeFiles/tpanel.dir/tnameformat.cpp.o -MF CMakeFiles/tpanel.dir/tnameformat.cpp.o.d -o CMakeFiles/tpanel.dir/tnameformat.cpp.o -c /home/<user>/tpanel/tnameformat.cpp
85
/home/<user>/tpanel/tnameformat.cpp:29:2: error: "This module needs Android API level 28 or newer!"
357 andreas 86
#error "This module needs Android API level 28 or newer!"
87
 ^
359 andreas 88
/home/<user>/tpanel/tnameformat.cpp:223:18: error: use of undeclared identifier 'iconv_open'
357 andreas 89
    iconv_t cd = iconv_open(from.c_str(), to.c_str());
90
                 ^
359 andreas 91
/home/<user>/tpanel/tnameformat.cpp:240:7: error: use of undeclared identifier 'iconv'; did you mean 'lconv'?
357 andreas 92
                if (iconv(cd, &in_buf, &in_left, &out_buf, &out_left) == (size_t) -1)
93
                    ^
94
...
95
```
96
You can see the line `#error "This module needs Android API level 28 or newer!"`. This happens when you try to make a multi architecture APK file. There is a bug in the cmake macros used for Android. Here is how you can fix this.
97
 
388 andreas 98
- Go to the directory where Qt is installed (e.g. `/opt/Qt/6.6.0`)
357 andreas 99
- Make sure you have the right to write all files and directories.
100
- With a text editor open the file `android_x86_64/lib/cmake/Qt6Core/Qt6AndroidMacros.cmake`.
101
- Search for a function called `_qt_internal_configure_android_multiabi_target`.
388 andreas 102
- Scroll down to (about line 1216)
357 andreas 103
```
104
...
105
    if(DEFINED QT_HOST_PATH_CMAKE_DIR)
106
        list(APPEND extra_cmake_args "-DQT_HOST_PATH_CMAKE_DIR=${QT_HOST_PATH_CMAKE_DIR}")
107
    endif()
108
 
109
    if(CMAKE_MAKE_PROGRAM)
110
        list(APPEND extra_cmake_args "-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}")
111
    endif()
112
...
113
```
114
- Add the following lines:
115
```
116
    if(ANDROID_PLATFORM)
117
        list(APPEND extra_cmake_args "-DANDROID_PLATFORM=${ANDROID_PLATFORM}")
118
    endif()
119
 
120
```
121
- Save the file and exit the editor.