Skip to content

Qt for Android better than ever before What's new in Qt 5.14 for Android

As you already know KDAB is the largest independent contributor to Qt code. Of course we didn’t get lazy and we’ve added a lot of cool stuff to Qt 5.14.

In this article I’m going to write about the super cool stuff that we’ve added to Qt 5.14 for Android.

Android multi arch build in one go

Folks, this is the biggest feature added to Qt on Android since I made the Qt on Android port! I dreamt on this change for a very loong time! I found that is possible to add such support to qmake by mistake :). I had to do some work on Windows (which is not my platform of choice) and there I found that debug and release builds are different on Windows, the makefiles generated by qmake will build twice your source files.

This was exactly what I needed to add multi abi for Android! A few days later I had a WIP patch and, with the help of The Qt Company people, we landed the change in Qt 5.14 alpha!

Let’s see what is new:

  • First and foremost from Qt 5.14 there will be a single Qt for Android SDK. Same as the Android NDK, the Qt for Android SDK contains the libs & plugins built for all Android platforms (armv7a, arm64-v8a, x86, x86_64). If you’re building Qt from sources and you want to build only for e.g. arm architectures, you can filter them using the new -android-abis configure parameter:
     ./configure -android-abis armv7a,arm64-v8a -developer-build -xplatform android-clang -android-ndk /home/bogdan/android/ndk-bundle -android-sdk /home/bogdan/android
    
  • If not specified otherwise, your application will be built by default for all these platforms in one go. You can filter which ABI(s) you want to build for using the ANDROID_ABIS qmake variable, this is useful while you develop your application, to cut the build time. Build only for arm64-v8a

    qmake ANDROID_ABIS="arm64-v8a"

    Build only for armv7a and arm64-v8a

    qmake ANDROID_ABIS="armeabi-v7a arm64-v8a"

Yes, we changed Qt Creator to make it easier to choose which platforms you want to build for, check the next image:

In order to support this super cool feature we had to change a few things:

  • All the .so files produced by qmake are suffixed with the android abi. If you’re using Qt library/plugins classes you don’t need to take any actions, otherwise qmake sets QT_ARCH variable for the ABI you’re currently building, so you can use it to know which suffix you need to add e.g:

    # ...
    android: DEFINES += LIBS_SUFFIX='\\"_$${QT_ARCH}.so\\"'
    # ...
    

    Then you can use LIBS_SUFFIX macro in your srcs.

  • Because on android we have only one libs folder level, we must rename all the [qml] plugins to make sure we don’t have any name clashes. We use the following naming scheme:
    lib + "plugin/path".replace('/','_') + {plugin_name} + _$${QT_ARCH}.so.

    If you have a plugin which uses ANDROID_LIB_DEPENDENCIES qmake variable make sure you use the previous naming scheme. Here https://codereview.qt-project.org/c/qt/qtgamepad/+/273676/2/src/gamepad/gamepad.pro you can see how we did it for Qt Gamepad module. Initially I did the renaming from androiddeployqt, but soon I found that this breaks the plugins debugging, as the gdb won’t find the renamed files on the Qt folders, and for me not being able to debug my precious plugins was unacceptable.

Android App Bundles (aab)

I’m going to tell you a secret, Android App Bundles were the main reason for doing the multi arch build in one go :). Without multi arch build in one go you can’t have aab, well at least not without a lot of work, pain and sorrow. Because I’m a happy, lazy person, I don’t like to work more than I must, therefore I had to find a solution to make our life easier. In Qt 5.14, it’s very easy to build an .aab file:

$ make aab

it’s all you need to run on a terminal to build it!

Same as above, I added a new option to Qt Creator to enable .aab packages with a single check box, see the following image:

Load Qt plugins directly from android libs folder

Since Qt 5.14, the Qt plugins were stored to android assets and then extracted to your home folder at the very first start. There are two problems with this approach:

  • The very first startup time needed more time to extract all the files
  • It occupies more disk space

Starting with 5.14, instead of bundling the plugins and QML resources in assets and extracting them on first start, Qt now creates an .rcc file and registers it before invoking the main function.

