Android: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
Line 1: Line 1:
This page has a lot of overlap with "another page":http://wiki.qt.io/Qt5ForAndroidBuilding about building Qt for Android.
This page has a lot of overlap with "another page":http://wiki.qt.io/Qt5ForAndroidBuilding about building Qt for Android.


= Qt on Android =
= Qt on Android =


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.
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.


== How to build Qt ==
== How to build Qt ==
Line 11: Line 11:
Set several environment variables depending on which versions of things you have installed and which ones you would like to use:
Set several environment variables depending on which versions of things you have installed and which ones you would like to use:


<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>
<code>
export JAVA_HOME=/usr/lib/jvm/java-default-runtime
export ANDROID_HOME=/opt/android-sdk
export ANDROID_SDK_ROOT=/opt/android-sdk
export ANDROID_SWT=/usr/share/java
export ANDROID_NDK_ROOT=/opt/android-ndk
export ANDROID_NDK_HOST=linux-x86_64
export ANDROID_BUILD_TOOLS_REVISION=19.0.3
export ANDROID_NDK_PLATFORM=android-9
export ANDROID_TARGET_ARCH=armeabi-v7a
export ANDROID_NDK_TOOLCHAIN_VERSION=4.8
export ANDROID_NDK=/opt/android-ndk
</code>


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.
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.
Line 17: Line 29:
Go to a fresh directory which you will use for building Qt, and run
Go to a fresh directory which you will use for building Qt, and run


<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>
<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
$ make
</code>


When it is all done, you will have the modules installed under qtbase, just as when you do a build on any desktop OS.
When it is all done, you will have the modules installed under qtbase, just as when you do a build on any desktop OS.
Line 23: Line 37:
While it is building, set up your qtchooser configuration:
While it is building, set up your qtchooser configuration:


<code>$ cd <sub>/.config/qtchooser<br />$ vi 5a.conf</code>
<code>$ cd ~/.config/qtchooser
<br />and create the contents something like this (adjusting paths as necessary):
$ vi 5a.conf</code>
<br /><code><br /></sub>/dev/qt5-android-arm7-stable-rel/qtbase/bin<br /><sub>/dev/qt5-android-arm7-stable-rel/qtbase/lib<br /></code>
 
<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.
and create the contents something like this (adjusting paths as necessary):
<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>
 
<br />h2. How to build an application
<code>
<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.
~/dev/qt5-android-arm7-stable-rel/qtbase/bin
<br />This is a useful script which you can create and put somewhere in your path, called deploy-android:
~/dev/qt5-android-arm7-stable-rel/qtbase/lib
<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>
</code>
<br />Assuming you have a project with a C++ main() and a .pro file, connect your Android device over USB, and do this:
 
<br /><code><br />cd /path/to/project<br />qmake<br />deploy-android<br /></code>
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 />It will build and install on your device.
 
<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.
<code>
<br />h2. Make it look like it belongs
mkcd qttools (or mkdir and then cd, if you don't have the mkcd alias)
<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.
qtchooser 5a
<br />h2. qmlscene
qmake /path/to/qt/qttools
<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.
make
<br />h2. Other notes
</code>
<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.
 
<br />h3. Debugging
h2. How to build an application
<br />With thanks to:<br />http://betelco.blogspot.com/2010/01/buildingdebugging-android-native-c.html
 
<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>
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.
<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
 
This is a useful script which you can create and put somewhere in your path, called deploy-android:
 
<code>
echo "Using Qt in ${QTDIR}"
make install INSTALL_ROOT=.
androiddeployqt —output . —deployment debug —install
adb logcat -c; adb logcat -C
</code>
 
Assuming you have a project with a C++ main() and a .pro file, connect your Android device over USB, and do this:
 
<code>
cd /path/to/project
qmake
deploy-android
</code>
 
It will build and install on your device.
 
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 "—deployment debug" flag to androiddeployqt will do the same thing as the "Deploy local Qt libraries to temporary directory" 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 "temporary directory", 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.
 
h2. Make it look like it belongs
 
When you get tired of the default green "droid" 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- 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 "git clean" without losing it. If you are using Creator though, there is special support for editing the manifest.
 
h2. qmlscene
 
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 "window") 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 "home" button to get the application switcher menu, and then go back to qmlscene; that will force a refresh.
 
