RFC-0216:Fuchsia 托管代码库指南

RFC-0216:Fuchsia 托管代码库指南
状态已接受
区域
  • 开发者
  • 治理
  • 常规
说明

在 fuchsia.git 之外开发 Fuchsia 托管代码的指南

问题
Gerrit 更改
作者
审核人
提交日期(年-月-日)2022-1-17
审核日期(年-月-日)2023-04-20

摘要

随着 Fuchsia 获得全面的 Bazel 支持,以及越来越多地关注功能齐全的 Fuchsia SDK,在 fuchsia.git 中开发 Fuchsia 组件的优势已大大降低。此 RFC 简要介绍了在其他 Fuchsia 托管的代码库中开发组件的要求和最佳实践。它无法满足 fuchsia.git 之外的汇编需求。

设计初衷

自 Fuchsia 项目问世以来,大部分开发工作都在由 jiri 工具管理的单一环境中进行,该工具会协调多个源代码库中的开发工作,就像它们是单个代码库一样。目前,我们非正式地将该环境称为 fuchsia.git,因为 Fuchsia 的大部分开发工作都集中在该代码库中。

单个受管理环境(通常位于单个代码库中)在开发方面具有显著优势。您可以快速更新整个代码库中的代码(通常只需进行一次更改),从而减少在不同代码库中协调不同版本的复杂性。开发者工具和第三方 / 库代码的更新可以集中进行,这意味着整个组织都可以分享升级和代码清理的优势。通用代码标准让您无需再为代码样式或目录布局争论。开发者知道要搜索任何给定代码时应使用哪个代码库。

不过,集中式代码库无法满足所有 Fuchsia 开发者的需要。Fuchsia 的代码库要求开发者构建整个系统映像和 SDK,这会显著影响开发速度。由于需要在 fuchsia.git 中构建系统映像和 SDK,因此对于许多开发者来说,构建体验会截然不同。

或许更重要的是,Fuchsia 团队会为不使用 fuchsia.git 的开发者创建抽象,但我们自己通常不会使用这些抽象。这给开始在 fuchsia.git 中工作并期望使用标准 Fuchsia 工作流程的开发者带来了问题,因为他们会遇到 fx 工具和各种脚本,这些脚本与我们与基于 SDK 的开发者分享的脚本几乎完全不同,但也不完全不同。这也使得基于 fuchsia.git 的开发者更难以对基于 SDK 的开发者感同身受,因为他们使用的工作流不同,因此没有相同的动力来改进这些工作流。

Fuchsia Build 团队正在努力解决基于 fuchsia.git 的工作流与基于 SDK 的工作流之间的一些差异,但差异始终会存在,即使只是因为在其他代码库中使用基于 SDK 的工作流的开发者永远不必在这些工作流中构建 SDK 或系统映像。

我们预计,所有开发者都不会在短期内将其代码迁移到基于 SDK 的工作流。2023 年,该团队将专注于支持将驱动程序从 fuchsia.git 迁移出去。对于其他项目,移出 fuchsia.git 是可选操作。近期,我们预计大多数可完全基于基于 SDK 的 API 构建的组件都将从 fuchsia.git 中迁移出去。

为了提高不必为 SDK 做出贡献的项目的开发者工作效率,并提高对 Fuchsia 团队中基于 SDK 的开发者的同理心,Fuchsia 社区希望鼓励开发者在 fuchsia.git 之外使用基于 SDK 的工作流。不过,我们没有关于如何实现此目标的明确指南。本 RFC 旨在根据我们在过去几年内使用基于 SDK 的工作流和 fuchsia.git 工作流的经验,开始填补这些空白。

利益相关方

教员

  • David Moore(davemoore@google.com)

Reviewers:

  • Adam Barth (abarth@google.com) - FEC
  • Chase Latta (chaselatta@google.com) - Bazel 支持
  • Nathan Mulcahey (nmulcahey@google.com) - EngProd
  • Suraj Malhotra (surajmalhotra@google.com) - 驱动程序

咨询了

我们还就此 RFC 咨询了以下人员:

  • Andres Oportus (andresoportus@google.com)
  • Christopher Anderson (cja@google.com)
  • Clayton Wilkinson (wilkinsonclay@google.com)
  • Danny Rosen(dannyrosen@google.com)
  • Harsh Priya NV (harshanv@google.com)
  • Janna Shaftan (jshaftan@google.com)
  • John Wittrock (wittrock@google.com)
  • Renato Mangini Dias
  • Marc-Antoine Ruel (maruel@google.com)
  • Nico Haley(nicoh@google.com)
  • Niraj Majmudar (nirajm@google.com)
  • Seth Ladd(sethladd@google.com)
  • Tim Kilbourn(tkilbourn@google.com)

