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
 评论