# 构建指南 ## 环境 - JDK 17、Android SDK 35、Android NDK。 - Python 3.11+,使用项目自带的 Gradle wrapper。 - 设置 `JAVA_HOME` 和 `ANDROID_HOME`(或 `ANDROID_SDK_ROOT`)。 只编译应用源码,无需准备完整运行镜像: ```powershell ./gradlew.bat :core:compileKotlin :app:compileBootstrapReleaseKotlin ``` ## 完整包输入 完整 APK 面向 ARM64。源码仓库保留应用与原生源码、运行环境安装配方和来源锁,不包含预制镜像、原生预编译程序或维护者的辅助工具。打包前需要准备: | 输入 | 默认位置 | 内容 | | --- | --- | --- | | 完整镜像与 manifest | `runtime/apk-assets/bootstrap/arm64-v8a/` | Ubuntu、AstrBot、NapCat、Linux QQ、Python 及依赖 | | 原生程序 | `app/src/main/jniLibs/` | PRoot、原生运行器及匹配库 | | 基础环境资产 | `app/src/main/assets/bootstrap/` | 初始化使用的资源 | | 源码与许可输入 | `.cache/` 或工程外缓存 | 来源锁指定的上游源码、依赖元数据及源码伴随包 | 运行环境配方为 `runtime/provision-base.sh`、`runtime/provision-astrbot.py`、`runtime/provision-napcat.py`,导出入口为 `runtime/export-runtime.sh`。在不含业务数据的 ARM64 构建环境中准备与版本锁一致的组件和依赖,再导出镜像与匹配的 manifest。不要从含 QQ 会话、API Key 或个人业务配置的手机制作分发镜像。来源及摘要以 `runtime/` 中的锁文件为准。 管理器原生运行器来自 `native/process_runner.c`、`native/terminal_runner.c`。例如在 Windows 设置 `ANDROID_NDK_HOME` 后编译 ARM64: ```powershell $buildToolchain = Join-Path $env:ANDROID_NDK_HOME 'toolchains/llvm/prebuilt/windows-x86_64' New-Item -ItemType Directory -Force 'app/src/main/jniLibs/arm64-v8a' | Out-Null foreach ($buildRunner in @('process', 'terminal')) { & "$buildToolchain/bin/clang.exe" --target=aarch64-linux-android26 "--sysroot=$buildToolchain/sysroot" -fPIE -pie -O2 -Wall -Wextra -Werror '-Wl,-z,max-page-size=16384' "native/${buildRunner}_runner.c" -o "app/src/main/jniLibs/arm64-v8a/lib${buildRunner}-runner.so" if ($LASTEXITCODE -ne 0) { throw '原生运行器编译失败' } } ``` Linux 使用 NDK 的 `linux-x86_64/bin/clang`。PRoot 和其他库还需按锁定来源准备,不由上述两个 C 文件生成。发行材料要求见[发行材料](发行材料.md)。 ## 工程外输入 复制 `docs/examples/local.properties.example` 为根目录的 `local.properties`,按本机位置设置: ```properties runtimeAssetsDir=D:/astrbot-build-inputs/runtime/apk-assets distributionAssetsDir=D:/astrbot-build-inputs/runtime/distribution-assets bootstrapAssetsDir=D:/astrbot-build-inputs/app/src/main/assets nativeLibsDir=D:/astrbot-build-inputs/app/src/main/jniLibs ``` 也可用同名 `-P` 参数覆盖。上述输入、本机配置和构建输出不提交 Git。 ## 一键构建正式包 准备完整输入后,仅首次建立新的签名身份时执行: ```powershell python -B -X utf8 tools/build_release.py --init-signing ``` 已有应用必须恢复原密钥,不能重新生成。Windows 双击根目录 `build.bat`,或运行: ```powershell ./build.bat # 其他系统 python3 -B tools/build_release.py ``` 构建入口先核对签名身份,收集实际发行依赖,生成并校验随包许可材料,再构建 ARM64 Release、运行 lint,并检查 APK 签名、包名、版本、架构和摘要。APK 使用同一长期证书同时提供 v1、v2、v3 签名;缺少任一签名或验证失败时停止导出,`release.json` 记录各签名方案的核验结果。默认流程不依赖本地测试或独立维护工具。校验通过后导出到已忽略的 `dist/`,最多保留最近两份候选 APK,并生成 `output-metadata.json`、`release.json` 和 `SHA256SUMS`。 长期签名保存在 `.local/signing/`:`release.p12` 是密钥库,`release.properties` 保存别名和密码,`identity.json` 保存公开证书指纹。整个 `.local/` 已被 Git 忽略。请备份整个签名目录;后续版本必须使用相同包名、相同签名并提高 `appVersionCode`,才能覆盖升级。密钥缺失或指纹变化时脚本停止,不生成替代密钥。 构建路径可通过已忽略的 `.local/build.json` 配置: ```json { "javaHome": "D:/tools/jdk-17", "androidSdk": "D:/tools/Android/Sdk", "gradleUserHome": "D:/build-cache/gradle", "workDirectory": "D:/build-cache/astrbot", "outputDirectory": "D:/build-output/astrbot", "sourceCacheDirectory": "D:/build-inputs/cache", "distributionDirectory": "D:/release-materials/astrbot", "pythonSourceDirectory": "D:/release-materials/python-sources" } ``` 也可使用 `--output-dir`、`--signing-properties` 指定输出和私有签名配置。直接运行 Gradle 时,可用 `-PreleaseSigningProperties=配置文件路径` 或 `ASTRBOT_RELEASE_SIGNING_PROPERTIES` 指定相同配置。没有签名配置时,Gradle 可生成 unsigned Release;一键正式构建则要求长期密钥存在。 公开的 [tools 目录](../tools/README.md)只包含上述打包入口及其直接依赖。许可材料记录的实际待确认事项不会因构建通过而清除。 ## 版本与包名 默认包名 `io.astrbot.android`,版本配置在 `gradle.properties`:`appVersionName=1.0.0`、`appVersionCode=10000`,可通过同名 `-P` 参数覆盖。每次公开 APK 更新都提高 versionCode。不同包名不能覆盖安装,同包名覆盖还要求签名一致;更新目录签名见[更新与分发](更新与分发.md)。