Qt5.14で生まれ変わったQt/Androidのビルド環境


初めに

Qt5.14で、Qt/Androidビルド環境が大きく変わりました。

  • マルチABIサポート
  • AAB(Android App Bundle)パッケージ形式サポート

の2点の機能がリリースされました。
これらにより、Qt/Androidアプリを作成及び配布が容易になりました。

マルチABI

Qt5.13までは、Qt/Androidのアプリをビルドする際、CPUの種類(正確にはABI(Application Binary Interface))毎にビルドターゲットを変更する必要がありました。
Qt5.13でもQt5.14でもQt/Androidビルドで選択できるABIの種類は下記の4つです。

ABI 説明
armeabi-v7a 端末の32ビットCPUアーキテクチャ
arm64-v8a 端末の64ビットCPUアーキテクチャ
x86 シミュレータの32ビットCPUアーキテクチャ
x86_64 シミュレータの64ビットCPUアーキテクチャ

ABIについて、詳しく知りたい方は、Android DevelopersのABI 管理ページをご覧ください。

Qt5.13において、Qt Creatorで端末動作用のAPKを作成する場合、端末のABIに合わせて、armeabi-v7aとarm64-v8aのどちらかに切り替えてビルドする必要がありました。
Qt5.14では、1つのビルドで複数のABIをまとめてビルドできます。
まずはMaintenanceToolから見ていきましょう。

Qt5.13.2では、Android向けコンポーネントが4つあったのが、Qt5.14.0では、Android1つに統合されています。

次に、プロジェクト作成時に「キットの選択」です。

このようにAndroid向けのキットが1つにまとめられています。

次に作成されたAPKの中身を見ていきましょう。APKはZip形式で固めただけのファイルである為、解凍ツールで解凍すれば中身が見れます。
ビルドディレクトリ/android-build/build/outputs/apk/debug/にAPKファイルが格納されています。

│  AndroidManifest.xml
│  classes.dex
│  resources.arsc
│  
├─assets
│      android_rcc_bundle.rcc
│      
├─lib
│  └─armeabi-v7a
│          libAndroidSample_armeabi-v7a.so
│          libc++_shared.so
│          libplugins_bearer_qandroidbearer_armeabi-v7a.so
│          libplugins_imageformats_qgif_armeabi-v7a.so
│          libplugins_imageformats_qicns_armeabi-v7a.so
│          libplugins_imageformats_qico_armeabi-v7a.so
│          libplugins_imageformats_qjpeg_armeabi-v7a.so
│          libplugins_imageformats_qtga_armeabi-v7a.so
│          libplugins_imageformats_qtiff_armeabi-v7a.so
│          libplugins_imageformats_qwbmp_armeabi-v7a.so
│          libplugins_imageformats_qwebp_armeabi-v7a.so
│          libplugins_platforms_qtforandroid_armeabi-v7a.so
│          libplugins_qmltooling_qmldbg_debugger_armeabi-v7a.so
│          libplugins_qmltooling_qmldbg_inspector_armeabi-v7a.so
│          libplugins_qmltooling_qmldbg_local_armeabi-v7a.so
│          libplugins_qmltooling_qmldbg_messages_armeabi-v7a.so
│          libplugins_qmltooling_qmldbg_nativedebugger_armeabi-v7a.so
│          libplugins_qmltooling_qmldbg_native_armeabi-v7a.so
│          libplugins_qmltooling_qmldbg_preview_armeabi-v7a.so
│          libplugins_qmltooling_qmldbg_profiler_armeabi-v7a.so
│          libplugins_qmltooling_qmldbg_quickprofiler_armeabi-v7a.so
│          libplugins_qmltooling_qmldbg_server_armeabi-v7a.so
│          libplugins_qmltooling_qmldbg_tcp_armeabi-v7a.so
│          libqml_QtGraphicalEffects_private_qtgraphicaleffectsprivate_armeabi-v7a.so
│          libqml_QtGraphicalEffects_qtgraphicaleffectsplugin_armeabi-v7a.so
│          libqml_QtQuick.2_qtquick2plugin_armeabi-v7a.so
│          libqml_QtQuick_Controls.2_Fusion_qtquickcontrols2fusionstyleplugin_armeabi-v7a.so
│          libqml_QtQuick_Controls.2_Imagine_qtquickcontrols2imaginestyleplugin_armeabi-v7a.so
│          libqml_QtQuick_Controls.2_Material_qtquickcontrols2materialstyleplugin_armeabi-v7a.so
│          libqml_QtQuick_Controls.2_qtquickcontrols2plugin_armeabi-v7a.so
│          libqml_QtQuick_Controls.2_Universal_qtquickcontrols2universalstyleplugin_armeabi-v7a.so
│          libqml_QtQuick_Templates.2_qtquicktemplates2plugin_armeabi-v7a.so
│          libqml_QtQuick_Window.2_windowplugin_armeabi-v7a.so
│          libQt5Core_armeabi-v7a.so
│          libQt5Gui_armeabi-v7a.so
│          libQt5Network_armeabi-v7a.so
│          libQt5QmlModels_armeabi-v7a.so
│          libQt5QmlWorkerScript_armeabi-v7a.so
│          libQt5Qml_armeabi-v7a.so
│          libQt5QuickControls2_armeabi-v7a.so
│          libQt5QuickParticles_armeabi-v7a.so
│          libQt5QuickTemplates2_armeabi-v7a.so
│          libQt5Quick_armeabi-v7a.so
│          
├─META-INF
│      CERT.RSA
│      CERT.SF
│      MANIFEST.MF
│      
└─res
    └─layout
            splash.xml            

