Matter 本地编译与工程裁剪实践


1. 快速结论

  • Matter 本地构建的核心流程是:激活环境 -> gn gen 生成构建文件 -> ninja 编译。
  • Android 架构建议显式指定 current_cpu,并区分 arm(32 位)与 arm64(64 位)产物目录。
  • 体积优化步骤:关闭测试构建 -> 精简链接目标 -> 对最终 so 执行 strip。
  • 裁剪必须和功能回归一起做,避免“体积下降但功能异常”。

2. 适用环境

  • 系统:macOS
  • 构建系统:gn + ninja
  • SDK:Android SDK / NDK
  • 代码仓库:Matter(connectedhomeip)

3. 前置条件:GN 安装

GN 是 Matter 构建链路中的前置工具。若本机没有可用 GN,后续 gn gen 无法执行。

参考文章:http://blog.fpliu.com/it/software/gn

3.1 GN 安装步骤
git clone https://gn.googlesource.com/gn
python build/gen.py
ninja -C out/
ln -sf out/gn /usr/local/bin
3.2 常用命令

打印某个构建目录可配置参数:

gn args out/mybuild
3.3 记录一个 GN 相关问题(Chromium 构建)

报错信息:

ninja: error: '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk/usr/include/mach/exc.defs'

背景:

  • 在编译 Chromium 时持续报错。
  • 本机 Xcode 已升级到 15.0.1,理论上不应继续引用 MacOSX13.3.sdk

排查尝试:

  • 从 GitHub 下载 13.3 SDK,复制到对应目录,仍报错。
  • 系统从 13.1 升级到 14.1.2,问题依旧。
  • 因此判断不只是系统或 Xcode 本身问题。

最终结论与解决:

  • 本机 gn 是之前为 Matter 编译时构建并软链接的旧产物,构建环境残留了旧 SDK 路径信息。
  • 删除旧 GN 产物后,重新 clone GN 源码并编译、重新链接,问题解决。

建议:

  • 将 GN 作为“可重建工具”,不要长期依赖历史产物。
  • 遇到 SDK 路径异常时,优先检查 which gn 指向和 GN 本体构建时间。
3.4 激活环境
source scripts/activate.sh
3.5 生成 Android 构建文件
gn gen out/android --args='is_debug=false target_os="android" \
android_sdk_root="<ANDROID_SDK_ROOT>" \
android_ndk_root="<ANDROID_NDK_ROOT>"'
3.6 开始编译
ninja -C out/android
3.7 构建目标
gn gen out/ios --args='is_debug=false target_os="mac"'

这里保留了原有目录命名(out/ios),关键是 target_os="mac"

4. Android 多架构构建参数

arm-v7(32 位)
gn gen out/android --args='is_debug=false target_os="android" \
current_cpu="arm" \
android_sdk_root="<ANDROID_SDK_ROOT>" \
android_ndk_root="<ANDROID_NDK_ROOT>"'
arm-v8(64 位)
gn gen out/android --args='is_debug=false target_os="android" \
current_cpu="arm64" \
android_sdk_root="<ANDROID_SDK_ROOT>" \
android_ndk_root="<ANDROID_NDK_ROOT>"'

5. 体积对比

5.1 横向体积记录
项目 armv8 armv7
我的 15.1MB 11.8MB
涂鸦 26.7MB 12.4MB

注:以上为原始记录数据,主要用于横向参考,不代表统一构建配置下的绝对对比。

5.2 本地构建目录观察
  • connectedhomeip/out/android-arm64-chip-tool/lib 下,静态库总量约 220MB(原始工程状态)。
  • 目录中包含大量功能库、测试库、第三方依赖库,默认集成成本较高。

原始裁剪记录截图如下:
Matter 裁剪

Matter 构建产物目录截图
Matter 构建产物

6. 裁剪前先做模块识别

建议先做“目录 -> 功能”映射,避免误删核心链路:

File / Folder Contents
app Application Layer,包含 Zigbee Cluster Library(ZCL)等应用层能力
ble BLE 传输层(Bluetooth Transport Protocol, BTP)

实际工程中建议补全 controllercredentialsmessagingplatform 等目录说明,形成可维护的“依赖字典”。

7. 裁剪策略与命令

7.1 构建阶段先减法

先关闭测试相关构建项,让产物聚焦业务目标:

# arm64
gn gen out/android64 --args='is_debug=false chip_build_tests=false \
chip_link_tests=false chip_build_test_static_libraries=false \
target_os="android" current_cpu="arm64" \
android_sdk_root="<ANDROID_SDK_ROOT>" \
android_ndk_root="<ANDROID_NDK_ROOT>"'
ninja -C out/android64

# armv7
gn gen out/android32 --args='is_debug=false chip_build_tests=false \
chip_link_tests=false chip_build_test_static_libraries=false \
target_os="android" current_cpu="arm" \
android_sdk_root="<ANDROID_SDK_ROOT>" \
android_ndk_root="<ANDROID_NDK_ROOT>"'
ninja -C out/android32
7.2 链接阶段做白名单
  • 以功能清单为依据,只链接业务必须的模块。
  • commissioning/test 等可选能力按需启用,不默认全量链接。
7.3 产物阶段裁剪符号
<NDK_TOOLCHAIN_PATH>/bin/llvm-strip -S <YOUR_LIB>.so

8. 建议的落地流程

  1. 先测量:记录裁剪前各架构 SO 体积。
  2. 再裁剪:按模块功能关掉不必要构建目标。
  3. 再测量:记录裁剪后体积并做功能回归。
  4. 固化脚本:把参数沉淀到脚本,避免后续回退。

9. 常见问题与排查

1) 命令可执行但编译失败
  • 先确认 source scripts/activate.sh 已执行。
  • 检查 ANDROID_SDK_ROOT / ANDROID_NDK_ROOT 是否匹配本机版本。
2) 架构不符合预期
  • 检查 current_cpuarmarm64 不能混用。
  • 检查输出目录是否对应(如 out/android32out/android64)。
3) 体积降了但运行异常
  • 优先排查是否误删 commissioning / transport / crypto 相关依赖。
  • 对比链接日志,确认关键库仍在最终链路中。
4) 体积几乎没变化
  • 检查是否仍在链接测试静态库。
  • 检查 strip 命令是否作用于最终 so 而非中间文件。
5) 构建耗时过长
  • 关闭测试构建项(chip_build_tests 等)。
  • 优先单架构增量构建,减少重复编译。

10. 注意事项

  • 路径建议统一环境变量化,避免脚本和机器强绑定。
  • 构建参数建议沉淀到脚本(如 build_android.sh)。
  • 调试期可用 is_debug=true,发布前切回 false 验证最终产物。
  • 每次优化保留参数快照,便于问题回溯。

11. 参考资料

11.1 资料入口
11.2 Connectedhomeip 关键参考页
11.3 Silicon Labs 相关资料
11.4 参考文档
11.5 官方构建流程(补充)
./scripts/build/build_examples.py --target android-arm64-chip-tool build

注意:使用该命令构建的产物体积较大,无法用于release环境

9 次浏览

发表回复