第二章内容优化

This commit is contained in:
feiocng 2023-07-05 16:54:50 +08:00
parent d2a7aaff43
commit bf886a43a0

View File

@ -1,11 +1,14 @@
# 第二章 系统开发环境与工具 # 第二章 系统开发环境与工具
经过第一章的学习,对`AOSP`定制进行简略的介绍后,对于系统定制开发的基础,有了大致的理解。所谓的系统定制,实际相当于在一款成熟的产品上进行二次开发。和常见的软件项目的二次开发的学习步骤类似,不会有太大的出入,细节的区别就在于,`Android`源码相比其他软件项目要更加庞大复杂,修改编译以及测试系统所花费的时间周期更长。 经过第一章的学习,对`AOSP`定制进行简略的介绍后大家应该对系统定制开发的基础有了大致的理解。所谓的系统定制实际相当于在一款成熟的产品上进行二次开发。二次开发最耳熟能详的要属开发板二次开发领域了比如知名经典的ARM架构开发板树霉派厂家在出厂时提供了一些基础的系统与工具套件开发人员可以扩展这个板子的玩法实现玩具车、智能家居、电视盒子、路由器、小型内容服务器等多种功能的开发这里面涉及到的二次开发知识也是相当的丰富。
当然,本书不讨论功能庞大复杂的系统定制,而是以安全领域为面,技术功能为切入点的形式来讨论系统二次定制的一般方法。和常见的软件项目的二次开发的学习步骤类似,不会有太大的出入,细节的区别就在于,`Android`源码相比其他软件项目要更加庞大复杂,需要做一些基础知识的储备,另外,修改编译以及测试系统是一个反复执行的动作,它占用了定制开发中所耗费的大多数时间。
尽管`Android`源码结构非常庞大,但对于初学者,并不需要完整的吃透所有代码。关键在于,掌握`Android`源码跟踪分析的思路,阅读理解工程的整体结构,了解`Android`系统框架的运行原理,结合思考与实践,实现自定义定制的功能。 尽管`Android`源码结构非常庞大,但对于初学者,并不需要完整的吃透所有代码。关键在于,掌握`Android`源码跟踪分析的思路,阅读理解工程的整体结构,了解`Android`系统框架的运行原理,结合思考与实践,实现自定义定制的功能。
学习的流程需要循序渐进,有的放矢,以免迷失在纷繁复杂的代码海洋中。通常,第一步需要了解如何将整个系统项目成功编译并刷机。这一章将详细讲解在各种不同的环境下,应该如何编译`Android`源码,并将其刷入手机中。 学习的流程需要循序渐进,有的放矢,以免迷失在纷繁复杂的代码海洋中。通常,第一步需要了解如何将整个系统项目成功编译并刷机。这一章将详细讲解在各种不同的环境下,应该如何编译`Android`源码,并将其刷入手机中。
## 2.1 环境准备 ## 2.1 环境准备
安卓系统在版本`10`之前,是支持`macOS`系统上编译`AOSP`代码的。在新版本系统的演进过程中,安卓官方已经放弃在`macOS`系统平台上做`AOSP`开发的支持,官方开发指导环境采用了`Linux`上比较流行的`Ubuntu`发行版本。在`Mac m1/m2`下可采用`docker+orbstack`的方案进行编译,`Mac Inter`下可使用`vmware``Parallels Desktop`虚拟机准备编译环境。 安卓系统在版本`10`之前,是支持`macOS`系统上编译`AOSP`代码的。在新版本系统的演进过程中,安卓官方已经放弃在`macOS`系统平台上做`AOSP`开发的支持,官方开发指导环境采用了`Linux`上比较流行的`Ubuntu`发行版本。在`Mac m1/m2`下可采用`docker+orbstack`的方案进行编译,`Mac Inter`下可使用`vmware``Parallels Desktop`虚拟机准备编译环境。
@ -16,7 +19,7 @@
由于在`Windows`中缺少了各种底层编译器与开发库的支持,一般情况下,开发人员不会直接在`Windows`环境中编译,而是选择在`Windows`中创建一个`Linux`的虚拟环境,然后在虚拟环境中安装编译所需要用到的底层依赖。在`Windows`系统上部署`Ubuntu`作为`Linux`虚拟环境有多种可选方案,例如`Docker、WSLWindows Subsystem for Linux、Vmware`虚拟机,`QEMU、HyperV`虚拟机平台等等。 由于在`Windows`中缺少了各种底层编译器与开发库的支持,一般情况下,开发人员不会直接在`Windows`环境中编译,而是选择在`Windows`中创建一个`Linux`的虚拟环境,然后在虚拟环境中安装编译所需要用到的底层依赖。在`Windows`系统上部署`Ubuntu`作为`Linux`虚拟环境有多种可选方案,例如`Docker、WSLWindows Subsystem for Linux、Vmware`虚拟机,`QEMU、HyperV`虚拟机平台等等。
几种方案经过编译对比测试,发现`Docker``Windows`系统上的体验并不怎么好,主要体现在编译这类大型项目时,需要较大的磁盘存储空间,选择外挂磁盘映射时,编译时`IO`性能较弱,而选择创建虚拟磁盘时,对宿主机的开机耗时明显变高。这里不太建议在`Windows`下采用`Docker`来编译源码。 几种方案经过编译对比测试,发现`Docker``Windows`系统上的体验并不怎么好,在编译这类大型项目时,需要较大的磁盘存储空间,选择外挂磁盘映射时,编译时`IO`性能较弱,而选择创建虚拟磁盘时,对宿主机的开机耗时明显变高。这里不太建议在`Windows`下采用`Docker`来编译源码。
`WSL``Windows`下内置的`Linux`子系统,最新的版本号为`2`,通常将其称为`WSL2`。它是一个非常轻量化的`Linux`系统,让那些想在`Windows`中编译与运行`Linux`程序的开发人员爱不释手。安装好`WSL2`后,只要在终端中输入一个`wsl`命令就可以启动环境。使用起来的感觉就好似直接使用命令行一样。并且编译性能相比`Vmware`这类虚拟机要更加高效。同一台机器编译测试后得到对比记录,`WSL2`完整编译的耗时为130分钟`Vmware`虚拟机的耗时是170分钟这是因为`WSL2`采用直通计算机硬件,`IO`性能有着较为显著的提升。 `WSL``Windows`下内置的`Linux`子系统,最新的版本号为`2`,通常将其称为`WSL2`。它是一个非常轻量化的`Linux`系统,让那些想在`Windows`中编译与运行`Linux`程序的开发人员爱不释手。安装好`WSL2`后,只要在终端中输入一个`wsl`命令就可以启动环境。使用起来的感觉就好似直接使用命令行一样。并且编译性能相比`Vmware`这类虚拟机要更加高效。同一台机器编译测试后得到对比记录,`WSL2`完整编译的耗时为130分钟`Vmware`虚拟机的耗时是170分钟这是因为`WSL2`采用直通计算机硬件,`IO`性能有着较为显著的提升。
@ -32,7 +35,7 @@
![image-20230102183708998](.\images\image-20230102183708998.png) ![image-20230102183708998](.\images\image-20230102183708998.png)
执行下面的命令开启功能 打开Powershell执行下面的命令开启功能
``` ```
//启用虚拟机平台 //启用虚拟机平台
@ -41,11 +44,12 @@ Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
``` ```
启动完成这些特性后,重新启动计算机,然后,就可以开始安装一个`Ubuntu`系统了。打开`Microsoft Store`应用商店搜索`Ubuntu`系统,然后选择自己需要的版本即可,例如我安装的是22.04版本,如下图。 启动完成这些特性后,重新启动计算机,就可以开始安装一个`Ubuntu`系统了。打开`Microsoft Store`应用商店输入关键字`Ubuntu`进行搜索,然后选择自己需要的版本即可,例如这里安装的是22.04版本,如下图。
![image-20230102184626538](.\images\image-20230102184626538.png) ![image-20230102184626538](.\images\image-20230102184626538.png)
成功获取`Ubuntu`系统后,从应用中启动系统即开始正式安装。安装过程只需要设置好用户名与密码即可。完成后会进行一个`shell`环境供用户输入。 成功获取`Ubuntu`系统后,从应用中启动系统即开始正式安装。安装过程只需要设置好用户名与密码即可。完成后会进行一个`shell`环境供用户输入。第一次启动时需要设置用户名与密码来完成初始化配置。以后只需要在终端工具的界面上选择Ubuntu就可以启动了整个启动过程中非常的快只要数秒就会在窗口中给出一个Shell提示符供用户输入操作。
需要注意的是,应用商店默认会将`WSL`安装在`C`盘中,而编译系统会占用相当大的空间,如果你的系统盘空间不够,需要做一个迁移操作,将子系统迁移到其他硬盘中。操作方法是:桌面任意位置右键选择终端,在打开的终端环境中自毁长城下面的命令,查询当前的子系统名称。 需要注意的是,应用商店默认会将`WSL`安装在`C`盘中,而编译系统会占用相当大的空间,如果你的系统盘空间不够,需要做一个迁移操作,将子系统迁移到其他硬盘中。操作方法是:桌面任意位置右键选择终端,在打开的终端环境中自毁长城下面的命令,查询当前的子系统名称。
``` ```
@ -170,17 +174,17 @@ export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo/'
#### 2.2.2 分支选择策略 #### 2.2.2 分支选择策略
根据自己的需求来选择合适的版本,比如想要在`Android12`的基础上进行二次开发参考官方文档https://source.android.com/docs/setup/about/build-numbers?hl=zh-cn找到对应的版本描述例如下图可以看到各个版本号关联的代码分支各分支版本支持哪些设备。 根据自己的需求来选择合适的版本,比如想要在`Android`12的基础上进行二次开发参考官方文档https://source.android.com/docs/setup/about/build-numbers?hl=zh-cn找到对应的版本描述例如下图可以看到各个版本号关联的代码分支各分支版本支持哪些设备。
![image-20230103220519836](.\images\image-20230103220519836.png) ![image-20230103220519836](.\images\image-20230103220519836.png)
这么多版本,要根据自身的需求选一个适合的版本,例如我的选择策略如下: 这么多版本,要根据自身的需求选一个适合的版本,例如我的选择策略如下:
1. 优先选择支持`Pixel 3`测试机的版本。 1. 优先选择支持`Pixel`3测试机的版本。
2. 除了支持你的这个设备外,还支持更多设备的版本。 2. 除了支持你的这个设备外,还支持更多设备的版本。
3. 满足上面两个条件的最高分支版本,即优先最新的代码分支。 3. 满足上面两个条件的最高分支版本,即优先最新的代码分支。
如果该`ROM`主要在虚拟机中刷机测试的,那么选择支持版本最多的分支即可。这里我的测试设备是`pixel 3`,根据上文中的选择策略找到了版本`SP1A.210812.016.A1`,对应的分支代码是`android-12.0.0_r3`,如下图。 如果该`ROM`主要在虚拟机中刷机测试的,那么选择支持版本最多的分支即可。这里我的测试设备是`pixel`3,根据上文中的选择策略找到了版本`SP1A.210812.016.A1`对应的分支代码是`android-12.0.0_r3`,如下图。
![image-20230103220838404](.\images\image-20230103220838404.png) ![image-20230103220838404](.\images\image-20230103220838404.png)
@ -189,7 +193,6 @@ export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo/'
通过前文锁定了要编译的目标分支,接下来的步骤是拉取源码。执行如下命令: 通过前文锁定了要编译的目标分支,接下来的步骤是拉取源码。执行如下命令:
``` ```
// 创建源码存放的目录 // 创建源码存放的目录
mkdir aosp_12 && cd aosp_12 mkdir aosp_12 && cd aosp_12
@ -216,9 +219,10 @@ repo sync -c -j$(nproc --all)
代码同步完成后,会提示`Success`,如果失败了,就重新拉取即可,多拉取几次后,基本都能同步成功。 代码同步完成后,会提示`Success`,如果失败了,就重新拉取即可,多拉取几次后,基本都能同步成功。
### 2.3 Android系统编译 ### 2.3 Android系统编译
系统的编译过程中使用到很多依赖库,执行下面的命令,安装相关依赖: 系统的编译过程中使用到很多依赖库,执行下面的命令,安装Ubuntu22.04系统上编译系统所需要的相关依赖
``` ```
// AOSP编译的相关依赖安装 // AOSP编译的相关依赖安装
@ -287,7 +291,7 @@ Which would you like? [aosp_arm-eng]
make -j$(nproc --all) make -j$(nproc --all)
``` ```
在上面选择版本中,可以看到`aosp_arm-eng``aosp_arm64-eng`的选项,这两个是模拟器使用的版本。而模拟器使用的版本是可以不需要导入设备驱动文件的。如果在`lunch`的菜单中没有看到你要编译的版本,并且直接`lunch aosp_blueline-userdebug `也提示错误,可能是没有成功导入驱动文件,或者下载的驱动文件错误。 在上面版本选择中,可以看到`aosp_arm-eng``aosp_arm64-eng`的选项,这两个是模拟器使用的版本。而模拟器使用的版本是可以不需要导入设备驱动文件的。如果在`lunch`的菜单中没有看到你要编译的版本,并且直接`lunch aosp_blueline-userdebug `也提示错误,可能是没有成功导入设备配置文件,或者下载的驱动文件错误。
同一个代号的编译有三种编译版本选择。分别如下: 同一个代号的编译有三种编译版本选择。分别如下:
@ -297,7 +301,7 @@ make -j$(nproc --all)
3. `aosp_blueline-eng` 为工程版本,同样也是用于测试和调试的环境,但是系统限制比`userdebug`要更加少,会禁用一些安全机制,比如签名验证,关闭一些编译优化等。会关闭用于提供良好用户体验的各种优化。 3. `aosp_blueline-eng` 为工程版本,同样也是用于测试和调试的环境,但是系统限制比`userdebug`要更加少,会禁用一些安全机制,比如签名验证,关闭一些编译优化等。会关闭用于提供良好用户体验的各种优化。
第一次完整编译非常的漫长笔者的电脑耗时约2个小时成功编译。编译成功后检查一下输出的文件。 第一次完整编译等待时间非常的漫长笔者的电脑耗时约2个小时成功编译。编译成功后检查一下输出的文件。
``` ```
// 查看输出目录的所有镜像文件 // 查看输出目录的所有镜像文件
@ -325,7 +329,8 @@ vbmeta.img
vendor.img vendor.img
``` ```
确定有编译出`vendor.img、system.img、boot.img`等镜像文件,就说明编译成功了。 确定有编译产出物:`vendor.img、system.img、boot.img`等镜像文件,就说明编译成功了。
### 2.4 模块编译 ### 2.4 模块编译
@ -358,17 +363,17 @@ Invoke ". build/envsetup.sh" from your shell to add the following functions to y
...... ......
``` ```
`croot` 命令可以跳转根目录,或者是根目录下的任意子目录 `croot` 命令可以跳转根目录,或者是根目录下的任意子目录
`m` 命令会直接在根目录运行编译,即使当前目录是在子目录也是相当于在根目录编译。也可以指定名称来编译单独的目标,例如`m droid` `m` 命令会直接在根目录运行编译,即使当前目录是在子目录也是相当于在根目录编译。也可以指定名称来编译单独的目标,例如`m droid`
`mm ` 编译当前目录中的所有模块及依赖项 `mm ` 编译当前目录中的所有模块及依赖项
`mmm` 编译指定目录中的所有模块及依赖项 `mmm` 编译指定目录中的所有模块及依赖项
`clean` 清除编译的结果相当于删掉out目录中的内容 `clean` 清除编译的结果相当于删掉out目录中的内容
可以通过`m help`查看可以单独编译哪些选项 可以通过`m help`查看可以单独编译哪些选项
``` ```
m help m help
@ -408,11 +413,12 @@ Common goals are:
通过帮助命令的提示,可以看到`m snod`就是单独编译`system`模块,命令`m vnod`就是单独编译`Vendor`。大多数时候,修改的内容都是在`system`模块中。可以根据自己对系统的修改情况,执行不同的模块编译。 通过帮助命令的提示,可以看到`m snod`就是单独编译`system`模块,命令`m vnod`就是单独编译`Vendor`。大多数时候,修改的内容都是在`system`模块中。可以根据自己对系统的修改情况,执行不同的模块编译。
### 2.5 内核编译 ### 2.5 内核编译
系统编译完成后,可以在编译的镜像结果中看到文件`boot.img`,这个文件是内核镜像文件。但是这个内核默认采用`Android`源码树中预编译好的内核文件,没有使用源码编译出来的内核文件,如果想要为编译的系统纳入自编译的内核,需要拉取对应分支的内核代码参与编译,并将编译结果放入`Android`源码树中的指定路径,最后再重新编译打包`Android`镜像。这样,生成的系统刷入手机后,使用的内核就是自编译的版本了。 系统编译完成后,可以在编译的镜像结果中看到文件`boot.img`,这个文件是内核镜像文件。但是这个内核默认采用`Android`源码树中预编译好的内核文件,没有使用源码编译出来的内核文件,如果想要为编译的系统纳入自编译的内核,需要拉取对应分支的内核代码参与编译,并将编译结果放入`Android`源码树中的指定路径,最后再重新编译打包`Android`镜像。这样,生成的系统刷入手机后,使用的内核就是自编译的版本了。
首先找到对应当前手机的内核分支官网提供了详细的说明文档https://source.android.com/docs/setup/build/building-kernels。根据下图可以看到对应`Pixel 3`测试机分支是`android-msm-crosshatch-4.9-android12` 首先找到对应当前手机的内核分支官网提供了详细的说明文档https://source.android.com/docs/setup/build/building-kernels。根据下图可以看到对应`Pixel`3测试机分支是`android-msm-crosshatch-4.9-android12`
![image-20230105221730348](.\images\image-20230105221730348.png) ![image-20230105221730348](.\images\image-20230105221730348.png)
@ -459,11 +465,10 @@ Linux localhost 4.9.270-g862f51bac900-ab7613625 #0 SMP PREEMPT Thu Aug 5 07:04:4
``` ```
cd android-kernel/private/msm-google cd android-kernel/private/msm-google
git checkout 862f51bac900 git checkout 862f51bac900
``` ```
除了检查该版本外,还需要查看内核使用的配置文件是否对应目标测试机`Pixel 3`。进入内核中配置目录,查看有哪些设备的配置。 除了检查该版本外,还需要查看内核使用的配置文件是否对应目标测试机`Pixel`3。进入内核中配置目录,查看有哪些设备的配置。
``` ```
cd android-kernel/private/msm-google/arch/arm64/configs cd android-kernel/private/msm-google/arch/arm64/configs
@ -475,7 +480,7 @@ b1c1_defconfig cuttlefish_defconfig ranchu64_defconfig sdm670-perf_defconfi
bonito_defconfig defconfig sdm670_defconfig sdm845_defconfig vendor bonito_defconfig defconfig sdm670_defconfig sdm845_defconfig vendor
``` ```
这些配置对应着不同的机型,其中`b1c1_defconfig`对应`Pixel 3`和`Pixel 3XL`,然后检查编译配置中是否确定是使用该配置进行编译的。编辑`build/build.config`,确定`DEFCONFIG``b1c1_defconfig`。如果这里不是正确的版本,则会出现无法正常进入系统的情况。 这些配置对应着不同的机型,其中`b1c1_defconfig`对应`Pixel`3和`Pixel`3XL,然后检查编译配置中是否确定是使用该配置进行编译的。编辑`build/build.config`,确定`DEFCONFIG``b1c1_defconfig`。如果这里不是正确的版本,则会出现无法正常进入系统的情况。
``` ```
DEFCONFIG=b1c1_defconfig DEFCONFIG=b1c1_defconfig
@ -519,6 +524,7 @@ lunch aosp_blueline-userdebug
make bootimage make bootimage
``` ```
### 2.6 刷机 ### 2.6 刷机
大多数情况下,`Android`系统的玩机爱好者,通常会使用傻瓜式的一键刷机工具,例如刷机大师、刷机精灵、奇兔等工具来刷机。这种刷机方式属于软刷(软件刷机);除此之外,还有第一章中介绍到的线刷和卡刷。不论刷机的方式是什么,他们最终都是对刷机包进行处理,然后将`ROM`文件写入对应的分区,替换掉原始文件。下面,将介绍如何进行线刷和卡刷。 大多数情况下,`Android`系统的玩机爱好者,通常会使用傻瓜式的一键刷机工具,例如刷机大师、刷机精灵、奇兔等工具来刷机。这种刷机方式属于软刷(软件刷机);除此之外,还有第一章中介绍到的线刷和卡刷。不论刷机的方式是什么,他们最终都是对刷机包进行处理,然后将`ROM`文件写入对应的分区,替换掉原始文件。下面,将介绍如何进行线刷和卡刷。
@ -584,6 +590,7 @@ fastboot flash vendor ./vendor.img
fastboot reboot fastboot reboot
``` ```
#### 2.6.2 卡刷 #### 2.6.2 卡刷
前面步骤编译出来的是系统线刷包,如果需要卡刷包,就需要使用`make otapackage`命令来进行编译。注意这种方式需要预先编译好卡刷包。具体的编译方法如下。 前面步骤编译出来的是系统线刷包,如果需要卡刷包,就需要使用`make otapackage`命令来进行编译。注意这种方式需要预先编译好卡刷包。具体的编译方法如下。
@ -620,7 +627,7 @@ adb reboot bootloader
fastboot reboot fastboot fastboot reboot fastboot
``` ```
这时的界面如下图,使用音量键减,切换到`Enter recovery`,然后按电源键进入`recovery`模式 这时的界面如下图,使用音量键减,切换到`Enter recovery`,然后按电源键进入`recovery`模式
![image-20230108190236615](.\images\image-20230108190236615.png) ![image-20230108190236615](.\images\image-20230108190236615.png)
@ -630,14 +637,17 @@ fastboot reboot fastboot
使用命令`adb devices`查看当前状态显示为`sideload`,即可直接通过命令`adb sideload ota.zip`进行刷机。 使用命令`adb devices`查看当前状态显示为`sideload`,即可直接通过命令`adb sideload ota.zip`进行刷机。
2. `twrp` 2. `TWRP`
TODO这里待补充 `TWRP`的刷机则更加简单,在刷好`TWRP`的设备上,执行`adb reboot recovery`进入其操作界面然后选择要刷入的ZIP包点击刷机即可。
### 2.7 源码的开发环境搭建
`Android`系统是一个非常庞大的工程,需要采用合适的编辑器或`IDE`来阅读与修改代码。如果改动不多,使用`vscode`导入工作区即可开始修改代码。`vscode`的智能提示和跳转相对`IDE`较为简陋,如果想要更加友好的开发体验,可以选择将源码导入`Android Studio`中编辑`java`部分代码,导入`Clion`中编辑`native`部分代码。下面介绍如何将源码导入`Android Studio` ### 2.7 源码开发环境搭建
`Android`系统是一个非常庞大的工程,需要采用合适的编辑器或`IDE`来阅读与修改代码。如果改动不多,使用`vscode`导入工作区即可开始修改代码。`vscode`的智能提示和跳转相对`IDE`较为简陋,如果想要更加友好的开发体验,可以选择将源码导入`Android Studio`中编辑`java`部分代码,导入`Clion`中编辑`native`部分代码。
下面介绍如何将源码导入`Android Studio`
``` ```
cd ~/aosp12 cd ~/aosp12
@ -740,9 +750,12 @@ add_subdirectory(system/core/lmkd/lmkd-arm64-android)
配置好`cmake`工程后,使用`clion`打开项目,选择上面的`CMakeLists.txt`文件所在的目录`out/development/ide/clion`。导入成功后,修改工程的根目录,`Tools->Cmake->Change Project Root`,然后选择源码根目录即可。 配置好`cmake`工程后,使用`clion`打开项目,选择上面的`CMakeLists.txt`文件所在的目录`out/development/ide/clion`。导入成功后,修改工程的根目录,`Tools->Cmake->Change Project Root`,然后选择源码根目录即可。
## 2.8 gitlab配合repo管理源码 ## 2.8 gitlab配合repo管理源码
将源码导入`idea`中后,已经可以正常的开始修改源码了。在日常的项目开中,需要考虑到源码的管理,便于随时能够查看自己的修改,切换不同的分支进行开发。这样一个巨大的项目,一个月后,再想要查找当时修改的逻辑,就非常困难了。如果你是个人开发,并且修改的逻辑不是特别复杂,或者是刚开始学习,那么可以选择跳过这个部分内容。 将源码导入`idea`中后,已经可以正常的开始修改源码了。在日常的项目开中,需要考虑到源码的管理,便于随时能够查看自己的修改,切换不同的分支进行开发。这样一个巨大的项目,一个月后,再想要查找当时修改的逻辑,就非常困难了。
`gitlab`配置不算复杂但也繁琐一般管理大型项目会用到尤其是私有ROM的管理。**如果你是个人开发,并且修改的逻辑不是特别复杂,或者是刚开始学习,那么可以选择跳过这部分内容。**
首先,需要对`repo`进行一定的了解,在前文中,有简单的介绍到,`repo``python`脚本实现的,是对`git`命令的封装,用来管理大型项目关联多个子项目的。重新回顾一下下载`Android`代码的过程。前文中,使用`repo`进行初始化指定分支,在完成初始化后,会在当前目录生成一个`.repo`的目录,查看目录中的`manifest.xml`文件,内容如下。 首先,需要对`repo`进行一定的了解,在前文中,有简单的介绍到,`repo``python`脚本实现的,是对`git`命令的封装,用来管理大型项目关联多个子项目的。重新回顾一下下载`Android`代码的过程。前文中,使用`repo`进行初始化指定分支,在完成初始化后,会在当前目录生成一个`.repo`的目录,查看目录中的`manifest.xml`文件,内容如下。
@ -793,7 +806,9 @@ add_subdirectory(system/core/lmkd/lmkd-arm64-android)
</manifest> </manifest>
``` ```
这个文件的内容实际上是一份`git`仓库清单,`repo init`初始化的过程就是下载`git`仓库清单文件,以及下载`repo`工具的仓库也就是`git-repo`项目,使用国内网络进行初始化时的速度非常慢的主要原因,在于`git-repo`项目较大且必须通过外网访问,很多读者使用国内源进行`repo init`前还需要通过设置环境变量`REPO_URL`修改`git-repo`的拉取地址。而`repo sync`步骤就是就是将清单文件中对应的子模块全部拉取下来。`default.xml`中的元素主要为以下几种。 这个文件的内容实际上是一份`git`仓库清单,`repo init`初始化的过程就是下载`git`仓库清单文件,以及下载`repo`工具的仓库也就是`git-repo`项目,使用国内网络进行初始化时的速度非常慢的主要原因,在于`git-repo`项目较大且必须通过外网访问,很多读者使用国内源进行`repo init`前,需要通过设置环境变量`REPO_URL`修改`git-repo`的拉取地址。而`repo sync`步骤就是就是将清单文件中对应的子模块全部拉取下来。
`default.xml`中的元素主要为以下几种。
1. `manifest`:根元素,所有元素都要定义再根元素中。 1. `manifest`:根元素,所有元素都要定义再根元素中。
2. `remote``git`仓库的地址以及名称。 2. `remote``git`仓库的地址以及名称。
@ -831,7 +846,6 @@ sudo gitlab-ctl reconfigure
// 启动gitlab // 启动gitlab
sudo gitlab-ctl start sudo gitlab-ctl start
``` ```
接下来在浏览器中输入局域网ip地址来访问`gitlab`页面,比如`http://192.168.2.189/`。然后注册一个账号。在登录的时候出现了下面这个错误 接下来在浏览器中输入局域网ip地址来访问`gitlab`页面,比如`http://192.168.2.189/`。然后注册一个账号。在登录的时候出现了下面这个错误
@ -1208,7 +1222,7 @@ fatal: 无法读取远程仓库。
platform/build/bazel: platform/build/bazel:
``` ```
检测代码后发现`bazel`仓库在路径`build`中不存在,这个仓库被建立在了`platform`下。导致这个问题的原因是,前面的创建`git`的脚本中,发现`build`被指定为`project`,所以创建为仓库,而`bazel`必须是在一个`group`下,路径才会成立。而`build`的仓库已经存在,创建这个`group`失败后,就默认使用了更上一层的`group`。而解决办法也非常简单,直接将`default`中的几个`build`路径下的几个`project`重新命名,不要放在`build``group`下即可。下面是解决后的`default.xml`配置。 检测代码后发现`bazel`仓库在路径`build`中不存在,这个仓库被建立在了`platform`下。导致这个问题的原因是,前面的创建`git`的脚本中,发现`build`被指定为`project`,所以创建为仓库,而`bazel`必须是在一个`group`下,路径才会成立。而`build`的仓库已经存在,创建这个`group`失败后,就默认使用了更上一层的`group`。而解决办法也非常简单,直接将`default`中的几个`build`路径下的几个`project`重新命名,不要放在`build``group`下即可。下面是解决后的`default.xml`配置。
``` ```
<project path="build/make" name="platform/build" groups="pdk" > <project path="build/make" name="platform/build" groups="pdk" >
@ -1263,7 +1277,7 @@ repo sync -j8
到这里就完成了`gitlab`源码管理AOSP源码开发了当修改代码后就可以使用`repo`来提交修改了。在根目录执行下面的命令提交修改代码。 到这里就完成了`gitlab`源码管理AOSP源码开发了当修改代码后就可以使用`repo`来提交修改了。在根目录执行下面的命令提交修改代码。
``` ```
repo forall -c 'git add .' repo forall -c 'git add .'
repo forall -c 'git commit -m "change my update" ' repo forall -c 'git commit -m "change my update" '
@ -1272,12 +1286,13 @@ repo forall -c 'git push'
在上面的命令中`repo forall -c`表示对清单中的所有`git`执行后面的命令。也可以选择直接在当前修改的`git`仓库中进行提交。 在上面的命令中`repo forall -c`表示对清单中的所有`git`执行后面的命令。也可以选择直接在当前修改的`git`仓库中进行提交。
### 2.9 小结
## 2.9 小结
本章主要讲述了如何从零开始,在`Windows`系统与`Ubuntu`系统中,搭建一个编译`Android`源码的环境。在环境搭建好后,讲解了如何选择合适的需要开发修改的`AOSP`版本,在系统版本确定后,讲解了拉取代码并编译的流程;接着,讲解了为系统集成自己编译的内核代码,然后将编译好的系统镜像,尝试多种方式刷入测试手机设备中。 本章主要讲述了如何从零开始,在`Windows`系统与`Ubuntu`系统中,搭建一个编译`Android`源码的环境。在环境搭建好后,讲解了如何选择合适的需要开发修改的`AOSP`版本,在系统版本确定后,讲解了拉取代码并编译的流程;接着,讲解了为系统集成自己编译的内核代码,然后将编译好的系统镜像,尝试多种方式刷入测试手机设备中。
在编译与刷机完成后,为后续开发和阅览代码做准备。讲述了如何使用`Android Studio``Clion`导入源码。 在编译与刷机完成后,为后续开发和阅览代码做准备。讲述了如何使用`Android Studio``Clion`导入源码的完整流程,对于边开发边调试代码的人员来说,这个步骤必不可少
最后,为了便于工程的长期维护和持续性的开发,讲解了搭建`gitlab`配合`repo`管理`Android`源码。 最后,为了便于工程的长期维护和持续性的开发,讲解了搭建`gitlab`配合`repo`管理`Android`源码,配置过程不算轻松,但完成后方便管理,一劳永逸
终于将一切准备就绪了。本章的内容操作性强,不同步骤之间由于各种原因可能会出现错误,出现操作流程被打断的情况下,不要急躁,冷静分析原因,结合网络上的搜索结果,发现定位并解决问题后,重复操作,直到编译刷机完成,配置好环境,为后面的课程做好准备。 本章的内容操作性强,不同步骤之间由于各种原因可能会出现错误,出现操作流程被打断的情况下,不要急躁,冷静分析原因,结合网络上的搜索结果,发现定位并解决问题后,重复操作,直到编译刷机完成,配置好环境,为后面的课程做好准备。