h2. Other notes
 
This page previously mentioned "Wayland on Android":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.
 
h3. Debugging
 
With thanks to:
http://betelco.blogspot.com/2010/01/buildingdebugging-android-native-c.html
 
<code>./platform-tools/adb shell LD_LIBRARY_PATH=/data/local/tmp/androidtest /data/local/tmp/androidtest/gdbserver :1234 /data/local/tmp/androidtest/androidtest<code>
 
(in a seperate terminal)
</code>~/androidtest% ~/android-ndk-r7c/./toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-gdb androidtest
(gdb) set solib-search-path /Users/burchr/code/qt/qt5/qtbase/lib
(gdb) target remote :1234
(gdb) b main
Breakpoint 1 at 0xd648: file main.cpp, line 87.
(gdb) c

Revision as of 08:58, 25 February 2015

This page has a lot of overlap with "another page":http://wiki.qt.io/Qt5ForAndroidBuilding about building Qt for Android.

Qt on Android

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.

How to build Qt

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.

Set several environment variables depending on which versions of things you have installed and which ones you would like to use:

export JAVA_HOME=/usr/lib/jvm/java-default-runtime
export ANDROID_HOME=/opt/android-sdk
export ANDROID_SDK_ROOT=/opt/android-sdk
export ANDROID_SWT=/usr/share/java
export ANDROID_NDK_ROOT=/opt/android-ndk
export ANDROID_NDK_HOST=linux-x86_64
export ANDROID_BUILD_TOOLS_REVISION=19.0.3
export ANDROID_NDK_PLATFORM=android-9
export ANDROID_TARGET_ARCH=armeabi-v7a
export ANDROID_NDK_TOOLCHAIN_VERSION=4.8
export ANDROID_NDK=/opt/android-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.

Go to a fresh directory which you will use for building Qt, and run

$ /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
$ make

When it is all done, you will have the modules installed under qtbase, just as when you do a build on any desktop OS.

While it is building, set up your qtchooser configuration:

$ cd ~/.config/qtchooser
$ vi 5a.conf

and create the contents something like this (adjusting paths as necessary):

~/dev/qt5-android-arm7-stable-rel/qtbase/bin
~/dev/qt5-android-arm7-stable-rel/qtbase/lib

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.

mkcd qttools (or mkdir and then cd, if you don't have the mkcd alias)
qtchooser 5a
qmake /path/to/qt/qttools
make

h2. How to build an application

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.

This is a useful script which you can create and put somewhere in your path, called deploy-android:

echo "Using Qt in ${QTDIR}"
make install INSTALL_ROOT=.
androiddeployqt output . deployment debug install
adb logcat -c; adb logcat -C

Assuming you have a project with a C++ main() and a .pro file, connect your Android device over USB, and do this:

cd /path/to/project
qmake
deploy-android

It will build and install on your device.

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 "—deployment debug" flag to androiddeployqt will do the same thing as the "Deploy local Qt libraries to temporary directory" 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 "temporary directory", 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.

h2. Make it look like it belongs

When you get tired of the default green "droid" 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- 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 "git clean" without losing it. If you are using Creator though, there is special support for editing the manifest.

h2. qmlscene

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 "window") 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 "home" button to get the application switcher menu, and then go back to qmlscene; that will force a refresh.

h2. Other notes

This page previously mentioned "Wayland on Android":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.

h3. Debugging

With thanks to: http://betelco.blogspot.com/2010/01/buildingdebugging-android-native-c.html

./platform-tools/adb shell LD_LIBRARY_PATH=/data/local/tmp/androidtest /data/local/tmp/androidtest/gdbserver :1234 /data/local/tmp/androidtest/androidtest<code>

(in a seperate terminal)

~/androidtest% ~/android-ndk-r7c/./toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-gdb androidtest

(gdb) set solib-search-path /Users/burchr/code/qt/qt5/qtbase/lib (gdb) target remote :1234 (gdb) b main Breakpoint 1 at 0xd648: file main.cpp, line 87. (gdb) c