构建与工具链¶
iOS 构建需在 macOS 上进行(需要 Xcode + Apple 工具链 + vcpkg)。 Android 构建可在 Windows / macOS / Linux 上进行(需要 NDK + vcpkg)。 根 CMake 设置
CMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake,依赖由 vcpkg manifest 安装。
前置要求¶
iOS / macOS(macOS 主机)¶
-
macOS(Apple Silicon 或 Intel)+ Xcode
-
CMake ≥3.28、Ninja、ccache(可选)
-
bison(TJS2 parser 生成,Homebrew:
/opt/homebrew/opt/bison) -
autoconf / automake / autoconf-archive / libtool / gettext / pkg-config (vcpkg 交叉编译 iOS 时需构建宿主工具:gperf→glib、libexif 等 autotools 端口; GNU libtool 提供
libtool.m4供 aclocal 使用)
⚠️ Homebrew 的 GNU libtool 会覆盖 PATH 里的
libtool。build_ios.sh已改为显式调用系统/usr/bin/libtool做静态库合并(-static),勿改回裸libtool。
Android(任意主机)¶
-
Android NDK(r25+ 推荐),设置环境变量:
build_android.sh会自动从ANDROID_NDK_HOME/ANDROID_NDK_ROOT/$ANDROID_HOME/ndk/*(取最新)定位 NDK。 -
JDK 17(AGP 8 要求,Android Studio 自带)
-
CMake ≥3.28、Ninja
-
Flutter SDK(
flutter在 PATH,或放到.devtools/flutter)——flutter doctor --android-licenses需通过 -
网络(vcpkg 首次会 clone 依赖)
快速开始¶
# 一键构建 iOS(默认 debug,需 macOS)
./build.sh ios debug
# 或 release
./build.sh ios release
# Android APK(Windows / macOS / Linux 均可)
./build.sh android debug
# macOS
./build.sh macos debug
iOS 构建步骤(build/build_ios.sh 内部)¶
- 定位 Flutter SDK(
.devtools/flutter或 PATH)。 - 定位/自举 vcpkg(
.devtools/vcpkg,bootstrap-vcpkg.sh)。 -
CMake 配置
iOS <Debug|Release> Config预设 → 构建iOS <Debug|Release> Build。 -
输出:
out/ios/<type>/bridge/engine_api/libengine_api.a(静态库) -
依赖装到
out/ios/<type>/vcpkg_installed/arm64-ios/(tripletarm64-ios) -
静态库合并:
-
工程库(排除
cpp/plugins顶层,保留深层子库如 psdparse 的独有.o)→libengine_project.a -
vcpkg 三方库(排除 libpng/libjpeg/libwebpdecoder/libharfbuzz-subset 冗余子集)→
libengine_vendors.a -
二者写入
bridge/flutter_engine_bridge/ios/Libs/(该目录*.a已 gitignore) -
flutter pub get+flutter build ios --<mode> --no-codesign -
产物:
apps/flutter_app/build/ios/iphoneos/Runner.app - 真机运行:Xcode 打开
apps/flutter_app/ios/Runner.xcworkspace。
macOS 构建步骤(build/build_macos.sh 内部)¶
- CMake
MacOS <Debug|Release> Config→ 构建 →out/macos/<type>/bridge/engine_api/libengine_api.dylib。 flutter build macos --<mode>→build/macos/Build/Products/<Debug|Release>/Runner.app。- 把 dylib 拷入
Contents/Frameworks/,install_name_tool设@executable_path/../Frameworks/,ad-hoc 重签。
Android 构建步骤(build/build_android.sh 内部)¶
- 定位 NDK(
ANDROID_NDK_HOME/ANDROID_NDK_ROOT/$ANDROID_HOME/ndk/*最新版)。 - 定位 Flutter SDK(
.devtools/flutter或 PATH)。 - 定位/自举 vcpkg(
.devtools/vcpkg,bootstrap-vcpkg.sh)。 -
CMake 配置
Android <Debug|Release> Config预设 → 构建Android <Debug|Release> Build。 -
输出:
out/android/<type>/bridge/engine_api/libengine_api.so(自包含共享库) -
依赖装到
out/android/<type>/vcpkg_installed/arm64-android/(tripletarm64-android) -
engine_api自包含打包:插件子库target_sources(PUBLIC)源码经INTERFACE_SOURCES直接编进 .so,engine_api普通链接krkr2core + krkr2plugin(不用--whole-archive, 否则 psbfile/motionplayer 对象重复触发 ld.lld 重复符号); JNI 胶水engine_api_android_jni.cpp提供krkr_GetNativeWindow及 Kotlin 可调用的nativeSetSurface/nativeDetachSurface。 - 拷贝
libengine_api.so→apps/flutter_app/android/app/src/main/jniLibs/arm64-v8a/(已 gitignore)。 -
flutter pub get+flutter build apk --<mode>。 -
产物:
apps/flutter_app/build/app/outputs/flutter-apk/app-<debug|release>.apk - 真机运行:
flutter run -d <device>(或adb installAPK)。
Android 渲染路径¶
- GPU 零拷贝(首选):Kotlin 插件
createSurfaceTexture创建SurfaceTexture→ JNInativeSetSurface把ANativeWindow交给引擎 →engine_tick自动挂载 EGL WindowSurface (ANGLE Vulkan 后端)→eglSwapBuffers直接把帧交给 Flutter。 - CPU 回读(兜底):
engineReadFrameRgba→ Dart →updateTextureRgba→ FlutterTexture 上传。 - 若 SurfaceTexture 创建失败,
engine_surface.dart会自动降级到回读路径。
产物路径速查¶
| 目标 | 引擎库 | App 产物 |
|---|---|---|
| iOS | out/ios/{debug,release}/bridge/engine_api/libengine_api.a |
apps/flutter_app/build/ios/iphoneos/Runner.app |
| Android | out/android/{debug,release}/bridge/engine_api/libengine_api.so |
apps/flutter_app/build/app/outputs/flutter-apk/app-{debug,release}.apk |
| macOS | out/macos/{debug,release}/bridge/engine_api/libengine_api.dylib |
apps/flutter_app/build/macos/Build/Products/{Debug,Release}/Runner.app |
常用操作¶
# 清理某平台产物
./build.sh --clean ios
./build.sh --clean android
./build.sh --clean macos
# 并行数
JOBS=16 ./build.sh ios release
CI 打包(GitHub Actions)¶
-
iOS:
.github/workflows/ios_package.yml(手动触发或v*标签),运行于macos-15。 -
Android:
.github/workflows/android_package.yml(手动触发或v*标签),运行于ubuntu-22.04: setup Flutter + JDK 17 + 自动安装 NDK(sdkmanager "ndk;27.0.12077973")+./build.sh android <type>。 -
引擎核心验证(Linux):
.github/workflows/engine_verify.yml(push/PR 自动触发), 运行于ubuntu-22.04:以宿主构建(Linux Debug预设,x64-linuxtriplet)编译引擎核心 + tools,跑 ctest(tests/ 目录,目前为空)+tools/xp3 --help冒烟。 这是最快的反馈闭环(5-10 分钟),后续 SIMD 逐像素比对等测试挂这里。 -
vcpkg 二进制缓存:
~/.cache/vcpkg(key 基于vcpkg.json/vcpkg-configuration.json/vcpkg/**), 通过环境变量VCPKG_BINARY_SOURCES=files,<path>,readwrite启用。 -
iOS 产物:未签名
Runner.app的 zip(ditto打包);Android 产物:APK。均保留 14 天。 -
iOS 真机安装需自行用 Apple 开发者证书签名;Android 可直接安装 APK。
版本号与发布(GitHub Actions)¶
- 版本号规则(X.Y.Z 三段式):一个版本号同时控制四处,需保持一致——
- Git tag / Release:
ios-vX.Y.Z(iOS)、android-vX.Y.Z(Android),分平台各自 Release; - 原生 app 版本:iOS
CFBundleShortVersionString、AndroidversionName(--build-name); - 原生构建号:Android
versionCode、iOSCFBundleVersion(--build-number),自动取major*10000 + minor*100 + patch(如0.1.4→104); - 软件内版本显示:设置 → 版本,副标题显示该版本号(
--dart-define=APP_VERSION注入)。 - 手动发布(推荐):
- Actions → 对应打包工作流 → Run workflow;
- 填
build_type=release,填发布版本号(X.Y.Z),勾选发布 Release; - 跑完自动建 tag
ios-vX.Y.Z/android-vX.Y.Z→ 建对应 GitHub Release → 挂产物。 - 注意:只测不发布则不勾「发布 Release」(产物仍保留 14 天);已存在 tag 再跑不会重复建
Release,只补充/覆盖产物;
debug类型即使发布也是 debug 包,正式发布请用release。
常见问题¶
-
找不到 bison:Homebrew 安装后路径在
HINTS里已列(tjs2/CMakeLists.txt)。 -
vcpkg 卡住:首次安装
arm64-ios依赖耗时长;--jobs控制并行。 -
符号找不到(iOS):确认
build_ios.sh的 libtool 合并步骤成功,ios/Libs/*.a已更新, 且 Runner 链接了这些库(podspec 配置)。 -
静态库重复符号:多为冗余三方库未排除(libpng/libjpeg/libwebpdecoder 等),核对合并脚本排除列表。