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)

审核者

  • 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)

共同化

此 RFC 的简短版本已与 EngProd、FHCP、Drivers、Eng Council、Bazel SDK Integration 和 DevRel 团队进行了沟通。

设计

以下是一组用于启动和开发基于 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/conformance 的目录下,该目录对应于相关驱动程序区域(例如,drivers/wlan.gitdrivers/audio.git)。

代码共享

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

通过 Fuchsia SDK 进行分享

Fuchsia 托管的代码库之间进行代码共享的主要机制是 Fuchsia SDK。Fuchsia SDK 用于开发在 Fuchsia 产品上运行的软件。Fuchsia 组织开发的 SDK 部分(例如,不包括模拟器)目前完全使用 fuchsia.git 开发,不过这种情况可能会随时间而变化。

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

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

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

由于它们与平台非常接近,我们主要希望基于 SDK 的 Fuchsia 托管代码库使用合作伙伴和内部类别 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 构建的代码可与从 Head 构建的 Fuchsia 产品搭配使用的时间长度。

  • 正在积极开发的代码库(其中使用的 SDK 正在积极更改,以更好地支持相应代码库中的用例)每天更新其 SDK(并根据解决不兼容问题、基础设施损坏和其他合理困难所需的时间进行调整)。

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

所有代码库所有者必须及时响应出于安全或兼容性原因而提出的更新请求。

多代码库开发

虽然所有已签入的代码都需要使用上述机制之一进行共享,但我们预计开发者会有一些用例,在这些用例中,同时更改多个代码库中的代码是有意义的。例如,开发者可能需要在 fuchsia.git 中开发新的 FIDL API,以供 SDK 工作流中的驱动程序使用,并且同时处理这两者的代码。

Fuchsia 团队在使多代码库工作流正常运行方面拥有丰富经验。在大多数情况下,它们属于以下某个类别:

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

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

  • 在某个源代码库中处理组件的开发者需要使该组件可在另一个(目标)源代码库中用于系统组装。

Fuchsia 团队将开发一些工具,以便轻松支持这些工作流。

构建系统

Fuchsia 托管的代码库必须使用 Bazel 构建系统。Fuchsia 对新代码库使用 Bazel 的承诺已在 RFC-0095RFC-0139 中详细阐述,此处无需赘述。

产品集成

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

实现

此 RFC 提供了有关项目应如何布局和管理其代码库的高级指南,但有意省略了实现细节。每个项目都可以通过多种方式遵循这些准则,我们不想通过规定过多的细节来人为地设置限制。基于 SDK 的新 Fuchsia 托管项目仍在启动中,我们在此处规划的任何内容都可能会随着项目的发展而过时。

性能

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

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

工效学设计

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

向后兼容性

随着代码库中共享的代码过时,向后不兼容的可能性会越来越大。因此,我们在保持最新状态部分中提供了相关建议。

安全注意事项

我们认为,Fuchsia 托管的代码库不会带来安全风险。

隐私注意事项

我们认为,Fuchsia 托管的代码库不会引发隐私权问题。

测试

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

文档

我们将创建有关如何启动新代码库的操作指南和参考资料。我们还将创建可轻松克隆的示例代码库(这些代码库在一定程度上已存在)。

缺点、替代方案和未知因素

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