社交

我们已与 EngProd、FHCP、Drivers、Eng Council、Bazel SDK Integration 和 DevRel 团队分享了此 RFC 的简短版本。

设计

以下是关于启动和开发基于 SDK 的 Fuchsia 托管代码库的一组准则。这些示例并非详尽无遗。例如,虽然我们列出了有关如何及时更新 Fuchsia 托管代码库中的 SDK 的一些准则,但我们尚未详细设计该流程。

代码库命名

代码库名称取决于代码库的内容。我们将指南细分为驱动程序代码库和非驱动程序代码库。

驱动程序

不特定于特定供应商的驱动程序代码应托管在以驱动程序领域命名的代码库中(例如,drivers/audio.git、drivers/wlan.git)。例如,这包括通用驱动程序(例如键盘和鼠标)的代码。这些代码库也不应包含闭源代码。

我们知道,这些区域的名称可能会随时间而变化。将代码库移至新路径可能并非易事。我们建议开发者谨慎选择地区名称,并确保日后更改名称时做好尽职调查。

特定于特定供应商的驱动程序代码应托管在 drivers///。例如,drivers/wlan/intel/iwlwifi。团队可以灵活地确定代码库边界(例如,drivers/wlan/intel/iwlwifi 是单独的代码库,还是位于 drivers/wlan 代码库中)。我们可以根据现有经验提供一些指导;我们相信,随着时间的推移,我们会积累更多经验

  • 如果驱动程序需要使用闭源软件进行构建,我们建议将其与完全开源的驱动程序放在不同的代码库中。

  • 如果多个驱动程序共用大量代码(请参阅下文中的代码共享部分),将它们与该代码一起保存在单个代码库中,可以避免在多个代码库中部署该代码的更新时遇到困难。在这种情况下,开发者通常很难找到所有相关代码库,在其中构建软件并进行测试。对于大多数代码,代码库越少,就意味着在跟上库、SDK 和工具链的最新更新方面需要做的工作就越少。

  • 有时,多个驱动程序会共享大量代码,但由于情况所致,需要将它们放在单独的代码库中。Gerrit 对名称重叠的代码库的支持很不方便(例如,如果 drivers/<area>drivers/<area>/<vendor> 都是代码库),并且当开发者想要将这两个代码库检出到同一目录时,重叠会导致意外冲突的可能性。我们建议将常用代码放置在名为 drivers/<area>/common 的代码库中,而不是名为 drivers/<area> 的代码库中。为了避免代码迁移费用,您可以在多个驱动程序需要之前,在公共区域开发代码。

  • 驱动程序团队可能会决定从稳定分支中发布其驱动程序以进行认证。如果这样做,他们可能会发现管理一个分支比管理多个分支更容易。Fuchsia 团队正在制定驱动程序认证的最佳实践,这可能会成为未来 RFC 的主题。

非驱动程序组件

与驱动程序无关的组件源代码可以托管在以下两个位置之一。开发者可以灵活选择。

组件可以托管在以赞助该组件的功能领域命名的代码库中(例如,experiences.git)。对于功能领域之外的开发者不太感兴趣的组件,我们建议采用这种方式。

组件可以托管在以项目命名的代码库中(例如,workstation.git、cobalt.git)。对于大型项目以及可能对功能领域之外的开发者感兴趣的项目,我们建议采用这种方法。

与驱动程序代码一样,共享源代码库也有优点和缺点。该部分中所述的注意事项也适用于组件。

代码库布局

代码布局应与 Fuchsia 源代码布局文档中的布局相同。必须更新源代码布局文档,以反映允许使用 Bazel 构建系统;即允许使用 BUILD.bazel 而非 BUILD.gn,以及 WORKSPACE 文件的存在。

我们将提供一个基础模板代码库,开发者可以将其克隆以创建新的代码库。我们可能还有其他代码库,其中包含专门用于驱动程序、组件以及产品集成(如果需要)的工具和布局。该模板将包含 Fuchsia 代码库所需的基本信息。例如,这目前包括 LICENSE 文件、包含预定义目标的 Bazel 构建文件(基础架构可以读取这些目标,以了解要构建和测试的内容),以及列有至少两位所有者的顶级 OWNERS 文件。

