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

# 初めに

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

* マルチABIサポート
* AAB（Android App Bundle）パッケージ形式サポート

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

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

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

ABIについて、詳しく知りたい方は、[Android DevelopersのABI 管理ページ](https://developer.android.com/ndk/guides/abis)をご覧ください。

Qt5.13において、Qt Creatorで端末動作用のAPKを作成する場合、端末のABIに合わせて、armeabi-v7aとarm64-v8aのどちらかに切り替えてビルドする必要がありました。
Qt5.14では、１つのビルドで複数のABIをまとめてビルドできます。
まずはMaintenanceToolから見ていきましょう。
![install.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69678/91fb867e-a5a6-c1c5-b87c-bbd4d29909b4.png)

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

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

![qt_android_kit_select.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69678/95f02643-a90a-d0f6-ec31-3e61cd3ff831.png)

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


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

```何も設定を変更させずにビルドした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」の詳細を表示させます。
![android_qmake_setting.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69678/42d507fe-bf5c-478f-199f-fc0c90247510.png)
すると、ABIsという項目が表示され、armeabi-v7aの項目だけチェックが付いています。arm64-v8aにもチェックをつけてビルドしてみましょう。
すると、

```armeabi-v7aとarm64-v8aにチェックを付けた場合のAPKの中身
│  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を指定すると、結構ビルド時間が長くなります。（複数ビルドするのだから当たり前といえば当たり前ですが）
従って、ビルド時間が気になる場合は、デバッグ時はあえて１つのABIだけにしぼって設定し、リリースするときはABIを複数選択する、といった運用にするのがよいかもしれません。

# AAB（Android App Bundle）パッケージ形式

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

AABについては、Android Developersの[こちら](https://developer.android.com/guide/app-bundle)をご覧ください。

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

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

![AAB.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69678/a8978d25-f262-f559-bb66-28af9ab215f9.png)

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

# 最後に

* マルチABIサポート
* AAB（Android App Bundle）パッケージ形式サポート

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