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 中所定义)。
这展示了两个问题:
- 有一个“Clang API 级别”和“FIDL API 级别”; 不同的值。
- API 级别有时用字符串表示,有时用整数表示。
clang、FIDL 以及...?
RFC-0002 将 API 级别定义为 64 位整数,而后续的 RFC
分配特定的 64 位整数并赋予其名称和含义。对于
实例,LEGACY
由 0xFFFFFFFFFFFFFFFF
标识。但根据代码,
而是将 0xFFFFFFFF
传递给 Clang,因为遗憾的是,API
在 Clang 中,级别限制为 32 位。
事实并非如此。
Clang 通过 availability
实现兼容性的原因
属性,它表示
VersionTuple
。VersionTuple
打包了一个 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
的一部分。"N
N <= 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 = 4293918720
。PLATFORM
以前扮演过角色 由LEGACY
提供,默认情况下,平台将通过 API 构建PLATFORM
级。之前,LEGACY
在0xFFFFFFFFFFFFFFFF
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 = 4291821568
。RFC-0239 中对NEXT
进行了说明,但 未指定数值。
该组可能会随着时间推移而视需要增加或缩小。
最初,这些值将硬编码到支持定位功能的 SDK 中
HEAD
或 NEXT
,但最终应在
//sdk/version_history.json
。
何时使用整数与字符串
命令行工具接受输入并生成字符串形式的输出,因此
应接受上述 API 级别的任何字符串表示形式,
并且应优先使用规范字符串形式输出 API 级别。
不过,这种做法有时不可行,或者会非常麻烦,因此使用
规范字符串形式不是必需的。例如,Clang 并不知道
特殊 Fuchsia API 级别的名称,因此 -ffuchsia-api-level
的值必须
应以整数形式提供。
在构建工具实现内,以整数形式存储 API 级别 。
构建系统可以采用最适合此 API 级别的方式来表示 API 级别 构建系统
性能
此更改应该不会对效果产生任何影响。
向后兼容性
LEGACY
和 HEAD
数值的变化不会
严格来说是向后兼容的不过,之前的 64 位值
实际上只在 fidlc
内使用,并且基本上对以下域的用户不可见
Fuchsia SDK。
从理论上说,C++ 代码中 HEAD
的当前定义为 0xFFFFFFFF
SDK 用户可见,但由于 Fuchsia 源代码树之外没有代码
当前以 HEAD
或 LEGACY
为目标平台,那么您也应该不注意到此更改。LSC
来确认这一点
PLATFORM
(之前为 LEGACY
)、HEAD
和 NEXT
的新值如下:
导致它们之间出现明显的差距。这样,我们就可以
增加特殊的 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)。理由不充分 认为我们不能按照同样的策略也取得成功。
-
Clang 使用
minor
中每个最高有效位,subminor
和build
作为标志。↩