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 构建团队正在努力解决基于 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
工作流的经验,旨在弥补这些不足。
利益相关方
教员:
- 大卫·摩尔 (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 (dannyrisen@google.com)
- Harsh Priya NV (harshanv@google.com)
- Janna Shaftan (jshaftan@google.com)
- John Wittrock (wittrock@google.com)
- 雷纳托·曼吉尼·迪亚斯
- Marc-Antoine Ruel (maruel@google.com)
- Nico Haley (nicoh@google.com)
- Nirajm@google.com
- Seth Ladd (sethladd@google.com)
- Tim Kilbourn (tkilbourn@google.com)
社交:
此 RFC 的简短版本已向 EngProd、FHCP、驱动程序、工程委员会、Bazel SDK 集成和 DevRel 团队进行社交。
设计
以下是一系列用于启动和开发基于 SDK 的由 Fuchsia 托管的代码库的指南。这些内容并非详尽无遗。例如,虽然我们提供了一些有关如何使 Fuchsia 托管代码库中的 SDK 保持更新的指南,但我们没有该过程的详细设计。
代码库命名
代码库名称取决于代码库的内容。我们将指南分为驱动程序代码库和非驱动程序代码库。
驱动程序
并非特定于特定供应商的驱动程序代码应托管在以驱动程序区域命名的代码库中(例如 drivers/audio.git、drivers/wlan.git)。例如,包括键盘和鼠标等通用驱动程序的代码。闭源代码也不应放入这些代码库中。
我们知道,这些区域的名称可能会随时间而变化。将代码库迁移到新路径可能很困难。我们建议开发者谨慎选择区域名称,并确保以后在更改名称时做好尽职调查。
特定于特定供应商的驱动程序代码应托管在 drivers//drivers/wlan/intel/iwlwifi
是单独的代码库,还是位于 drivers/wlan
代码库中)。我们可以根据现有经验提供一些指导;我们相信随着时间的推移,我们将积累更多这方面的经验
如果驱动程序需要闭源软件来构建,我们建议将其保存在与完全开源的驱动程序不同的代码库中。
如果多个驱动程序共享大量代码(请参阅下面的代码共享),则将它们保存在包含此代码的单个代码库中,可避免在多个代码库中发布对代码的更新。处于这种情况的开发者往往会发现很难找到所有相关的代码库,在其中构建软件并对其进行测试。对于大多数代码而言,代码库数量越少,就可及时跟上库、SDK 和工具链的最新更新的工作量,就越少。
有时,多个驱动程序共享实质性代码,但具体情况需要将它们保存在单独的代码库中。Gerrit 对名称重叠的代码库的支持(例如,如果
drivers/<area>
和drivers/<area>/<vendor>
都是代码库)很不方便,而且当开发者想要在同一目录中检查两个代码库时,重叠可能会造成意外冲突。我们建议将通用代码放置在名为drivers/<area>/common
的代码库中,而不是名为drivers/<area>
的代码库中。代码可在多个驾驶员需要之前在公共区域开发,以避免代码迁移费用。驾驶团队可能会决定从稳定分支发布其驱动程序以进行认证。如果他们这样做,他们可能会发现管理一个分支比管理多个分支更容易。Fuchsia 团队正在制定驾驶员认证最佳实践,未来 RFC 可能会将其作为主题。
非驱动程序组件
与驱动程序无关的组件源代码可托管在以下两个位置之一。开发者可以灵活选择。
组件可以托管在一个以支持该组件的功能区域命名的代码库中(例如 experience.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.git
、drivers/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,该 IDK 目前由一组合作伙伴 SDK 元素组成。
由于它们靠近平台,我们主要希望由 Fuchsia 托管的基于 SDK 的代码库使用合作伙伴和内部类别 SDK 元素。他们是使用合作伙伴产品还是内部产品,取决于具体使用场景:
应使用由
fuchsia.git
提供的合作伙伴类别 SDK 元素来开发 Fuchsia 托管的驱动程序。例如,这包括在 IDK 中找到的所有内容。作为 SDK 下游使用方的 Fuchsia 托管组件,应使用可从
fuchsia.git
分发的合作伙伴类别 SDK 元素进行开发。实现合作伙伴类别 SDK 接口的 Fuchsia 托管组件可以使用内部 SDK 元素。
如果开发者需要共享平台 API 或 ABI,则应使用 Fuchsia SDK。特别是,FIDL 定义是平台的接口,应通过 SDK 共享。如果开发者认为通过其他方式分享 FIDL 定义是有利的,应咨询 Fuchsia API Council。
通过 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 中)使用这种机制,例如 fbl
或 boringssl
库。
通过二进制文件分享
某些工具可通过二进制文件共享。例如,我们使用 CIPD 向基于 fuchsia.git
的开发者提供我们工具链的副本。我们将继续这种做法。最佳实践与上述 Git 子模块采用的最佳实践相同:建议开发者及时了解可用于其代码库的最新工具。
随时掌握最新动态
Fuchsia 托管的代码库对于最新发布的软件至关重要。
所有代码库都必须使用自动滚动器,以便每天(或更快)更新其依赖项。
如 RFC-0148 中所述,每个项目应该尝试快速发布和发布自己的内容。该 RFC 没有定义什么是快速发布,但暗示理想的状态是在发布后的几小时内滚动出新依赖项的状态。我们将由代码库所有者来解释如何确定快速部署,并遵循以下注意事项。
所有代码库都必须使用兼容性期内的 SDK。SDK 的兼容性窗口是指使用该 SDK 构建的代码在从头构建的 Fuchsia 产品可以运行的时长。
处于积极开发阶段的代码库(它们使用的 SDK 会在积极更改以更好地支持该代码库中的用例)应该每天更新其 SDK(调整解决不兼容问题、基础架构损坏和其他合理难题所需的时间)。
Fuchsia 组织将创建一个流程,以便在所有 Fuchsia 托管的代码库中执行更新 / LSC。每个代码库所有者都必须提供一个联系人,该联系人将快速响应紧急更新请求(例如,安全问题、工具链更新等)。此过程应该允许开发者进行大规模更改,以便跟踪其随时间的变化。
出于安全性或兼容性方面的考虑,所有代码库所有者都必须立即响应更新请求。
多代码库开发
虽然所有签入代码都需要使用上述机制之一进行共享,但我们希望开发者具有同时更改多个代码库中的代码的用例。例如,开发者可能需要在 fuchsia.git
中开发供驱动程序在基于 SDK 的工作流中使用的新的 FIDL API,并同时处理两者的代码。
Fuchsia 团队拥有让多代码库工作流正常运行的经验。它们通常属于以下某一类:
在
fuchsia.git
中工作的开发者对 SDK 进行更改,随后将更改导出以便在另一个(目标)仓库中使用。处理一个源代码代码库中的组件的开发者需要将该组件发布到另一个(目标)源代码代码库中托管的软件包代码库。
开发一个源代码库中的某个组件的开发者需要将该组件提供给另一个(目标)源代码库中的系统组装。
Fuchsia 团队将开发能够轻松支持这些工作流的工具。
构建系统
Fuchsia 托管的代码库必须使用 Bazel 构建系统。RFC-0095 和 RFC-0139 中详细介绍了 Fuchsia 对新代码库的 Bazel 承诺,在此无需重申。
产品集成
由于我们支持的产品 build 数量有限,因此目前我们不要求为产品使用特殊的产品集成代码库。工作站产品将继续在 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
之外开发更多代码,我们可能会再次访问本文档中的指南。