Qtライブラリとしては、armeabi-v7a用のライブラリだけが入っていました。
では、armeabi-v7aとarm64-v8aの両方のQtライブラリを含めたい場合はどうするのでしょうか。
Qt Creatorの画面左側にある「プロジェクト」を選択し、「ビルドステップ」の「qmake」の詳細を表示させます。

すると、ABIsという項目が表示され、armeabi-v7aの項目だけチェックが付いています。arm64-v8aにもチェックをつけてビルドしてみましょう。
すると、

│  AndroidManifest.xml
│  classes.dex
│  resources.arsc
│  
├─assets
│      android_rcc_bundle.rcc
│      
├─lib
│  ├─arm64-v8a
│  │      libAndroidSample_arm64-v8a.so
│  │      libc++_shared.so
│  │      libplugins_bearer_qandroidbearer_arm64-v8a.so
│  │      libplugins_imageformats_qgif_arm64-v8a.so
│  │      libplugins_imageformats_qicns_arm64-v8a.so
│  │      libplugins_imageformats_qico_arm64-v8a.so
│  │      libplugins_imageformats_qjpeg_arm64-v8a.so
│  │      libplugins_imageformats_qtga_arm64-v8a.so
│  │      libplugins_imageformats_qtiff_arm64-v8a.so
│  │      libplugins_imageformats_qwbmp_arm64-v8a.so
│  │      libplugins_imageformats_qwebp_arm64-v8a.so
│  │      libplugins_platforms_qtforandroid_arm64-v8a.so
│  │      libplugins_qmltooling_qmldbg_debugger_arm64-v8a.so
│  │      libplugins_qmltooling_qmldbg_inspector_arm64-v8a.so
│  │      libplugins_qmltooling_qmldbg_local_arm64-v8a.so
│  │      libplugins_qmltooling_qmldbg_messages_arm64-v8a.so
│  │      libplugins_qmltooling_qmldbg_nativedebugger_arm64-v8a.so
│  │      libplugins_qmltooling_qmldbg_native_arm64-v8a.so
│  │      libplugins_qmltooling_qmldbg_preview_arm64-v8a.so
│  │      libplugins_qmltooling_qmldbg_profiler_arm64-v8a.so
│  │      libplugins_qmltooling_qmldbg_quickprofiler_arm64-v8a.so
│  │      libplugins_qmltooling_qmldbg_server_arm64-v8a.so
│  │      libplugins_qmltooling_qmldbg_tcp_arm64-v8a.so
│  │      libqml_QtGraphicalEffects_private_qtgraphicaleffectsprivate_arm64-v8a.so
│  │      libqml_QtGraphicalEffects_qtgraphicaleffectsplugin_arm64-v8a.so
│  │      libqml_QtQuick.2_qtquick2plugin_arm64-v8a.so
│  │      libqml_QtQuick_Controls.2_qtquickcontrols2plugin_arm64-v8a.so
│  │      libqml_QtQuick_Templates.2_qtquicktemplates2plugin_arm64-v8a.so
│  │      libqml_QtQuick_Window.2_windowplugin_arm64-v8a.so
│  │      libQt5Core_arm64-v8a.so
│  │      libQt5Gui_arm64-v8a.so
│  │      libQt5Network_arm64-v8a.so
│  │      libQt5QmlModels_arm64-v8a.so
│  │      libQt5QmlWorkerScript_arm64-v8a.so
│  │      libQt5Qml_arm64-v8a.so
│  │      libQt5QuickControls2_arm64-v8a.so
│  │      libQt5QuickParticles_arm64-v8a.so
│  │      libQt5QuickTemplates2_arm64-v8a.so
│  │      libQt5Quick_arm64-v8a.so
│  │      
│  └─armeabi-v7a
│          libAndroidSample_armeabi-v7a.so
│          libc++_shared.so
│          libplugins_bearer_qandroidbearer_armeabi-v7a.so
│          libplugins_imageformats_qgif_armeabi-v7a.so
│          libplugins_imageformats_qicns_armeabi-v7a.so
│          libplugins_imageformats_qico_armeabi-v7a.so
│          libplugins_imageformats_qjpeg_armeabi-v7a.so
│          libplugins_imageformats_qtga_armeabi-v7a.so
│          libplugins_imageformats_qtiff_armeabi-v7a.so
│          libplugins_imageformats_qwbmp_armeabi-v7a.so
│          libplugins_imageformats_qwebp_armeabi-v7a.so
│          libplugins_platforms_qtforandroid_armeabi-v7a.so
│          libplugins_qmltooling_qmldbg_debugger_armeabi-v7a.so
│          libplugins_qmltooling_qmldbg_inspector_armeabi-v7a.so
│          libplugins_qmltooling_qmldbg_local_armeabi-v7a.so
│          libplugins_qmltooling_qmldbg_messages_armeabi-v7a.so
│          libplugins_qmltooling_qmldbg_nativedebugger_armeabi-v7a.so
│          libplugins_qmltooling_qmldbg_native_armeabi-v7a.so
│          libplugins_qmltooling_qmldbg_preview_armeabi-v7a.so
│          libplugins_qmltooling_qmldbg_profiler_armeabi-v7a.so
│          libplugins_qmltooling_qmldbg_quickprofiler_armeabi-v7a.so
│          libplugins_qmltooling_qmldbg_server_armeabi-v7a.so
│          libplugins_qmltooling_qmldbg_tcp_armeabi-v7a.so
│          libqml_QtGraphicalEffects_qtgraphicaleffectsplugin_armeabi-v7a.so
│          libqml_QtQuick.2_qtquick2plugin_armeabi-v7a.so
│          libqml_QtQuick_Controls.2_qtquickcontrols2plugin_armeabi-v7a.so
│          libqml_QtQuick_Templates.2_qtquicktemplates2plugin_armeabi-v7a.so
│          libqml_QtQuick_Window.2_windowplugin_armeabi-v7a.so
│          libQt5Core_armeabi-v7a.so
│          libQt5Gui_armeabi-v7a.so
│          libQt5Network_armeabi-v7a.so
│          libQt5QmlModels_armeabi-v7a.so
│          libQt5QmlWorkerScript_armeabi-v7a.so
│          libQt5Qml_armeabi-v7a.so
│          libQt5QuickControls2_armeabi-v7a.so
│          libQt5QuickParticles_armeabi-v7a.so
│          libQt5QuickTemplates2_armeabi-v7a.so
│          libQt5Quick_armeabi-v7a.so
│          
├─META-INF
│      CERT.RSA
│      CERT.SF
│      MANIFEST.MF
│      
└─res
    └─layout
            splash.xml         

