RFC-0268:SDK 类别更新

RFC-0268:SDK 类别更新
状态已接受
区域
  • 开发者
说明

更新 SDK 类别集并阐明其含义。

问题
Gerrit 更改
作者
审核人
提交日期(年-月-日)2025-02-20
审核日期(年-月-日)2025-04-02

问题陈述

更新了 RFC-0165 中记录的 SDK 类别集,以反映当前使用情况并阐明含义。

摘要

此 RFC 更改了 SDK 类别的集合,并包含更新后的语言,用于描述所有 SDK 类别的含义和用途。这些类别取代了 RFC-0165 中记录的 SDK 类别设计部分中的类别详细信息可用于更新 SDK 类别文档

利益相关方

教员:neelsa@google.com

审核者

  • 平台版本控制:hjfreyer@google.com
  • 开发者:wilkinsonclay@google.com
  • 测试:crjohns@google.com

共同化

此 RFC 中的更改是与平台版本控制团队一起提出和讨论的。问题 367760026 及相关问题中讨论了 CTF 测试的要求。

要求

更新类别的目的是:

  • 减少了用户对 SDK 类别及其适用情形的困惑。这包括移除未使用的过时类别。
  • 具体而言,要解决有关 partner_internal 的困惑,该属性经常被误解,部分原因是其名称含糊不清,并且包含“internal”。
    • 此类别并非 RFC-0165 中记录的 SDK 类别,而是 API 委员会讨论串的成果。
    • 此类别用于以下两种 ABI:a) SDK 中随附的预编译库使用的 ABI;b) 主机工具使用的 ABI。虽然前者也添加了此功能,但后者的使用次数是前者的两倍。此外,RealmFactory SDK 要求目前建议使用此类别。
    • 在交付组件中使用的库和开发者使用的工具可能具有截然不同的兼容性窗口要求 - 随着 Fuchsia 的成熟和处于弃用阶段的 API 级别数量的增加,这种差异可能会显著扩大。
  • 定义一种解决方案,用于稳定 CTF 测试所使用的 API,而无需在 SDK 中发布 API 的开销或承诺(问题 367760026)。
  • 根据使用情形和暴露程度或风险,实现不同的流程和兼容性窗口。
    • 具体而言,减少了稳定 CTF 测试所需且由主机工具使用的 API 的开销,这些 API 过去使用不稳定 API,因此存在兼容性中断的风险。

此 RFC 不会尝试解决理论上或非常罕见的场景,例如问题 369892217 中描述的场景。

设计

