repo详解与如何更改manifest快速获取和复用AOSP代码

2024-03-04 12:18

本文主要是介绍repo详解与如何更改manifest快速获取和复用AOSP代码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

源起

现在很多企业的网络一般都比较快, 但是有的企业却会限速, 如果需要从github和google code上面git clone大的仓库的话, 那么需要耗费的时间是很客观的,  例如从github或者google code, 或者其他托管服务站点获取Android中需要的多个Kernel仓库, 一般一个kernel仓库都有几GB, 如果是100KB/S的话, 那么将需要很长的时间.

与此同时, 不同的Android 版本(AOSP)代码, 他们一般都会依赖许多相同的组件, 甚至获取相同的仓库代码, 仅仅只是branch或者tag不同而已, 例如对于Nexus 7 flo平板而言, 不管是AOSP 4.4 Kitkat还是 5.X Lolipop, 都会去下载flo-kernel这个内核, 他们都remote都是一样的, 唯一不同的是tag使用的不同, 因此如果我们已经获取过Kitkat的代码,那么就可以复用其中的bare repo, 从而达到快速clone.

要了解如何做, 我们需要对AOSP的代码结构非常熟悉, 一般而言, 如果是系统工程师,那么几乎对AOSP的每一个目录都会很熟悉, 对自己需要编译的target的依赖的每一个repo都几乎会心中有数(例如external中的哪些, vendor, device都会用到哪些), 这种情况下, 就可以删除某些仓库的下载, 从而节省时间.

总结起来, 要节省git clone的时间就是从两个方面入手:

  • 1. 复用已经clone的bare repo
  • 2. 不要clone不需要的repo


repo分析

在实现前面的两点之前, 除了对AOSP的编译, 以及Target的依赖很熟悉外, 我们还需要对google 的 repo工具以及其流程有个基本的熟悉和了解.

repo的执行过程

  1. 解析传入的args
  2. checkout下来最新的repo
  3. 找到manifest的目录
  4. 解析manifest.xml
  5. 根据manifest或者其他xml文件调用git clone --bare-repo获取xml中定义的clone repo
  6. 从.repo/projects中的bare repo根据manifest xml中的projects信息checkout到当前目录

具体查看repo这个python脚本的源码.

下面使用具体例子来讲解.

repo init

repo init -u https://github.com/bluez-android/aosp_platform_manifest.git -b lollipop

这个init调用传入的-u这个用于指定需要下载的manifest的仓库地址: 

def _Checkout(cwd, branch, rev, quiet):"""Checkout an upstream branch into the repository and track it."""cmd = [GIT, 'update-ref', 'refs/heads/default', rev]if subprocess.Popen(cmd, cwd=cwd).wait() != 0:raise CloneFailure()_SetConfig(cwd, 'branch.default.remote', 'origin')_SetConfig(cwd, 'branch.default.merge', 'refs/heads/%s' % branch)cmd = [GIT, 'symbolic-ref', 'HEAD', 'refs/heads/default']if subprocess.Popen(cmd, cwd=cwd).wait() != 0:raise CloneFailure()cmd = [GIT, 'read-tree', '--reset', '-u']if not quiet:cmd.append('-v')cmd.append('HEAD')if subprocess.Popen(cmd, cwd=cwd).wait() != 0:raise CloneFailure()


例如前面的 init 执行完成后, 我们可以看到在.repo目录下有一个manifest.git目录:

$ cd .repo/manifests.git/$ git remote -v
origin	https://github.com/bluez-android/aosp_platform_manifest.git (fetch)
origin	https://github.com/bluez-android/aosp_platform_manifest.git (push)

注意这个manifest.git属于bare repo , 然后repo会checkout一份出来manifest working tree到manifest目录, 且使用的就是前面repo init中的-b指定的branch:

.repo/manifests$ git status
On branch default
Your branch is up-to-date with 'origin/lollipop'. // branch -b指定后在这里

然后我们可以看到有一个manifest.xml会指向checkout的working tree中的xml:

cd /Dir/Contain/.repo/../

$ ls -l
total 12
drwxrwxr-x  3 hexiongjun hexiongjun 4096 Feb 15 10:57 manifests // 从下面这个bare repo checkout
drwxrwxr-x 10 hexiongjun hexiongjun 4096 Feb 15 10:54 manifests.git  //bare repo
lrwxrwxrwx  1 hexiongjun hexiongjun   21 Feb 15 10:40 manifest.xml -> manifests/default.xml
drwxrwxr-x  7 hexiongjun hexiongjun 4096 Feb 15 10:40 repo // repo本身的working tree checkout

repo本身的checkout

在repo init执行的时候会到: https://gerrit.googlesource.com/git-repo

checkout最新的repo, checkout下来后放在了.repo/repo目录


manifest的修改

前面的ls -l命令中列出了manifest.xml指向的是manifests/default.xml, 然后这个xml中会指明各种fetch的url, 版本revision, 以及需要checkout下来的projects, 例如:

<?xml version="1.0" encoding="UTF-8"?>
<manifest><remote  name="aosp"fetch=".." /><default revision="refs/tags/android-5.0.0_r7"remote="aosp"sync-j="4" /><project path="build" name="platform/build" groups="pdk,tradefed" ><copyfile src="core/root.mk" dest="Makefile" /></project><project path="abi/cpp" name="platform/abi/cpp" groups="pdk" /><project path="art" name="platform/art" groups="pdk" />
.............<include name="bluez-android.xml" /></manifest>


里面的remote就是git remote获取得到的remote name, fetch指定的是从哪里checkout projects, 随后指定了revision, 以及sync的并心数.

