第2章 编译环境搭建(Ubuntu/Docker)

2.1 环境准备概述

核心要点:AOSP 编译环境要求 Ubuntu 18.04+(推荐 20.04/22.04 LTS)或 Docker 容器。必须安装基础依赖、Java/Go/Python 工具链、配置 ccache 加速。本章以 Ubuntu 22.04 LTS(x86_64)为例,同时提供 Docker 方案。

AOSP 编译系统依赖大量系统包和工具链。不完整或有版本冲突的环境会导致编译失败。下文按以下顺序搭建:

  1. 系统依赖包安装
  2. Java 工具链(OpenJDK 11/17)
  3. Go 工具链
  4. Python 工具链(Python 3.8+)
  5. ccache 配置
  6. Docker 环境快速搭建
  7. 常见错误与调试
  8. 性能优化
AOSP 编译环境搭建流程 Ubuntu / Docker 基础系统 安装系统依赖包(apt) Java 工具链(OpenJDK) Go 工具链 Python 工具链 配置 ccache 加速 验证编译环境(env setup) 提示:每一步均可通过 Dockerfile 固化至镜像

2.2 系统依赖包安装

AOSP 编译需要大量开发库和工具。使用 apt 安装以下关键包(按分组说明):

分组 包名 用途
基础工具 git-core gnupg flex bison build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 libncurses5 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev 编译工具、链接器、头文件
编译环境 libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig 图形库、XML处理、字体配置
Python 依赖 python3 python3-pip python3-venv Python 运行时与包管理
其他 rsync bc cpio 同步、计算、ramdisk创建
执行命令(推荐复制执行):
sudo apt update && sudo apt install -y \
  git-core gnupg flex bison build-essential zip curl zlib1g-dev \
  gcc-multilib g++-multilib libc6-dev-i386 libncurses5 \
  lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev \
  libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig \
  python3 python3-pip python3-venv rsync bc cpio
常见错误:若遇到 libncurses5 找不到,Ubuntu 22.04 已移除该包,请替换为 libncurses5-dev libncursesw5-dev。若仍报错,使用 apt search libncurses 确认可用包名。

2.3 Java 工具链配置

AOSP 9+ 依赖 OpenJDK 11(或 17,视分支而定)。推荐使用 OpenJDK 11:

sudo apt install -y openjdk-11-jdk
java -version
# 应输出 openjdk version "11.0.x"

若需多个 JDK 版本并存,通过 update-alternatives 配置默认版本:

sudo update-alternatives --config java
sudo update-alternatives --config javac
性能提示:AOSP 编译过程中 Java 堆内存开销大。建议在 ~/.bashrc 设置 export JACK_SERVER_VM_ARGUMENTS="-Xmx4096m"(针对旧版 Jack 工具链),或直接设置 JAVA_TOOL_OPTIONS="-Xmx8G"。

2.4 Go 工具链配置

AOSP 中部分工具(如 go 编译的 soong_gotools)需要 Go 1.17 以上。从 Go 官方下载并部署:

# 下载并解压(以 go1.20.6.linux-amd64.tar.gz 为例)
wget https://go.dev/dl/go1.20.6.linux-amd64.tar.gz
sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.20.6.linux-amd64.tar.gz

# 添加环境变量到 ~/.bashrc
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
source ~/.bashrc
go version
# 输出: go version go1.20.6 linux/amd64

若使用 Docker,建议将 Go 安装步骤写入 Dockerfile 以保持环境一致。

2.5 Python 工具链配置

AOSP 编译系统(Soong)主要使用 Python 3.8+。Ubuntu 22.04 自带 Python 3.10,无需额外安装。但需要确保 python 命令指向 Python 3(而非 Python 2):

python3 --version   # 应为 Python 3.10.x
# 若需要 python 命令,创建符号链接(谨慎)
sudo ln -s /usr/bin/python3 /usr/bin/python

安装常见 Python 包(pyyaml、jinja2 等,部分 AOSP 模块可能需要):

pip3 install --user pyyaml jinja2
# 注意:不要使用系统包管理器安装这些包,避免与 AOSP 内部冲突

2.6 ccache 设置

ccache 通过缓存编译中间结果大幅缩短增量编译时间。AOSP 官方推荐配置:

  1. 安装 ccache:sudo apt install -y ccache
  2. 配置缓存大小和路径:
