LV035-清单文件格式
这一篇其实可以查看 repo 源码仓库中 docs/manifest-format.md,也可以参考 OpenHarmony-SIG/manifest 中的一些文件。
一、安卓源码的 default.xml
这里写个笔记总结记录一下 xml 文件中关键的几个参数。这里是以安卓源码中的 default.xml 为例:
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<!--
remote:标签指定远程仓库的名字,
fetch :是所有git url真正路径的前缀,所有 git 的 project name加上这个前缀,就是 git url的真正路径;
review:指定Gerrit 的服务器名,用于repo upload操作
-->
<remote name="aosp"
fetch=".."
review="https://android-review.googlesource.com/" />
<!--
default:标签设定所有projects的默认属性值,如果在project元素里没有指定一个属性,则使用 default 元素的属性值
-->
<default revision="refs/tags/android-10.0.0_r45"
remote="aosp"
sync-j="4" />
<!-- project
name : git 的名称,用户生成git url. URL格式是: ${remote fetch}/${project name}.git 其中的fetch就是上面remote中的fetch元素.name 就是此处的name;
path : clone 到本地的git的工作目录,如果没有配置,跟name一样;
remote: 定义remote name, 如果没有定义的话,就用default中定义的remote name;
reversion: 指定需要获取的git提交点,可以定义成固定的branch,或者是明确的commit的哈希值;
groups: 列出project所属的组,以空格或者逗号分隔多个组名.所有的project都自动属于"all"组.
-->
<project path="build/make" name="platform/build" groups="pdk" >
<copyfile src="core/root.mk" dest="Makefile" />
<linkfile src="CleanSpec.mk" dest="build/CleanSpec.mk" />
<linkfile src="buildspec.mk.default" dest="build/buildspec.mk.default" />
<linkfile src="core" dest="build/core" />
<linkfile src="envsetup.sh" dest="build/envsetup.sh" />
<linkfile src="target" dest="build/target" />
<!-- src 表示在build/make/tools目录, dest表示本地路径build/tools软件链接文件链接到src
-->
<linkfile src="tools" dest="build/tools" />
</project>
<project path="build/blueprint" name="platform/build/blueprint" groups="pdk,tradefed" />
<project path="build/kati" name="platform/build/kati" groups="pdk,tradefed" />
<project path="build/soong" name="platform/build/soong" groups="pdk,tradefed" >
<linkfile src="root.bp" dest="Android.bp" />
<linkfile src="bootstrap.bash" dest="bootstrap.bash" />
</project>
<project path="tools/trebuchet" name="platform/tools/trebuchet" groups="tools,cts,pdk,pdk-cw-fs,pdk-fs" />
<!-- ...... -->
<repo-hooks in-project="platform/tools/repohooks" enabled-list="pre-upload" />
</manifest>后面我们详细学习一下。
二、主要结构
1. manifest
<manifest> 标签:用于标识整个 xml 配置文件的开始和结束。
<?xml version="1.0" encoding="UTF-8"?>
可以包含的子元素
<!DOCTYPE manifest [
<!ELEMENT manifest (notice?,
remote*,
default?,
manifest-server?,
remove-project*,
project*,
extend-project*,
repo-hooks?,
include*)>这个是配置的顶层元素,即根标志。
2. remote
<remote> 标签:用于指定远程仓库的信息。可以指定一个或多个远程元素。每个远程元素指定一个 Git URL。
<!ELEMENT remote EMPTY>
<!ATTLIST remote name ID #REQUIRED>
<!ATTLIST remote alias CDATA #IMPLIED>
<!ATTLIST remote fetch CDATA #REQUIRED>
<!ATTLIST remote pushurl CDATA #IMPLIED>
<!ATTLIST remote review CDATA #IMPLIED>
<!ATTLIST remote revision CDATA #IMPLIED>
例子1:
<remote fetch=".." name="zsgit" review="gerrit.xxxxx.com"/>
例子2:
<remote fetch="ssh://gerrit-sw.example.com:20418/" name="gerrit_01" review="gerrit.xxxxx.com"/>
<remote fetch="ssh://gerrit-os.example.com:20418/" name="gerrit_02" review="gerrit.xxxxx.com"/>(1)name:在每一个.git/config 文件的 remote 项中用到这个 name,即表示每个 git 的远程服务器的名字(这个名字很关键,如果多个 remote 属性的话,default 属性中需要指定 default remote)。git pull、get fetch 的时候会用到这个 remote name。一个项目清单中的代码可以来自不同服务器,所以 remote 元素可以有多个,用于存在多个 git 远程服务器的情况。就比如我们创建好本地版本库的时候要和远程仓库建立连接,我们会用以下命令:
git remote add origin git@github.com:sumumm/git-example.git这里的 origin 就相当于这里的 name。
(2)alias :远程 git 服务器的别名,如果指定了,则会覆盖 name 的设定。在一个 manifest 中,name 不能重名,但 alias 可以重名,可以用来指向不同的 remote url。当有多个 remote 时,远程仓库名称会不一样,为了保持远程仓库名称相同便于管理,可以通过该变量为仓库取别名。通常 name 不为 origin 时, 可以将别名取为 origin。
(3)fetch :所有 git url 真正路径的前缀,所有 git 的 project name(就是后面的 project 标签的 name 元素)加上这个前缀,就是 git url 的真正路径。如果使用此 remote 的所有项目的前缀和 manifest 仓库 前置 一致的话,可以使用 ... 代替。注意不包含仓库名。
(4)pushurl:设置 git push 使用的 url 地址, fetch 和 push 可以是 2 个不同的 url。
(5)review :指定 Git 的服务器名,用于 repo upload(上传所有仓库的提交记录到服务器)。如果没有指定,则 repo upload 没有效果。通常跟 fetch 变量保持一致即可。
(6)revision:git 分支的名字,例如 master 或者 refs/heads/master。
3. default
<default> 标签:用于指定 project 标签的默认参数。如果在 project 元素里没有指定一个属性,则使用 default 元素的属性值。需要注意的是 default 元素只能有一个。
<!ELEMENT default EMPTY>
<!ATTLIST default remote IDREF #IMPLIED>
<!ATTLIST default revision CDATA #IMPLIED>
<!ATTLIST default dest-branch CDATA #IMPLIED>
<!ATTLIST default upstream CDATA #IMPLIED>
<!ATTLIST default sync-j CDATA #IMPLIED>
<!ATTLIST default sync-c CDATA #IMPLIED>
<!ATTLIST default sync-s CDATA #IMPLIED>
<!ATTLIST default sync-tags CDATA #IMPLIED>(1)remote :为 <project> 标签中的 remote 属性指定默认值。其实就是之前定义的某一个 <remote> 标签中 name 属性值,用于指定使用哪一个远程 git 服务器。(上面 remote 属性中提到过,多个 remote 的时候需要指定 default remote,就是这里设置了)。
(2)revision :指定默认需要获取的 git 提交点,可以是 master, refs/heads/master, tag 或者某次提交的哈希字符串值。如果不设置的话,默认下载当前 project,默认分支上的最新代码。
(3)sync_j : 在 repo sync 中默认并行的数目。
(4)sync_c :如果设置为 true,则只同步指定的分支(revision 属性指定),而不是所有的 ref 内容
(5)sync_s : 如果设置为 true,则会同步 git 的子项目
(6)sync-tags: 控制是否下载 tags 标签
4. project
<project> 标签:用于指定具体仓库的名称、存储路径,远程仓库名称、分支等单个仓库下载所需的信息。就是指定一个需要 clone 的 git 仓库。
<!ELEMENT project (annotation*,
project*,
copyfile*,
linkfile*)>
<!ATTLIST project name CDATA #REQUIRED>
<!ATTLIST project path CDATA #IMPLIED>
<!ATTLIST project remote IDREF #IMPLIED>
<!ATTLIST project revision CDATA #IMPLIED>
<!ATTLIST project dest-branch CDATA #IMPLIED>
<!ATTLIST project groups CDATA #IMPLIED>
<!ATTLIST project sync-c CDATA #IMPLIED>
<!ATTLIST project sync-s CDATA #IMPLIED>
<!ATTLIST project sync-tags CDATA #IMPLIED>
<!ATTLIST project upstream CDATA #IMPLIED>
<!ATTLIST project clone-depth CDATA #IMPLIED>
<!ATTLIST project force-path CDATA #IMPLIED>
<project groups="zs_amss" name="AMSS/adsp_proc" path="AMSS/adsp_proc" />(1)name :仓库的名称,与 <remote> 标签中指定的 fetch 远程仓库的路径前缀拼接,形成完整代码下载地址(git url)。URL 格式是:${remote fetch}/${project name}.git 其中的 fetch 就是上面提到的 remote 中的 fetch 元素。
(2)path :仓库定 git clone 下载下来后代码在本地保存的路径(我自己理解就是下载下来后的目录名,可以与远程仓库不同的)。如果没有指定,则以 name 作为子目录名。
(3 )remote :指定远程仓库 <remote> 标签中的 name,从而获取其仓库下载地址前缀。如果没有定义的话就用 default 中定义的 remote name。如果想要管理不同的 git 服务器上的仓库,那么这里就必须要指定使用哪一个 remote name。
(4)revision :指定代码下载的提交点,可以是分支 master, refs/heads/master、 tag(tag 的话不能只写 tag 名称,要写成 refs/tags/tag_name)或者明确的 commit 哈希值(根据后面的测试,这里必须要是完整的那一个哈希值)。
(5)groups :列出 project 所属的组,以空格或者逗号分隔多个组名。所有的 project 都自动属于 "all" 组。每一个 project 自动属于 name:'name' 和 path:'path' 组。例如 <project name="monkeys" path="barrel-of"/>,它自动属于 default, name: monkeys, and path: barrel-of 组。如果一个 project 属于 notdefault 组,则,repo sync 时不会下载。
(6)sync_c :如果设置为 true,则只同步指定的分支(revision 属性指定),而不是所有的 ref 内容。
(7)sync_s : 如果设置为 true,则会同步 git 的子项目.
(8)upstream :在哪个 git 分支可以找到一个 SHA1。用于同步 revision 锁定的 manifest(-c 模式)。该模式可以避免同步整个 ref 空间
(9)annotation :可以有 0 个或多个 annotation,格式是 name-value,repo forall 命令是会用来定义环境变量。
(10)clone-depth:该设置获取此项目时要使用的深度,相当于 git clone --depth 参数。
注意:必须包含 name 和 path 属性,name 用于指定远程仓库位置,path 指定下载后的代码相对路径。
5. manifest-server
它的 url 属性用于指定 manifest 服务的 URL,通常是一个 XML RPC 服务。它要支持以下 RPC 方法:
(1)GetApprovedManifest(branch, target) :返回一个 manifest 用于指示所有 projects 的分支和编译目标。target 参数来自环境变量 TARGET_PRODUCT 和 TARGET_BUILD_VARIANT,组成$TARGET_PRODUCT-$TARGET_BUILD_VARIANT
(2)GetManifest(tag) :返回指定 tag 的 manifest
6. include
<!ELEMENT include EMPTY>
<!ATTLIST include name CDATA #REQUIRED>通过 name 属性可以引入另外一个 manifest 文件(路径相对与当前的 manifest.xml 的路径)。
name :另一个需要导入的 manifest 文件名字。可以在当前的路径下添加一个 another_manifest.xml,这样可以在另一个 xml 中添加或删除 project。
7. remove-project
<!ELEMENT remove-project EMPTY>
<!ATTLIST remove-project name CDATA #REQUIRED>从内部的 manifest 表中删除指定的 project。经常用于本地的 manifest 文件,用户可以替换一个 project 的定义。
8. copyfile
<!ELEMENT copyfile EMPTY>
<!ATTLIST copyfile src CDATA #REQUIRED>
<!ATTLIST copyfile dest CDATA #REQUIRED>project 元素的子元素,每个元素描述了一对 src-dest 文件对。
- src: 是相对于 project 标签的 path 属性值的相对路径。
- dest: 是相对于当前目录(执行 repo init 和 repo sync 命令的目录)的路径。
可以将零个或多个 copyfile 元素指定为项目元素的子元素。每个元素描述一个 src-dest 文件对;在 repo sync 命令中,src 文件将被复制到 dest 位置。通常会被用于 README 或 Makefile 或其他构建脚本。
“src”和“dest”必须是文件。不允许使用目录或符号链接。中间路径也不能是符号链接。如果缺少“dest”的父目录,将自动创建。
9. linkfile
<linkfile> 标签:用于创建软连接文件,是 <project> 标签的子元素,需要写在 <project> 与 </project> 之间。
<!ELEMENT linkfile EMPTY>
<!ATTLIST linkfile src CDATA #REQUIRED>
<!ATTLIST linkfile dest CDATA #REQUIRED>project 的子节点属性。它就像 copyfile 一样,与 copyfile 同时运行,但它不是复制,而是创建一个符号链接。符号链接在“dest”(相对于树的顶部)创建,并指向由“src”指定的路径,这是项目中的路径。如果缺少“dest”的父目录,将自动创建。符号链接的目标可以是一个文件或目录,但它不能指向 repo 客户端之外。
- dest 属性:软链接生成的路径
- src 属性:软链接链接的文件所在路径
三、一张图掌握?
