Android: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
(Undo revision 35696 by Bensuperpc (talk))
(43 intermediate revisions by 22 users not shown)
Line 1: Line 1:
This page has a lot of overlap with "another page":http://wiki.qt.io/Qt5ForAndroidBuilding about building Qt for Android.
[[Category:HowTo]]
[[Category:Qt for Android]]
These are build instructions for building Qt for Android on Linux or Mac OS X. For cross-compiling on Windows, this is currently [[Building qt-android on windows| possible under cmd.exe]].


= Qt on Android =
For general information about Qt 5 for Android, please visit the [[Qt5ForAndroid| wiki]] for that.


It has been working since "Qt 5.1":http://qt.io/qt5/qt51. You can build and install Qt applications on any Android device (Gingerbread or newer, API version 9 or newer). You can already download a complete Qt SDK for Android, start up Creator, write applications and deploy from Creator; however this page is about how to build Qt for Android and how to build applications from the command line, on Linux. The process is similar on other OSes.
N.B.


== How to build Qt ==
* When using GCC toolchains on Windows (MinGW, Android NDK, etc.) take into account that there is a restrictions on a build path prefix length [https://bugreports.qt.io/browse/QTBUG-52242 QTBUG-52242].
* When using MSys shell you should not pass Unix-like paths in <tt>-prefix</tt> argument [https://bugreports.qt.io/browse/QTBUG-52675 QTBUG-52675]


You will need to install the Android SDK and Android NDK, Java and Ant. On Arch Linux, these are all available as packages (some of them only in AUR though). If your distro does not have them, you can download from Google and install them in your own home directory.
= Building Qt 5 for Android =


Set several environment variables depending on which versions of things you have installed and which ones you would like to use:
The following sections will help you configure the Android SDK and NDK, deploy an X86 android emulator, and configure the emulator and SDK for use with Qt Creator.


<code><br />export JAVA_HOME=/usr/lib/jvm/java-default-runtime<br />export ANDROID_HOME=/opt/android-sdk<br />export ANDROID_SDK_ROOT=/opt/android-sdk<br />export ANDROID_SWT=/usr/share/java<br />export ANDROID_NDK_ROOT=/opt/android-ndk<br />export ANDROID_NDK_HOST=linux-x86_64<br />export ANDROID_BUILD_TOOLS_REVISION=19.0.3<br />export ANDROID_NDK_PLATFORM=android-9<br />export ANDROID_TARGET_ARCH=armeabi-v7a<br />export ANDROID_NDK_TOOLCHAIN_VERSION=4.8<br />export ANDROID_NDK=/opt/android-ndk<br /></code>
== Installing the Android SDK and NDK ==


You will need to pay attention and update these whenever you update the SDK or NDK: the tools revision should match for example /opt/android-sdk/build-tools/19.0.3 or whatever newer version you may have; toolchain 4.8 maps to /opt/android-ndk/toolchains/arm-linux-androideabi-4.8. The chosen NDK platform (android-9) will be the minimum supported version, and does not preclude you from running the application on the newest version of Android. The target arch can be armeabi-v7a for a device with an Arm 7, or armeabi for a device with an Arm 5. Arm 5 builds are good for distribution because they are forward-compatible with newer devices, but then the performance is not optimized for newer devices.
=== Scripted installation for Linux ===
The following packages (alternatives may be supported) for debian-based linux are required:
apt install build-essential default-jre openjdk-8-jdk-headless android-sdk android-sdk-platform-23 libc6-i386
The following bash script will download the SDK and NDK version r18b. Run the script from the directory you wish to install to, such as /home/username/android_tools


Go to a fresh directory which you will use for building Qt, and run
'''Important:''' Run the script as the user that will be using it later (do not sudo)<syntaxhighlight lang="bash">
#!/bin/bash


<code>$ /path/to/qt/configure -developer-build -xplatform android-g++ -android-ndk /opt/android-ndk -android-sdk /opt/android-sdk -nomake tests -nomake examples -opensource -confirm-license<br />$ make<br /></code>
ndkVersion="r18b"
sdkBuildToolsVersion="28.0.3"
sdkApiLevel="android-28"
toolsVersion="r26.1.1"


When it is all done, you will have the modules installed under qtbase, just as when you do a build on any desktop OS.
repository=https://dl.google.com/android/repository
toolsFile=sdk-tools-linux-4333796.zip
toolsFolder=android-sdk-tools
ndkFile=android-ndk-$ndkVersion-linux-x86_64.zip
ndkFolder=android-ndk-$ndkVersion


While it is building, set up your qtchooser configuration:
rm -rf $toolsFolder
rm -rf $ndkFolder


<code>$ cd <sub>/.config/qtchooser<br />$ vi 5a.conf</code>
echo "Downloading SDK tools from $repository"
<br />and create the contents something like this (adjusting paths as necessary):
wget -q $repository/$toolsFile
<br /><code><br /></sub>/dev/qt5-android-arm7-stable-rel/qtbase/bin<br /><sub>/dev/qt5-android-arm7-stable-rel/qtbase/lib<br /></code>
unzip -qq $toolsFile -d $toolsFolder
<br />Usually qttools will not be built automatically (although it really should be). And normally you would build qtwebkit first, because Assistant will make good use of it; but since that takes a long time, and we don't care about building Assistant, it can be skipped. The main thing we need is androiddeployqt.
 
<br /><code><br />mkcd qttools (or mkdir and then cd, if you don't have the mkcd alias)<br />qtchooser 5a<br />qmake /path/to/qt/qttools<br />make<br /></code>
echo "Downloading NDK from $repository"
<br />h2. How to build an application
wget -q $repository/$ndkFile
<br />We will assume you have qtchooser installed and configured, so that giving the full path to tools like qmake and androiddeployqt is not necessary. Otherwise you will need to prepend the full path every time you run one of these tools.
unzip -qq $ndkFile
<br />This is a useful script which you can create and put somewhere in your path, called deploy-android:
 
<br /><code><br />echo &quot;Using Qt in ${QTDIR}&quot;<br />make install INSTALL_ROOT=.<br />androiddeployqt —output . —deployment debug —install<br />adb logcat -c; adb logcat <s>C<br /></code>
rm $toolsFile
<br />Assuming you have a project with a C++ main() and a .pro file, connect your Android device over USB, and do this:
rm $ndkFile
<br /><code><br />cd /path/to/project<br />qmake<br />deploy-android<br /></code>
 
<br />It will build and install on your device.
echo "Configuring environment"
<br />If you are using Creator, you will have 3 choices in the Run configuration: bundle Qt with the application, deploy Qt separately, or use Ministro to install Qt. Ministro is another application from the Play Store which your application will depend on. It is a nice way to install multiple applications so that they can share a common version of Qt, and perhaps the best way to package applications for distribution. If you bundle Qt with the application, the package will be quite large (usually at least 10 MB), but your application will keep working with the same bundled version of Qt regardless what other versions of Qt may be installed elsewhere on your device. But for debugging, the &quot;—deployment debug&amp;quot; flag to androiddeployqt will do the same thing as the &quot;Deploy local Qt libraries to temporary directory&amp;quot; option in Creator: it will send over only the files which have changed (for example when you rebuild parts of Qt). So your application package is small, quick to deploy, and it saves wear-and-tear on your device's flash memory to avoid installing a large quantity of files each time you want to try a little change in your application. Applications which you have installed this way should hopefully keep working even when you push a newer version of Qt to the &quot;temporary directory&amp;quot;, because Qt has a binary compatibility guarantee. (The temp directory BTW is /data/local/tmp/qt .) So installing this way is much like a typical desktop Linux Qt installation.
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
<br />h2. Make it look like it belongs
export PATH=$PATH:$JAVA_HOME/bin
<br />When you get tired of the default green &quot;droid&amp;quot; icon, you might notice that AndroidManifest.xml was automatically generated when you built your application. (Where it was generated may vary with different Qt versions.) Of course you can customize it</s> google for details about how to set the icon, name of the application, etc. If you have a git repo for your project, commit AndroidManifest.xml to the repo so that you can revert it in case it ever gets overwritten, and so that you can do &quot;git clean&amp;quot; without losing it. If you are using Creator though, there is special support for editing the manifest.
 
<br />h2. qmlscene
# Optional workaround for issue with certain JDK/JRE versions
<br />qmlscene is not built by default in Android builds, but it actually works if you build it yourself, just like any other application. Then you can make a directory like /sdcard/qtquick, put QML files there, start up qmlscene from the launcher, and load any QML that you would like to test. The main caveat is that qmlscene still uses the QFileDialog, which at best does not provide an optimal UI for touch devices, and at worst, you may run into bugs related to the fact that the dialog tries to create another window, which is not supported on Android. (That's why the build does not include qmlscene by default.) The Qt workaround for this problem (rendering widgets into a layer in the same &quot;window&amp;quot;) has been mostly working in recent times though. If you see that the dialog does not go away when you hit OK, you might need to hold down the &quot;home&amp;quot; button to get the application switcher menu, and then go back to qmlscene; that will force a refresh.
#cp $toolsFolder/tools/bin/sdkmanager $toolsFolder/tools/bin/sdkmanager.backup
<br />h2. Other notes
#sed -i 's/^DEFAULT_JVM_OPTS.*/DEFAULT_JVM_OPTS='"'\"-Dcom.android.sdklib.toolsdir=\$APP_HOME\" -XX:+IgnoreUnrecognizedVMOptions --add-modules java.se.ee'"'/' \
<br />This page previously mentioned &quot;Wayland on Android&amp;quot;:http://ppaalanen.blogspot.de/2012/04/first-light-from-weston-on-android.html but that is not the focus of the regular Android Qt port.
#        $toolsFolder/tools/bin/sdkmanager
<br />h3. Debugging
 
<br />With thanks to:<br />http://betelco.blogspot.com/2010/01/buildingdebugging-android-native-c.html
echo "Installing SDK packages"
<br /><code>./platform-tools/adb shell LD_LIBRARY_PATH=/data/local/tmp/androidtest /data/local/tmp/androidtest/gdbserver :1234 /data/local/tmp/androidtest/androidtest<code>
cd $toolsFolder/tools/bin
<br />(in a seperate terminal)<br /></code></sub>/androidtest% ~/android-ndk-r7c/./toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-gdb androidtest<br />(gdb) set solib-search-path /Users/burchr/code/qt/qt5/qtbase/lib<br />(gdb) target remote :1234<br />(gdb) b main<br />Breakpoint 1 at 0xd648: file main.cpp, line 87.<br />(gdb) c
echo "y" | ./sdkmanager "platforms;$sdkApiLevel" "platform-tools" "build-tools;$sdkBuildToolsVersion" >> sdkmanager.log
echo "y" | ./sdkmanager --install "emulator" >> sdkmanager.log
echo "y" | ./sdkmanager --install "system-images;android-21;google_apis;x86" >> sdkmanager.log
echo "no" | ./avdmanager create avd -n x86emulator -k "system-images;android-21;google_apis;x86" -c 2048M -f >> sdkmanager.log
 
echo "Provisioniong complete. Here's the list of packages and avd devices:"
./sdkmanager --list
./avdmanager list avd
</syntaxhighlight>
 
=== Manual Installation ===
# If the Android SDK is not installed with the package manager and script above, it can be obtained as part of the official Android Studio release.
#* Download Android Studio: https://developer.android.com/studio/index.html
#* Open Android Studio and run the SDK Manager tool, which is found under [https://developer.android.com/studio/intro/update.html#sdk-manager Tools > Android > SDK Manager] (if you don't have the SDK Manager menu item in the Tools menu and the toolbar isn't visible, you can enable this from the View menu by checking Toolbar).
#* '''Important:''' For Qt 5.6 or earlier: Install API levels 10, 11, 16 and 18 (you may need to check the "Obsolete" checkbox to see these in the SDK manager). '''Beginning with Qt 5.7''', any API level >= 18 will work.
#** Android API level 11 is required to build QtMultimedia.
#** Android API level 18 is required to build QtBluetooth (from Qt 5.5 onwards).
#** Android API level 10, 11 and 16 are required for QtBase.
#** Note that this is only necessary for building Qt itself. You can build Qt applications against any API level you wish, As long as it is equal to or higher than 13.
# You also need an Android NDK: https://developer.android.com/tools/sdk/ndk/index.html
#* '''Important:''' As of Qt 5.12, Android NDK r18b is required, and GCC toolchains are no longer supported in the android NDK.
#* '''Important:''' If you are building Qt with the gcc toolchain (pre-Qt 5.12 only), you will need the Android NDK r10e. This is because NDK r11, r12 and r15 are known to have issues<ref name="known-issues">[[Qt for Android known issues| Known issues with the Qt for Android build]]</ref> with gcc. NDK r13 and r14 are also likely to have the same issues. r15 produces applications that fail with the error message 'This application failed to start because it could not find or load the Qt platform plugin "android"'. We recommend to use the android-clang toolchain for compiling, in which case the latest NDK release should be preferred.
#* You need to make sure that the NDK supports the API level you're targeting. You can do this by checking the path-to-NDK/platforms directory.
# Install a JDK whose version is at least 1.6. This can be found on Oracle's website. Alternatively, OpenJDK can be used on Linux. <pre>apt-get install openjdk-8-jdk</pre>
#* If you're on a 64 bit Ubuntu/Debian, you may also need to install a 32 bit runtime environment:
#*:<pre>apt-get install libc6-i386</pre>
 
== Building Qt ==
# Get Qt Creator 2.7.2 (or later): http://qt.io/download#qt-creator
# Get Qt 5:
#:<pre>git clone git://code.qt.io/qt/qt5.git qt5</pre>
#:<pre>cd qt5</pre>
#:<pre>perl init-repository</pre>
# Optionally checkout target Qt version to use.
#:<pre>git checkout v5.12.2</pre>
#:<pre>git submodule update --recursive</pre>
# Configure Environment Variables.
#* You need to set JAVA_HOME and add JAVA_HOME/bin to your PATH. On Linux, a good place to do this is at the end of ~/.profile:
#:<pre>export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64</pre>
#:<pre>export PATH=$PATH:$JAVA_HOME/bin</pre>
# Configure Qt and skip unsupported modules:
#:<pre>./configure -xplatform android-clang --disable-rpath -nomake tests -nomake examples -android-ndk <path/to/ndk> -android-sdk <path/to/sdk> -android-ndk-host <e.g. linux-x86_64> -android-toolchain-version <e.g. 4.9> -skip qttranslations -skip qtserialport -no-warnings-are-errors</pre>''-android-toolchain-version'' can be any version listed in the toolchains directory of your NDK directory (-android-ndk). For example, arm-linux-androideabi-4.9 would be 4.9.
#:''-android-ndk-host'' will be windows-x86_64 if you're on 64-bit Windows, for example. For more values, check qtbase/configure.pri.
#:'''Note:''' the highest API level that the r10e NDK supports is 21, so it may be necessary to install that and then pass the following in addition to the arguments listed above: <code>-android-ndk-platform android-21</code>
# Build. Run the ''make'' command to build the configured Qt parts.
#:<pre>make -j 8</pre>
#Install. Run the ''make install'' command to install the built Qt parts. If you have not used the configure option ''--prefix <install-dir>'' the installation is done under the directory path ''/usr/local/Qt-<version>''.  Under Debian/Ubuntu you should prefix the make command with the ''sudo'' command.<pre>make install</pre>
 
== Configuring Qt Creator ==
# Start the Qt Creator you built or downloaded earlier.
# Go into Tools -> Options -> Devices -> Android and set the right paths to Java, and the Android SDK and NDK, etc. For example:
#*JDK Location: /usr/lib/jvm/java-8-openjdk-amd64
#*Android SDK Location: /home/johnsmith/dev/android-sdk-tools
#*Android NDK Location: /home/johnsmith/dev/android-ndk-r18b
# Add your newly built Qt version to Tools -> Options -> Kits -> Qt Versions.
# Add a new kit using that Qt version (or clone an existing pre-built Qt for Android kit and just change the Qt version) in Tools -> Options -> Kits -> Kits.
# At this point you should be able to create a project and configure it for the Android kit. In order to test, go into the Run settings for your project. Under Deploy Configuration, check the Use Qt libraries from local device option. Also select the Deploy local Qt libraries radio button.
 
==References==
<references />

Revision as of 10:26, 18 June 2019

These are build instructions for building Qt for Android on Linux or Mac OS X. For cross-compiling on Windows, this is currently possible under cmd.exe.

For general information about Qt 5 for Android, please visit the wiki for that.

N.B.

  • When using GCC toolchains on Windows (MinGW, Android NDK, etc.) take into account that there is a restrictions on a build path prefix length QTBUG-52242.
  • When using MSys shell you should not pass Unix-like paths in -prefix argument QTBUG-52675

Building Qt 5 for Android

The following sections will help you configure the Android SDK and NDK, deploy an X86 android emulator, and configure the emulator and SDK for use with Qt Creator.

Installing the Android SDK and NDK

Scripted installation for Linux

The following packages (alternatives may be supported) for debian-based linux are required:

apt install build-essential default-jre openjdk-8-jdk-headless android-sdk android-sdk-platform-23 libc6-i386

The following bash script will download the SDK and NDK version r18b. Run the script from the directory you wish to install to, such as /home/username/android_tools

Important: Run the script as the user that will be using it later (do not sudo)

#!/bin/bash

ndkVersion="r18b"
sdkBuildToolsVersion="28.0.3"
sdkApiLevel="android-28"
toolsVersion="r26.1.1"

repository=https://dl.google.com/android/repository
toolsFile=sdk-tools-linux-4333796.zip
toolsFolder=android-sdk-tools
ndkFile=android-ndk-$ndkVersion-linux-x86_64.zip
ndkFolder=android-ndk-$ndkVersion

rm -rf $toolsFolder
rm -rf $ndkFolder

echo "Downloading SDK tools from $repository"
wget -q $repository/$toolsFile
unzip -qq $toolsFile -d $toolsFolder

echo "Downloading NDK from $repository"
wget -q $repository/$ndkFile
unzip -qq $ndkFile

rm $toolsFile
rm $ndkFile

echo "Configuring environment"
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
export PATH=$PATH:$JAVA_HOME/bin

# Optional workaround for issue with certain JDK/JRE versions
#cp $toolsFolder/tools/bin/sdkmanager $toolsFolder/tools/bin/sdkmanager.backup
#sed -i 's/^DEFAULT_JVM_OPTS.*/DEFAULT_JVM_OPTS='"'\"-Dcom.android.sdklib.toolsdir=\$APP_HOME\" -XX:+IgnoreUnrecognizedVMOptions --add-modules java.se.ee'"'/' \
#        $toolsFolder/tools/bin/sdkmanager

echo "Installing SDK packages"
cd $toolsFolder/tools/bin
echo "y" | ./sdkmanager "platforms;$sdkApiLevel" "platform-tools" "build-tools;$sdkBuildToolsVersion" >> sdkmanager.log
echo "y" | ./sdkmanager --install "emulator" >> sdkmanager.log
echo "y" | ./sdkmanager --install "system-images;android-21;google_apis;x86" >> sdkmanager.log
echo "no" | ./avdmanager create avd -n x86emulator -k "system-images;android-21;google_apis;x86" -c 2048M -f >> sdkmanager.log

echo "Provisioniong complete. Here's the list of packages and avd devices:"
./sdkmanager --list
./avdmanager list avd

Manual Installation

  1. If the Android SDK is not installed with the package manager and script above, it can be obtained as part of the official Android Studio release.
    • Download Android Studio: https://developer.android.com/studio/index.html
    • Open Android Studio and run the SDK Manager tool, which is found under Tools > Android > SDK Manager (if you don't have the SDK Manager menu item in the Tools menu and the toolbar isn't visible, you can enable this from the View menu by checking Toolbar).
    • Important: For Qt 5.6 or earlier: Install API levels 10, 11, 16 and 18 (you may need to check the "Obsolete" checkbox to see these in the SDK manager). Beginning with Qt 5.7, any API level >= 18 will work.
      • Android API level 11 is required to build QtMultimedia.
      • Android API level 18 is required to build QtBluetooth (from Qt 5.5 onwards).
      • Android API level 10, 11 and 16 are required for QtBase.
      • Note that this is only necessary for building Qt itself. You can build Qt applications against any API level you wish, As long as it is equal to or higher than 13.
  2. You also need an Android NDK: https://developer.android.com/tools/sdk/ndk/index.html
    • Important: As of Qt 5.12, Android NDK r18b is required, and GCC toolchains are no longer supported in the android NDK.
    • Important: If you are building Qt with the gcc toolchain (pre-Qt 5.12 only), you will need the Android NDK r10e. This is because NDK r11, r12 and r15 are known to have issues[1] with gcc. NDK r13 and r14 are also likely to have the same issues. r15 produces applications that fail with the error message 'This application failed to start because it could not find or load the Qt platform plugin "android"'. We recommend to use the android-clang toolchain for compiling, in which case the latest NDK release should be preferred.
    • You need to make sure that the NDK supports the API level you're targeting. You can do this by checking the path-to-NDK/platforms directory.
  3. Install a JDK whose version is at least 1.6. This can be found on Oracle's website. Alternatively, OpenJDK can be used on Linux.
    apt-get install openjdk-8-jdk
    • If you're on a 64 bit Ubuntu/Debian, you may also need to install a 32 bit runtime environment:
      apt-get install libc6-i386

Building Qt

  1. Get Qt Creator 2.7.2 (or later): http://qt.io/download#qt-creator
  2. Get Qt 5:
    git clone git://code.qt.io/qt/qt5.git qt5
    cd qt5
    perl init-repository
  3. Optionally checkout target Qt version to use.
    git checkout v5.12.2
    git submodule update --recursive
  4. Configure Environment Variables.
    • You need to set JAVA_HOME and add JAVA_HOME/bin to your PATH. On Linux, a good place to do this is at the end of ~/.profile:
    export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
    export PATH=$PATH:$JAVA_HOME/bin
  5. Configure Qt and skip unsupported modules:
    ./configure -xplatform android-clang --disable-rpath -nomake tests -nomake examples -android-ndk <path/to/ndk> -android-sdk <path/to/sdk> -android-ndk-host <e.g. linux-x86_64> -android-toolchain-version <e.g. 4.9> -skip qttranslations -skip qtserialport -no-warnings-are-errors
    -android-toolchain-version can be any version listed in the toolchains directory of your NDK directory (-android-ndk). For example, arm-linux-androideabi-4.9 would be 4.9.
    -android-ndk-host will be windows-x86_64 if you're on 64-bit Windows, for example. For more values, check qtbase/configure.pri.
    Note: the highest API level that the r10e NDK supports is 21, so it may be necessary to install that and then pass the following in addition to the arguments listed above:
    -android-ndk-platform android-21
    
  6. Build. Run the make command to build the configured Qt parts.
    make -j 8
  7. Install. Run the make install command to install the built Qt parts. If you have not used the configure option --prefix <install-dir> the installation is done under the directory path /usr/local/Qt-<version>. Under Debian/Ubuntu you should prefix the make command with the sudo command.
    make install

Configuring Qt Creator

  1. Start the Qt Creator you built or downloaded earlier.
  2. Go into Tools -> Options -> Devices -> Android and set the right paths to Java, and the Android SDK and NDK, etc. For example:
    • JDK Location: /usr/lib/jvm/java-8-openjdk-amd64
    • Android SDK Location: /home/johnsmith/dev/android-sdk-tools
    • Android NDK Location: /home/johnsmith/dev/android-ndk-r18b
  3. Add your newly built Qt version to Tools -> Options -> Kits -> Qt Versions.
  4. Add a new kit using that Qt version (or clone an existing pre-built Qt for Android kit and just change the Qt version) in Tools -> Options -> Kits -> Kits.
  5. At this point you should be able to create a project and configure it for the Android kit. In order to test, go into the Run settings for your project. Under Deploy Configuration, check the Use Qt libraries from local device option. Also select the Deploy local Qt libraries radio button.

References