Jump to content

Android: Difference between revisions

From KDE Community Wiki
Cola (talk | contribs)
Use Docker Container: explain how to change the container size
Redstrate (talk | contribs)
Fix android build link
 
(20 intermediate revisions by 8 users not shown)
Line 1: Line 1:
{{Construction}}
== KDE Software on Android ==
Android is currently ''the'' mobile platform regarding market share and number of provided applications. Hence, it is a platform very well suited to increase the availability and usage of applications by the KDE community.


= KDE software on Android =
=== Contact ===
Android is currently ''the'' mobile platform regarding market share and number of provided applications. Hence, it is a platform very well suited to increase the availability and usage of applications by the KDE community. In the following, we give an overview of the technical steps required to setup a build system for cross-compiling a Qt5/KF5 based Android application, the necessary steps to deploy it, and a reference list of the porting steps by different applications/people.
For questions and discussion around KDE software on Android join our [https://matrix.to/#/#kde-android:kde.org Matrix channel] and [https://mail.kde.org/mailman/listinfo/kde-android mailing list].


= Tutorial for Building Applications on Android =
=== Getting Applications ===
For building Qt applications on Android, some extra steps are required in comparison to building directly on Linux. The following instruction expects that KF5/Qt5 based applications can already be built and all necessary tools are installed (gcc, cmake, git,...). The main idea for the setup is that we use precompiled Qt libraries (named NDK and SDK), which are built for the ARM-based Android platform. All building then is done by using these libraries. Still the build-process itself will use the tools from your Linux system (in the following called "host system"; while the Android device is called "target system"). The additional tools mostly are the Java Development Kit and other tools for building Java applications.


Stable releases for our Android apps are available on [https://play.google.com/store/apps/dev?id=4758894585905287660 Google Play] and [https://f-droid.org/ F-Droid].


= Setup Build Environment =
Nightly test builds can be found in the [[Android/FDroid | Nightly F-Droid repo]].
We explain two ways on how to setup a build environment. The easiest one is to use our prepared Docker image, which installs all dependencies and setups all environment variables automatically. On the other hand, you can do all these configuration steps by yourself.


== Use Docker Container ==
=== Build Environment ===
Obviously, you must install Docker on your system, which should be available via your distribution. Then you only have to checkout the Docker image configuration in <code>git clone git://anongit.kde.org/android-builder.git</code>.
There are different ways to setup a build environment:
# '''[https://develop.kde.org/docs/packaging/android/building_applications/ Use Ready-to-Build Docker Container with Craft]''' - This is the most convenient way to setup a system. It also brings the advantage to have a clear separation between your Linux build system and your cross-compile system; in particularly when you require several cross-compiled libraries for your application.
# '''[[Android/Environment|Setup your Build Environment Manually]]''' - This tutorial for setting up the cross-compiling environment requires considerably more time and brings the disadvantage to make no clear separation between your system and the cross-compile environment.
# '''DEPRECATED [[Android/Environment_via_Container|Use Ready-to-Build Docker Container with android tooling]]''' - This works very similar to using Craft since it uses a docker environment too. However the tooling is now deprecated and no longer supported. You should use Craft in a container instead.


Then in folder <code>image</code> perform the following commands to build, then create, and finally to run your KDE on Android build image:
You can also get the binaries from binary-factory.kde.org. Here's some explanation about how it works:
<syntaxhighlight lang="bash">
cd image
docker build -t kde-android-sdk .
docker create -ti --name myproject kde-android-sdk bash
docker start -i myproject
</syntaxhighlight>
More details can be found in the README.md file in the checked out repository.
 
==== Change Container Size ====
By default Docker containers have a size of 10GB. This is sufficient for the typical use case, but usually much too small if you setup a full cross-building toolchain. For this, you have to increase the default container size (note: the following deletes all your current containers, hence do backups and do it with care!)
* Documentation: https://docs.docker.com/engine/reference/commandline/daemon/
<syntaxhighlight lang="bash">
service docker stop
rm -rf /var/lib/docker
service docker start
docker -d --storage-opt dm.basesize=20G &
</syntaxhighlight>
 
== Setup Environment Manually ==
=== Prerequisites / Setup of Cross-Compiling Build System ===
At first we prepare your system with all necessary packages to build your application for Android.
For this tutorial we assume that everything is done in the folder '''/opt/android/''' (you can adapt the tutorial accordingly when using another folder).
 
# Some 32 bit system libraries are required for the host system (because some tools are 32 bit):
#* libgcc, zlib, libc
#** installing on Debian based system:
#** <code>dpkg --add-architecture i386</code>
#** <code>apt-get install zlib1g:i386 libgcc1:i386 libc6:i386</code>
# Extra-CMake-Modules
#* we require at least version >= 5.15 due to https://git.reviewboard.kde.org/r/125183
#* you can also use a smaller version >= 1.7.0 if applying this change directly to your cmake files
# Android SDK
#* Download: http://developer.android.com/sdk/index.html to /opt/android/
#* Unpack, run "tools/android update sdk" and select the following packages:
#** Android SDK Tools (24.3.4)
#** Android SDK Platform-tools (23.0.1)
#** Android SDK Build-tools (22.0.1)
#** Android 5.1.1 (API 22): SDK Platform (only "SDK Platform" needed, i.e. no docs, samples or sources)
#* result: now the SDK should be installed in /opt/android/android-sdk-linux
# Android NDK
#* Download: https://developer.android.com/ndk/index.html to /opt/android/
#* unpack the package (see the instructions on the download page)
#* result: now the NDK should be installed in /opt/android/android-ndk-r10e
# Qt with support for Android devices
#* Download the Qt 5.5.0 for Android: https://www.qt.io/download-open-source/#section-2  (32-bit or 64-bit as it fits your host system; usually 64-bit)
#* Variant 1: Offline Installers ("Skip" can be used without problem when asked to register an account)
#* Variant 2: Online installer ("Skip" can be used without problem when asked to register an account)
#* install the following components to /opt/android/Qt5.5.0:
#** Android armv7
#** Qt Creator 3.4.2 (cannot be disabled, some of its tools are used from other parts)
#** Recommended components:
#*** Qt Quick Controls
#*** Qt Location
#*** Qt Script
#*** Optional components (there might be KDE software using it):
#*** Qt WebEngine
#*** Qt Canvas 3D
#*** Qt3D
#*** Qt Quick 1
# Install the following software packages on your host system from your package manager (if not yet installed):
#* CMake: >= 2.8.6
#* Java Development Kit 7 (openjdk-7-jdk)
#* Ant
 
=== Environment Variables ===
The build environment is the name for the shell in that the application is build. The shell is prepared by exporting a series of environment variables that then are picked up by the build scripts.
<syntaxhighlight lang="bash">
export ADIR=/opt/android
export ANDROID_NDK=$ADIR/android-ndk-r10e
# note the _ROOT postfix here, different pattern
export ANDROID_SDK_ROOT=$ADIR/android-sdk-linux
export Qt5_android=$ADIR/Qt5.5.0/5.5/android_armv7/
export PATH=$ADIR/android-sdk-linux/platform-tools/:$PATH
# adapt the following path to your ant installation
export ANT=/usr/bin/ant
# adapt the following path to your openjdk location, eg:
#  openSUSE: /usr/lib64/jvm/java (needs default version being properly set, see notes below)
#  Debian: /usr/lib/jvm/java-7-openjdk-amd64
export JAVA_HOME=/usr/lib/jvm/java-7-openjdk/
</syntaxhighlight>


'''Some notes:'''
https://community.kde.org/Android/BinaryFactory
* /opt/android should be replaced with the custom build folder selected by you
* Java platform 7 is needed (both JRE and JDK). One can select the Java platform versions e.g. with <code>update-alternatives --config java</code> and <code>update-alternatives --config javac</code>
* Use <code>jrunscript -e 'java.lang.System.out.println(java.lang.System.getProperty("java.home"));'</code> to find the JAVA_HOME


= Building=
=== Building===
 
The following examples do not apply if you use Craft to build the software.
== Example: Building Marble ==
==== Example: Building Marble ====
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
cd /opt/android
cd /opt/android
Line 109: Line 29:
mkdir marble/build
mkdir marble/build
cd marble/build
cd marble/build
cmake -DCMAKE_PREFIX_PATH=${Qt5_android} -DCMAKE_TOOLCHAIN_FILE=/PATH/TO/ECM/toolchain/Android.cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../export  ..
cmake -DCMAKE_TOOLCHAIN_FILE=/PATH/TO/ECM/toolchain/Android.cmake -DECM_ADDITIONAL_FIND_ROOT_PATH=${Qt5_android} -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../export  ..
make install/strip
make install/strip
</syntaxhighlight>
</syntaxhighlight>
Line 116: Line 36:
* <code>make install/strip</code> strips build symbols from the binaries and reduces sizes considerably
* <code>make install/strip</code> strips build symbols from the binaries and reduces sizes considerably


== Building with KDESRC-BUILD ==
==== Building with KDESRC-BUILD ====
For building the below mentioned frameworks on Android, you can use the following kdesrc-buildrc config file:
For building the below mentioned frameworks on Android, you can use the following kdesrc-buildrc config file:
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
Line 129: Line 49:


== Packaging and Deployment of APKs ==
== Packaging and Deployment of APKs ==
{{Note|See ECM Toolchain documentation, to be added here as example}}
= Status of KDE Frameworks 5 =
The following frameworks can currently be used for Qt5/KF5 based applications. They are not (yet?) provided as precompiled libraries but can easily be compiled via kdesrc-build.
== Built Successfully ==
* kconfig (note: unit tests must be disabled)
* kcompletion
* kitemmodels
* kitemviews
* kcodecs
* karchive
* kguiaddons
* kwidgetsaddons
* attica
* kdnssd
* kapidox
* kimageformats
* kplotting
* ki18n ([https://github.com/j-jorge/libintl-lite libintl-lite] is required, since [https://en.wikipedia.org/wiki/Bionic_%28software%29 BIONIC] does not fully support gettext)
=== Current Blockers ===
The following frameworks cannot yet be built and block building of further Tier 1 frameworks:
* kcoreaddons: unix specific backend not compatible with Android's libc
== "Hello KWorld" example ==
Simple example how to create Qt-based apps for Android using CMake and ECM.
Take a simple "Hello world" example app using QtQuick2 with a resource file:
<syntaxhighlight lang="cpp-qt">
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    return app.exec();
}
</syntaxhighlight>
It's CMakeLists.txt files would be the same as for a normal/desktop application. All special setup for the target system is done via the toolchain file, which is passed via the cmake parameter on the commandline.
Well, almost the same currently with ECM < 5.15.0, as some issues need work-arounds still to be done. See the section in the <tt>if</tt> in the toplevel CMakeLists.txt:
<syntaxhighlight lang="cmake">
project(hellokandroid)
# AndroidToolchain needs it
cmake_minimum_required(VERSION 3.1.0)
set(QT_REQUIRED_VERSION 5.3.0)
find_package(Qt5Qml)
find_package(Qt5Quick)


if (CMAKE_SYSTEM_NAME STREQUAL Android)
See [https://api.kde.org/ecm/toolchain/Android.html ECM Android Toolchain] documentation.
    find_package(ECM)
    # TODO: possibly should be setup by toolchain one day
    set(QT_QMAKE_EXECUTABLE "$ENV{Qt5_android}/bin/qmake")
    # workaround until this fix is in released ECM
    if(ECM_VERSION VERSION_LESS "5.15.0")
        add_definitions(-DANDROID)
    endif()
endif()


add_subdirectory(src)
== KDE Frameworks 5 & Third Party Libraries ==
</syntaxhighlight>


When creating the APK package, as with normal Android apps a manifest file is needed which describes what the package contains and needs, named AndroidManifest.xml. For a simple application that should appear on the app grid this would be the minimum needed with an Qt-based app:
=== KDE Frameworks 5 ===
<syntaxhighlight lang="xml">
* supported frameworks are listed at [https://api.kde.org]
<?xml version="1.0"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="0.0.3" package="org.kde.hellokandroid" android:installLocation="auto" android:versionCode="7">
        <application android:name="org.qtproject.qt5.android.bindings.QtApplication"
                    android:label="Hello KWorld"
                    android:icon="@drawable/kde">
                <activity android:name="org.qtproject.qt5.android.bindings.QtActivity"
                          android:label="Hello KWorld"
                          android:screenOrientation="unspecified"
                          android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|fontScale|keyboard|keyboardHidden|navigation">
                        <intent-filter>
                                <action android:name="android.intent.action.MAIN"/>
                                <category android:name="android.intent.category.LAUNCHER"/>
                        </intent-filter>
                        <meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
                        <meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
                        <meta-data android:name="android.app.repository" android:value="default"/>
                        <meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
                        <meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
                        <!-- Deploy Qt libs as part of package -->
                        <meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
                        <meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/>
                        <meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/>
                        <!-- Run with local libs -->
                        <meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
                        <meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
                        <meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/>
                        <meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
                        <meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
                        <!--  Messages maps -->
                        <meta-data android:name="android.app.ministro_not_found_msg" android:value="@string/ministro_not_found_msg"/>
                        <meta-data android:name="android.app.ministro_needed_msg" android:value="@string/ministro_needed_msg"/>
                        <meta-data android:name="android.app.fatal_error_msg" android:value="@string/fatal_error_msg"/>
                </activity>
        </application>
        <supports-screens android:anyDensity="true" android:normalScreens="true" android:smallScreens="true" android:largeScreens="true"/>
        <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="19"/>
</manifest>
</syntaxhighlight>
"android:label" would be the display name of your app. For the icon to be used for your app, "android:icon" defines it. The value "@drawable/kde" refers to an icon in PNG format, that is to be found in a subdir "res/drawable" relative to the manifest file, in our case "res/drawable/kde.png".


Get the complete example code, incl. step-by-step build instructions with workarounds for current issues in ECM < 5.15.0, by git clone git://anongit.kde.org/scratch/kossebau/hellokandroid.git
=== Third Party Libraries ===
* [https://github.com/j-jorge/libintl-lite libintl-lite]: is required for KI18n, since [https://en.wikipedia.org/wiki/Bionic_%28software%29 BIONIC] does not fully support gettext


= Further References =
== Further References ==
=== References: ===
=== References: ===
* [https://mail.kde.org/mailman/listinfo/kde-android KDE Android - Discussion Mailing List]
* [https://phabricator.kde.org/project/profile/45/ Phabricator Project]
* Extra-CMake-Modules Toolchain: [http://api.kde.org/ecm/toolchain/Android.html API documentation]
* Extra-CMake-Modules Toolchain: [http://api.kde.org/ecm/toolchain/Android.html API documentation]


=== Application specific build instructions: ===
=== Application specific build instructions: ===
* Marble: [https://techbase.kde.org/Projects/Marble/AndroidCompiling build instructions]
* Marble: [[Marble/AndroidCompiling | build instructions]]


=== Blog posts about building for Android (careful: instructions may be outdated) ===
=== Blog posts about building for Android (careful: instructions may be outdated) ===
Line 252: Line 72:
* 2015-04 - Péterffy Gábor: [http://pgabor.blogspot.de/2015/05/it-is-official-marble-is-coming-to.html Marble is coming to Android]
* 2015-04 - Péterffy Gábor: [http://pgabor.blogspot.de/2015/05/it-is-official-marble-is-coming-to.html Marble is coming to Android]
* 2015-01 - GCompris Devels: [http://gcompris.net/newsall-en.html#2015-01-06 GCompris is now released on Android]
* 2015-01 - GCompris Devels: [http://gcompris.net/newsall-en.html#2015-01-06 GCompris is now released on Android]
* 2014-06 - Alex Pol: [http://www.proli.net/2014/06/12/kde-software-on-android/ KDE Software on Android]
* 2014-06 - Aleix Pol: [http://www.proli.net/2014/06/12/kde-software-on-android/ KDE Software on Android]
 
== Current TODOS ==
* add ported applications to kdesrc file -> CoLa

Latest revision as of 01:56, 11 June 2023

KDE Software on Android

Android is currently the mobile platform regarding market share and number of provided applications. Hence, it is a platform very well suited to increase the availability and usage of applications by the KDE community.

Contact

For questions and discussion around KDE software on Android join our Matrix channel and mailing list.

Getting Applications

Stable releases for our Android apps are available on Google Play and F-Droid.

Nightly test builds can be found in the Nightly F-Droid repo.

Build Environment

There are different ways to setup a build environment:

  1. Use Ready-to-Build Docker Container with Craft - This is the most convenient way to setup a system. It also brings the advantage to have a clear separation between your Linux build system and your cross-compile system; in particularly when you require several cross-compiled libraries for your application.
  2. Setup your Build Environment Manually - This tutorial for setting up the cross-compiling environment requires considerably more time and brings the disadvantage to make no clear separation between your system and the cross-compile environment.
  3. DEPRECATED Use Ready-to-Build Docker Container with android tooling - This works very similar to using Craft since it uses a docker environment too. However the tooling is now deprecated and no longer supported. You should use Craft in a container instead.

You can also get the binaries from binary-factory.kde.org. Here's some explanation about how it works:

https://community.kde.org/Android/BinaryFactory

Building

The following examples do not apply if you use Craft to build the software.

Example: Building Marble

cd /opt/android
git clone kde:marble
mkdir marble/build
cd marble/build
cmake -DCMAKE_TOOLCHAIN_FILE=/PATH/TO/ECM/toolchain/Android.cmake -DECM_ADDITIONAL_FIND_ROOT_PATH=${Qt5_android} -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../export  ..
make install/strip

Note:

  • /PATH/TO/ECM/toolchain/Android.cmake must be replaced with the actual path to toolchain/Android.cmake, if using the docker image it probably is at /opt/android/kde/install/share/ECM/toolchain/Android.cmake
  • make install/strip strips build symbols from the binaries and reduces sizes considerably

Building with KDESRC-BUILD

For building the below mentioned frameworks on Android, you can use the following kdesrc-buildrc config file:

cd /opt/android
git clone git://anongit.kde.org/scratch/cordlandwehr/kdesrc-conf-android.git
mkdir -p extragear/kdesrc-build
git clone git://anongit.kde.org/kdesrc-build extragear/kdesrc-build
ln -s extragear/kdesrc-build/kdesrc-build kdesrc-build
ln -s kdesrc-conf-android/kdesrc-buildrc kdesrc-buildrc
./kdesrc-build extra-cmake-modules frameworks-android

Packaging and Deployment of APKs

See ECM Android Toolchain documentation.

KDE Frameworks 5 & Third Party Libraries

KDE Frameworks 5

  • supported frameworks are listed at [1]

Third Party Libraries

Further References

References:

Application specific build instructions:

Blog posts about building for Android (careful: instructions may be outdated)