Fuchsia 软件包是文件分层集合,可为 Fuchsia 系统提供一个或多个程序、组件或服务。Fuchsia 软件包是一个表示分发单元的术语。不过,与许多其他软件包系统不同,该单元由多个部分组成,而不是单个二进制文件 BLOB
。
某些软件包在启动时存在于 Fuchsia 系统上,您还可以通过 BLOB
从 Fuchsia 软件包服务器下载其他软件包。Fuchsia 软件包服务器是 HTTP(S) 服务器。这些 BLOB
由 Merkle 根唯一定义。BLOB
使用 Fuchsia Merkle Root 算法以其内容命名。如果两个 BLOB
的内容相同,则它们的名称也相同。因此,每个 BLOB
都有一个唯一标识符,并使用此 Merkle 根作为键写入永久性存储空间。此过程旨在消除软件包之间可能存在的重复 BLOB
。例如,存在于多个软件包中的共享库只会在设备上存储一次。
软件包服务器充当信任根,因为它会验证每个软件包的真实性。
构建规则将软件包与每个子软件包的构建目标相关联。在构建时,软件包构建工具会记录父软件包的元数据中的子软件包,并将每个子软件包名称映射到其软件包哈希值(用于标识子软件包的 BLOB
ID)。这样可以确保子软件包的列表和每个子软件包的内部结构都不会改变,除非同时改变父软件包的 Merkle(软件包哈希值)。
子软件包可实现以下功能:
- 封装的依赖项(软件包本质上就是“软件包树”)
- 隔离的
/pkg
目录(已分组的组件不需要将其文件、库和元数据合并到单个共享命名空间中) - 可靠的依赖项解析(系统和构建工具可确保子软件包始终“随其软件包一起移动”)
如需详细了解如何使用子软件包将组件及其依赖项打包,请参阅子打包组件。
软件包类型
构成 Fuchsia 操作系统的软件包分为三组,这三组会影响其管理方式:
基础软件包
这些软件包是 Fuchsia 操作系统基础的一部分,被认为对于安全性和系统至关重要。解析基于正在运行的 Fuchsia 系统的软件包始终返回设备上的版本,而不是软件包服务器上可能存在的新版本。不过,您可以在 OTA 流程中更新基础软件包。
由于这些软件包在系统运行时内是不变的,因此必须使用 fx ota
更新这些软件包,以触发无线下载 (OTA) 更新。
缓存的软件包
这些是设备上的非基础软件包。这些软件包在设备刷写或铺砌时就存在,因此如果设备在没有网络连接的情况下启动,这些软件包就可以使用。如果软件包服务器上有其他软件包,系统会在解析过程中更新缓存的软件包。这些软件包不会在系统更新期间更新,而是会提前更新。
Fuchsia 还可以逐出正在运行的系统上缓存的软件包,以根据运行时资源需求释放资源。
Universe 软件包
这些软件包存在于软件包服务器上,但不存在于设备上。
软件包的结构
在大多数情况下,Fuchsia 中的软件包是 BLOB
的集合,其中至少包含一个名为 meta.far
的内容地址 BLOB
。
在 Fuchsia 中,您可以使用 ffx package build
命令或旧版 pm
工具构建软件包,这两种工具都位于 Fuchsia IDK 的 //tools/
目录中。
从本质上讲,软件包是由零个或多个内容地址项组成的树状结构。软件包包含以下内容:
meta.far
软件包元数据归档 meta.far
包含有关软件包的元数据,以 meta/
目录表示。meta.far
具有 merkleroot,在实际意义上,它也称为软件包的 merkleroot。
软件包的 meta/
目录至少包含两个文件:
meta/package
软件包身份文件。这是一个包含软件包名称和版本的 JSON 文件。
meta/contents
内容文件。此文件由
ffx package build
命令(或旧版pm update
和pm build
命令)创建。此文件将软件包面向用户的文件名映射到这些文件的 Merkle 根。
如果该软件包声明了子软件包,meta/
目录中也会包含以下内容:
meta/fuchsia.pkg/subpackages
子软件包文件。这是一个 JSON 文件,其中包含每个声明的子软件包的名称和版本。从父级软件包的角度来看,子软件包名称在解析子软件包时用作相对软件包网址。
软件包构建工具会遍历子软件包引用(通过 build 依赖项声明和引用每个子软件包的其他软件包清单文件的软件包清单文件声明),以计算每个子软件包的版本(软件包哈希)并生成
subpackages
文件。
此外,meta/
目录还可包含组件清单等文件。如需详细了解组件清单,请参阅组件清单。
meta/
外的 BLOB
软件包中的大多数文件都存在于 meta/
目录之外,每个文件都是 BLOB
。
例如,这些文件可能如下所示:
bin/foo
lib/libfdio.so
data/mydata.db
标识软件包
Fuchsia 中的每个软件包都由一个 package-url
进行标识。
绝对软件包网址
绝对 Fuchsia 软件包网址标识系统可寻址软件包,无需任何其他上下文,如下所示:
fuchsia-pkg://repository/package-name?hash=package-hash#resource-path
Fuchsia 针对 fuchsia-pkg
网址提供不同的互联形式,具体取决于网址的哪些部分。
- 如果存在代码库、软件包和资源部分,则网址用于标识软件包中的指定资源。
- 如果仅存在代码库和软件包部分,则网址标识指定的软件包本身。
- 如果仅存在代码库部分,则网址标识指定的代码库本身。
软件包部分可以表达不同的特异性。必须至少提供软件包名称,后面可视需要添加软件包哈希。
如果缺少软件包哈希,软件包解析器会从客户端可用的软件包变体的最新版本中提取资源。
相对包网址
相对 Fuchsia 软件包网址将之前加载的软件包(或子软件包)的子软件包标识为“上下文”。代码库和父软件包是隐式的,子软件包名称用于在父软件包的 "meta/fuchsia.pkg/subpackages"
文件中查找软件包哈希值。(软件包哈希值无法替换)。相对软件包网址如下所示:
package-name#resource-path
与绝对软件包网址一样,资源路径可以包含也可能不包含。