Ubuntu18.04 编译安卓6.0刷入Nexus 5
zsk Lv4

有台闲置的nexus 5,想着刷机,之前都是刷入编译好的系统包,就琢磨着自己编译安卓源码刷入。
一开始用ubuntu22.04,各种踩坑,放弃了改为用ubuntu18.04
资料链接:
https://source.android.com/docs/setup/about/build-numbers?hl=zh-cn#platform-code-names-versions-api-levels-and-ndk-releases
https://source.android.com/docs/setup/build/running?hl=zh-cn#selecting-device-build

环境配置

安装和配置git

1
2
3
$ sudo apt install git
$ git config --global user.name "Your Name"
$ git config --global user.email "you@example.com"

更换软件源为清华

1
sudo gedit /etc/apt/sources.list

在文件最前面加入下面代码:

1
2
3
4
5
6
7
8
9
10
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse

修改完成后,保存文件,执行

1
2
sudo apt-get update
sudo apt-get upgrade

安装依赖:

1
2
3
4
5
6
7
8
9
10
11
sudo apt-get install -y git flex bison gperf build-essential libncurses5-dev:i386
sudo apt-get install libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-dev g++-multilib
sudo apt-get install tofrodos python-markdown libxml2-utils xsltproc zlib1g-dev:i386
sudo apt-get install dpkg-dev libsdl1.2-dev libesd0-dev
sudo apt-get install git-core gnupg flex bison gperf build-essential
sudo apt-get install zip curl zlib1g-dev gcc-multilib g++-multilib
sudo apt-get install libc6-dev-i386
sudo apt-get install lib32ncurses5-dev x11proto-core-dev libx11-dev
sudo apt-get install lib32z-dev ccache
sudo apt-get install libgl1-mesa-dev libxml2-utils xsltproc unzip m4
sudo apt-get install lib32stdc++6

所需JDK:
https://source.android.com/docs/setup/start/older-versions?hl=zh-cn

JDK

  • Android 7.0 - Android 8.0:
    • Ubuntu:OpenJDK 8
    • Mac OS X:JDK 8u45 或更高版本
  • Android 5.x (Lollipop) - Android 6.0 (Marshmallow):
    • Ubuntu:OpenJDK 7
    • Mac OS X:jdk-7u71-macosx-x64.dmg

nexus 5官方只支持到 android-6.0.1_r77,这里用openJDK7,我给找好了
链接:https://pan.baidu.com/s/1YMCsApMD_jeI5S7wmpJgTg
提取码:aupw
将openJDK7解压到/usr/lib/jvm这个目录下面,比如我的目录/usr/lib/jvm/openjdk-1.7.0_121
打开/etc/profile文件:

1
sudo gedit /etc/profile


在末尾追加下面代码:

1
2
3
4
export JAVA_HOME=/usr/lib/jvm/openjdk-1.7.0_121
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH

修改了/etc/profile文件需要 重启 才能生效,但使用下面命令可以在不重启的情况下在 当前 bash环境生效:
验证

1
source /etc/profile

配置python
Ubuntu 18.04.6已内置python3,安装位置在/usr/bin/python3.6
AOSP 12及以上用python3,只需要建立一个python的链接

1
sudo ln -s /usr/bin/python3 /usr/bin/python

AOSP 12以下,需要安装python2

1
2
sudo apt install python-minimal
python2 --version

python2的安装路径为/usr/bin/python2.7。因为系统中安装了多个python版本,需要使用update-alternatives来切换版本,update-alternatives是Linux上的一个版本管理工具

1
2
sudo update-alternatives --install /usr/bin/python python /usr/bin/python2.7 1
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.6 0

update-alternatives后面按顺序共5个参数,其中:
第一个参数–install表示向update-alternatives注册服务名。
第二个参数/usr/bin/python是注册的最终地址,以后管理就是管理这个软链
第三个参数python为服务名
第四个参数为被管理命令的绝对路径
第五个参数为优先级,数字越大优先级越高
配置完毕后,可以使用python –version查看当前使用的python版本

1
2
3
4
5
6
7
zsk@ubuntu:~$ update-alternatives --display python
python - 自动模式
最佳链接版本为 /usr/bin/python2.7
链接目前指向 /usr/bin/python2.7
链接 python 指向 /usr/bin/python
/usr/bin/python2.7 - 优先级 1
/usr/bin/python3.6 - 优先级 0

后面如果需要切换python版本,执行如下命令

1
2
3
4
5
6
7
8
9
10
zsk@ubuntu:~$ sudo update-alternatives --config python
有 2 个候选项可用于替换 python (提供 /usr/bin/python)。

选择 路径 优先级 状态
------------------------------------------------------------
* 0 /usr/bin/python2.7 1 自动模式
1 /usr/bin/python2.7 1 手动模式
2 /usr/bin/python3.6 0 手动模式

要维持当前值[*]请按<回车键>,或者键入选择的编号:

如果需要安装对应版本的pip
python3安装pip(先切换到python3下)

