背景
- Android Studio でビルドしたくない
- SDK のダウンロードとかでは使った方が楽かと思います
- gradle を使いたくない
- C/C++ でグラフィックスや機械学習コードを cli で動かしたいがメインなので, Java レイヤーとか作る必要がない
- cmake のビルドで ./a.out を作る感じで apk まで作りたい(e.g. CI 向け)
参考情報
C++ メインな Android アプリの APK を gradle を使わずビルドする
https://qiita.com/syoyo/items/1a8a603e5b9bacf5f2b5
NativeActivity サンプル
https://developer.android.com/ndk/samples/sample_na
CMake script for creating/running Android APK
https://github.com/hunter-packages/android-apk
Build Android NDK project with Cmake
https://stackoverflow.com/questions/19207721/build-android-ndk-project-with-cmake
環境
ネットで漁るとかなり古い情報(~2013)がひっかかり, 最近の Android SDK では対応していなかったり(e.g. android
コマンド)するので注意です. 以下の環境を想定します.
- Android SDK tools version 26+
- Android SDK Build-Tools version 29.0.3+
- Android SDK version(API level) 28+(Android 9+)
- API level 26 から NativeActivity で no JAVA コード実行対応していますので, 一応 minSdkLevel 26 にすれば Android 8 でも動きます.
- Android NDK r21+(一応 r19+ でも動くと思われます)
- Android sdkmanager で落とせる Android 向けにカスタマイズされた CMake(3.10) or 通常の cmake 3.7 以上
デバッグ APK 用の鍵生成とか, SDK のダウンロードとかはコマンドラインだとめんどいので, Android Stuio 入れて落としておいたほうが楽かと思います.
また, 開発環境は Linux を想定します(少量の変更で Windows, macOS でも動作させることができると思います)
事前準備
NDK, SDK などのインストール, zipalign などへパスを通しておく.
debug 用の keystore はコマンドラインで keytool
でも生成できます.
debug用keystoreについて調べてみた
https://qiita.com/taka0125/items/c408df4061a0af49c9b3
手順
- NativeActivity ベースで
AndroidManifest.xml
を生成する.- meta-data に .so の名前を記述しておく必要があるので注意. https://qiita.com/syoyo/items/c4ea702bf2ac4b2600e0
- CMake で .so をビルド
- CMake カスタムコマンドで, 以下を行う
- APK のファイルレイアウトに添うように
AndroidManifest.xml
,lib
フォルダ(.so を含んでいる)を配置する -
aapt
で APK を作成 -
jarsigner
orapksigner
で署名- 自前で作った keystore か, Android Studio(or gradle?) で生成されるデバッグ用の鍵
~/debug.keystone
を使う.- storepass, keypass は
android
になっていると思われる.
- storepass, keypass は
- 自前で作った keystore か, Android Studio(or gradle?) で生成されるデバッグ用の鍵
-
zipalign
でアライン - optional で
adb
で apk インストールなどする
- APK のファイルレイアウトに添うように
jarsigner の場合は zipalign 前, apksigner の場合は zipalign した後に呼ぶ必要があります.
SDK 26 あたりから apksigner
が推奨になったようですので, 可能なかぎり apksinger
を使いましょう.
SDK tool に apksigner
などありますが, Ubuntu 18.04 だと, aapt
, apksigner
, zipalign
は apt でも入ります.
APK を作る CMake 例は以下を参考ください.
https://github.com/lighttransport/mlspv/tree/master/cmake/android
mlspv のは, OrbitEngine のを参考にしています.
https://github.com/mlomb/OrbitEngine
aapt などはパスが通っていることを想定しています.
OrbitEngine のは古い android
コマンドや ant
ビルドを想定していて動かないので, そのあたり mlspv のほうに修正を入れています.
AndroidManifest.xml
Java コードを使わない(システムにインストールされている NativeActivity)を使う場合は,
hasCode="false"
にし,
activity android:name="android.app.NativeActivity"
と android.app.NativeActivity
を指定します.
meta-data android:name="android.app.lib_name"
で .so のファイル名を指定します.
android:exported
は "true" がいいかもしれません.
libc++_shared.so
ANDROID_STL
を c++_shared
にしている場合は, libc++_shared.so
を NDK からコピってきて apk パッケージに入れるのを cmake custom command で記述します.
address saintizzer, vulkan validation layers など
その他 .so も, 必要に応じてパッケージングするのを cmake に記述します.
Android Vulkan で ValidationLayers をインストール, 有効にするメモ
https://qiita.com/syoyo/items/2e6f9b999452ac6c041f
Android + cmake で ASAN(Address Sanitizer)を使う
https://qiita.com/syoyo/items/4f01e6946ad0aee733f7
adb 注意点
adb も含めて cmake custom command で実行する場合, adb でデバイスに接続していないとそのまま反応がないようです. cmake custom command + ninja でビルドするとメッセージが出ずにハマります(Makefile ビルドではメッセージが出る).
adb コマンドでは timeout 指定できなようなので, bash で timeout 使うなどする必要があります.
Windows は個別のバッチスクリプトをでっちあげないと cmake custom command 実行はa難しいかも?
もしくは, fb-adb でなにかできるかも? > https://github.com/facebook/fb-adb
Windows ビルド対応
このようなバッチスクリプトで, cmake -> ninja で APK ビルドできるようになりました.
現状 SDK, NDK などへいくらかパスを通しておく必要はあります.
optional
debug build は, ant
を使う手もありますが, この場合 build.xml
を作ってくれる android update project
は廃止されたので, なんらかの方法で build.xml
など作ることになります.
TODO
- 普通に adb install だと Android Studio, Flutter などと比べてインストールまでの処理が遅い気がするので, 高速に adb install できる方法があるか調べる
- Java 依存をさらに減らす(apksigner などを, C++ で再実装したものなどで代用できないか)
- cmake で, Android SDK, NDK などのパスをうまく環境変数などから拾ってきて設定する.
- asset, resource ファイルを扱う.
- APK 作るところを meson の python で記述し, meson でもビルドできるようにする.
- Hunter の cmake APK を参考にして, cmake スクリプトを改善する
- ndk-gdb or lldb で CLI でデバッグする手順を確認する.
- cmake だけで完結するので, VSCode などと連携できるようにする