第三方源代码管理

第三方代码是 Fuchsia 代码库的一部分,但既不受 Fuchsia 作者的版权保护,也不受 Fuchsia 的许可约束。换句话说,任何并非完全由 Fuchsia 作者拥有的代码都作为第三方代码进行管理。

Fuchsia 项目会在签出中的 //third_party/ 目录下维护第三方代码依赖项的副本。这也称为“供应商化”。 供应商化可确保第三方代码从 Fuchsia 拥有的源代码库中提供,并以已知可与 Fuchsia 代码库中的其他代码搭配使用的修订版本提供。

添加第三方代码时,请按照以下步骤操作,以确保代码符合 Fuchsia 项目政策。

前期准备

所有外部代码都必须通过开源审核委员会 (OSRB) 流程才能添加到 Fuchsia 平台源代码树中。OSRB 请求获得批准后,请继续执行以下步骤。

如果依赖项或子依赖项不会在 Fuchsia 代码库中使用,请在 OSRB 请求中指定这一点,并说明将通过添加到此屏蔽列表来将该依赖项或子依赖项列入 Fuchsia 代码库的屏蔽列表。 如果要在 Fuchsia 结账中使用,则会产生大多数许可问题。

添加第三方依赖项时,代码所有者有责任保持依赖项处于最新状态。系统会监控新鲜度,并在依赖项不合规时通知 OWNERS。非特定于语言的依赖项的新鲜度来源于每个依赖项的 README.fuchsia,尤其是其 Revision 和 URL 字段,如 README.fuchsia 文档中所述。

目前,如果依赖项满足以下条件,则被视为最新:

  • 满足新上游版本的更新 SLO(定义如下)。

  • 由活跃的上游项目维护。

    • 活跃:最新的上游版本或提交内容不超过 2 年,且代码库未被归档或弃用。

如果内容未保持新鲜度,则可通过提交例外情况来管理例外流程。

之后,为了被视为最新版本,第三方依赖项还需要注册自动推送更新;我们将单独管理针对该要求的例外流程。

更新 SLO

  • 如果依赖项在生产环境中使用,基于 Head 的依赖项必须在 30 天内跟踪上游。如果依赖项基于发布版本,则必须在 30 天内跟踪次要版本,并在 3 个月内跟踪主要版本。

  • 对于其他依赖项,基于 Head 的依赖项必须在 90 天内跟踪上游。如果依赖项是基于发布版本的,则必须在 90 天内跟踪次要版本,并在 1 年内跟踪主要版本。

特定于语言的指南

如果您要添加 Rust、Go 或 Python 依赖项,请按照以下指南操作:

对于所有其他语言,请继续执行以下步骤。

获取代码

所有外部代码都必须遵循以下第三方源代码布局(以 googletest 为例):

root [fuchsia.googlesource.com/fuchsia]
  third_party/
    googletest/
      src/ [fuchsia.googlesource.com/third_party/github.com/google/googletest]
      BUILD.gn
      OWNERS
      README.fuchsia

//third_party/googletest/src/ 是 Fuchsia 拥有的镜像代码库的根目录,其中包含 googletest 的上游代码库的副本。(注意:对于 Python 代码库,请将 /src 替换为 /<module_name>,以遵循 Python 的惯例。pyright 等常用 Python 工具需要遵循此惯例。)

//third_party/googletest/ 目录是 fuchsia.git 代码库的一部分。

//third_party/googletest/BUILD.gn 为 googletest 库定义 build 目标。由于此文件属于 fuchsia.git(而非 googletest 代码库),因此可以与其他依赖于 googletest 的 Fuchsia BUILD.gn 文件同步更新。这样一来,构建重构和其他大规模变更会更加轻松。

将第三方代码适配到 Fuchsia 项目所需的其他文件可能位于 //third_party/googletest(在本例中)下。

添加所有者

每个依赖项都必须有一个关联的 OWNERS 文件。由于它是在 fuchsia.git 中定义的,因此可以包含 Fuchsia 项目中其他位置的其他文件中的所有者。

OWNERS 文件必须在开头两行中列出两个 Fuchsia 开发者账号,或者包含指向另一个 OWNERS 文件的 file: 指令。这样可确保随着时间的推移,代码维护责任能够落实到位。