驱动程序需要进行认证测试。该认证计划称为 Fuchsia 硬件认证计划 (FHCP)。托管在 fuchsia.git 中的 FHCP 测试应位于相关源代码区域中名为 tests/conformance 的顶级目录中。请注意,源代码区域的顶级目录一定与代码库根目录相同,因此 fuchsia.git 中的 tests/conformance 目录不一定位于代码库根目录中。托管在其他 Fuchsia 托管的基于 SDK 的代码库中的 FHCP 测试必须位于相应驱动程序区域(例如,tests/conformancedrivers/wlan.gitdrivers/audio.git)。

代码共享

Fuchsia 组织支持在代码库之间共享代码的多种方法。

通过 Fuchsia SDK 分享

在 Fuchsia 托管的代码库之间共享代码的主要机制是 Fuchsia SDK。Fuchsia SDK 用于开发在 Fuchsia 产品上运行的软件。SDK 中由 Fuchsia 组织开发的部分(例如,模拟器除外)目前仅在 fuchsia.git 中开发,但这可能会随时间而变化。

Fuchsia SDK 由多个软件工件或元素组成。RFC-0165 介绍了多个 SDK 类别;每个元素都分配到其中一个类别。这些类别大致描述了我们认为每个工件有多稳定,以及我们认为它们在哪些场景中可以适当地使用。其中有三个类别与本 RFC 相关:

  • internal:支持在 Fuchsia 平台源代码树中使用;
  • partner:部分合作伙伴支持使用;
  • public:可供公众使用。

Fuchsia 开发者可能熟悉 IDK,它目前由一组合作伙伴 SDK 元素组成。

由于这些仓库与平台的距离较近,因此我们主要希望由 Fuchsia 托管且基于 SDK 的仓库使用合作伙伴和内部类别 SDK 元素。他们使用合作伙伴还是内部账号取决于其使用场景:

  • Fuchsia 托管驱动程序应使用通过 fuchsia.git 提供的合作伙伴类别 SDK 元素进行开发。例如,这包括在 IDK 中可以找到的所有内容。

  • 作为 SDK 下游使用方的 Fuchsia 托管组件应使用可通过 fuchsia.git 提供的合作伙伴类别 SDK 元素进行开发。

  • 实现合作伙伴类别 SDK 接口的 Fuchsia 托管组件可以使用内部 SDK 元素。

如果开发者需要共享平台 API 或 ABI,则应使用 Fuchsia SDK。具体而言,FIDL 定义是平台的接口,应通过 SDK 共享。如果开发者认为通过其他方式共享其 FIDL 定义有优势,则应咨询 Fuchsia API 委员会。

通过 git 子模块共享

通过 git 子模块共享代码是 fuchsia.git 中的常见模式。Git 子模块是指在其他项目中使用的 Git 项目。本部分中的建议适用于由 jiri 工具和 git 子模块管理的代码库。

在许多情况下,使用 SDK 共享代码是不合适的。我们不希望通过 SDK 重新分发大多数第三方代码,因为这样一来,我们(而非第三方)就必须为所有 SDK 用户提供对该代码的支持。我们还有一些库仅供 Fuchsia 团队使用,例如 fbl。这些库可能会包含在内部 SDK 中,但也可能适合使用合作伙伴 SDK 的 Fuchsia 团队使用。

此外,还有一些工具用于提高工程效率,但仅适用于 Fuchsia 的基础架构和代码标准,例如代码格式设置工具和用于查询 Gerrit 的各种 fx 工具。

如需共享不应包含在合作伙伴 SDK 中的共享代码,可以将其迁移到 git 子模块,并在需要该代码的代码库之间共享。API 委员会和 RFC 流程会对可在合作伙伴 SDK 中包含的内容进行仲裁。

对于目前存储在 fuchsia.git 中且我们希望在 Fuchsia 组织开发者之间共享但不想放入 SDK 中的代码(例如 fblboringssl 库),我们可能会使用此机制。

通过二进制文件分享

某些工具可能会通过二进制文件共享。例如,我们使用 CIPD 为基于 fuchsia.git 的开发者提供我们的工具链副本。我们将继续坚持这一做法。最佳实践与上面的 git 子模块相同:我们建议开发者及时了解适用于其代码库的最新工具。

随时掌握最新动态