接下来是projects的list, path指定checkout下来后放到哪里, 例如下面这行:

  <project path="device/htc/flounder-kernel" name="device/htc/flounder-kernel" groups="device,flounder" clone-depth="1" />

指定了从fetch/name这个位置clone, 因为repo本身会将所有的projects放到.repo/projects目录下面, 这个存放的位置就是由后面的groups来指定的, 例如上面的flounder-kernel的repo 本地bare repo位于:

.repo/projects/device/flounder-kernel.git

而这个repository的objects则位于:

.repo/project-objects/aosp_device_asus_flo-kernel.git/

这个objects目录大小为:

$ du -sh ../../project-objects/aosp_device_asus_flo-kernel.git/
1.2G	../../project-objects/aosp_device_asus_flo-kernel.git/


然后repo在为每一个project建立了bare repository之后, 会从本地使用git clone一份出来, 且版本为前面指定的revision.


最后xml还可以使用include来包含, 实现"重载"


了解了repo的工作过程后,我们就可以想办法来重用以前的bare repository了, 也知道如何不去clone和建立不需要的project的bare repository.


如何重用已有的bare repo仓库来加快clone

假设我们已经有了一个AOSP 4.4 Kitkat的flo-kernel的bare repository了, 而AOSP 5.1 Lollipop也需要fetch 这个project,那么我们就可以按照下面这个方式来做.

1. 拷贝project objects到对应目录

2. 拷贝projects下的对应目录到新的需要checkout的目录, 例如从AOSP4到5

然后直接repo sync, sync完成后, 我们可以看到对应的branch被重新checkout下来了:

$ git branch  -aremotes/github/kitkatremotes/github/lollipopremotes/m/kitkat -> github/kitkatremotes/m/lollipop -> github/lollipop
可以看到既有kitkat也有lollipop, 这个和我们期望的一致:

  <project path="device/asus/flo-kernel" name="aosp_device_asus_flo-kernel" groups="device,flo" revision="lollipop" remote="github" />

这个xml中的project还指定了路径, 我们到里面确定一下:

 cd ../device/asus/flo-kernel/$ git branch  -a
* (no branch)remotes/github/kitkatremotes/github/lollipopremotes/m/kitkat -> github/kitkatremotes/m/lollipop -> github/lollipop

然后我们使用gitk看看, 可以确定是我们需要的branch中:



删除不需要的代码仓库

例如我们使用的Nexus 7 flo来做开发, 并不需要Nexus 9等其他的内核, 那么可以直接在xml中注释掉其他的, repo就不会去下载了:



如果后来又需要checkout这些仓库,那么取消注释, 然后重新repo sync即可.

也可以使用remove-project指定, 如同上图中的前面几行.

其他的例如drawn, MIPS等一些用不到的仓库也可以删除掉.

这篇关于repo详解与如何更改manifest快速获取和复用AOSP代码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/773146

相关文章

Python获取中国节假日数据记录入JSON文件

《Python获取中国节假日数据记录入JSON文件》项目系统内置的日历应用为了提升用户体验,特别设置了在调休日期显示“休”的UI图标功能,那么问题是这些调休数据从哪里来呢?我尝试一种更为智能的方法:P... 目录节假日数据获取存入jsON文件节假日数据读取封装完整代码项目系统内置的日历应用为了提升用户体验,

微信公众号脚本-获取热搜自动新建草稿并发布文章

《微信公众号脚本-获取热搜自动新建草稿并发布文章》本来想写一个自动化发布微信公众号的小绿书的脚本,但是微信公众号官网没有小绿书的接口,那就写一个获取热搜微信普通文章的脚本吧,:本文主要介绍微信公众... 目录介绍思路前期准备环境要求获取接口token获取热搜获取热搜数据下载热搜图片给图片加上标题文字上传图片

Linux换行符的使用方法详解

《Linux换行符的使用方法详解》本文介绍了Linux中常用的换行符LF及其在文件中的表示,展示了如何使用sed命令替换换行符,并列举了与换行符处理相关的Linux命令,通过代码讲解的非常详细,需要的... 目录简介检测文件中的换行符使用 cat -A 查看换行符使用 od -c 检查字符换行符格式转换将

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

使用C#代码在PDF文档中添加、删除和替换图片

《使用C#代码在PDF文档中添加、删除和替换图片》在当今数字化文档处理场景中,动态操作PDF文档中的图像已成为企业级应用开发的核心需求之一,本文将介绍如何在.NET平台使用C#代码在PDF文档中添加、... 目录引言用C#添加图片到PDF文档用C#删除PDF文档中的图片用C#替换PDF文档中的图片引言在当

详解C#如何提取PDF文档中的图片

《详解C#如何提取PDF文档中的图片》提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使用,下面我们就来看看如何使用C#通过代码从PDF文档中提取图片吧... 当 PDF 文件中包含有价值的图片,如艺术画作、设计素材、报告图表等,提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使

C#使用SQLite进行大数据量高效处理的代码示例

《C#使用SQLite进行大数据量高效处理的代码示例》在软件开发中,高效处理大数据量是一个常见且具有挑战性的任务,SQLite因其零配置、嵌入式、跨平台的特性,成为许多开发者的首选数据库,本文将深入探... 目录前言准备工作数据实体核心技术批量插入:从乌龟到猎豹的蜕变分页查询:加载百万数据异步处理:拒绝界面

Android中Dialog的使用详解

《Android中Dialog的使用详解》Dialog(对话框)是Android中常用的UI组件,用于临时显示重要信息或获取用户输入,本文给大家介绍Android中Dialog的使用,感兴趣的朋友一起... 目录android中Dialog的使用详解1. 基本Dialog类型1.1 AlertDialog(

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放