RFC-0246:API 级别为 32 位

RFC-0246:API 级别为 32 位
状态已接受
领域
  • 常规
说明

将 API 级别重新定义为 32 位数字,而不是 64 位

Gerrit 更改
作者
审核人
提交日期(年-月-日)2024-04-01
审核日期(年-月-日)2024-04-29

摘要

此方案将 API 级别的定义更改为无符号 32 位 整数。这将取代 RFC-0002,后者将其定义为无符号 64 位 整数。

设计初衷

目前可在以下位置找到以下代码: target_api_level.gni(为清楚起见,请转述):

if (override_target_api_level == -1) {
    clang_fuchsia_api_level = 4294967295
    fidl_fuchsia_api_level = "LEGACY"
}

一般来说,这表示如果在构建时未指定 API 级别, 在 fuchsia.git 中,clang_fuchsia_api_level 应设置为 0xFFFFFFFF,并且 fidl_fuchsia_api_level 应设置为字符串值 "LEGACY"。这个 字符串稍后会被 fidlc 解释为值的别名 0xFFFFFFFFFFFFFFFF(如 RFC-0083 中所定义)。

这展示了两个问题:

  1. 有一个“Clang API 级别”和“FIDL API 级别”; 不同的值。
  2. API 级别有时用字符串表示,有时用整数表示。

clang、FIDL 以及...?

RFC-0002 将 API 级别定义为 64 位整数,而后续的 RFC 分配特定的 64 位整数并赋予其名称和含义。对于 实例,LEGACY0xFFFFFFFFFFFFFFFF 标识。但根据代码, 而是将 0xFFFFFFFF 传递给 Clang,因为遗憾的是,API 在 Clang 中,级别限制为 32 位。

事实并非如此。

Clang 通过 availability 实现兼容性的原因 属性,它表示 VersionTupleVersionTuple 打包了一个 4 的元组 表示版本的整数 major[.minor[.subminor[.build]]] 转换为 128 位结构。Fuchsia API 级别建模为“主要版本”在此 因此被限制为 32 位。

Clang 是 Fuchsia 平台版本管理的关键部分, 必须解决不一致的问题。

string对阵int对阵...?

主机工具和构建系统在 代表 API 级别即使在 fuchsia.git 的构建系统中, 如上述代码块所示。

这不一定是问题,而且此 RFC 也无法完全解决问题。 不过,本文将尝试提供指导来应对这种不明确的情况。

利益相关方

教员:abarth@google.com

审核者

  • ddorwin@google.com
  • mkember@google.com
  • haowei@google.com

已咨询

  • chaselatta@google.com
  • phosek@google.com
  • ianloic@google.com

社交化

与平台成员就 Google 内部错误展开讨论 版本控制工作组和工具链团队。

要求

API 级别必须能表示为字符串,包括在这两种命令行中, 以及文件和目录的名称中。

API 级别必须是完全有序的,因此我们可以这样说:“添加了 Foo 因此 Foo 是 API 级别 M 的一部分。"NN <= M

我们必须能够为某些 API 级别指定特殊名称和行为。另一个 本节中的要求同样适用于这些“特殊”规则,API 级别。

设计

整数表示法

API 级别将重新定义为无符号 32 位整数。

此空间的下半部分(即,低于 0x80000000 的 API 级别)为 视为“正常”API 级别。此空间的上半部分已预留。这个 RFC 和未来的 RFC 将定义大于 或 的特定值的含义 等于 0x80000000

统一处理所有 API 级别的工具可能会忽略 “normal”和保留值,并将它们全部视为无符号 32 位整数, 按典型方式进行排序

具有适用于特定 API 级别的特殊逻辑的工具应拒绝 指定了它无法理解的预留 ABI 级别值。

字符串表示法

API 级别可以用字符串以多种不同的方式表示:

  • 表示 [0, 232)是 API 级别的字符串表示(例如, "7")。
  • 特殊 API 级别可以由其名称表示,该名称采用大写形式(对于 示例 "HEAD")。
  • 工具不应接受更深奥的值,例如 "0016""0x20"。 因为这样做可能会产生混淆例如,"0016" 是八进制还是 小数吗?"2A" 可能是十六进制数,但如果被接受,则为 "29" 是十六进制值还是十进制数?不过,字符串解析逻辑 超出单个工具作者控制范围的库,因此工具可能接受 这些值。

每个 API 级别都有且只有一种规范字符串表示法

  • 针对“normal”API 级别,则使用 base-10 UTF-8 字符串表示形式是规范的 (例如 "13")。
  • 对于“特殊”API 级别,则以大写形式指定规范名称(例如, "NEXT")。

需要知道某个 API 级别的规范字符串表示法的工具 必须返回错误,才能获取 预留的 API 级别(即大于或等于 0x80000000 的级别) 因为他们不知道这个特殊名称

特殊 API 级别

