Arch 编译 Android 11 源码

2,080 阅读3分钟

很多人都写,如何在 Ubuntu 下编译 Android 源码。今天,标新立异一次。

环境准备

本次编译基于 Arch 系统。需要安装些开发组件,比较容易。

sudo pacman -S base-devel

至于 jdk 环境,有人说需要安装 open jdk 8 ,但是看 Android 源码中,prebuilts 目录下有提供 jdk 目录。

下载源码

国内下载源码,一般通过清华大学 AOSP 镜像中国科技大学 AOSP 镜像。他们也提供具体教程。 尝试过很多次,总结出一个比较实用的下载方式。

下载 repo 工具

Android 源码仓库有数百个,因此 google 使用 python 写 repo 用于管理其源码库。

# 在用户目录下创建bin目录,并进入
mkdir ~/bin
cd ~/bin
# 将bin目录加入到环境变量
vim ~/.bash_profile
# 添加下面配置
export PATH=$PATH:~/bin
# 使配置的环境变量生效
source ~/.bash_profile
# 下载 repo 工具,有两种方式,我使用第二种
# 方式一,清华大学 aosp 提供的下载方式
curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo -o repo
chmod +x repo  # 添加可执行权限
# 方式二
git clone https://mirrors.tuna.tsinghua.edu.cn/git/git-repo
ln -sf git-repo/repo repo 

检查 repo 版本。

repo init 原理

在执行 repo init 命令之前,有必要了解下 repo 的工作原理。可以更好的知道,后买每步操作的意义,如无兴趣,可跳过。

repo 本身只是一个 python 文件,但是他的功能很多,远远超出一个文件所能承受的能力。因此,在执行 repo init 命令时,它首先会 clone 一份自己的仓库,也即 REPO_URL 所指定的地址。其次再去从 -u 指定的 url 中获取源码仓库的清单文件。

REPO_URL = os.environ.get('REPO_URL', None)
if not REPO_URL:
  REPO_URL = 'https://gerrit.googlesource.com/git-repo'

这段代码表示,repo 默认从 goole 的服务器同步。解决方案有两种。

# 方式一,添加 REPO_URL 环境变量
vim ~/.bash_profile # 添加下面的内容
export REPO_URL=https://mirrors.tuna.tsinghua.edu.cn/git/git-repo
source ~/.bash_profile # 使配置生效
# 方式二
# 执行 init 命令时,手动指定 repo url
repo init --repo-url=https://mirrors.tuna.tsinghua.edu.cn/git/git-repo -u manifest

但是,之前下载 repo 工具时,已经 clone 过 git-repo 仓库。是可以复用的。

mkdir ~/aosp # 创建 Android 源码目录
cd ~/aosp    # 后面所有命令都在此目录下执行
mkdir .repo  # 创建 .repo 目录,其实 init 执行时也会创建
ln -sf ~/bin/git-repo .repo/repo  # 创建快捷方式,指向之前的 repo 仓库

此方案,建议熟悉 linux 命令的同鞋使用,如果你是一只 linux 小白或菜鸟,或许有难度。

初始化仓库

很多教程,有介绍使用 -b 参数,表示需要同步的代码版本,如 -b android-4.0.1_r1 。想说,查找能同步的代码版本列表,是个难题。因为我们打不开这个地址 source.android.com/setup/start… (有梯子的可以嘲笑下)。或许有哪些热心的小伙伴整理过。但是,完全没有必要使用 -b

# 此处假装,你已经知道了配置 REPO_URL 或复用 git-repo 仓库。
# 不推荐使用 http 协议,因此只能使用科大的源
repo init -u git://mirrors.ustc.edu.cn/aosp/platform/manifest

下面是复用了 git-repo 仓库的截图。

也许会提示没有配置 git 用户信息,使用下面两条命令即可。

git config --global user.name " Your Name "
git config --global user.email " Your Email"
git config -l # 查看配置的结果

选择同步指定分支

刚说了,没有必要在 init 时,指定 -b 参数。因为有更便捷的方式。

cd .repo/manifests
git branch -a # 查看全部版本列表
# 如同步 android-11.0.0_r27
git checkout -b android-11.0.0_r27 origin/android-11.0.0_r27
cd ../../

如果后面还需要同步其他分支的代码时,还可以用这种方式。

同步代码

执行下面命令,静等即可。建议选择白天,如果网速可以。两三小时就可以下载完成。

repo sync 

# 上面的命令可能会执行失败,因此需要一个自动继续执行的脚本
vim ~/bin/auto-repo # 添加下面的内容

#!/bin/bash
echo "=========start repo sync=========="
repo sync

while [ $? != 0 ]
do
	echo "========sync failed,re-sync again=========="
	sleep 2
	repo sync
done

然后使用 auto-repo 同步仓库即可。下载完成后如图:

切换源

如果之前已同步过 aosp 代码,现在去要切到清华或科大的源。只需修改 manifests 的仓库地址。

[core]
	repositoryformatversion = 0
	filemode = true
[filter "lfs"]
	smudge = git-lfs smudge --skip -- %f
	process = git-lfs filter-process --skip