# 编辑 ~/.bashrc 或 /etc/environment
export USE_CCACHE=1
export CCACHE_DIR=/home/yourname/.ccache
export CCACHE_COMPILERCHECK=content
export CCACHE_SLOPPINESS=file_macro,locale,time_macros
export CCACHE_BASEDIR=$HOME/aosp

# 设置最大缓存(建议 50-100 GB)
ccache -M 100G
ccache -s   # 查看当前状态

AOSP 编译系统自动检测 USE_CCACHE 变量。若未生效,可手动在 build/make/envsetup.sh 中启用:

# 在 source build/envsetup.sh 前执行
export USE_CCACHE=1
export CCACHE_DIR=~/aosp/.ccache
# 或者直接修改 aosp 目录下的 .ccache 软链接到 SSD 分区
性能优化点:
  • 将 ccache 目录放在 SSD 上,避免机械硬盘 I/O 瓶颈。
  • 对于 Docker 环境,使用 volume 挂载 ccache 目录到宿主机,镜像重建后不会丢失缓存。
  • 设置 CCACHE_BASEDIR 为 AOSP 源码根目录,避免路径差异导致缓存未命中。

2.7 Docker 环境快速搭建

为避免宿主机依赖冲突,推荐使用 Docker 编译。以下 Dockerfile 封装了完整的编译环境:

FROM ubuntu:22.04

ENV DEBIAN_FRONTEND=noninteractive

# 安装基础依赖(同 2.2 节)
RUN apt update && apt install -y \
  git-core gnupg flex bison build-essential zip curl zlib1g-dev \
  gcc-multilib g++-multilib libc6-dev-i386 libncurses5 \
  lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev \
  libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig \
  python3 python3-pip python3-venv rsync bc cpio \
  openjdk-11-jdk ccache

# 安装 Go
RUN rm -rf /usr/local/go && \
  curl -fsSL https://go.dev/dl/go1.20.6.linux-amd64.tar.gz | tar -C /usr/local -xz && \
  ln -s /usr/local/go/bin/go /usr/bin/go

# 设置环境变量
ENV USE_CCACHE=1
ENV CCACHE_DIR=/ccache
ENV CCACHE_COMPILERCHECK=content
ENV CCACHE_SLOPPINESS=file_macro,locale,time_macros

# 创建工作目录
WORKDIR /aosp

构建镜像并运行:

docker build -t aosp-builder .
docker run -it --rm \
  -v /path/to/aosp:/aosp \
  -v /path/to/ccache:/ccache \
  -e CCACHE_DIR=/ccache \
  aosp-builder /bin/bash
提示:推荐使用 --privileged 参数(若需挂载 FUSE)或 --security-opt seccomp=unconfined 避免权限限制。

2.8 常见错误与调试

错误场景 原因 解决方法
/usr/bin/ld: cannot find -lncurses 缺少 32 位 ncurses 库 sudo apt install lib32ncurses-dev
ERROR: Could not find a supported JDK version JDK 版本不匹配(需要 JDK 11) 运行 java -version 检查;安装 OpenJDK 11 并切换默认
Go version too old 系统 Go 版本 < 1.17 按 2.4 节手动安装新版 Go
ccache: error: Failed to create cache CCACHE_DIR 权限或路径问题 检查目录是否存在,并设置 chmod 777 $CCACHE_DIR
Python: ModuleNotFoundError: No module named 'yaml' 缺少 Python 包 pip3 install pyyaml

2.9 性能优化总结

  • ccache 缓存策略:结合 CCACHE_BASEDIR 和 CCACHE_SLOPPINESS 提高命中率。
  • 并行编译:设置 make -jN,N = CPU 核心数×2(物理核心+超线程)。
  • RAM 磁盘:将 out/ 目录挂载到 tmpfs 可极大加速,但需确保足够物理内存(≥32 GB)。
  • Docker 持久化:将 ccache 和 out 目录映射到宿主机 SSD 卷,避免容器重建后全量编译。
  • 环境固化:将 Dockerfile 纳入版本管理,团队统一环境,消除“在我机器上能编译”问题。

完成以上步骤后,运行 source build/envsetup.sh && lunch aosp_arm64-eng 验证环境。若未报错,则编译环境搭建成功。