以下 API 级别具有特殊名称:

  • PLATFORM = 0xFFF00000 = 4293918720PLATFORM以前扮演过角色 由 LEGACY 提供,默认情况下,平台将通过 API 构建 PLATFORM 级。之前,LEGACY0xFFFFFFFFFFFFFFFF FIDL,无法在 Clang 中表示。

    LEGACY 已被 RFC-0232 弃用,目前正在移除 但即使在该工作完成后,平台构建、C++ 和 Rust 代码将使用 PLATFORM 来检测正常的平台 build。

    PLATFORM 仅适用于在 OS build 和 是 IDK 的一部分。在此类库中,目标 API 级别低于 PLATFORM 表示代码作为 SDK 的一部分进行构建,并且只能使用 API 元素。如果 目标 API 级别等于 PLATFORM,则代码将作为 操作系统,并且必须提供对“supported”中的所有 API 级别的支持或 “日落”阶段。如需了解详情,请参阅 RFC-0239

  • HEAD = 0xFFE00000 = 4292870144。以前,HEAD 的值为 FIDL 中的 0xFFFFFFFFFFFFFFFE 和 Clang 中的 0xFFFFFFFF

  • NEXT = 0xFFD00000 = 4291821568RFC-0239 中对 NEXT 进行了说明,但 未指定数值。

该组可能会随着时间推移而视需要增加或缩小。

最初,这些值将硬编码到支持定位功能的 SDK 中 HEADNEXT,但最终应在 //sdk/version_history.json

何时使用整数与字符串

命令行工具接受输入并生成字符串形式的输出,因此 应接受上述 API 级别的任何字符串表示形式, 并且应优先使用规范字符串形式输出 API 级别。 不过,这种做法有时不可行,或者会非常麻烦,因此使用 规范字符串形式不是必需的。例如,Clang 并不知道 特殊 Fuchsia API 级别的名称,因此 -ffuchsia-api-level 的值必须 应以整数形式提供。

在构建工具实现内,以整数形式存储 API 级别 。

构建系统可以采用最适合此 API 级别的方式来表示 API 级别 构建系统

性能

此更改应该不会对效果产生任何影响。

向后兼容性

LEGACYHEAD 数值的变化不会 严格来说是向后兼容的不过,之前的 64 位值 实际上只在 fidlc 内使用,并且基本上对以下域的用户不可见 Fuchsia SDK。

从理论上说,C++ 代码中 HEAD 的当前定义为 0xFFFFFFFF SDK 用户可见,但由于 Fuchsia 源代码树之外没有代码 当前以 HEADLEGACY 为目标平台,那么您也应该不注意到此更改。LSC 来确认这一点

PLATFORM(之前为 LEGACY)、HEADNEXT 的新值如下: 导致它们之间出现明显的差距。这样,我们就可以 增加特殊的 API 级别,而无需重新定义现有 API 级别。任何此类新的 我们创建的 API 级别应添加到两个相邻 API 的中间位置 级别。在最坏的情况下,我们可以将每个区间细分 20 次。

安全注意事项

此更改应该不会影响安全性。

隐私注意事项

这项变更应该不会对隐私权产生任何影响。

测试

此 RFC 主要涉及 Fuchsia 的构建系统和 SDK 中的代码。对于 或者让代码经过专门自动测试的程度最低。不过, 在实践中,如果构建系统损坏,很快就会被注意到 当测试失败、构建中断以及本地开发流程中断时。

文档

NEXT”“HEAD”和“PLATFORM”的含义和值将纳入 RFC-0239 中引入的概念的后续文档。

缺点、替代方案和未知问题

缺点:32 位是否足够?

如果按顺序分配,即使我们每小时发布一个新的 API 级别,它也会 需要大约 245,000 年才能用完所设置的 231 个 API 级别 。看来是够了。

但是,API 级别并不总是需要进行密集分配。这一 RFC 定义了 特殊的 3 个 API 级别,每个级别之间有 1048576 个未使用的 API 级别。您看可以吗?

对于 64 位的 API 级别,我们很难想象 即使我们将其分配非常稀疏(例如, 连续版本之间长达数千、数百万或数十亿的间隙, 与 VersionTuple 执行的操作相同)。

对于 32 位 API 级别,我们在分配时必须更加谨慎。

我可能会把自己变成一股老梗: 232 API 级别应该足以满足所有人的需求。

备选:切换为 Major.Minor 方案

明确编写 VersionTuple.h 时假设功能 可能会在类似于 12.5 的版本中引入或移除,甚至 30.1.2.3。以这种方式构建其版本的平台最多可表示 21251 个不同的版本。或许紫红色可以 只使用其中 232 个值表示 Fuchsia 的版本控制 不恰当?

许多成功的平台都使用 单个整数(例如 Chromium 和 Android)。理由不充分 认为我们不能按照同样的策略也取得成功。


  1. Clang 使用 minor 中每个最高有效位, subminorbuild 作为标志。