Other pretty nice changes

  • Same as above, in Qt 5.14 you can easily create an apk from the command line:
    $ make apk

    is all you need to type on your terminal to create it.

  • Reworked assets support – the new version fixes QDirIterators, also it lists all the files and folders.
  • NDK r20+ is needed as I updated the clang mkspecs to follow https://android.googlesource.com/platform/ndk/+/ndk-release-r20/docs/BuildSystemMaintainers.md guide. With this change, let’s hope we’ll have less issues with newer NDK versions, as you probably noticed Google folks are restless and they are doing their best to break other tools from time to time :).
  • Drop gcc support – this was a change that personally I didn’t like to do it, but I had to, mostly because it was quite challenging to support NDK r10e (the recommended NDK for gcc).
  • Last but not least, an easy way to run tests on Android:
    $ make check

    It’s all you need. For more details and tweaks about it, you can come to my Qt World Summit presentation ;-).

  • See more about KDAB Talks at Qt World Summit
FacebookTwitterLinkedInEmail

8 thoughts on “Qt for Android better than ever before”

  1. Was this work done mostly for qmake projects or is there a CMake alternative available?

    Either way, great work!

    1. BogDan Vatra

      Only qmake fully supports this feature. It’s also possible to add it to qbs, as it has first class multi abi support.
      Cmake is limited to only one ABI. Cmakes doesn’t support at all multi abi, and according to https://gitlab.kitware.com/cmake/cmake/issues/18450 there are no good news for the future…

      This means that without quite some magic in QtCreator to spawn cmake for each ABI needed to hide the cmake limitation, it will be impossible have multi abi .apk/.aab support for cmake projects. See https://codereview.qt-project.org/c/qt-creator/qt-creator/+/270196/8#message-59b94fa5dc631c0ec1bfd484ff261a102a12e172 for more info on this matter.

      1. I pretty much like these changes in Qt – I bet they will make deploying to Android much easier, especially since with AAB you only have one build artifact to upload and deploy 🙂

        Regarding your notes on the cmake support: I understand that cmake itself does not support multiple archs in one go (which is a shame, but we have to take it for granted right now). However:

        * My understanding is, that with Qt 6, Qt itself will migrate to cmake and – while qmake based builds will still be supported – qmake will probably be deprecated and as a consequence I’d assume it would be better to migrate to cmake latest then. Do you have a forecast for us on how things might evolve in the further development of Qt?
        * I have an app which currently uses cmake as build system. With the changes coming in Qt 5.14, it seems tempting to migrate back to qmake. On the other side, I have dependencies to some other libraries (basically, KF5 based ones) which in turn use cmake. What would be the best way to integrate such libraries with qmake based application? Do you have any recommendations?
        * Finally, how to deal with ANDROID_EXTRA_LIBS in qmake? Would you just add all libraries for all architectures and Qt itself takes care for the rest?

        1. BogDan Vatra

          * Sadly in this moment we are all puzzled by TQC decision regarding Qt 6 build system. For sure I’ll discuss this matter at Qt Contributors Summit.
          * the best way to add any libs to a qmake project for android is to add them to ANDROID_EXTRA_LIBS. If you think it’s acceptable to change your project files you can try Cristian’s approach (check the comment below).
          * you add all your external libs (yes, for all abis) to ANDROID_EXTRA_LIBS qmake variable. androiddeployqt checks every single library and it will copy it to the right abi folder.

      1. BogDan Vatra

        I’ve been on that road with your colleague, Alexandru Croitoru, and we found a few flows:
        – there is no way to pass all user defined arguments to “ExternalProject_Ad”*. Please check with Alexandru for more info on this matter, IIRC he created a bug report for cmake folks on this matter.
        – last but for sure not least: you are forcing people to change and tweak *their* project files, which for me doesn’t fall into easy, nor first class support at all.

        For a qmake project you don’t need to change anything in your .pro/.pri files to enjoy multi abi for android, it just works! This is what *I* call an easy, professional & first class solution for multi abi builds in one go ;-).

        1. For the arguments missing you can use an initial CMake pre cache file which you pass via -C, and then you have everything you need to give forward.

          Regarding modifying user’s project files, CMake 3.15 introduced CMAKE_PROJECT_INCLUDE exactly for the purpose of controlling projects without modifying them.

          Or you can use PreLoad.cmake which gets injected automatically, and works in older CMake versions.

          Any other problems?

Leave a Reply

Your email address will not be published. Required fields are marked *

By continuing to use the site, you agree to the use of cookies. More information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close