速通AOSP,成功编译调试Android源码

e7b8e2db3773e2638efcf9fe64d70faa.jpeg

/   今日科技快讯   /

近日据不少网友反馈,爱奇艺App开始对投屏功能作出限制,之前黄金VIP会员支持最高4K清晰度投屏,现在只能选最低的480P清晰度,要想进行4K投屏必须购买白金VIP会员。不少网友表示,480P清晰度太低,几乎无法观看。

/   作者简介   /

大家好,今天是年前的最后一篇文章,下周我就要休假回家过年了,公众号也会暂时停更。这里提前祝大家新年快乐,我们年后再见。

本篇文章转自coder_pig的博客,文章主要分享了系统源码快速上手的方案,相信会对大家有所帮助!

原文地址:

https://juejin.cn/post/7038543675109933070

/   前言   /

早些年刚毕业,在老东家参与开发Launcher的时候就接触过AOSP,那时的早教平板还是基于Android 4.4的源码进行定制的。后续跑路了,就一直在应用层摸鱼,最近一时兴起,想复习一些基础姿势,所以本文来了~

Tips:本文并非笔者亲身实践,是借鉴了参考文献处几位大佬的文章总结得出。aosp源码的下载费时,笔者没有编译扫写源码的需求,只是解BUG或了解底层机制时看看源码,SDK自带的android.jar和一些在线源码站点已经够用。环境搭建流程基本是一致的,遇到问题善用搜索引擎~

/   名词   /

① AOSP

中文官网:https://source.android.google.cn/

Android Open Source Package,安卓系统开源源码包,Android移动终端平台 (高通、MTK等) 先基于原生的Android代码进行更改,形成自己的平台代码,其他 手机厂商 再根据平台代码提供自己的移动端解决方案 (系统定制)。

aosp源码编译后会生成一系列的产物(out目录下):

  • /out/host → Android开发工具相关的产物,包含各种SDK工具,如adb、dex2oat、aapt等;

  • /out/target/common → 一些通用的编译产物,包含Java应用代码和Java库;

  • /out/target/product/[product_name] → 针对特定设备的编译产物,以及平台相关C/C++代码与二进制文件(如system.img、ramdisk.img、userdata.img、boot.img等);

我们平时在AS里看到的源码库 android.jar 是打包后的 classes.jar,详细路径:

