30、构建系统未来趋势:Bazel集成、构建系统演进、社区动态

聊到构建系统的未来,我其实挺感慨的。十年前大家还在纠结用Make还是Python脚本,现在Bazel已经成了AOSP官方钦定的下一代构建引擎。这个转变不是拍脑袋决定的,背后是整个Android生态对构建速度、可复现性、跨平台能力的需求在倒逼。

为什么是Bazel?

说白了,Soong虽然比Make快了不少,但它本质上还是为单一代码仓库设计的。Google内部早就用Bazel(Blaze的开源版)管理着地球上最大的单体仓库之一。我参与过几个大型项目的迁移,最直观的感受是:Bazel的增量构建和远程缓存能力,能把全量编译从小时级压缩到分钟级

核心优势对比

特性 Make/Soong Bazel
增量构建 基于文件时间戳,容易误判 基于内容哈希,精确可靠
远程执行 需要额外工具链 原生支持,内置RBE
依赖管理 全局变量,容易冲突 严格沙箱,隔离性好
跨平台 Linux为主 Linux/macOS/Windows全支持

Bazel集成现状与挑战

目前AOSP里已经能看到Bazel的痕迹了。比如build/bazel目录下就有官方的迁移工具和规则集。但说实话,完全替换Soong还需要时间。我去年帮一个团队做迁移时发现,最大的坑是第三方预编译库的依赖声明——Bazel要求每个输入都显式声明,而Soong里很多依赖是隐式的。

我的建议:如果你现在开始新项目,直接用Bazel的android_binary规则。对于存量项目,可以先用--experimental_bazel_mode跑一下,看看哪些模块能平滑迁移。

构建系统演进路线

从Make到Soong再到Bazel,这条演进路线其实反映了三个核心诉求:

  • 速度:并行度从单机多核扩展到集群分布式
  • 确定性:同样的输入必须产生同样的输出,杜绝"在我机器上能编译"
  • 可审计性:每个构建产物都能追溯到源码和工具链版本

我记得有一次排查线上崩溃,发现是构建时链接了不同版本的libc++。如果是Bazel的沙箱模式,这种问题根本不会出现——它强制每个依赖都锁定版本。

社区动态与生态

社区这边,Google在2023年正式宣布了Bazel for Android的长期支持计划。几个值得关注的方向:

  • Bazel 7.x:改进了Android规则集,支持了AGP 8.x的新特性
  • rules_android:社区维护的规则库,比官方更激进地支持新API
  • Bazelisk:版本管理工具,我建议团队统一用它,避免"你用的Bazel版本不对"这种低级错误

避坑指南:我曾经遇到过一个坑——Bazel的.bazelrc里配置了build --remote_cache,但没配认证信息,结果缓存一直没生效。排查了半天才发现是配置遗漏。记住:远程缓存一定要配好--tls_client_certificate--google_credentials

知识体系总览

下面这张图梳理了构建系统未来的核心脉络,你可以把它当作路线图来参考:

构建系统未来趋势全景图 Bazel集成 构建系统演进 社区动态 增量构建与远程缓存 严格沙箱与可复现性 跨平台支持 Make → Soong → Bazel 分布式构建(RBE) 构建产物可审计性 Bazel 7.x 长期支持 rules_android 社区库 Bazelisk 版本管理 核心目标:更快、更稳、更可追溯

实际迁移建议

如果你团队正在考虑迁移到Bazel,我建议分三步走:

  1. 先跑通一个模块:选一个依赖简单、不涉及预编译库的模块,用bazel build //path:target验证流程
  2. 配置远程缓存:搭建或接入已有的RBE服务,这一步能立刻看到构建速度提升
  3. 逐步扩大范围:每次增加10-20个模块,同时监控构建失败率。我见过一次性迁移太多导致回滚的案例

小技巧:在.bazelrc里加上build --verbose_failuresbuild --sandbox_debug,排查问题时能省不少时间。

嗯,构建系统的演进不会停。Bazel之后可能还会有更智能的构建引擎,但核心思想不会变——让开发者把精力花在写代码上,而不是等编译。我个人觉得,未来两年内Bazel会成为Android构建的事实标准,现在开始学绝对不亏。


公众号:蓝海资料掘金营,微信deep3321