1
sudo apt install python3-pip

python2安装pip

1
2
3
sudo apt-get install curl  #安装curl下载工具
sudo curl https://bootstrap.pypa.io/pip/2.7/get-pip.py -o get-pip.py #下载安装脚本
sudo python get-pip.py #运行安装脚本

安装repo

上面是谷歌官方的地址,如果下载不了,可以使用下面清华镜像地址

1
curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo > ~/bin/repo

初始化repo和manifest仓库

1
repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-6.0.0_r1 --depth=1

后面记得加–depth=1,这样就会只拉最新的git版本。而不是把所有版本都拉下来。不然会有几百G大
如果提示无法连接到 gerrit.googlesource.com,repo的运行过程中会尝试访问官方的git源更新自己,如果想使用tuna的镜像源进行更新,可以将如下内容复制到你的~/.bashrc里

1
export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo/'

同步

1
repo sync

下载驱动

需要下载对应的驱动
https://developers.google.com/android/drivers#hammerheadm4b30z
适用于 Android 6.0.0 (MRA58K) 的 Nexus 5 (GSM/LTE) 二进制文件

硬件组件 公司 下载 SHA-256 校验和
NFC、蓝牙、Wi-Fi Broadcom Link 4009c98b916f679a96cc9d9459b811498e198c478b656652537fd7d705d28acc
摄像头、传感器、音频 LG Link 42bca1a416903020f7e90bf1cc8651fa6b045b6137291dc21bfe5cf3626424ea
图形、GSM、摄像头、GPS、传感器、媒体、DSP、USB Qualcomm Link 489df79f864abdc4947f39f45923b7999589db49a40dcd3c180d8cd924b73ae3
1
2
3
wget https://dl.google.com/dl/android/aosp/broadcom-hammerhead-mra58k-bed5b700.tgz
wget https://dl.google.com/dl/android/aosp/lge-hammerhead-mra58k-25d00e3d.tgz
wget https://dl.google.com/dl/android/aosp/qcom-hammerhead-mra58k-ff98ab07.tgz

下载后解压得到三个shell脚本文件,放到源码的根目录中
依次执行这三个脚本文件,这里要注意,三个脚本文件的作用是生成驱动文件,但是在执行操作前,它会让你阅读相关协议,你必须一直按enter键一行一行往下读,更不能一键摁到底,因为程序在最后会让你输入“I ACCEPT”,如果你一键摁到底,也就是说最后一步也摁enter键的话它就会执行默认操作,即不接受此协议,那生成驱动文件的操作就不会执行。

开始编译

修改 源码目录/art/build/Android.common_build.mk 文件,定位到75行,将下面的代码:

1
ifneq ($(WITHOUT_HOST_CLANG),true)改为ifeq ($(WITHOUT_HOST_CLANG),false) //对应问题3

如果之前编译过,删除所有以前编译操作的已有输出

1
2
make clobber
make clean
  1. 在 .bashrc文件末尾添加:export USE_CCACHE = 1, 只要编译过aosp,执行过这一句代码,以后再编译aosp,就不用再执行了
    1
    echo export USE_CCACHE=1 >> ~/.bashrc 
  2. 为了提高编译效率,设置编译器高速缓存
    1
    prebuilts/misc/linux-x86/ccache/ccache -M 100G
  3. 初始化编译环境 source
    1
    source build/envsetup.sh
  4. 运行lunch命令选择编译目标
变体 说明
eng
    这是默认变种
  • 安装带有 eng 或 debug 标记的模块。
  • 除了带有标记的模块之外,还会根据产品定义文件安装相应模块。
  • ro.secure=0
  • ro.debuggable=1
  • ro.kernel.android.checkjni=1
  • adb 默认处于启用状态。
user
    打算作为最终发布版本的变体。
  • 安装带有 user 标记的模块。
  • 除了带有标记的模块之外,还会根据产品定义文件安装相应模块。
  • ro.secure=1
  • ro.debuggable=0
  • adb 默认处于停用状态。
userdebug
    与 user 相同,但以下几点除外:
  • 还会安装带有 debug 标记的模块。
  • ro.debuggable=1
  • adb 默认处于启用状态。

https://source.android.com/docs/setup/build/running#selecting-device-build

- - -
Nexus 6P angler aosp_angler-userdebug
Nexus 5X bullhead aosp_bullhead-userdebug
Nexus 6 shamu aosp_shamu-userdebug
Nexus Player fugu aosp_fugu-userdebug
Nexus 9 volantis (flounder) aosp_flounder-userdebug
Nexus 5 (GSM/LTE) hammerhead aosp_hammerhead-userdebug
1
2
lunch
// 1. aosp_arm-eng不会生成我们需要的5个文件,17. aosp_hammerhead-userdebug可以
1
export LC_ALL=C //对应问题2

查看CPU核心数:

1
cat /proc/cpuinfo | grep processor