out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar。以前在一些场景,需要使用SDK中隐藏的API (@hide注解),一种解法就是用aosp编译生成的classes.jar替换原生sdk中的android.jar。具体导入示例可见:《Android Studio 3.5导入AOSP编译的classes.jar》(https://www.jianshu.com/p/d5c3e191865e)

② Gerrit

Android使用Git作为代码管理工具,开发了 Gerrit 进行 代码审核,以便更好地对代码进行集中式管理。实际上就是一个 Git服务器,它为在其服务器上托管的Git仓库提供了一系列 权限控制,以及一个用作Code Review 的 Web页面。

③ Repo

Repo命令行工具,用Python对Git命令进行封装,简化对多个Git库的集中式管理。

/   Repo工作流   /

d1bfccf4312ba7cf4ca36917c1943f2a.jpeg

简要描述下关键命令:

  • repo init → 在当前目录下初始化Repo,生成 .repo 目录,其中会包含一个 manifest.xml 文件,列出每个project的克隆方式 (版本库地址、和工作区地址的对应关系、分支对应关系等);

  • repo sync → 同步所有project到本地工作区;

  • repo start → 创建并切换到本地工作分支;

  • Git相关命令 → 本地修改某些Project的代码,常规提交;

  • repo upload → 将代码修改发布到审核服务器;

  • repo prune → 功能开发完,合并后,安全移除过时主题分支;

更详细内容可参见:《源代码控制工作流程》

https://source.android.google.cn/setup/create/coding-tasks?hl=zh-cn)

/   系统准备   /

只是单纯下载源码,啥系统都可以,但如果还想进行编译的话,需要 Linux 或 Mac OS 系统。

Windows想编译的话,可以通过 虚拟机 安装上述系统间接达成,常规方式:Docker 或 VirtualBox。后者安装示例可见:《Android AOSP基础(一)VirtualBox 安装 Ubuntu》

http://liuwangshu.cn/framework/aosp/1-install-ubuntu.html)

更详细内容可参见:《搭建构建环境》(https://source.android.com/setup/build/initializing#using-a-separate-output-directory)

/   源码下载   /

走一波下述命令~

# ① 安装Git、Curl、Python,有些系统自带~
sudp apt-get install git
sudo apt-get install curl
sudo apt-get install python

# ② 创建bin,并添加到PATH中
mkdir ~/bin
PATH=~/bin:$PATH

# ③ 下载Repo工具,并设置为可执行
# Tips:国外源可能有问题,可以替换为国内镜像,比如:https://mirrors.tuna.tsinghua.edu.cn/git/git-repo
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo

# ④ 创建工作文件目录 (存源码)
mkdir aosp
cd aosp

# Tips:Repo在运行过程中会尝试访问官方Git源更新自己,如果想用tuna镜像更新,可复制
# 下述内容到~/.bashrc中
export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo/'

# ⑤ Git设置身份信息(名字、邮箱)
git config --global user.name  "User Name"
git config --global user.email "user@example.com"

# ⑥ 初始化仓库 (同样支持替换镜像源)
repo init -u https://android.googlesource.com/platform/manifest

# 也支持指定分支,可选值查看:https://source.android.com/source/build-numbers#source-code-tags-and-builds
repo init -u https://android.googlesource.com/platform/manifest -b android-9.0.0_r8 

# ⑦ 同步代码 (拉取aosp源码到工作目录,一般要几个小时)
repo sync

# Tips:下载过程可能出现某些project找不到,可能是镜像问题,也可能是网的问题,
# 试试可以单独同步该项目,支持-jN参数,-j4如:
repo sync -c platform/frameworks/layoutlib

# 附:aosp不包含内核代码,有需要可以单独下载,版本有很多,如:
# common → 通用linux内核、goldfish → Android模拟器内核、msm → 高通MSM芯片
mkdir kernel
cd kernel
git clone https://aosp.tuna.tsinghua.edu.cn/kernel/goldfish.git
cd goldfish
# 可以查看有哪些内核版本分支可以下载
git branch -a
# 下载对应版本内核代码
git checkout remotes/origin/android-goldfish-3.4

更详细内容可参见:《下载源代码》(https://source.android.com/setup/build/downloading)

另外,国外镜像难免不稳定,也可以直接用 清华镜像(https://mirrors.tuna.tsinghua.edu.cn/help/AOSP/),首次同步容易失败,建议先用迅雷等软件直接下载初始化包 aosp-latest.tar (https://mirrors.tuna.tsinghua.edu.cn/aosp-monthly/aosp-latest.tar)进行初始化,然后再同步。

/   编译   /

同样,先是一些名词的解释:

  • Makefile → Android平台编译系统,用Makefile写出来的一个独立项目,定义了编译规则,实现自动化编译,将分散在数百个Git库中的代码整合起来,统一编译,而且把产物分门别类地输出到一个目录,打包成手机ROM,还可以生成应用开发时使用的SDK、NDK等。

  • Android.mk → 定义一个模块的必要参数,使模块随着平台编译,简单点说就是告诉系统以什么规则编译源代码,并生成对应目标文件;

  • kati → Google专门为Android研发的小工具,基于Golang和C++,作用是:将Android中的Makefile转换为Ninja文件

  • Ninja → 致力于速度的小型编译系统,把Makefile看做高级语言,那它就是汇编,文件后缀为.ninja;

  • Android.bp → 替换Android.mk的配置文件;

  • Blueprint → 解析Android.bp文件翻译成Ninja语法文件;

  • Soong → Makefile编译系统的替代品,负责解析Android.bp文件,并将之转换为Ninja文件;

关系描述:

  • Android工程越来越大,Makefile编译耗时越来越长,Android 7.0引入速度和并行效率更佳的Ninja来编译系统;

  • Soong 借助 Blueprint定义的Android.bp语法,完成Android.bp的解析,最终转换成Ninja文件;

  • Makefile文件(.make或.mk)通过kati转换为Ninja文件(.ninja);

  • Makefile是设计来给开发编写的,而Ninja则是设计给其他程序生成的,可类比做高级语言和汇编语言;

① 编译环境准备

# ① 安装jdk 8
sudo apt-get update
sudo apt-get install openjdk-8-jdk

# Tips:使用ubuntu 14+,还需要安装下述依赖包
sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip

② 源码整编

# ① 初始化环境
source build/envsetup.sh

# ② 删除out与中间文件,clean会删除本次设置生成的、clobber会删除所有配置生成的
make clobber

# ③ 选择编译目标,下述命令会进入菜单,选择相应的版本,输入序号回车
# 编译目标都采用 BUILD-BUILDTYPE 形式,BUILD 表示特定功能代号,BUILDTYPE是以下类型之一:
# user → 权限受限、适用于生产环境,没root权限,不能debug,adb默认处于停用状态;
# userdebug → 与user类似,但具备root权限和debug权限,一般用于调试真机。
# eng → 具有额外调试工具的开发配置,拥有最大的权限(root等),一般用于模拟器。
# 编译目标示例 → Pixel 3a XL的编译目标 → aosp_bonito-userdebug
lunch

# 也可以直接指定编译目标,如:lunch aosp_bonito-eng
# 还可以直接用序号,如:lunch 8,但不建议,因为不同的系统版本序号对应可能有偏差~

# ③ 开始编译,后面的-jN参数用来设置编译的并行任务数,CPU核心数为6,N值最好选6-12间
# 根据自己CPU核心数动态修改哈,见过有32的~
make -j6

# 也可以把输出结果打印到log文件中:make -j6 2>&1 | tee build_20211206_1403.log

# 编译成功后会生成out目录,比如这里的:~/aosp/out/target/product/bonito

# Tips:有需要还可以键入:make sdk,编译SDK生成修改后的android.jar

③ 源码单编

整编一般会耗费几小时,有时可能只是修改了其中某个应用模块,只需单独编译这个模块,以设置模块为例:

source build/envsetup.sh
lunch aosp_bonito-eng
# 进入模块目录
cd package/apps/Setting

# 编译单独模块的可选指令如下:
# mm → 编译当前目录下的模块,不编译依赖模块
# mmm → 编译指定目录下的模块,不编译依赖模块
# mma → 编译当前目录下的模块及其依赖项
# mmmma → 编译指定路径下所有模块,切包含依赖
mm

# 编译成功会提示生成文件的存放路径,除了生成Setting.odex外,还会在
# priv-app/Settings目录下生成Settings.apk,可直接adb push或adb install
# 安装APK验证效果,也可以使用make snod命令重新打包生成system.img,运行模拟器查看

/   刷机   /

① 亲儿子Pixel或Nexus

恭喜,可以直接刷,先到 Driver Binaries for Nexus and Pixel Devices(https://developers.google.com/android/drivers) 根据自己的机型和Android版本号,下载对应的驱动。接着解压执行:

./extract-qcom-sargo.sh
./extract-google_devices-sargo.sh

进入bootloader,执行烧写命令(-w代表清空数据)

adb reboot bootloader
fastboot flashall -w

然后等待烧写完成即可~

② Android虚拟机

得自己编译AVD镜像,lunch那里选择 sdk_phone_x86_64 编译目标,除常规编译外,还得附加 sdksdk_repo 包。

d5955939b50801ecde10c30ea923d7e6.jpeg

上述方法不生效的话,可以把镜像Copy到 SDK/system-images/android-xx/ 的其中一个目录中。

③ 其他手机

不是亲儿子,驱动啊、厂商库啥的,只能找第三方ROM进行二次开发咯,以前最出名的就是CM (CyanogenMod) 了,不过好像凉凉了,可以试试 LineageOS(https://download.lineageos.org/chiron)

eb30c6705cbb3ae087988e6462efd6c6.jpeg

限于篇幅,就一一叙述了,感兴趣想自己试下的可参考:《自己动手编译Android(LineageOS)源码》(https://www.cnblogs.com/luoyesiqiu/p/10701419.html)

/   查看源码   /

除了直接把完整源码下载到本地外,还可以直接在线查看,或者通过AS直接查看。

① 在线查看

不用下一堆代码,而且多个版本挑着看,很香~

  • cs.android.com (官方,速度快,可能需要科学上网)(https://cs.android.com/)

  • platform_frameworks_base (Github直接看)(https://github.com/aosp-mirror/platform_frameworks_base)

  • googlesource (非常全,适合单个模块直接git clone)(https://android.googlesource.com/)

  • AndroidXref (有点旧了,最新版本到Android 9)(http://androidxref.com/)

② AS快速查看

依次点击:Settings → Appearance&Behavior → System Settings → Android SDK → 选择所需Android SDK版本源码下载:

0842e2372c066ac2be18ee7586b9f555.jpeg

接着build.gradle设置下 compileSdk 版本号,Sync一下,点击跳转Framework的类即可跳转。

83f06a2133488fc808e89bd96d934e35.jpeg

/   调试源码   /

① 生成索引

Android源码提供了直接生成AS可识别的文件工具,编译完成Android源码后,会在源码根目录生成一个 android.ipr。

AS 以 Open an existing Android Studio Project 方式打开此文件,静待索引生成完毕。

索引生成后,调整下AS监视源代码的目录,如out这样的目录,每次编译完都会产生变化,但基本不会用到此目录,直接去掉索引(Excluded掉),以out目录为例,其他不需要的目录也是这样处理:

cd00470ee0ae5e7f29caf2b72cfd0b1f.jpeg

② 设置JDK和SDK

dba57b8b1a4dfaa2042d6e7babf1a18d.jpeg

根据源码版本选择对应的SDK:

902a2cef698adba97e8b0ea7f03f01dc.jpeg

设置JDK:

60b9a1c652d8ee04248b9eeee63ed5e0.jpeg

③ 调试源码

源码下断点,然后点击 Attach Debugger to Android Process

304544ea40c0b743d586b206963704cc.jpeg

选中待调试进程,然后就可以愉快的调试啦~

f93f142d509c21ea9f409d469bfacc2a.jpeg

真机想调试系统进程需要Root权限,然后利用Magisk等软件修改:ro.debuggable = 1,可以新建模拟器时选择 非 Google Play的64位镜像,也可以得到 ro.debuggable = 1 的设备。

大部分时候调试源码是用不到所有的AOSP源码的,也可以直接导入部分源码进行调试。

另外,真机调试,可能出现调试行号与源码不一致,行号跑注释里的情况,大多数原因是国产ROM对相关源码进行了修改,可以在Debugger/Frames看到调用方法,了解这一步进入的哪个方法,然后Ctrl+F查找方法名,定位到正确位置。

推荐阅读:

我的新书,《第一行代码 第3版》已出版!

2022年终总结,我的10年Android之旅

再看LayoutInflater,这次你可能又会有新的认识

欢迎关注我的公众号

学习技术或投稿

448aec1da7e97ac82d1e588cc96f427e.png

b871485f27ebd130aef857a4a64a3a8f.jpeg

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值