SDK 类别

每个 SDK Atom 都有一个类别,用于定义哪些类型的 SDK 使用方可以看到该 Atom。随着 SDK Atom 的成熟,我们可以提高其曝光度,这意味着提高其稳定性保证。

设计初衷

Fuchsia 的构建方式是将许多不同的组件组合在一起,这些组件使用 FIDL 中定义的架构与协议进行交互。Fuchsia 项目中的组件使用与第三方编写的组件与 Fuchsia 平台交互的相同机制相互交互。因此,我们可以使用一种统一的机制来开发 Fuchsia 和针对 Fuchsia 进行开发,这对我们来说很有帮助。

最简单的方法是将所有 FIDL 定义放入 Fuchsia SDK,然后让所有开发者在开发组件时使用这些相同的 FIDL 定义。不过,这种方法会失效,因为设计 API 时会出现一个常见的矛盾:API 设计者需要能够迭代其设计,而 API 使用方需要稳定性,以便在 API 之上构建应用。

本文档介绍了 SDK 类别,这是 Fuchsia 平衡这些问题的主要机制。

设计

FIDL 库是 SDK Atom 的一个示例,但还有其他类型的 SDK Atom,包括 C++ 客户端库、文档和工具。SDK 类别适用于每种类型的 SDK Atom,但本文档使用 FIDL 库作为运行示例。

SDK 类别通过认识到不同的 API 使用方具有不同的稳定性需求,从而平衡 API 的迭代和稳定性需求。与 API 设计师“更近”的 API 使用方通常对稳定性的需求较低,并且通常是第一个向 API 设计师提供实现反馈的客户。

每个 SDK Atom 都带有 SDK 类别注解,该注解定义了哪些 SDK 使用方可以依赖于该 SDK Atom。例如,如果 fuchsia.foo FIDL 库的 SDK 类别为 internal,则表示只有 Fuchsia 项目中的 SDK 使用方可以依赖于 fuchsia.foo。如果有人想要更改 fuchsia.foo,则可能会破坏 Fuchsia 项目中的使用方,但不会破坏其他项目中的使用方。

再举一个例子,假设有一个 SDK 类别为 partnerfuchsia.bar FIDL 库,这意味着 fuchsia.bar 既可以在 Fuchsia 项目中使用,也可以由与 Fuchsia 项目建立合作伙伴关系的 SDK 使用1。当有人更改 fuchsia.bar 时,他们更有可能破坏使用方,因为他们可能会破坏依赖于 fuchsia.bar 的合作伙伴。

除了定义一系列逐渐增加的 API 使用方集之外,SDK 类别还定义了逐渐增加的稳定性时间范围。例如,fuchsia.foo 在一天之内可能会发生巨大变化,因为 internal 类别会限制对 Fuchsia 项目本身的曝光度。更改 fuchsia.foo 的用户可以同时更改所有客户端和服务器,这意味着 API 所需的稳定性时间窗口非常小或为零。相比之下,Fuchsia 与合作伙伴项目签订的协议中包含了对兼容性时间范围的预期。

如果不希望将预构建 partner SDK 原子中使用的 API 公开给 SDK 用户,则需要为这些 API 提供额外的 SDK 类别。此 partner_internal 类别将强制执行与 partner 类别相同的 API 兼容性时间范围,而无需将这些 API 添加到 SDK API Surface 区域。

典型的 SDK Atom 在 SDK 之外开始其生命周期,没有 SDK 类别。当 SDK 中的托管工具或预编译库需要使用它时,系统可能会先将其添加到 partner_internal 类别的 SDK 中。在某个时候,API 委员会会将 SDK Atom 直接提升到 partner SDK 类别,通常是在合作伙伴需要访问 Atom 中包含的 API 时。

请注意,此机制与用于平台版本控制@available 机制相辅相成。@available 机制会记录 FIDL API 的更改时间和方式。SDK 类别机制决定了 API 设计师可以更改的速度政策

类别

SDK 类别已在 每个 SDK Atom 都有一个 category 参数,该参数的值为以下值之一:

  • internal:已废弃(不允许新用途)
  • compat_test:支持在 Fuchsia 的兼容性测试中使用
  • partner_internal:支持在 partner 类别的非源 SDK 原子中使用,但不会向 SDK 用户公开
  • partner:部分合作伙伴支持使用

这些类别构成一个有序列表,受众群体呈单调递增趋势。例如,partner 类别中的 SDK Atom 必须可用于兼容性测试,partner 在此列表中位于 compat_test 之后。

承诺

将 API 添加到 partnerpartner_internal 类别,就相当于向合作伙伴承诺,我们不会破坏其代码或对其施加不当的流失。每个拥有这类 API 的团队都有责任履行这些承诺。

internal

除了适用于 Fuchsia 项目中的所有代码的承诺之外,internal 类别中的 API 没有其他承诺。

如果您的 API 仅由树内代码调用,并且通信的两端始终是从 Fuchsia 源代码的同一修订版构建的(例如两个平台组件相互通信的情况),则应为 internal

请注意,即使您的 API 的所有客户端都在树中,也不足以说它属于 internal。例如,ffx 的源代码位于 Fuchsia 树中,但不符合第二个要求:在一个 Fuchsia 修订版中构建的 ffx 子工具将经常与在另一个修订版中构建的设备通信。因此,ffx 子工具以及 SDK 中分发的任何其他工件不得依赖于 internal API。

partner_internal

合作伙伴不会使用 partner_internal API 编写自己的代码,但他们仍然会通过 Fuchsia 团队编写的工具、库或软件包间接依赖于这些 API。由于 Fuchsia 团队拥有使用这些 API 的代码,因此我们可以更改这些 API,而不会流失合作伙伴。不过,使用 partner_internal API 的工具、库和软件包通常会采用与其所对接的平台组件不同的修订版本进行构建。因此,每当我们更改 partner_internal API 时,都必须遵循我们的 ABI 兼容性政策。

也就是说,partner_internal 类别的 API 所有者同意:

  • 在其 API 上使用 FIDL 版本控制注解。
  • 仅在 in-development API 级别或 HEAD 级别修改其 API。 一旦 API 级别被声明为稳定版,便不应再更改(请参阅 version_history.json)。
  • 确保实现这些 API 的平台组件与 Fuchsia 支持的所有 API 级别兼容(请参阅 version_history.json)。

如需详细了解 API 兼容性,请参阅 API 演变指南

partner

合作伙伴直接使用 partner API。这些 API 是我们合作伙伴构建应用的基础,我们有责任确保该基础可靠且稳定。

partner 类别的 API 所有者同意:

  • 执行上文 partner_internal 部分中的所有版本控制提交操作。
  • 掌控合作伙伴在使用此 API 时的开发者体验,包括:

    • 提供良好的文档。
    • 遵循一致的样式。
    • 您希望在所用 SDK 中看到的任何其他内容。

    如需了解相关规则和建议,请参阅 API 开发指南

  • 承认对新 API 级别进行向后不兼容的更改会给我们的合作伙伴带来成本,即使我们遵循 API 演变指南也是如此。如果合作伙伴选择更新其目标 API 级别,则需要在其代码库中进行修改,以适应您的更改。因此,切勿轻易做出这些更改。

    如果您决定进行不向后兼容的更改,则同意根据流失率政策支付该更改的大部分下游费用。

    partner API 相比,对 internal API 进行更改要容易得多,因此,任何计划中的 API 重构都应在将 API 添加到 partner 类别之前完成,而不是之后。

更改历史记录


  1. 目前,这组合作伙伴尚未对外公开。随着项目的扩大,我们可能需要重新考虑合作伙伴关系的做法。