花了两个半小时编译完成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
make_ext4fs -s -T -1 -S out/target/product/hammerhead/root/file_contexts -L system -l 1073741824 -a system out/target/product/hammerhead/obj/PACKAGING/systemimage_intermediates/system.img out/target/product/hammerhead/system out/target/product/hammerhead/system
Creating filesystem with parameters:
Size: 1073741824
Block size: 4096
Blocks per group: 32768
Inodes per group: 8192
Inode size: 256
Journal blocks: 4096
Label: system
Blocks: 262144
Block groups: 8
Reserved block group size: 63
Created filesystem with 1718/65536 inodes and 105291/262144 blocks
Install system fs image: out/target/product/hammerhead/system.img
out/target/product/hammerhead/system.img+out/target/product/hammerhead/obj/PACKAGING/recovery_patch_intermediates/recovery_from_boot.p maxsize=1096212480 blocksize=135168 total=416118221 reserve=11083776

#### make completed successfully (02:27:25 (hh:mm:ss)) ####

编译后输出的文件都放在了源码根目录下的 /out/target/product/hammerhead/
可以在该目录下面找到boot.img、system.img、recovery.img、cache.img、userdata.img五个镜像文件,这表示编译成功,这也是刷机需要的文件。

问题1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Export includes file: frameworks/base/tools/aidl/Android.mk -- out/host/linux-x86/obj/EXECUTABLES/aidl_intermediates/export_includes
build/core/binary.mk:609: recipe for target 'out/host/linux-x86/obj/EXECUTABLES/aidl_intermediates/aidl_language_y.cpp' failed
make: *** [out/host/linux-x86/obj/EXECUTABLES/aidl_intermediates/aidl_language_y.cpp] Error 127
make: *** 正在等待未完成的任务....
Lex: aidl <= frameworks/base/tools/aidl/aidl_language_l.l
Notice file: frameworks/base/tools/aidl/NOTICE -- out/host/linux-x86/obj/NOTICE_FILES/src//bin/aidl.txt
flex-2.5.39: loadlocale.c:130:_nl_intern_locale_data: ?? 'cnt < (sizeof (_nl_value_type_LC_TIME) / sizeof (_nl_value_type_LC_TIME[0]))' ???
build/core/binary.mk:646: recipe for target 'out/host/linux-x86/obj/EXECUTABLES/aidl_intermediates/aidl_language_l.cpp' failed
make: *** [out/host/linux-x86/obj/EXECUTABLES/aidl_intermediates/aidl_language_l.cpp] 已放弃 (core dumped)
注: 某些输入文件使用了未经检查或不安全的操作。
注: 有关详细信息, 请使用 -Xlint:unchecked 重新编译。
注: 某些输入文件使用了未经检查或不安全的操作。
注: 有关详细信息, 请使用 -Xlint:unchecked 重新编译。

make failed to build some targets (02:10 (mm:ss))

执行: make -j8 update-api

问题2:

1
2
3
4
Lex: aidl <= frameworks/base/tools/aidl/aidl_language_l.l
flex-2.5.39: loadlocale.c:130:_nl_intern_locale_data: ?? 'cnt < (sizeof (_nl_value_type_LC_TIME) / sizeof (_nl_value_type_LC_TIME[0]))' ???
build/core/binary.mk:646: recipe for target 'out/host/linux-x86/obj/EXECUTABLES/aidl_intermediates/aidl_language_l.cpp' failed
make: *** [out/host/linux-x86/obj/EXECUTABLES/aidl_intermediates/aidl_language_l.cpp] 已放弃 (core dumped)

编译前:export LC_ALL=C

问题3:

1
2
3
clang: error: linker command failed with exit code 1 (use -v to see invocation)
build/core/host_shared_library_internal.mk:51: recipe for target 'out/host/linux-x86/obj/lib/libart.so' failed
make: *** [out/host/linux-x86/obj/lib/libart.so] Error 1

修改 源码目录/art/build/Android.common_build.mk 文件,定位到75行,将下面的代码:
ifneq ($(WITHOUT_HOST_CLANG),true)改为ifeq ($(WITHOUT_HOST_CLANG),false)

将镜像刷入Nexus5

在源码根目录下输入以下命令:

1
adb reboot bootloader

随后手机就会进入recovery模式。
执行 fastboot oem unlock 解锁bootloader,如果已经解锁,启动界面的google图标下有一把打开的锁。
开始刷机:

1
sudo fastboot -w flashall

如果遇到 error: ANDROID_PRODUCT_OUT not set
执行 $ export ANDROID_PRODUCT_OUT=/home/zsk/bin/out/target/product/hammerhead
或者进到 /home/zsk/bin/out/target/product/hammerhead 目录下,执行刷入5个镜像文件

1
2
3
4
5
6
sudo fastboot flash recovery recovery.img
sudo fastboot flash boot boot.img
sudo fastboot flash system system.img
sudo fastboot flash cache cache.img
sudo fastboot flash userdata userdata.img
sudo fastboot reboot
 评论
评论插件加载失败
正在加载评论插件
由 Hexo 驱动 & 主题 Keep
访客数 访问量