目录
一、安装环境
二、下载源码
1.下载repo
2.初始化repo
3.同步源代码
关于驱动
三、编译源码
四、导入源码到AS
五、刷入真机
六、修改源码
总结:
3.同步源代码
关于驱动
三、编译源码
四、导入源码到AS
五、刷入真机
总结:
1.Ubuntu16.04 内存6G 硬盘200G 源码大概在十几个G,不用aosp-laster.tar的方法去同步代码的话,硬盘空间足够用了
2.android6.0.1_r1源码下载
3.jdk7.0安装
环境配置可参考https://blog.csdn.net/pengtgimust/article/details/90758507
执行命令:
mkdir ~/bin
加入可执行路径
PATH=~/bin:$PATH
a.国内下载地址(推荐)
curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo -o repo
b.科学下载地址
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
repo是放在新建的~/bin/目录下的
c.添加权限
chmod a+x ~/bin/repo
repo init的过程主要是下载一堆manifest配置文件,项目的remote url,项目包含的所有git仓库的地址,项目的版本等等。
a.新建源码文件夹android6.0.1_r1,源码目录名随便起
mkdir android6.0.1_r1
cd android6.0.1_r1
b.初始化该目录repo
repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-6.0.1_r1
指定特定版本的Android源代码,但是在后面同步的时候下载了非常多代码,几乎把所有版本分支都同步下来,后面用一下命令只同步当前的版本的源代码
repo init --depth=1 -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-6.0.1_r1
--depth=1
表示只下载最近版本的代码,只保留最近的commit版本。以节省磁盘空间.
如果出错提示timeout的可以尝试下面命令:
repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-6.0.1_r1 --repo-url=https://mirrors.tuna.tsinghua.edu.cn/git/git-repo
一般用:
repo sync -c -f --no-tags --no-clone-bundle -j`nproc`
-j
参数指定同时运行多少个job,nproc
是当前计算机的处理单元个数,比如2核,最大就是4
-c 或者--current-branch表示只拉取当前分支代码,坑爹啊,我在init指定了分支,同步的时候,却给我拉了整个分支。
--no-tags 不拉取tags,tag虽然不大,但架不住多
--no-clone-bundle 不使用clone.bundle,clone.bundle是git bundle一样的打包文件,使用bundle文件可以做cdn下载的分流,cdn听上去不错,但是如果cdn到google的服务器,或者clone.bundle本来就占空间,不是很划算,所以不使用clone.bundle
-f 如果sync失败,继续同步(想想当年LZ写了一个while循环解决同步失败终止问题的)
--force-sync 如果文件目录有差异,强制覆盖掉
至此等待一个小时(看网速)你应该可以将对应的源码下下来了,如图:
接下来还有一个vendor目录源码中是没有的,就是一些驱动,如果没有,编译出来的只能在模拟器中运行,其实就是三个bash文件,去这里下载这三个文件,放在源码根目录,分别运行这三个bash文件,按空格阅读完条款,按提示输入I ACCEPT就行,运行完就会出现vendor目录.
上面的网站是有关各种型号的真机和android源码build版本的二进制驱动脚本,只要下载相对应的脚本,按上面的方法运行之后就会在当前文件下生成vendor目录,但是我的是nexus 5x,编译的是android6.0.1r1,网站上关于nexus5x的驱动只有7.0-8.0的驱动,所以没有可用的驱动怎么办呢?经过查找可以用官方的对应版本的工厂镜像,里面含有驱动镜像,由他生成自己的驱动.
去这里下载对应手机型号,对应android build版本的工厂镜像:
https://developers.google.com/android/images#bullhead
然后下载这个工程:
git clone [email protected]:anestisb/android-prepare-vendor.git
接着进入这个工程,执行下面的命令:
sudo ./execute-all.sh -d bullhead -b mmb29k -o $(pwd) -i ~/nexus5x/bullhead-mmb29k-factory-c3b91ce3.zip -k
解释一下参数:
-d 后面是设备代号,nexus6p是angler
-b build id,分支编译时的代号
-o 输出目录
-i 下载好的谷歌工厂镜像路径
-k (保留所有提取的工厂映像和修复的数据,默认false)
注意,这里要用root权限,不然会报错.
完成后会在图中路径下生成相对应手机型号bullhead,build版本mmb29k的vendor目录,将其先转换所属者,变成当前用户,然后复制到源码根目录
sudo chown -R username:uesername ./vender #usernamae为用户名
cp vendor ~/android6.0.1-r1/
之后开始编译源码.
执行以下命令:
export USE_CCACHE=1
prebuilts/misc/linux-x86/ccache/ccache -M 50G
source build/envsetup.sh
指定编译目标:
yrl@Ubuntu1604:~/android6.0.1—r1$ lunch
------------------------------
You're building on Linux
Lunch menu... pick a combo:
1. aosp_arm-eng
2. aosp_arm64-eng
3. aosp_mips-eng
4. aosp_mips64-eng
5. aosp_x86-eng
6. aosp_x86_64-eng
7. aosp_deb-userdebug
8. aosp_flo-userdebug
9. full_fugu-userdebug
10. aosp_fugu-userdebug
11. mini_emulator_arm64-userdebug
12. m_e_arm-userdebug
13. mini_emulator_mips-userdebug
14. mini_emulator_x86_64-userdebug
15. mini_emulator_x86-userdebug
16. aosp_flounder-userdebug
17. aosp_angler-userdebug
18. aosp_bullhead-userdebug
19. aosp_hammerhead-userdebug
20. aosp_hammerhead_fp-userdebug
21. aosp_shamu-userdebug
Which would you like? [aosp_arm-eng] 18
aosp_bullhead-userdebug,解释一下,最基础的在模拟器中运行选1,如果要往设备上装,bullhead是Nexus 5X的代号aosp_bullhead-userdebug表示对应设备是Nexus5X,每个设备对应的代号如下:
userdebug 是编译类型,含义如下:
user 用于正式产品
userdebug 和user类似,但是有root权限,并且可以调试,主要用于调试
eng 开发用的选项,配有额外的调试工具。
如果编译后只在模拟器上运行,则lunch时选择:1
这里我们的目标是要编译后刷入nexus 5x,所以 lunch 时选择:18
如果你不知道lunch该选哪一个,请参考下面的链接,根据第三列选择编译选项:
https://source.android.com/source/running.html
执行编译:
make -j4
先前编译失败的要先清理掉:make clean
出现这个就说明编译成功.在对应的out/target/product/bullhead下会有三个img文件就说明编译成功.
编译过程中遇到的一些问题:
问题1: pp frameworks/base/tools/aidl/aidl_language_y.y 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] 断开的管道 make: *** 正在等待未完成的任务.... Lex: aidl <= frameworks/base/tools/aidl/aidl_language_l.l frameworks/base/tools/aidl/aidl_language_l.l:55: warning, 无法匹配规则 flex-2.5.39:严重内部错误,exec of /usr/bin/m4 failed 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] Error 1 make: *** Deleting file 'out/host/linux-x86/obj/EXECUTABLES/aidl_intermediates/aidl_language_l.cpp' 注: 某些输入文件使用或覆盖了已过时的 API。 注: 有关详细信息, 请使用 -Xlint:deprecation 重新编译。 注: 某些输入文件使用了未经检查或不安全的操作。 注: 有关详细信息, 请使用 -Xlint:unchecked 重新编译。 解决办法:
1 更换软件源为阿里云
为了更快的安装软件,我们需要更换软件源为国内的软件源,这里推荐使用Ubuntu官方指定的国内软件源阿里云,具体方法是:
sudo gedit /etc/apt/sources.list
在文件最前面加入下面代码:
deb http://mirrors.aliyun.com/ubuntu/ quantal main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ quantal-security main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ quantal-updates main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ quantal-proposed main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ quantal-backports main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ quantal main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ quantal-security main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ quantal-updates main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ quantal-proposed main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ quantal-backports main restricted universe multiverse
2 安装依赖
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
Ubuntu 16.04请务必使用上面的依赖,Ubuntu 16.04需要的依赖和Ubuntu 14.04所需要的依赖是不同的
问题2:
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 make: *** 正在等待未完成的任务.... 据说这个错误只在ubuntu16.04 上出现
修改源码
修改
75 #ifneq ($(WITHOUT_HOST_CLANG),true)mydroid/art/build/Android.common_build.mk
文件,定位到75行,注释掉75-78:
76 # By default, host builds use clang for better warnings.
77 # ART_HOST_CLANG := true
78 #endif
或者将两个true改为false
如果不修改这里,会遇到一个比较棘手的编译错误,修改的目的是把CLANG这个编译选项关掉,详见后面的编译记录,百度搜狗都无解,这个错误只会在Ubuntu16.04上遇到,Ubuntu14.04则不存在这个问题
问题3:
把源码换到了全英文的路径下面
问题4:
后面又出现了无法fork,无法分配内存的错误,
难道是内存太小了?make -j8开的线程太多了?尝试增大虚拟机的内存由3G到4G,结果最后还是内存不足,有增大到6G,将make -j8调成make -j2,虽然速度慢,但是最后还是成功的编译了,虽然中间出现了许多warning,虚拟机性能比较差,足足跑了七个小时,开的线程多的话会大大加快编译速度,要看机器的cpu的核数,根据自己而定.
问题5:
删掉$ HOME下的所有.jack *文件夹/设置
终于编译成功!
模拟器运行,编译成功后,不关终端的情况下直接运行:emulator
如果关闭了终端:
source build/envsetup.sh
lunch [选择刚刚设置的目标版本]
emulator
生成AS的项目配置文件
如果你整编过源码,查看out/host/linux-x86/framework/idegen.jar是否存在,如果不存在,进入源码根目录执行如下的命令:
|
如果没整编过源码,可以直接执行如下命令单编idegen模块:
|
关于Android系统源码的编译可以查看Android AOSP基础(三)Android系统源码的整编和单编这篇文章。
idegen模块编译成功后,会在 out/host/linux-x86/framework目录下生成idegen.jar,执行如下命令:
|
这时会在源码根目录生成android.iml 和 android.ipr 两个文件,这两个文件一般是只读模式,这里建议改成可读可写,否则,在更改一些项目配置的时候可能会出现无法保存的情况。
|
配置AS的项目配置文件
由于要将所有源码导入AS会导致第一次加载很慢,可以在android.iml中修改excludeFolder配置,将不需要看的源码排除掉。等源码项目加载完成后,还可以通过AS对Exclude的Module进行调整。如果你的电脑的性能很好,可以不用进行配置。
在android.iml中搜索excludeFolder,在下面加入这些配置。
|
导入系统源代码到AS中
在AS安装目录的bin目录下,打开studio64.vmoptions文件,根据自己电脑的实际情况进行设置,这里修改为如下数值:
|
如果你是在VirtualBox中下载的系统源码,那么将VirtualBox中的系统源码拷贝到共享文件夹中,这样源码就会自动到Windows或者Mac上,如果你不知道如何设置VirtualBox共享文件夹,可以查看Android AOSP基础(一)VirtualBox 安装 Ubuntu这篇文章。
通过AS的Open an existing Android Studio project选项选择android.ipr 就可以导入源码,这里我用了大概7分钟就导入完毕。导入后工程目录切换为Project选项就可以查看源码。
首先检测ubuntu下面fastboot可不可以用,在SDK/platform-tools/将这个路径加入ubuntu环境变量
sudo gedit /etc/profile
在里面添加:
export PATH=/home/***/***/Sdk/platform-tools:$PATH
之后执行:
source /etc/profile
这样下面的工具就可以用了,比如adb fastboot等
让手机进入fastboot模式,可以手动(音量减+电源键),或输入adb命令
adb reboot bootloader
运行查看fastboot是否能检测到设备:
fastboot devices
结果显示:
no permissions (user in plugdev group; are your udev rules wrong?
没有权限?经过查找文章,最终找到了解决方法:
很多都说是没有权限,说sudo fastboot devices就可以了,结果根本不行,还有的说是执行
lsusb
将自己的设备ID加入到/etc/udev/rules.d/11-android.rules(.rules文件可以新建)
SUBSYSTEMS=="usb", ATTRS{idVendor}=="18d1", MODE="0660"
然后赋予其权限,执行
sudo service udev restart
之后再查看fastboot devices应该就可以了,但是对我还是不行,最后找到了github上的文章
按照这个方法安装之后,再查看发现已经可以了,其实这个仓库就一个文件
51-android.rules这个规则文件,里面把所有的idVendor写进去了,所以不管你的idVendor是啥都能检测到
之后就是刷系统了
将编译好的源码路径写入环境变量
sudo gedit /etc/profile
添加到文件末:
export ANDROID_PRODUCT_OUT="/home/yrl/android6.0.1-r1/out/target/product/bullhead"
再执行:
source /etc/profile
注意:当前不会立即生效,需要注销当前用户重新进入才可生效!
之后就是刷入系统了,执行
fastboot -w flashall
这里成功不成功关键就在于你编译的时候lunch选择对不对,第一次我没有选对就提示了
checking product failed!
device is “bullhead”
Update require ‘ ’
..........
所以要选对lunch,如果到这里你就需要重新选择lunch的版本,重新编译,当然想要安装到真机上需要按照上面的驱动步骤下载相关驱动(源码下的vendor目录)
又是经过漫长的等待,再编译一次,这里我用的是Mac笔记本,内存12G,编译环境是ubuntu16.04虚拟机,内存6G,2核CPU,经过漫长的6个多小时,终于编译成功,中间会出现一些错误,无法分配内存,是之前的内存4G太小了.
先说一下刷机的几个步骤:
首先进入fastloader模式:
adb reboot bootloader
进入后手机会显示bootloader解锁状态,如果是locked就需要解锁了
解锁:
对于新款设备(2015 年及之后发布的设备):
fastboot flashing unlock
对于老款设备(2014 年及之前发布的设备):
fastboot oem unlock
在屏幕上确认解锁。
注意:在 Nexus 10 上,解锁引导加载程序后,内部存储空间仍将保持未格式化状态。您可以依次使用 fastboot format cache 和 fastboot format userdata 来格式化设备。
刷完机记得上锁,其实上不上锁也无所谓,了解一下
重新锁定引导加载程序
要重新锁定引导加载程序,请执行以下命令:
对于新款设备(2015 年及之后发布的设备):
fastboot flashing lock
对于老款设备(2014 年及之前发布的设备):
fastboot oem lock
解完锁,之后就是刷机了:
正常的顺序:
1.刷机命令,他会将目录下所有的img镜像刷入
fastboot -w flashall
第一次是由于源码编译的版本不对(lunch选择的不对),停止了,见上面的错误信息,经过编译后第二步又出错:
yrl@yrl-virtual-machine:~/android6.0.1-r1$ fastboot -w flashall
--------------------------------------------
Bootloader Version...: BHZ10r
Baseband Version.....: M8994F-2.6.32.1.13
Serial Number........: 01be7e27a275ce93
--------------------------------------------
Checking 'product' OKAY [ 0.019s]
Checking 'version-bootloader' FAILED
Device version-bootloader is 'BHZ10r'.
Update requires 'BHZ10k'.
fastboot: error: requirements not met!
提示bootloader版本不一致,查了半天没结果,最后在编译出来的bullhead文件夹下的android-info.txt里面找到了这个定义的文件:
require board=bullhead
require version-bootloader=BHZ10k
require version-baseband=M8994F-2.6.30.0.68
尝试将其改为和设备一致BHZ10r,再次刷入,又有问题:
--------------------------------------------
Bootloader Version...: BHZ10r
Baseband Version.....: M8994F-2.6.32.1.13
Serial Number........: 01be7e27a275ce93
--------------------------------------------
Checking 'product' OKAY [ 0.017s]
Checking 'version-bootloader' OKAY [ 0.032s]
Checking 'version-baseband' FAILED
Device version-baseband is 'M8994F-2.6.32.1.13'.
Update requires 'M8994F-2.6.30.0.68'.
fastboot: error: requirements not met!
又是版本不对,再次修改和设备版本一致,再次刷入,猜想这样修改会不会导致刷入失败?上面还有一个叫Serial Number........: 01be7e27a275ce93的不是md5校验吗?修改了肯定不对啊,不管了,舍不得孩子套不住狼,可怜我刚买的nexus5x,刷成砖就凉了,再次刷入.果然没有在提示错误:
--------------------------------------------
Bootloader Version...: BHZ10r
Baseband Version.....: M8994F-2.6.32.1.13
Serial Number........: 01be7e27a275ce93
--------------------------------------------
Checking 'product' OKAY [ 0.050s]
Checking 'version-bootloader' OKAY [ 0.020s]
Checking 'version-baseband' OKAY [ 0.020s]
Sending 'boot' (11461 KB) OKAY [ 15.432s]
Writing 'boot' OKAY [ 0.117s]
Sending 'recovery' (12517 KB) OKAY [ 8.631s]
Writing 'recovery' OKAY [ 0.141s]
Sending sparse 'system' 1/2 (524262 KB) OKAY [100.476s]
Writing 'system' OKAY [ 6.510s]
Sending sparse 'system' 2/2 (296569 KB) OKAY [ 45.088s]
这个过程一致胆战心惊,害怕出错,结果.........说曹操曹操就到,果然出错了:
Sending sparse 'system' 2/2 (296569 KB) OKAY [ 45.088s]
Writing 'system' OKAY [ 3.674s]
Sending 'vendor' (190689 KB) OKAY [ 18.482s]
Writing 'vendor' OKAY [ 2.453s]
Erasing 'userdata' OKAY [ 1.038s]
mke2fs 1.45.4 (23-Sep-2019)
Creating filesystem with 6661115 4k blocks and 1667904 inodes
Filesystem UUID: 57a4416a-80cb-4eb1-96b2-758de1da6238
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000
Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done
Sending 'userdata' (4272 KB) OKAY [ 0.646s]
Writing 'userdata' FAILED (remote: 'Bogus size sparse and chunk header')
在刷入userdata的时候提示错误,看提示有可能是快太大了,受不了?哈哈,经过查找原因,有人说哪个地方错了就把错误的地方一个一个重新刷入,试一试呗,都这样了:
fastboot erase userdata
fastboot flash userdata userdata.img
fastboot erase cache
fastboot flash cache cache.img
yrl@yrl-virtual-machine:~/android6.0.1-r1/out/target/product/bullhead$ fastboot erase userdata
******** Did you mean to fastboot format this ext4 partition?
Erasing 'userdata' OKAY [ 0.467s]
Finished. Total time: 0.497s
yrl@yrl-virtual-machine:~/android6.0.1-r1/out/target/product/bullhead$ fastboot flash userdata userdata.img
Sending 'userdata' (137774 KB) OKAY [ 14.647s]
Writing 'userdata' OKAY [ 1.340s]
Finished. Total time: 16.035s
yrl@yrl-virtual-machine:~/android6.0.1-r1/out/target/product/bullhead$ fastboot erase cache
******** Did you mean to fastboot format this ext4 partition?
Erasing 'cache' OKAY [ 0.071s]
Finished. Total time: 0.101s
yrl@yrl-virtual-machine:~/android6.0.1-r1/out/target/product/bullhead$ fastboot flash cache cache.img
Sending 'cache' (5688 KB) OKAY [ 0.643s]
Writing 'cache' OKAY [ 0.071s]
Finished. Total time: 1.170s
yrl@yrl-virtual-machine:~/android6.0.1-r1/out/target/product/bullhead$ fastboot reboot
Rebooting OKAY [ 0.009s]
Finished. Total time: 0.297s
最后fastboot reboot,重启,激动人心的时刻到了,是否能成功进入系统呢?经过一小段很长的等待,内心焦虑,终于...........进入系统了,而且功能还都正常,就是界面没有原来的好看了,是最原始的谷歌系统.来张帅图:
顺便说一下调试源码的framework层和用AS调试app过程一样,先启动DDMS进行端口转发,然后启动AS进行远程连接,就可以像调试app一样调试源码。
修改源码在AS终究可以实现,AS还会有一些提示,就和平常开发一样会有一些错误提示,这对修改源码来说已经很有帮助了。之后就是通过调试找到想要修改的地方就行。
以下是修改源码过程出现的问题:
1.修改完源码后mmm单独编译某个模块,出现依赖“xxxx”needed by “xxxxxx”,解决方法目前是整编译,后面看看有没有单独编译模块的方法。就算单模块编译成功后,make snod 生成新的system.img镜像刷入真机导致开机卡logo,需要整编译之后就行安装,后面还要看看单独编译生成的system.img怎么成功刷入真机。
2.修改某一个api后,编译会报一些类似于说您已更新某某API,请检查checktext或让你更新api
执行 make update-api
3.编译成功后再次修改源码,没有make clean(为了提高变异速度就没有make clean),结果出现以下找不到符号等错误
为什么之前可以用,修改完之后AS可以找到相应的包,而编译的时候却报错呢?想了一下可能是整编的时候符号链接到了,但是你再次修改,import的包没有被链接进去,导致之前的可以用,而你新添加的却找不到对应包名,所以还需要全编译一遍。
注:只要修改代码不涉及导入包名,类内部的代码随便修改,只要涉及新的包名的导入必须把相关的模块(有依赖的模块)重新编译,简单的办法就是全编译一遍。
下面附上我参考的链接:
android编译系统源码 参考了userdata刷机失败的问题
nexus 5 刷机 参考了刷机步骤
Android 6.0源码编译及烧录到真机过程记录 参考编译过程
Ubuntu16.04编译Android 6.0系统源码过程简要记录总结 参考一些依赖
这次从下载源码,编译,模拟器运行,导入AS查看源码,调试,到烧录到真机,可谓过程艰辛,不过收获到了很多不知道的东西,最后成功安装到了真机,还真是很开心的呢,在一步就是调试源码,研究修改源码了,再接再厉吧!