このプロジェクトは、吉里吉里Z (Krkrz) を Android で 動作させるためのプロジェクトテンプレートです
ライブラリ参照に vcpkg を使っているので、 環境変数 VCPKG_ROOT に vcpkg のルートフォルダを指定する必要があります
吉里吉里Zのソース参照用に、環境変数 KRKRZ_BASE に krkrz_dev (krkrz + plugin 共通プロジェクトフォルダ)がある場所を指定しておきます。
以下のフォルダを参照するように app/src/main/cpp/CMakeLists.txt が記載されています
吉里吉里本体 ${KRKRZ_BASE}/krkrz_dev/src/core
吉里吉里プラグインソース ${KRKRZ_BASE}/krkrz_dev/src/plugins
同時リンクするプラグインの構成は app-config.json の cmake セクションで指定します
(後述「CMake プラグイン構成 (cmake)」参照)。ビルド時にこの設定から
${PROJECT_DIR}/build/android/app/generated/cmake/myapp.cmake (サンプル動作時は
リポジトリ直下の build/android/app/generated/cmake/) が自動生成され、
CMake から取り込まれます。生成物は build/android/ 配下なのでクリーンビルドで
自動的に消えます。直接編集せず JSON を編集してください。
このリポジトリは「共通のビルドシステム」、ビルド対象の案件 (app-config.json + リソース) は別フォルダ、という構成を取れます。
| 変数 | 意味 |
|---|---|
BUILD_SYSTEM_DIR |
このリポジトリのルート (gradle/cmake/cpp/java のソースが置いてある場所)。常に固定で、Makefile / settings.gradle が自動で解決します |
PROJECT_DIR (環境変数) |
案件フォルダ。${PROJECT_DIR}/app-config.json が参照され、${PROJECT_DIR}/build/android/ 以下にビルド出力 (app/ と root/) が掃き出されます |
PROJECT_DIR 未設定時は BUILD_SYSTEM_DIR にフォールバックするので、このリポジトリ
単体で「サンプル案件」としてビルドできます (リポジトリ同梱の app-config.json /
resource/ がそのまま使われる)。
# サンプル動作 (このリポジトリ単体)
make build
# 案件ビルド
export PROJECT_DIR=/path/to/myproject
make build # ${PROJECT_DIR}/app-config.json を読み、
# ${PROJECT_DIR}/build/android/app/outputs/apk/... に APK 出力app-config.json 内の ${...} 展開と相対パス解決は PROJECT_DIR 基準 です。
ビルドシステム側 (このリポジトリ内のソース) を指したい場合は ${BUILD_SYSTEM_DIR}/...
を明示してください (例: Android 専用プラグインの app/src/main/cpp 配下)。
local.properties (SDK パス・署名情報) は 案件横断のビルド環境設定 なので、
案件側ではなく BUILD_SYSTEM_DIR 直下のみが参照されます。
案件を切り替えた直後の注意: AGP の仕様上
.cxx/だけは${BUILD_SYSTEM_DIR}/app/.cxx/固定で生成されます。前案件の CMake / vcpkg キャッシュが残っているとリンクエラーになることがあるので、案件切り替え時は 一度make clean-cmakeを流すのを推奨します。
SDLの .aar ファイルを app/libs/ ディレクトリに配置してください。
SDL3-x.x.x.aar(SDL3 ライブラリ)
※ app/build.gradle の設定により、libs フォルダ内のすべての .aar ファイルが自動的に読み込まれます。
install-sdl-aar.sh で指定バージョンの SDLをダウンロードして配置できます
吉里吉里Zの実行に必要なデータは app/src/main/assets/ 以下に配置します。
- スクリプト・データ:
app/src/main/assets/data/以下に配置するとその中のstartup.tjsから起動します
外部のプロジェクトフォルダから assets にコピーしたい場合は、後述の assetPack によるアセット自動コピー を参照してください。
リポジトリ外にあるプロジェクト一式 (data フォルダや tjs スクリプト群)
を、ビルド時に自動で assets/ に取り込む仕組みです。
app-config.json に assetPack セクションを追加すると、
packAssets タスクが自動で preBuild 前に走り、指定したファイルを
${PROJECT_DIR}/build/android/app/generated/assetPack/ に書き出して
assets.srcDirs 経由で APK に含めます。
KrkrZ 本体の必須資材である ${KRKRZ_BASE}/krkrz_dev/src/core/resource も
assetPack.sources の 1 エントリとして取り込みます (以前は assets.srcDirs に
直接追加していましたが、優先度制御と同名ファイル衝突回避のため assetPack
に一本化しました)。assetPack の sources は 記載順に処理され、先勝ち
なので、自プロジェクト側のファイルを先に書けば本体側を上書きできます。
リポジトリ同梱の app-config.json がそのまま設定例です。本体 resource を
ルートに展開しつつ、自プロジェクト側の resource/ で個別ファイルを
先勝ちで上書きする構成になっています。
commentのような未知のキーは無視されるので、各 source の意図を 書き残しておく用途で自由に使えます。
| キー | 必須 | 内容 |
|---|---|---|
baseFolder |
相対 from を使うなら必須 |
コピー元のベースフォルダ。${PROJECT_DIR} 基準の相対パス、絶対パス、${ENV_VAR} / ${BUILD_SYSTEM_DIR} / ${PROJECT_DIR} 展開が利用可能 |
transfer |
省略可 | 転送方式。"copy" (既定) または "hardlink" |
resOverride |
省略可 | baseFolder 配下のフォルダ名 (string) または配列。詳細は後述 |
sources |
◯ | コピー定義の配列。記載順に処理されます |
sources[].type |
◯ | "mirror" または "flatten" |
sources[].from |
◯ | フォルダパス。相対なら baseFolder 起点、絶対 (${ENV_VAR} 展開後に絶対) ならそのまま参照 |
sources[].include |
省略可 | Ant パターンの配列 (例: "**/*.png")。既定 ["**/*"] |
sources[].exclude |
省略可 | Ant パターンの配列。既定 [] |
sources[].to |
省略可 | assets 配下の出力先パス。省略時は mirror+相対 from=from と同じ、mirror+絶対 from=from の末尾フォルダ名、flatten="" (assets 直下)。"" を明示すれば常に assets 直下に展開 |
mirror:from配下を Ant パターンでフィルタし、 ディレクトリ構造を維持したままassets/<to>/以下にコピーします。 例:from: "data"→assets/data/.../from: "${KRKRZ_BASE}/krkrz_dev/src/core/resource"→assets/resource/.../ 同上 +to: ""→assets/...(root に展開)flatten: 同様にフィルタしますが、ヒットしたファイルを サブディレクトリを捨ててassets/<to>/直下にファイル名のみで 配置します。
複数の source や flatten のサブディレクトリ間で同じ出力パスに
書き込もうとした場合、最初に現れたファイルが採用 され、
後続のものは Gradle の警告ログ付きでスキップされます。
> Task :app:packAssets
[assetPack] duplicate skipped (first wins): assets/config.cf
kept : <PROJECT_DIR>/resource/config.cf
skipped: <KRKRZ_BASE>/krkrz_dev/src/core/resource/config.cf
[assetPack] 15 file(s) total: 8 copied, 7 unchanged, 0 removed
注意:
app/src/main/assets/との衝突は first-wins 対象外first-wins による吸収は
assetPack内 (sources[]同士) に限られます。app/src/main/assets/(AGP 既定の assets srcDir) に置いたファイルとassetPackが生成するファイルに同名のものがあると、後段の AGP のmergeAssetsでDuplicateDataExceptionでビルドが失敗 します。 AGP 側に「片方を勝たせる」ような DSL は無いため、以下のいずれかで回避してください:
- 衝突するファイルを
app/src/main/assets/から削除し、必要ならassetPack.sources側 (例:${PROJECT_DIR}/assets-extraを mirror) に移すassetPack.sources[].excludeでassetPack側からそのファイルを除外するリポジトリの
app/src/main/assets/は テンプレートとして基本空 (.gitignore対象) であり、運用上はassetPack経由で資材を取り込むのが推奨フローです。
通常のビルド (./gradlew assembleDebug 等) では preBuild 経由で
自動実行されますが、コピーだけ確認したい場合は以下で単独実行できます。
./gradlew :app:packAssets入力ファイルが変わらない限り UP-TO-DATE でスキップされます。
強制再実行したい場合は --rerun-tasks を付けてください。
packAssets は Sync ライクに差分のみ更新します。
- ソース側で削除されたファイル は出力ディレクトリからも自動的に削除されます。
- 内容に変更がないファイル は再コピーされず、タイムスタンプもそのまま保持されます (後続の
mergeAssetsを不必要に走らせない)。 - 追加・変更されたファイルだけ がコピーされます。
- 実行末尾に
N file(s) total: X copied, Y unchanged, Z removedのサマリが出ます。
ソースとビルド出力先が 同じドライブ・同じファイルシステム上 にある場合、
transfer: "hardlink" を指定するとコピーの代わりに NTFS / ext4 等のハードリンク
を使ってファイル実体を共有します。数 GB のアセットでもディスクをほぼ消費せず、
転送も実質ゼロ時間になります。
"assetPack": {
"baseFolder": "${KRKRZ_BASE}/myproject",
"transfer": "hardlink",
"sources": [ ... ]
}挙動:
- ソース側でファイルを編集すると、ビルド出力側にも 即座に反映 されます (同じ inode を共有しているため)。
packAssetsの差分判定は引き続き mtime/size ベースなので、 ソースを 置き換え (delete & re-create) した場合は次回ランで再リンクされます。- リンク作成に失敗したファイル (異ドライブ・ネットワーク FS・FAT 等
ハードリンク非対応の環境) は 自動的にコピーへフォールバック します。
サマリに
X linked, Y copied (fallback)と表示され、フォールバックが 発生した場合は警告ログも出ます。 - Windows の NTFS では管理者権限不要で動作します。シンボリックリンクは 対応しません (Windows では昇格が必要なため)。
注意:
- ソースを別途編集する運用 (例: ビルド前にスクリプトでソースを書き換える等)
がある場合、出力側も同時に書き換わるため副作用に注意してください。
そういった運用がある場合は既定の
copyを使うのが安全です。 - 差分更新ロジック上、ソースを 置き換え (古いファイルを消して新ファイル作成) したケースのみ再リンク対象になります。インプレース編集はリンクが 自動追従するので何もしません (それで意図通り)。
baseFolder 配下に Android res/ 規約に従ったフォルダを置いておけば、
resOverride でそれを app/src/main/res/ の上に重ね、個別ファイル単位 / values
要素単位で上書き できます。各 buildType の res.srcDirs に追加する形で実装
されており、AGP のリソースマージ機構をそのまま使うので、独自タスクや事前コピーは
不要です。
"assetPack": {
"baseFolder": "${KRKRZ_BASE}/myproject",
"resOverride": "android-res",
// 配列で複数のオーバーレイも指定可能 (後ろほど優先):
// "resOverride": ["base-res", "brand-res"],
"sources": [ ... ]
}外部フォルダ構造の例 (<baseFolder>/android-res/ 配下):
android-res/
├── mipmap-mdpi/ic_launcher.webp # ← app/src/main/res の同名を上書き
├── mipmap-hdpi/ic_launcher.webp
├── mipmap-xhdpi/ic_launcher.webp
├── mipmap-xxhdpi/ic_launcher.webp
├── mipmap-xxxhdpi/ic_launcher.webp
├── mipmap-anydpi-v26/ic_launcher.xml # adaptive icon
├── drawable/ic_launcher_foreground.xml
└── values/strings.xml # <string name="app_name">..</string>
# など要素単位で上書き可能
仕様:
resOverrideの値はbaseFolderからの相対フォルダ名 (またはその配列)。- フォルダ構造は Android
res/規約 (mipmap-*,drawable*,values*等の qualifier dir 構造) に従ってください。素の PNG をフラットに置く形には対応しません。 - 全 buildType (debug / release / releaseDebugSigned) に同じオーバーレイが適用されます。
values/strings.xmlのようなvaluesリソースは 要素単位でマージ されるため、app_nameだけ書いたファイルを置けば他の string はそのまま残ります。- 配列で指定した場合、後ろの要素ほど優先 (AGP の
srcDirsの追加順に従う)。
数 GB の xp3 / 動画は APK に同梱できず Play で配信できないため、Play Asset Delivery の
asset pack として配信する。assetPack (APK 同梱・小物用) はそのまま残し、大容量データを
app-config.json の padPacks に宣言する。ソース規則 (mirror / flatten /
include / exclude / to) は上記 assetPack と共通。
"padPacks": [
{
"name": "coredata", // gradle module 名 & packName。[a-z0-9_]+ のみ
"deliveryType": "on-demand", // install-time | fast-follow | on-demand (既定 on-demand)
"baseFolder": "${PROJECT_DIR}",
"sources": [
{ "type": "flatten", "from": "build/_temp/archive", "include": ["data.xp3", "others.xp3"] }
]
}
// 1GB 前後を目安に複数パックへ分割する
]settings.gradleが各パックの asset pack モジュールを自動生成し、app/build.gradleがandroid.assetPacksに紐付け +packPad_<name>タスクでデータをコピーする。padPacksが 無ければ従来どおり (サンプルは影響なし)。- ランタイムは
BootstrapActivity+PadAssetResolverがパックを取得し、展開先の絶対パスを<filesDir>/padroot/に symlink 統合して engine (setAssetCacheDir) へ渡す (native 無改修)。
| 目的 | コマンド |
|---|---|
ローカル実機で検証 (bundletool --local-testing) |
make pad-install |
| 軽量イテレーション (コードだけ入替・変更パックのみ再push) | make pad-fast |
| Play アップロード用 AAB | make pad-aab |
| 配布用ポータブルインストーラ (配布先は Java + adb だけ) | make pad-package |
make pad-fastは一度make pad-installした後のコード反復用。素のassembleDebugをadb install -rし、内容が変わったパックだけ再 push する (未変更なら数秒)。仕組み・配信タイプ・パック分割・リリース署名/メモリ/シンボルの注意・トラブルシュートの 詳細は docs/android-play-asset-delivery.md を参照。 adb でのファイル確認・削除など日常操作は docs/android-adb-tips.md。
app-config.json 内のパス文字列は ${...} 形式で展開できます。
${BUILD_SYSTEM_DIR}: 予約変数。このリポジトリのルート (gradle / cmake / cpp/java のソース置き場) の絶対パスに展開されます。Android 専用プラグインなどビルドシステム側のフォルダを指す用途。${PROJECT_DIR}: 予約変数。案件フォルダ (app-config.jsonを含むフォルダ) の絶対パスに展開されます。環境変数PROJECT_DIR未設定時はBUILD_SYSTEM_DIRと同値 (サンプル動作)。${ENV_VAR}: プロセスの環境変数を参照します。未定義時は 空文字 に展開されます (例:${KRKRZ_BASE}/fooでKRKRZ_BASE未設定なら/fooになる)。
${...} 展開後に相対パスが残っている場合、${PROJECT_DIR} 基準 で解決されます
(以前は「このリポジトリのルート」基準でしたが、案件フォルダ分離に合わせて変更)。
| 設定 | 役割 |
|---|---|
APP_CONFIG_FILE (local.properties / 環境変数) |
外部 app-config.json のパス。指定無しなら ${PROJECT_DIR}/app-config.json |
assetPack.baseFolder |
sources[].from の相対起点 |
assetPack.sources[].from |
コピー元フォルダ (絶対指定時) |
assetPack.resOverride |
res オーバーレイフォルダ。文字列または配列 |
cmake.pluginFolders[] |
プラグイン配置ディレクトリ |
cmake.plugins/cmake.staticPluginsはパスではなくプラグイン名なので展開対象外です。
{
"assetPack": {
"baseFolder": "${PROJECT_DIR}",
"resOverride": "android-res",
"sources": [
{ "type": "mirror", "from": "data" },
{ "type": "mirror",
"from": "${KRKRZ_BASE}/krkrz_dev/src/core/resource",
"to": "" }
]
},
"cmake": {
"pluginFolders": [
"${BUILD_SYSTEM_DIR}/app/src/main/cpp",
"${KRKRZ_BASE}/krkrz_dev/src/plugins"
]
}
}プロジェクトのルートディレクトリで以下のコマンドを実行してください。
./gradlew assembleDebug生成された APK は ${PROJECT_DIR}/build/android/app/outputs/apk/debug/ に出力されます (サンプル動作時はリポジトリ直下の build/android/app/outputs/apk/debug/)。
Android デバイスを接続した状態で実行します。
./gradlew installDebug./gradlew assembleRelease※ リリースビルドを行うには、以下の署名設定 (Signing Config) が必要です。
Google Play にアプリを公開するには、リリース用の署名が必要です。
keytool コマンドでキーストアファイル(.jks)を生成します。
keytool -genkey -v -keystore release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias my-key-alias| オプション | 説明 |
|---|---|
-keystore |
生成するキーストアファイル名 |
-keyalg |
鍵アルゴリズム(RSA推奨) |
-keysize |
鍵サイズ(2048以上推奨) |
-validity |
有効日数(10000日 ≒ 27年) |
-alias |
鍵のエイリアス名 |
コマンド実行時に以下の情報を入力します:
- キーストアのパスワード
- 姓名、組織名、都市、国コード など
- 鍵のパスワード(キーストアと同じでも可)
重要: キーストアファイルとパスワードは紛失しないよう安全に保管してください。Google Play にアップロードしたアプリの更新には同じ鍵が必要です。
署名情報は local.properties に記載します。このファイルは既に .gitignore に含まれているため、機密情報が Git にコミットされる心配がありません。
app/build.gradle には local.properties を読み込んで署名設定に使用するコードが既に含まれています。以下のプロパティを local.properties に追記するだけで署名が有効になります。
local.properties に追記:
# Release signing
RELEASE_STORE_FILE=../release-key.jks
RELEASE_STORE_PASSWORD=your_keystore_password
RELEASE_KEY_ALIAS=my-key-alias
RELEASE_KEY_PASSWORD=your_key_passwordCI/CD 環境など local.properties が存在しない場合は、環境変数でも指定できます:
export RELEASE_STORE_FILE=../release-key.jks
export RELEASE_STORE_PASSWORD=your_keystore_password
export RELEASE_KEY_ALIAS=my-key-alias
export RELEASE_KEY_PASSWORD=your_key_passwordキーストアファイルをリポジトリにコミットしないよう .gitignore に以下を追加します。
(local.properties は既に .gitignore に含まれているため、署名情報は自動的に除外されます)
# Signing keys
*.jks
*.keystore設定完了後、以下のコマンドで署名済み APK/AAB を生成できます。
# 署名済み APK
./gradlew assembleRelease
# Google Play 用 App Bundle (推奨)
./gradlew bundleRelease生成物の場所:
- APK:
${PROJECT_DIR}/build/android/app/outputs/apk/release/app-release.apk - AAB:
${PROJECT_DIR}/build/android/app/outputs/bundle/release/app-release.aab
リリースビルド (proguard / minify などのリリース設定が適用された状態) を、
release キーストアを用意せずに debug キーで署名 して動作確認したい場合のための
ビルドタイプ releaseDebugSigned を用意しています。
用途:
- リリース構成での挙動・パフォーマンスを手元の端末で確認したい
- まだ release キーストアを発行していない / CI に署名情報を渡せない段階でも、 リリース構成の APK を生成・インストールしたい
- Play Console 用ではなく、社内配布や動作検証用の APK が欲しい
app/build.gradle の buildTypes.releaseDebugSigned で release を initWith した上で
signingConfig を signingConfigs.debug に差し替える構成になっています。
local.properties の RELEASE_* 設定は不要です。
# Release 構成 + debug 署名で APK を生成
make release-debug
# 端末にインストール
make install-release-debug直接 Gradle を叩く場合:
./gradlew :app:assembleReleaseDebugSigned
./gradlew :app:installReleaseDebugSigned生成された APK は ${PROJECT_DIR}/build/android/app/outputs/apk/releaseDebugSigned/ に出力されます。
注意: debug キーで署名されるため、Google Play へはアップロードできません。 あくまで動作検証専用です。Play 配布用には通常の
assembleRelease/bundleRelease(release キーストア署名) を使用してください。 また、Google Play Games Services を利用する場合は debug キーストアの SHA-1 も Play Console 側に登録しておく必要があります (docs/android-play-games.md 参照)。
生成された APK/AAB が正しく署名されているか確認できます。
# APK の署名確認
apksigner verify --verbose "${PROJECT_DIR:-.}/build/android/app/outputs/apk/release/app-release.apk"
# AAB の署名確認 (bundletool 使用)
jarsigner -verify -verbose "${PROJECT_DIR:-.}/build/android/app/outputs/bundle/release/app-release.aab"Google Play Console では「Play App Signing」を利用することを推奨しています。これを使用すると:
- Google がアップロード鍵とは別の署名鍵でアプリに再署名
- アップロード鍵を紛失しても Google に依頼して復旧可能
- より安全な鍵管理が可能
初回アップロード時に Play App Signing への登録を選択できます。
GitHub Actions などの CI/CD 環境では、秘密情報を Secrets として登録し、環境変数経由で渡します。
GitHub Actions の例:
env:
RELEASE_STORE_PASSWORD: ${{ secrets.RELEASE_STORE_PASSWORD }}
RELEASE_KEY_ALIAS: ${{ secrets.RELEASE_KEY_ALIAS }}
RELEASE_KEY_PASSWORD: ${{ secrets.RELEASE_KEY_PASSWORD }}キーストアファイルは Base64 エンコードして Secret に保存し、ビルド時にデコードします。
- name: Decode Keystore
run: echo "${{ secrets.RELEASE_KEYSTORE_BASE64 }}" | base64 -d > release-key.jks独自のアプリとしてリリースする場合、以下のファイルを修正してください。
プロジェクトルートの app-config.json ファイルを編集してください。
(または下記「外部 app-config.json への切り替え」で別ファイルを参照させることもできます)
{
"applicationId": "com.example.mygame",
"versionCode": 2,
"versionName": "1.1",
"compileSdk": 36,
"minSdk": 29,
"ndkVersion": "28.2.13676358"
}applicationId: アプリの一意な識別子(パッケージ名)versionCode: 内部バージョン番号(整数、リリースごとに増やす)versionName: ユーザーに表示されるバージョン文字列compileSdk: コンパイルに利用するSDKバージョンminSdk: 最小動作対象SDKバージョンndkVersion: 利用する NDK のバージョン
※ app/build.gradle はこの JSON ファイルを自動的に読み込みます。
apk セクションでビルド成果物のファイル名を制御できます。
"apk": {
"baseName": "myapp" // 既定: "app"
}挙動:
- ファイル名:
<baseName>-<versionName>-<variant>.apk形式に変更 (例:myapp-1.0-debug.apk、myapp-1.0-release.apk、myapp-1.0-releaseDebugSigned.apk)。AGP 標準の出力先 (${PROJECT_DIR}/build/android/app/outputs/apk/<variant>/) のファイル名が そのまま変わります。 - AAB の出力先は
app-<variant>.aabのまま (AGP 制約)。
仕様:
apkセクション省略時は AGP 既定 (app-<variant>.apk/app-<variant>.aab)。- 出力先を別フォルダに集めたい場合は、案件側で
PROJECT_DIRを切り替えるか、 シェルスクリプト等で${PROJECT_DIR}/build/android/app/outputs/apk/...から コピー / リンクしてください (以前あったapk.outputDir機能はPROJECT_DIR方式に統合して廃止しました)。
通常の運用は PROJECT_DIR 環境変数を使ってください (前述
「ビルドシステムフォルダと案件フォルダの分離」参照)。PROJECT_DIR を指定すると
案件側の app-config.json、リソース、ビルド出力先すべてがその配下に揃います。
export PROJECT_DIR=/path/to/myproject
./gradlew assembleDebugPROJECT_DIR 未指定時は BUILD_SYSTEM_DIR (このリポジトリ) にフォールバックします。
より細かい上書き: APP_CONFIG_FILE — app-config.json の位置だけを別の場所に
向けたい場合 (例: PROJECT_DIR は案件フォルダのままで、config だけバリアント切替)
に使えます。
優先順位:
local.propertiesのAPP_CONFIG_FILE=...- 環境変数
APP_CONFIG_FILE=... - 未指定時は
${PROJECT_DIR}/app-config.json
# local.properties
APP_CONFIG_FILE=C:/work/myproject/app-config.json
# 環境変数展開も可
# APP_CONFIG_FILE=${KRKRZ_BASE}/myproject/app-config.json仕様:
- パス文字列は
${BUILD_SYSTEM_DIR}/${PROJECT_DIR}/${ENV_VAR}の展開に対応 - 絶対パス、または相対パス (相対の場合は
PROJECT_DIR基準 で解決) - 指定があってファイルが存在しない場合は ビルドが即座にエラー停止 (誤指定の早期発見)
注意:
- Makefile 側の MSYS2 制約: MSYS2 の make は外部シェルの環境変数を取りこぼす
ことがあるため、
make経由でPROJECT_DIRを渡すときは make 引数として 指定するのが確実です:make build PROJECT_DIR=/path/to/myproject
./gradlew直接呼び出しは環境変数 (export PROJECT_DIR=...) で問題ありません。
AndroidManifest.xml 内の ${KEY} 形式のプレースホルダを、
app-config.json の manifestPlaceholders で置換できます。
画面向き、API キー、Deep Link のホスト名など、Manifest 直書きの単一値を
Manifest を直接編集せずに アプリごとに切り替える用途に使えます。
{
"applicationId": "com.example.mygame",
"manifestPlaceholders": {
"screenOrientation": "landscape",
"deepLinkHost": "example.com"
}
}AndroidManifest.xml 側でプレースホルダを書いておくと、ビルド時に置換されます:
<activity
android:name="..."
android:screenOrientation="${screenOrientation}" >
<intent-filter>
<data android:scheme="https" android:host="${deepLinkHost}" />
</intent-filter>
</activity>manifestPlaceholders を省略した場合は何も置換されないので、
プレースホルダを使わない既定の Manifest はそのままビルドできます。
KrkrZ プラグインの取り込み構成 (旧 myapp.cmake の内容) は app-config.json の
cmake セクションで管理します。preBuild および CMake configure 前に
generateMyappCmake タスクがこのセクションを読み、
${PROJECT_DIR}/build/android/app/generated/cmake/myapp.cmake を自動生成し、
CMake (app/src/main/cpp/CMakeLists.txt) から
-DMYAPP_CMAKE_FILE=<absolute path> 経由で include() されます。
"cmake": {
"pluginFolders": [
"${BUILD_SYSTEM_DIR}/app/src/main/cpp",
"${KRKRZ_BASE}/wamsoft_work",
"${KRKRZ_BASE}/krkrtemplate/plugins"
],
"plugins": [
"csvParser",
"playgames",
"json",
"saveStruct"
],
"staticPlugins": [
"playgames"
]
}| キー | 内容 | 生成される CMake 変数 |
|---|---|---|
pluginFolders |
プラグインを探すフォルダ。相対パス (PROJECT_DIR 基準) / 絶対パス / ${BUILD_SYSTEM_DIR} / ${PROJECT_DIR} / ${ENV_VAR} 展開が利用可能 |
TVP_PLUGIN_FOLDERS |
plugins |
リンクするプラグイン名の列挙 | TVP_PLUGINS |
staticPlugins |
libkrkrz.so に静的に組み込むプラグイン名 |
TVP_PLUGINS_STATIC |
仕様:
- 生成先は
${PROJECT_DIR}/build/android/app/generated/cmake/myapp.cmakeで、build/android/配下なので既存の.gitignore(build/) で自動的にコミット 対象外になります。直接編集しても次回ビルドで上書きされるので、設定変更は必ずapp-config.json側で行ってください。 - 各パスは gradle 側で 絶対パスに解決 された状態で書き出されます。
CMake 側で
${CMAKE_CURRENT_LIST_DIR}等を意識する必要はありません。 - このリポジトリ内 (
app/src/main/cpp等) のプラグインフォルダを指す場合は${BUILD_SYSTEM_DIR}/app/src/main/cppを明示してください。相対パスは${PROJECT_DIR}基準で解決されるので、案件フォルダ側に存在しないと無視されます。 cmakeセクション自体を省略した場合、generateMyappCmakeは何もしません。
app/src/main/res/values/strings.xml を開き、app_name を変更してください。
<resources>
<string name="app_name">あなたのアプリ名</string>
</resources>アプリアイコンは app/src/main/res/ 以下の mipmap フォルダに格納されています。
AndroidManifest.xml では以下のように定義されています。
- 通常アイコン:
@mipmap/ic_launcher - 丸型アイコン:
@mipmap/ic_launcher_round(Android 7.1以降で使用)
以下の各フォルダにある ic_launcher.png と ic_launcher_round.png を、自前のアイコン画像に差し替えてください。
mipmap-mdpi/(48x48)mipmap-hdpi/(72x72)mipmap-xhdpi/(96x96)mipmap-xxhdpi/(144x144)mipmap-xxxhdpi/(192x192)
※ Android Studio の "Image Asset Studio" 機能を使うと、これらのアイコンを一括で生成・配置できるため便利です。
ビルドシステムの app/src/main/res/mipmap-anydpi/ic_launcher.xml に既定の
アダプティブアイコン (<adaptive-icon>) が入っている。Android 8.0 (API 26) 以降では
この anydpi 定義が密度別 PNG (mipmap-*dpi/ic_launcher.png) より優先されるため、
resOverride で密度別 PNG だけを差し替えてもアイコンが変わらない (既定アイコンが出る)。
案件側 (resOverride フォルダ) に mipmap-anydpi-v26/ic_launcher.xml と
ic_launcher_round.xml も置いて上書きすること (-v26 は無印 anydpi より優先される)。
完成済みの不透明な PNG アイコンをそのまま見せたい場合は、背景レイヤに全面表示する のが手軽 (前景は透明。ランチャー形状にマスクされる):
<!-- <resOverrideフォルダ>/mipmap-anydpi-v26/ic_launcher.xml (round も同様) -->
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher" />
<foreground android:drawable="@android:color/transparent" />
</adaptive-icon>きちんとアダプティブ対応する場合は、前景 (安全領域内の図柄) と背景を分けた
<foreground> / <background> を用意する。反映確認は
aapt dump badging <apk> | grep icon で icon= が mipmap-anydpi-v26/... を
指していれば OK。
デフォルトの KrkrzActivity を継承して、独自の初期化処理や機能追加を行うことができます。
app/src/main/java/ ディレクトリを作成し、パッケージ名に合わせたフォルダ階層を作成します。
例: パッケージ名が com.example.mygame の場合
app/src/main/java/com/example/mygame/
jp.wamsoft.krkrz.KrkrzActivity を継承したクラスを作成します。
例: MainActivity.java
package com.example.mygame;
import android.os.Bundle;
import jp.wamsoft.krkrz.KrkrzActivity;
public class MainActivity extends KrkrzActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ここに独自の初期化処理を記述
}
}app/src/main/AndroidManifest.xml を開き、<activity> タグの android:name 属性を作成したクラス名に変更します。
<activity
android:name="com.example.mygame.MainActivity"
android:exported="true"
android:configChanges="layoutDirection|locale|orientation|..."
>
<!-- ... -->
</activity>吉里吉里Z の機能に加え、ネイティブコード (C/C++) で 独自の処理を実装する場合の手順です。
app/src/main/cpp/ 以下に C++ ソースファイル(例: native-lib.cpp)を配置します。
app/src/main/cpp/ の CMakeLists.txt を編集して、ビルド設定を記述します。
例: CMakeLists.txt
add_library(my-native-lib SHARED
native-lib.cpp)
find_library(
log-lib
log)
target_link_libraries(
my-native-lib
${log-lib})継承した Activity (例: MainActivity.java) でライブラリをロードし、ネイティブメソッドを宣言します。
public class MainActivity extends KrkrzActivity {
static {
System.loadLibrary("my-native-lib");
}
// ネイティブメソッドの宣言
public native String stringFromJNI();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ...
}
}プロジェクトルートの Makefile から gradlew を呼び出して、ビルド・インストール・起動・デバッグ・テストなどを行えます。
前提
- GNU Make が利用できるシェル環境 (Git Bash / MSYS2 / WSL 等)
- Android SDK (
adb) はlocal.propertiesのsdk.dirから自動検出。見つからない場合はADBで明示指定可能
主なターゲット
- build/assemble:
assemble<BUILD_TYPE>の実行 (既定: Debug) - bundle:
bundle<BUILD_TYPE>の生成 - release-debug / install-release-debug: Release 構成を debug 鍵で署名した APK の生成 / インストール (release キーストア不要、Play 配布不可)
- install/reinstall/uninstall: 端末へのインストール/再インストール/アンインストール
- run: ランチャーアクティビティを起動
- debug: デバッガ待機で起動 (
am start -D)、後からアタッチ - stop: アプリの強制停止
- logcat:
adb logcatのフォロー - clean: gradle clean (build/ 配下クリーン)
- clean-cmake: CMake 生成物 (
.cxx/、build/intermediates/cxx、build/generated/cmake) のみ削除。プラグイン構成変更後の再構成に - distclean: clean + clean-cmake。新規チェックアウト相当の状態に戻す (vcpkg 再 install、CMake 完全再 configure)
- test/connected: ユニットテスト/計測テスト
- devices: 接続デバイス一覧
- vars: 変数の解決結果を表示
上書き可能な変数
- MODULE: 対象モジュール名 (既定:
app) - BUILD_TYPE:
DebugまたはRelease(既定:Debug) - APP_ID: アプリID。
app/build.gradleのapplicationId→AndroidManifest.xmlのpackageの順で自動検出。未検出時は明示指定 - ADB:
adbのパス。未指定時はsdk.dirから推測、無ければadb - GRADLEW:
gradlewの呼び出し (既定:./gradlew)
使用例
# ビルド (Debug 既定)
make build
# Releaseビルド
make build BUILD_TYPE=Release
# インストールと起動
make run
# デバッガ待機で起動し、IDEからアタッチ
make debug
# 再インストール
make reinstall
# アンインストール
make uninstall
# ログを表示 (終了は Ctrl+C)
make logcat
# ユニットテスト / 計測テスト
make test
make connected
# Play Asset Delivery (大容量データ配信)
make pad-install # ローカル実機に入れて検証 (bundletool --local-testing)
make pad-fast # コード反復用: 素の assembleDebug を install + 変更パックだけ再push (要 事前 pad-install)
make pad-aab # Play アップロード用 AAB を生成
make pad-package # 配布用インストーラ一式 (Java + adb だけで入る) を生成
# REPL (adb 経由の TJS 対話シェル, Debug ビルド専用。詳細 docs/android-repl.md)
make repl # forward + nc で接続
make repl-py # forward + 高機能 Python クライアント (編集/履歴/複数行)
# 変数の確認
make vars
# 例: アプリIDを明示して起動
make run APP_ID=com.example.mygame
# 例: 別モジュールを対象
make install MODULE=myfeature
# 例: adb を明示指定 (Windows の SDK 既定パス例)
make devices ADB="/c/Android/sdk/platform-tools/adb"メモ
- Windows の場合は Git Bash / MSYS2 などの GNU Make 環境での実行を推奨します。
mingw32-makeでも可。
TJS から PlayGames クラスで Google Play Games (サインイン / 実績 / クラウドセーブ) を
使えます。有効 / 無効は app-config.json の cmake.plugins に "playgames" を入れるか
外すかの 1 スイッチで切り替わり、無効にすると gms 依存も Manifest エントリも drawer メニューも
一切入りません (app/build.gradle や Manifest を手で触る必要なし)。
Play Games 対応をやるとき・切り替えの仕組みを知りたいときは docs/android-play-games.md を参照 (入口ドキュメント)。 Play Console の具体手順・TJS レシピ・API はそこからリンクしています。
コンソールを開かず make から AAB アップロード / 現状照会 / トラック昇格 / 段階公開 /
リリースノート管理ができます (Play Developer API を Python で直叩き)。
| 目的 | コマンド |
|---|---|
| 現状照会 (読み取り専用・コンソール不要) | make play-status |
| AAB を internal テストへ | make play-upload |
| 本番へ昇格 + 段階公開 (再アップロード不要) | make play-promote FROM=internal TO=production ROLLOUT=0.1 |
| 段階公開率の増減 / 停止 | make play-rollout FRACTION=0.5 / make play-rollout HALT=1 |
| 全言語リリースノート雛形生成 / 検査 | make play-notes-new / make play-notes-check |
前提:
pip install -r scripts/requirements-play.txt+ 認証をlocal.propertiesに設定。 認証は2方式で自動判定 — ローカルは OAuth(自分のアカウントでブラウザ同意PLAY_OAUTH_CLIENT_JSON)、 CI はサービスアカウント(PLAY_SERVICE_ACCOUNT_JSON)。差分アップロードの有無・テスト→本番の流れ・ リリースノート運用・dry-run・トラブルシュートは docs/android-play-publishing.md を参照。
{ "applicationId": "jp.wamsoft.krkrz.sample", "versionCode": 1, "versionName": "1.0", "compileSdk": 36, "targetSdk": 36, "minSdk": 29, "ndkVersion": "28.2.13676358", "assetPack": { "baseFolder": "${KRKRZ_BASE}/krkrz_dev/src/core", "sources": [ { "comment": "Override files from this project's own resource folder (wins on conflict)", "type": "mirror", "from": "${PROJECT_DIR}/resource", "to": "" }, { "comment": "KrkrZ engine base resource (mandatory)", "type": "mirror", "from": "${KRKRZ_BASE}/krkrz_dev/src/core/resource", "to": "" }, { "comment": "Game data tree under baseFolder/data", "type": "mirror", "from": "data", "include": ["**/*"], "exclude": ["**/*.bak", "**/*.psd"] }, { "comment": "Pack .xp3 archives flatly under assets root", "type": "flatten", "from": "archive", "include": ["*.xp3"] } ] } }