RFC-0165 中一样,新类别的受众群体单调递增。括号中显示的是被替换的现有类别。

  • compat_test(之前称为 cts
  • host_tool(之前位于 partner_internal 内)
  • prebuilt(之前位于 partner_internal 内)
  • partner

每个类别名称都是一个单数名词,用于描述相应类别的受众群体或相应类别中的 API 可在何处使用。如需为受众群体命名,请在类别名称中添加“开发者”。例如,“宿主工具开发者”。

除了上述被替换的类别之外,以下RFC-0165 中记录的 SDK 类别也被移除:

  • excluded:在功能上等同于不指定 SDK 类别。此类别很少使用,并且不清楚这些用途是否表明原子应永远不包含在 SDK 中。您可以改用注释,这种方式更灵活,也更清晰。
  • experimental:在 RFC-0165 中被描述为意义不大。
  • internal:相当于未指定 SDK 类别。(大多数用途已被移除。其余用途已重新利用此类别 - 请参阅问题 372986936。在这些使用情形被淘汰之前,我们将继续为该类别提供有限的支持。)
  • public:从未实现。在扩大 SDK 的受众群体范围时,我们可以重新评估该机制。我们日后可以轻松添加此类类别。

移除 public 后,partner 等同于“已在 SDK 中发布”。之所以保留现有名称,是因为它被广泛使用,其含义被广泛认知和理解,并且未来可能会容纳 public 或类似内容。

以下部分将详细介绍每个类别的含义和兼容性要求,首先提供可在 sdk_atom() 模板等位置使用的简短说明。以下是关键点总结:

  • prebuiltpartner 类别的库可用于最终用户设备上的生产用例,因此对平台实现具有相同的兼容性要求。
  • 只有 partner 类别的 API 可供树外开发者(SDK 使用者)直接使用。
  • 所有类别均可用于 FIDL 库。其他 SDK atom 类型通常直接向开发者公开,因此其他类别对他们来说不太有意义。
    • 因此,当前实现仅允许非 FIDL Atom 类型位于 partner 类别中。
  • 不稳定的库(在 SDK 中公开,但仅在 HEAD 中公开,且不保证兼容性)允许归入 partner 类别。其他类别的目的是实现兼容性,因此不稳定的库不太适合这些类别。
    • 因此,当前实现仅允许 partner 类别的库不稳定。
  • 在旨在检测和防止稳定 API 级别发生更改的机制方面,所有类别的库都受到同等对待。
    • 目前,此类测试仅限于针对 FIDL 库的 API 摘要黄金文件的比较。每个稳定的数字 API 级别在创建时都会进行快照。NEXT 的快照也会作为 API 更改检测和审批机制来维护。如需了解详情,请参阅 SDK 历史记录

下表总结了上述信息。反映当前实现的列会标明。

名称 上一个类别 可在最终用户设备的正式版中使用 可供 OOT 开发者直接使用(“在 SDK 中”) 强制执行更改检测 是否与 FIDL 库搭配使用? 与其他 SDK atom 类型搭配使用?(当前实现) 可能不稳定(当前实现)
compat_test cts(未实现)
host_tool partner_internal
prebuilt partner_internal
partner 不适用

compat_test

“可用于配置和运行兼容性测试,但可能不会在 SDK 中公开以供生产环境使用,也不会被主机工具使用。”

注意:为了在当前机制和实践的背景下清晰起见,本部分使用“CTF”代替“兼容性测试”。不过,此 RFC 并未禁止在未来可能出现的类似类型的平台兼容性测试中使用。

此类别的库很可能包含 CTF 测试 realm 工厂协议,或者通过 realm 工厂返回的 fuchsia.testing.harness/RealmProxyfuchsia.component.sandbox/Dictionary 提供给测试。这些协议为比较不同 Fuchsia 版本中相同操作的行为提供了一个稳定的测试框架,并且框架协议本身也必须具有兼容性保证,以确保兼容性测试可以在相关的 Fuchsia 版本上运行。

虽然此类别中的 API 可在平台内的生产代码中使用,但只能通过 CTF 测试领域或类似方式在平台外公开。

注意:此类别中的 FIDL 库(与所有 SDK 类别中的 FIDL 库一样)必须在 "fuchsia" FIDL 平台中进行版本控制。因此,如果库名称以 test. 或除 fuchsia. 之外的任何字符串开头,则必须在库的 @available 属性中指定 platform="fuchsia"

  • 曝光度:CTF 测试以及负责这些测试的 Fuchsia 平台开发者。CTF 测试非常重要,因为它们有助于确保 ABI 兼容性,尤其是对之前 API 级别的运行时支持。
  • ABI 兼容性窗口:只要我们需要运行相关的 CTF 测试,就必须支持相应 API。
    • 一般来说,这意味着只要 支持弃用阶段(“运行时支持”)的 API 级别的测试使用它们,它们就会被纳入。
    • 我们可以选择停止运行测试、重新构建测试以使用其他 API,或者引入代理来使用新 API。

host_tool

“可供平台组织提供的主机工具(例如 ffx)使用,但不得供 SDK 中的正式版代码或预构建的二进制文件使用。”

  • 公开范围:使用平台提供的工具与支持相应工具所支持的 API 级别的目标 Fuchsia 设备互动的开发者。
  • ABI 兼容性窗口:必须支持 API,直到平台不再支持在任何支持这些 API 的 API 级别与主机工具通信为止。
    • 这与使用不同版本的宿主工具与给定的平台版本进行通信有关。
    • 注意:平台为此主机工具提供的运行时支持的 API 级别集可能与以下任一或两者都不同:
      • 当前平台版本支持的组件目标 API 级别集(组件运行时兼容性)。
      • 当前版本中的宿主工具支持用于与目标设备通信的 API 级别集。
  • 由于此类别中的 API 不在 IDK/SDK 中使用:
    • 任何非平台组件(即由树外开发者构建的组件)都无法使用它们(除非进行破解)。
    • 我们可以打破它们,而不会影响最终用户,只要我们愿意处理对下游开发者的影响。我们还需要考虑 CTF 测试的任何使用情况。

实现备注:IDK/SDK 中的宿主工具具有 "partner" 类别,但可能会使用此类别中的 API。不过,"partner" 中的 API、代码、预编译库和预构建软件包不得使用此类别中的 API。

预构建

“可能是 SDK 中包含的预构建二进制文件用于与平台交互的 ABI 的一部分。此类别中的 API 在 SDK 中不可用,无法供树外开发者直接使用。”

SDK 中的预构建二进制文件(用于生产环境)目前包括预编译的静态库、预编译的共享库和软件包。从树外开发者的角度来看,这些是二进制文件的实现细节的一部分,不会在面向开发者的库或封装组件的 API 中使用。预构建库和软件包内部使用的源集和库不需要属于任何 SDK 类别,但它们用于与平台互动的 API 需要属于某个 SDK 类别。

  • 曝光对象:最终用户。
  • ABI 兼容性窗口:只要支持 API 的任何 API 级别处于受支持日落阶段,就必须支持这些 API。也就是说,与 partner 相同的窗口。
  • 因为平台团队控制着使用此类别中 API 的所有软件:
    • 我们不必过于担心开发者人机工程学。
    • 我们无需担心第三方组件的使用。
    • 我们可以替换 SDK 预编译库和预构建软件包中针对新 API 级别 (NEXT) 的用途,从而比我们担心下游用途时更快地放弃运行时支持(无需弃用)。

伴侣

“包含在 SDK 中,供树外开发者直接使用相应 API。”

  • 曝光度:最终用户、树外开发者和产品所有者
  • ABI 兼容性窗口:只要支持 API 的任何 API 级别处于受支持日落阶段,就必须支持这些 API。
  • 此类别的功能由树外开发者和/或产品组件路由到组件或从组件路由。
    • 例如,功能产品所有者必须将功能路由到平台,并且必须将功能路由到 SDK 中的预构建软件包或从预构建软件包路由功能。

实现

实现将分以下阶段完成:

  1. excludedexperimental 已移除。
  2. 移除了对 public 的引用。
  3. cts 替换为 compat_test 并实现它。
  4. 将 https://fxbug.dev/365602422 中跟踪的 FIDL 库添加到 compat_test 类别,并从许可名单中移除这些库。
  5. partner_internal 替换为 host_testprebuilt
    • 更新了 ffx 插件和工具使用的 SDK 标记机制,以允许同时使用两者。
    • 添加了临时措施,以允许将 FIDL 库的重新分配推迟到下一步。
  6. 使用 partner_internal 将 FIDL 库分配给 host_testprebuilt(视情况而定)。
  7. 最终,在现有用途已升级到受支持的类别或已移除后,移除对 internal 的支持(问题 372986936)。

性能

由于类别只会影响 build,并且只会更改现有机制中使用的字符串,因此不会对性能产生影响。

工效学设计

平台开发者使用的机制保持不变。类别数量减少,名称更加精确,应该有助于您了解这些类别的含义以及哪种类别适合给定的使用情形。

向后兼容性

此 RFC 仅影响平台 build 规则。在实现过程中,系统会更新已移除类别的所有用途。

安全注意事项

此 RFC 不会更改 build 中存在的或向开发者公开的 ABI 表面。

隐私注意事项

此 RFC 不会更改 build 中存在的或向开发者公开的 ABI 表面。

测试

//build/sdk/sdk_common/sdk_common_unittest.py 中的类别测试将更新,以反映每个类别更改。

此外,任何这些类别中的 FIDL 库都应在 //sdk/history 中包含 <library_name>.api_summary.json 文件。对于添加到 compat_test 的库,可以验证这一点。此外,我们可以在本地删除所有此类文件,并确保它们已生成(Git 中没有缺失的文件)。

文档

主要 SDK 类别文档将进行更新。此外,还将更新 RealmFactory SDK 要求参考文档,以反映 partner_internal

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

大多数替代方案都涉及较少的选项,以减少平台开发者需要了解的内容和做出的决策。例如,将 partnerprebuilt 组合在一起,因为它们具有相同的兼容性要求,甚至可以只使用一个位来表示某个内容“在 SDK 中”/需要兼容性或不需要兼容性。有人曾非正式地提议用两个布尔值完全替换现有类别

虽然这些选项在适当情况下可以实现确保兼容性的目标,但它们无法满足一些非技术要求。例如,平台开发者表示希望在不进行完整 API 校准的情况下获得兼容性保证。(或许在未来,这方面的问题会减少。)此外,如果我们知道平台团队拥有 API 的所有使用权,则可以提供更大的灵活性。这可能尤其适用于平台是客户端的 FIDL 协议(请参阅 RFC-0241)。有人建议采用命名惯例来保留这些属性。不过,这可能会造成更多混淆,并且更难强制执行,例如在 build 规则中。

此 RFC 中的更改是增量式的,继续使用类别字符串的概念和现有的强制执行机制,这意味着可以快速实现这些更改。做出这些更改并不妨碍我们在未来积累更多经验并更好地了解兼容性需求后做出此类更改。具体而言,我们可能需要一些机制来为 SDK 中的 API 定义不同的兼容性窗口。

另一种替代方案是保留单个类别 partner_internal(可能使用新名称),以用于宿主工具和预编译库用例。不过,通过描述使用情形来解释某些内容似乎比找到一个涵盖两者的明确名称更容易。如果将来需要考虑打破兼容性,单独设置类别还可以提供使用记录。分离还允许两者各自的支持窗口有所不同,以防平台和宿主工具具有不同的兼容 API 级别范围。

在先技术和参考资料

  • RFC-0165 定义了当前类别集,这些类别已记录在现有 SDK 类别文档中。
  • API 委员会帖子讨论了许多相关问题,最终确定了 partner_internal 类别,其中包括:
    • 需要 SDK 中没有的稳定 API。
    • 不希望向应用直接公开某些 API 的需求,以及控制所有使用 API 的代码的优势。
    • CTF 测试作者会有类似的使用场景。
    • 新类别的说明为“内部可见,合作伙伴稳定”,这为最终名称 partner_internal 提供了背景信息。
    • 建议将 "prebuilts" 作为新类别的名称。
      • 有人基于其他含义对该名称提出异议,但从轶事来看,在 SDK 中提及静态库和共享库时,该术语似乎变得越来越常见。
  • 问题 328322682 包含对现有 SDK 类别的早期评估。
  • 问题 367760026 提供了 compat_test 的动机。
  • RealmFactory SDK 要求描述了 RealmFactory FIDL 协议的要求。