C++ メインな Android アプリの APK を gradle を使わずビルドする 

# 背景

* AR, Vision や 3D レンダリング(GLES, Vulkan)などで, C++ + CMake がメインで Android native で動くアプリを開発したい(エミュレータを使うのができない. GPU の性能を実デバイスで確認する必要があるなど)
* Android での C++ 部分の動作確認が主であるので, release APK を作るとか, 凝った UI を作る必要はない.
* デバッグはビジュアルデバッグ(画面に色をつけたり, グラフを出したり)がメインなので gradle にあるように build variant などプロジェクトのビルド構成を変える必要がない(C++ パートは CMake などでビルド構成を設定) 
* **gradle が遅くてつらい**. **gradle すぐバージョンアップしたり仕様かわったりで, バージョンミスマッチとかでてつらい**. **gradle でよくわからないモジュールがたくさんダウンロード必要になってつらい**
* Ant の時代はよかった. しかし Ant でのビルドは deprecated 扱いとなっている.

gradle も Ant なども, 実際には Android SDK のツールを呼び出しているだけなはずので, gradle 非依存でビルド環境を整えることができるはず.

# 手順

先人たちの素晴らしい記事があります. **顧客が本当に欲しかったものです**. ありがとうございます.

How to make Android apps without IDE from command line
https://medium.com/@authmane512/how-to-build-an-apk-from-command-line-without-ide-7260e1e22676

Building an Android App from the Command Line
https://www.hanshq.net/command-line-android.html

先人たちの素晴らしい記事を参考にし, 作成した APK が Android 9(Pixel3) で動きました. ありがとうございます.

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">ねんがんの gradle なしでの APK ビルドに成功したぞ!!!! 🎉🎉🎉🎉🎉🎉🎉🎉🤘🤘🤘🤘🤘🤘😆😆😆😆😆😻😻😻😻😻😊😊😊😊 しかし SDK 28 を使ってビルドしたのは Android 9 では warning が出てしまいました. 最近また何か変わったのかしらん. 日々精進あるのみですね. <a href="https://t.co/znuff1eVv7">pic.twitter.com/znuff1eVv7</a></p>&mdash; Syoyo Fujita ⚡️ No ray tracing No life (@syoyo) <a href="https://twitter.com/syoyo/status/1098547127053996032?ref_src=twsrc%5Etfw">2019年2月21日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


## APK とは?

中身は単に zip で圧縮したフォルダっぽい.
C++ は .so ファイルで, Java レイヤーは jar で格納
フォルダのレイアウトで, アセットやアーキティクチャの管理をしたりしている模様.

## 注意点など

apksigner で署名したあとに zipalign すると adb install できない(バイナリのレイアウトが変わってハッシュ値が変わるから?).

zipalign でアラインは, 昨今のスマホの性能向上で基本不要かも?(e.g. Android 8 以降くらいの端末とか)

# 参考文献

Filament では .lib/.so は CMake + Ninja, 最後の APK を作るところは gradle を使っていますね.

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">If your app is mostly native your Gradle file should be pretty simple. We build Filament as a library with CMake and Ninja then use Gradle+CMake for the JNI+APK</p>&mdash; Romain Guy (@romainguy) <a href="https://twitter.com/romainguy/status/1098415951391862785?ref_src=twsrc%5Etfw">2019年2月21日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## SDK version

SDK 28 でビルドし, Android 9 で動かすと, "古い環境向けにビルドされています" warning が出ます.
min sdk version を指定していないためです.

昨今では, SDK バージョンは `AndroidManifest.xml` に記載するのではなく, apksigner の引数で指定が推奨のようです.

https://developer.android.com/studio/command-line/apksigner

## apkzlib

並列 zip 圧縮などして, より高速に apk を作るツール.

https://android.googlesource.com/platform/tools/apkzlib/ 

<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">We never used aapt to build the APK because it&#39;s not incremental. We moved assets from aapt directly into our apk builder to be more efficient. APKZlib also handles incrementally updating apks, doing parallel compression, and doing apk + signing v2 + zipalign in 1 pass.</p>&mdash; Xavier Ducrohet (@droidxav) <a href="https://twitter.com/droidxav/status/956974948727242753?ref_src=twsrc%5Etfw">January 26, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


あんまり公開情報はないのでつらい.

# TODO

* Meson build と組み合わせ, CMake 依存を無くす. e.g. https://github.com/glimpse-project/glimpse/blob/master/build_apk.py
* aapt/zipalign/apksigner あたりを呼ぶスクリプトを書く
* Clang/LLVM を Android native でビルドして, C++ コードの Android 上での動的コンパイル(JIT コンパイル)を試す.
* Java(UI)のアプリと, C++ 処理の部分を切り分け, C++ 部分はバックグランドサービス(Intent?)として動かし, C++ 部分のリコンパイルと差し替えをやりやすくする.