[remote "origin"]
  # 清华地址
	# url = https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest
  # 可科大地址
	url = git://mirrors.ustc.edu.cn/aosp/platform/manifest
	fetch = +refs/heads/*:refs/remotes/origin/*
[branch "default"]
	remote = origin
	merge = refs/heads/master
[branch "android-11.0.0_r27"]
	remote = origin
	merge = refs/heads/android-11.0.0_r27

编译代码

# 初始化编译环境
source build/envsetup.sh
# 选择要编译的目标版本
lunch

#-----------以下是终端显示内容----------------
You're building on Linux

Lunch menu... pick a combo:
     1. aosp_arm-eng
     2. aosp_arm64-eng
     3. aosp_blueline-userdebug
     4. aosp_blueline_car-userdebug
     5. aosp_bonito-userdebug
     6. aosp_bonito_car-userdebug
     7. aosp_bramble-userdebug
     8. aosp_car_arm-userdebug
     9. aosp_car_arm64-userdebug
     10. aosp_car_x86-userdebug
     11. aosp_car_x86_64-userdebug
     12. aosp_car_x86_64_app-userdebug
     13. aosp_cf_arm64_auto-userdebug
     14. aosp_cf_arm64_phone-userdebug
     15. aosp_cf_x86_64_phone-userdebug
     16. aosp_cf_x86_auto-userdebug
     17. aosp_cf_x86_phone-userdebug
     18. aosp_cf_x86_tv-userdebug
     19. aosp_coral-userdebug
     20. aosp_coral_car-userdebug
     21. aosp_crosshatch-userdebug
     22. aosp_crosshatch_car-userdebug
     23. aosp_flame-userdebug
     24. aosp_flame_car-userdebug
     25. aosp_redfin-userdebug
     26. aosp_sargo-userdebug
     27. aosp_sunfish-userdebug
     28. aosp_trout_arm64-userdebug
     29. aosp_trout_x86-userdebug
     30. aosp_x86-eng
     31. aosp_x86_64-eng
     32. arm_krait-eng
     33. arm_v7_v8-eng
     34. armv8-eng
     35. armv8_kryo385-eng
     36. beagle_x15-userdebug
     37. beagle_x15_auto-userdebug
     38. car_x86_64-userdebug
     39. db845c-userdebug
     40. fuchsia_arm64-eng
     41. fuchsia_x86_64-eng
     42. hikey-userdebug
     43. hikey64_only-userdebug
     44. hikey960-userdebug
     45. hikey960_tv-userdebug
     46. hikey_tv-userdebug
     47. pixel3_mainline-userdebug
     48. poplar-eng
     49. poplar-user
     50. poplar-userdebug
     51. qemu_trusty_arm64-userdebug
     52. silvermont-eng
     53. uml-userdebug
     54. yukawa-userdebug
     55. yukawa_sei510-userdebug

Which would you like? [aosp_arm-eng] 31

============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=11
TARGET_PRODUCT=aosp_x86_64
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_ARCH=x86_64
TARGET_ARCH_VARIANT=x86_64
TARGET_2ND_ARCH=x86
TARGET_2ND_ARCH_VARIANT=x86_64
HOST_ARCH=x86_64
HOST_2ND_ARCH=x86
HOST_OS=linux
HOST_OS_EXTRA=Linux-5.10.9-arch1-1-x86_64-Arch-Linux
HOST_CROSS_OS=windows
HOST_CROSS_ARCH=x86
HOST_CROSS_2ND_ARCH=x86_64
HOST_BUILD_TYPE=release
BUILD_ID=RQ1A.210105.003
OUT_DIR=out
PRODUCT_SOONG_NAMESPACES=device/generic/goldfish device/generic/goldfish-opengl hardware/google/camera hardware/google/camera/devices/EmulatedCamera device/generic/goldfish device/generic/goldfish-opengl
============================================

由于使用模拟器测试,因此选择 x86x86_64 的编译目标。我选择 31 aosp_x86_64-eng

在执行,最后的编译操作之前,需要了解下电脑的 CPU 核心数量。

cat /proc/cpuinfo | grep 'process'
# 下面表示 4 核
processor	: 0
processor	: 1
processor	: 2
processor	: 3

最后,使用 make -j4 执行编译。

我的电脑性能比较差,如图。耗时约 10 小时。建议睡前执行。万一不出错的情况下,睡醒就完成了。

编译成功之后,使用 emulator 命令启动模拟器。

遇到的错误

编译过程中,遇到两个 so 文件没有,通过添加快捷方式引用到系统中,其他新版本的 so 。

libncurses.so.5 -> /usr/lib64/libncursesw.so.6
libtinfo.so.5 -> libtinfo.so.6

sudo ln -sf /usr/lib64/libncursesw.so.6 /usr/lib/libncurses.so.5 
sudo ln -sf /usr/lib/libtinfo.so.6 /usr/lib/libtinfo.so.5

遇到 command not found 错如,如 zip ,直接安装即可。

sudo pacman -S zip

其他错误还未遇到。