构建在树莓派上运行的 Chromium (一)

1 背景

最近打算树莓派上显示一些 UI ,因为使用的是没有桌面环境的 Raspbian Lite,选项比较有限。最终选择了支持无桌面环境的 Chromium,这样 UI 部分可以基于 Web 技术开发。

虽然 Raspbian 系统也提供 Chromium,但却是依赖桌面环境的,对于无桌面环境的场景,只能自己构建了。

Chromium 官方提供的教程,只介绍了使用最新版代码,构建桌面浏览器的步骤。对于定制化的需求,只能从各个文档中的收集线索,自己梳理流程,因此就有了这篇笔记。

2 环境

文中的操作步骤,仅保证在以下环境中有效,在别的环境中请自行调整。

  • 主机系统: Manjaro 21.0.3
  • 主机 CPU 架构: x86-64
  • 目标系统: Raspbian Buster Lite
  • 目标 CPU 架构: ARMv7
  • Chromium 源码版本: 90.0.4430.93

Chromium 的稳定版本,可以从这里查询:https://chromiumdash.appspot.com/releases?platform=Linux


在国内的网络环境下,需要科学上网,因为 Chromium 及其依赖项目的代码,都托管在 Google 的服务器上。

3 构建过程

3.1 总览

根据 Chromium 的文档,整个构建过程可以分为以下几步:

  • 安装工具包
  • 下载代码
  • 生成构建脚本
  • 构建

是不是像 “把大象放进冰箱” 一样简单?

由于我对 Chromium 的编译有一些定制化的需求,教程仅可作为参考,每一步的操作都要参考文档和命令说明来调整。

3.2 安装工具包

工具包直接从 git 仓库下载:

1
2
# Download the latest version
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git

然而,这个工具包是不断更新的,且并不保证向下兼容,为避免构建过程中出现奇怪的错误,需要将其回滚到与 Chromium 代码相近的时间点。

从 Chromium 的代码仓库中,可以查到 90.0.4430.93 这个 Tag 的提交时间为:Sat Apr 24 00:08:45 2021,因此 depot_tools 也需要回滚到这个时间点附近的版本。

在 depot_tools 的目录下,执行如下命令:

1
2
3
4
5
6
# Query the commit id which is near to "Sat Apr 24 00:08:45 2021"
git rev-list -n 1 --before="Sat Apr 24 00:08:45 2021" master
# Output: 61bf6e8d69c4cb084b1541a996fc3f4990cd2535

# Check out to the commit
git checkout 61bf6e8d69c4cb084b1541a996fc3f4990cd2535

最后,创建一个脚本文件 build-env.sh,内容为:

1
2
export PATH="$PATH:/path/to/depot_tools"
export DEPOT_TOOLS_UPDATE=0

每次要进行构建工作时,先在终端执行:

1
source /path/to/build-env.sh

3.3 下载代码

3.3.1 常规操作

1
2
3
4
5
6
7
8
# Create and go to work directory
mkdir -p /path/to/chromium && cd /path/to/chromium

# Fetch source code
fetch --nohooks chromium

# Run hook functions
gclient runhooks

这里比较坑的是,如果要构建旧版本的代码,首先需要 clone 完整的 Chromium 代码库(包含历史记录),然后自己通过 git 命令切换到特定的 tag。而完整的代码库,压缩之后有 24GB 左右,在需要科学上网的环境下,很容易下载失败。

现实是我试了整整一天,也没成功把整个代码仓库拉下来。

3.3.2 优化操作

经过分析 fetchgclient 命令的逻辑,最终找到了一种更高效的下载代码的方法:

1
2
3
4
5
6
7
8
9
# Create and go to work directory
mkdir -p /path/to/chromium && cd /path/to/chromium

# Directly clone source
git clone --depth 1 --branch 90.0.4430.93 \
https://chromium.googlesource.com/chromium/src.git

# Manually create .gclient file
vim .gclient

在 “.gclient” 文件中,输入如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
solutions = [{
"name" : 'src',
"url" : 'https://chromium.googlesource.com/chromium/src.git@f46f037392518e6b7665d3f3f626d6d80cad1c2d',
"deps_file" : 'DEPS',
"managed" : True,
"custom_deps" : {},
"custom_vars" : {},
}]

target_os = ["linux"]
target_os_only = True
target_cpu = ["arm"]
target_cpu_only = True

配置文件中的 f46f037392518e6b7665d3f3f626d6d80cad1c2d,为 90.0.4430.93 这个版本的 Commit ID。

最后执行如下命令,同步依赖库:

1
2
3
4
5
# Synchronize dependencies
gclient sync --nohooks

# Run hook functions
gclient runhooks

3.3.3 原理

fetch 命令内部,实际上就是做了这么两件事情:

  • 创建 “.gclient” 文件。
  • 调用 gclient sync 同步项目代码和依赖库代码。

gclient sync 命令,会判断哪些项目需要下载,如果已存在,且不需要更新版本,则跳过。

因此,直接通过 git clone 下载的 Chromium 源码,也是有效的。并且通过在 “.gclient” 中指定代码的 Commit ID,让 gclient 跳过了对 Chromium 源码的更新,直接开始下载依赖库。

4 总结

到这里,解决了下载代码的问题。

当然,如果空间足够大,网络足够好,这些都不是问题。

下一篇笔记,会讲关于交叉编译的配置方法。

5 参考