除非另有说明,否则 OWNERS 通常是使用相应依赖项的代码的所有者。

依赖项的 OWNERS 通过以下方式帮助确保 Fuchsia 及其用户的安全:* 在不再需要依赖项时将其移除 * 在上游修复安全或稳定性 bug 时更新依赖项 * 帮助确保使用依赖项的 Fuchsia 功能随着时间和依赖项的变化,继续以最佳方式使用依赖项。

添加了 README.fuchsia

您需要一个 README.fuchsia 文件,其中包含有关您要重用代码的项目的信息。如需查看必须包含的字段列表,请参阅 README.fuchsia。

获取评价

所有第三方添加项和实质性更改(例如重新许可)都需要获得以下批准:

  • 按照 OSRB 批准中的说明审核代码。
    • 如果依赖项或子依赖项不会在 Fuchsia 代码库中使用,请在 OSRB 请求中指定这一点,并说明将通过添加到此屏蔽列表来将该依赖项或子依赖项列入 Fuchsia 代码库的屏蔽列表。 如果要在 Fuchsia 结账中使用,则会产生大多数许可问题。
  • 如果第三方项目对安全性至关重要(如 README.fuchsia 中所定义),请让 security-dev@fuchsia.dev 中的某个人审核相应更改。

特殊情况

大多数第三方依赖项都可以遵循上述布局。不过,有一小部分依赖项在特殊情况下会以不同的方式进行管理。

如果存在异构依赖项,可能会增加复杂性和维护费用,而这些费用是由第三方代码的直接依赖项产生的。此外,它们还会增加常见全局维护任务的复杂性,例如:

  • 执行 Git 管理任务。
  • 更新和维护工具链。
  • 通过更新来自上游来源的易受攻击的第三方代码,来应对已披露的安全漏洞。
  • 重构 build 规则,例如强制执行新的编译时检查。

请在另辟蹊径时仔细考虑。

将旧版第三方代码迁移到当前布局

将所有现有的 //third_party 代码迁移到上述布局仍在进行中,欢迎贡献。

如需将旧版第三方代码库迁移到此布局,请按照以下步骤操作:

  1. 更新清单。

    1. 将 //third_party/<name> 处现有第三方项目的 path(而非 name)替换为 //third_party/<name>/src,同时保持修订版本不变。

    2. 更新 //.gitignore,以便跟踪 //third_party/<name> 但不跟踪 //third_party/<name>/src。

    然后运行 jiri update -local-manifest-project=fuchsia,将项目移至本地签出中的新位置。

  2. 将 Fuchsia 特定的 BUILD.gn 文件移至 fuchsia.git。

    1. 将 BUILD.gn 文件从 //third_party/<name>/src 复制到 //third_party/<name>(现在是 fuchsia.git 的一部分)。
    2. 在复制的 BUILD.gn 文件中,将对第三方文件的路径引用(格式为 //third_party/<name>/)更新为 //third_party/<name>/src/ 格式。
    3. 将 OWNERS 从 //third_party/<name>/src 复制到 //third_party/<name>,如果 不存在,则创建它。查看 OWNERS 文件,确保其遵循最佳实践。
    4. 将 README.fuchsia 从 //third_party/<name>/src 复制到 //third_party/<name>。查看此文件的内容,确保元数据正确无误。在极少数情况下,第三方代码会在第三方代码库中进行修改,此类更改会列在 README.fuchsia 中。本地修改通常需要您做出本指南中未涵盖的特殊调整。
    5. 查看 //third_party/<name>/src 中是否有任何其他第一方 .gni 文件,并将这些文件也移至 //third_party/<name>。
    6. 更新 //third_party/<name>/BUILD.gn(以及包含源路径的其他文件,例如 .gni 文件),以使用新的源位置 //third_party/<name>/src。这需要更新所有来源,包括目录路径等。
  3. 将 //third_party/<name>/src 变成镜子。

    更改 //third_party/<name>/src 以跟踪上游,使其仅在 git log 中包含上游更改。为此,您可以更新清单以引用上游提交哈希。

    示例:http://tqr/427570

  4. 提交并推送您的更改。所有这些更改都可以在单个 CL 中完成。

您可以通过运行 jiri update -local-manifest-project=fuchsia,然后进行 build(例如使用 fx build)在本地验证更改。

深入阅读