确保 Fuchsia 托管的代码库始终包含最新发布的软件至关重要。

  • 所有代码库都必须使用每天(或更快)更新依赖项的自动滚动器。

  • RFC-0148 中所述,每个项目都应尝试以较快的节奏发布和推出自己的内容。该 RFC 并未定义什么是快速节奏,但建议理想状态是,新依赖项在发布后数小时内即可发布。我们将快速节奏的解释权交给代码库所有者,但有以下注意事项。

  • 所有代码库必须使用兼容期内的 SDK。SDK 的兼容性窗口是指使用该 SDK 构建的代码与从头构建的 Fuchsia 产品可以一起使用的时间长度。

  • 处于积极开发阶段的代码库(其使用的 SDK 正在积极更改,以更好地支持该代码库中的用例)每天更新其 SDK(根据解决不兼容性、基础架构损坏和其他合理问题所需的时间进行调整)。

Fuchsia 组织将创建一个流程,用于在所有 Fuchsia 托管的代码库中执行更新 / LSC。每个代码库所有者都必须提供一个联系人,该联系人将快速回复紧急更新请求(例如安全问题、工具链更新的修复程序等)。此流程应允许进行大规模更改的开发者跟踪其更改随时间推移的变化。

出于安全或兼容性原因,所有代码库所有者必须及时回复更新请求。

多代码库开发

虽然所有已提交的代码都需要使用上述某种机制进行共享,但我们预计开发者会遇到需要同时更改多个代码库中代码的用例。例如,开发者可能需要在 fuchsia.git 中开发新的 FIDL API,以供基于 SDK 的工作流中的驱动程序使用,同时还需要同时处理这两者的代码。

Fuchsia 团队有丰富的多代码库工作流程运作经验。大多数问题都属于以下某个类别:

  • fuchsia.git 中工作的开发者对 SDK 进行更改,然后将其导出以供在其他(目标)代码库中使用。

  • 在一个源代码库中处理组件的开发者需要将该组件发布到托管在另一个(目标)源代码库中的软件包代码库。

  • 在一个源代码库中处理组件的开发者需要将该组件提供给另一个(目标)源代码库中的系统汇编。

Fuchsia 团队将开发易于支持这些工作流的工具。

构建系统

Fuchsia 托管的代码库必须使用 Bazel 构建系统。RFC-0095RFC-0139 详细介绍了 Fuchsia 对使用 Bazel 管理新代码库的承诺,因此无需在此重复说明。

产品集成

由于我们支持的产品 build 数量有限,因此目前我们不会要求产品提供专用产品集成代码库。Workstation 产品将继续在 workstation.git 中执行组装(2023 年第 3 季度备注RFC-0220 已废弃此在 workstation.git 中执行组装的计划)。

实现

此 RFC 提供了有关项目应如何布局和管理其代码库的概要指南,但刻意不对实现细节进行详述。每个项目都可以通过多种方式遵循这些准则,我们不希望通过规定过多具体要求而造成人为限制。基于 Fuchsia 托管 SDK 的新项目仍处于起步阶段,随着项目的不断演变,我们在此处列出的所有内容都可能会过时。

性能

我们认为,存在多个代码库不会对性能产生显著影响。

目前,由于 fuchsia.git 中的所有代码都是使用相同的依赖项和工具链配置从头构建的,因此不同组件之间的共享代码是完全相同的。Fuchsia 的文件系统使用此功能来删除二进制文件的重复项,从而节省目标设备上的空间。在多个代码库中拆分代码会导致工具链和依赖项之间出现版本偏差,可能会导致将同一二进制文件的不同版本部署到设备,从而占用空间。您可以尽量在所有代码库中使用相同的 SDK 和工具链,以缓解此问题(请参阅上文中的保持最新状态部分)。

工效学设计

正如“动机”部分所述,我们认为,增加 Bazel 和 SDK 的使用有助于驱动程序和组件开发者缩短开发周期。

向后兼容性

随着代码库让其共享代码过时,向后不兼容的可能性会增加。因此,我们在及时了解最新动态部分中提供了相关建议。

安全注意事项

我们认为 Fuchsia 托管的代码库不会造成安全风险。

隐私注意事项

我们认为 Fuchsia 托管的代码库不会造成隐私问题。

测试

我们认为不需要进行大量的新测试。无论来源位置如何,Fuchsia 基础架构仍会运行所有相关测试。

文档

我们将创建有关开始使用新代码库的操作指南和参考文档。我们还将创建一些可轻松克隆的示例代码库(在某种程度上,这些代码库已经存在)。

缺点、替代方案和未知情况

我们在 Fuchsia 托管的基于 SDK 的代码库中进行重大开发之前,发布了此 RFC。这里的许多标准都是根据经验做出的最佳猜测,可能无法满足我们的需求。随着我们在这些工作流方面获得更多经验,并鼓励在 fuchsia.git 之外开发更多代码,我们可能会重新审视本文档中的指南。