のように、armeabi-v7aとarm64-v8a両方のQtライブラリが含まれるようになりました。
ビルドしてみて感じたのですが、複数のABIを指定すると、結構ビルド時間が長くなります。(複数ビルドするのだから当たり前といえば当たり前ですが)
従って、ビルド時間が気になる場合は、デバッグ時はあえて1つのABIだけにしぼって設定し、リリースするときはABIを複数選択する、といった運用にするのがよいかもしれません。

AAB(Android App Bundle)パッケージ形式

マルチABIサポートのサポートだけだと、ABIの種類分APKにライブラリが含まれる為、APKのファイルサイズがどうしても大きくなってしまいます。そのファイルサイズ問題が解決できるであろう機能がAAB(Android App Bundle)です。

AABについては、Android Developersのこちらをご覧ください。

このページによると、Google Play の新しいアプリ配信モデルである「Dynamic Delivery」に、AAB形式のファイルを登録することにより、個々のユーザーのデバイス設定に合わせて最適化された APK を生成、配信される、つまり、無駄なライブラリはAPKに含まれなくなります。(残念ながら、Google Playを使用した検証まではできていません)

AAB形式でビルドするには、Qt Creatorにおいて、

Qt Creatorの画面左側にある「プロジェクト」を選択し、「ビルドステップ」の「Build Android APK」の詳細を表示させ、「Advanced Actions」のところにある「Build .aab(Android App Build)」にチェックを付けるだけです。

最後に

  • マルチABIサポート
  • AAB(Android App Bundle)パッケージ形式サポート

の対応により、端末にAPKをデプロイすること。Google Playに登録することがやりやすくなったと思います。
ぜひQt5.14で、Qt/Androidアプリを作成してみてください。