LLVM 开发者政策

简介

本文档包含 LLVM 开发者政策,该政策定义了项目对开发者及其贡献的政策。该政策的目的是消除由于 LLVM 开发的分布式特性而可能产生的误解、返工和困惑。通过明确说明政策,我们希望每位开发者在做出 LLVM 贡献之前都能知道会遇到什么情况。此政策涵盖所有 llvm.org 子项目,包括 Clang、LLDB、libc++ 等。

此政策也旨在实现以下目标

  1. 吸引用户和开发者参与 LLVM 项目。

  2. 尽可能简化贡献者的工作。

  3. 保持主干尽可能稳定。

  4. 让项目贡献者了解项目的版权、许可和专利政策

此政策针对 LLVM 的频繁贡献者。有兴趣贡献一次性补丁的人可以通过非正式的方式将其发送到llvm-commits 邮件列表并与其他开发者互动以完成流程。

开发者政策

本节包含与 LLVM 频繁开发者相关的政策。我们始终欢迎来自不定期为 LLVM 做贡献的人的一次性补丁,但我们期望频繁贡献者做出更多努力,以使系统尽可能高效地为所有人服务。为了 LLVM 能够保持高质量标准,期望 LLVM 频繁贡献者满足以下要求。

保持知情

开发者应通过阅读LLVM Discourse 论坛并订阅感兴趣的类别以获取通知来保持知情。

关注他人正在进行的更改是了解其他人感兴趣的内容以及观察整个项目流程的好方法。

对项目的贡献是通过GitHub Pull Request进行的。您可以通过加入pr-subscribers-* GitHub 团队之一来订阅代码库某些区域的通知。此映射指示哪个团队与存储库中的特定路径相关联。

您还可以订阅您感兴趣的子项目的“提交”邮件列表,例如llvm-commitscfe-commitslldb-commits

缺少的功能和错误通过我们的GitHub 问题跟踪器进行跟踪并分配标签。我们建议活跃的开发者监控传入的问题。您可以通过加入issue-subscribers-*团队之一来订阅特定组件的通知。您还可以订阅llvm-bugs邮件列表以跟踪整个项目中发生的错误和增强功能。我们非常感谢那些积极主动地发现其组件中的传入错误并及时处理它们的人。

请注意,所有公共 LLVM 邮件列表和 Discourse 论坛都是公开的并且已存档,并且无法尊重保密或保密协议。

创建和提交补丁

在创建补丁以供审查时,目标是使审阅者尽可能轻松地阅读它。因此,我们建议您

  1. 针对 git main 创建您的补丁,而不是针对分支,也不是针对旧版本的 LLVM。这使得应用补丁变得容易。有关如何从 git 克隆的信息,请参阅入门指南

  2. 类似地,补丁应在生成后尽快提交。如果基础代码在创建补丁和应用补丁之间发生了更改,则旧补丁可能无法正确应用。

  3. 创建补丁后,为其创建一个GitHub Pull Request(或在适用时直接提交)。

提交补丁时,请勿在补丁本身添加保密或保密协议通知。这些通知与 LLVM 许可条款相冲突,可能导致您的贡献被排除。

代码审查

LLVM 有一项代码审查政策。代码审查是提高软件质量的一种方法。有关 LLVM 代码审查流程的更多信息,请参阅LLVM 代码审查政策和实践

进行可能破坏性更改

升级到较新版本的工具时,请帮助通知用户和供应商潜在的中断。例如,弃用将来预计将删除的功能、删除已弃用的功能、将诊断从警告升级为错误、切换重要的默认行为或任何其他可能导致中断的情况,这些情况被认为值得引起注意。对于此类更改,应执行以下操作

警告

Phabricator 已弃用,并且处于只读模式,对于新的代码贡献,请使用GitHub Pull Request。本节包含需要更新的旧信息。

  • 在执行更改的代码审查时,请将任何适用的“供应商”组添加到审查中以供其了解。这些组的目的是让供应商尽早知道正在考虑但尚未接受的潜在破坏性更改。供应商可以对更改提供早期测试反馈,以提醒我们不可接受的破坏。当前的供应商组列表为

    有兴趣加入供应商组的人可以通过点击 Phabricator 中供应商“成员”页面上的“加入项目”链接来加入。

  • 将更改提交到存储库时,请在项目的发布说明的Potentially Breaking Changes部分添加有关潜在破坏性更改的适当信息。发布说明应包含有关更改内容、其潜在破坏性内容以及任何代码示例、链接和动机的信息,这些信息适合与用户共享。这有助于用户了解升级到该版本的潜在问题。

  • 将更改提交到存储库后,发布说明中描述的潜在破坏性更改应发布到 Discourse 上的公告频道。该帖子应使用potentially-breaking标签和特定于项目的标签(例如clangllvm等)进行标记。这是我们可以预先通知用户潜在破坏性更改的另一种机制。它是加入“供应商”组的流量较低的替代方案。要自动接收带有potentially-breaking标签的新公告通知,请转到 Discourse 中的用户偏好设置页面,并将标签添加到Notifications->Tags下的其中一个观察类别中。

代码所有者

LLVM 项目依靠其流程中的两个功能来保持快速开发以及其源代码库的高质量:代码审查与受信任维护人员的事后审查相结合。拥有这两者是项目利用大多数人在大多数时间都做正确的事情这一事实的一个好方法,并且只有在他们确信自己正确时才会在没有预提交审查的情况下提交补丁。

诀窍在于,该项目必须保证所有提交的补丁在提交后都会得到审查:您不希望每个人都假设其他人会审查它,从而导致补丁未经审查。为了解决这个问题,我们有一个代码片段“所有者”的概念。代码所有者的唯一责任是确保对其代码区域的提交得到适当的审查,无论是由他们自己还是由其他人审查。当前代码所有者的列表可以在 LLVM 源代码树根目录中的文件CODE_OWNERS.TXT中找到。

请注意,代码所有权与审阅者完全不同:任何人都可以审查代码片段,我们欢迎任何感兴趣的人进行代码审查。代码所有者是“最后一道防线”,以确保所有提交的补丁都得到实际审查。

代码所有者是一个相对不显眼的角色,但对于项目的持续成功至关重要。由于人们会忙碌起来,兴趣会发生变化,以及意外情况的发生,代码所有权完全是自愿的,任何人都可以随时选择辞去其“头衔”。目前,我们还没有关于如何选举代码所有者的正式政策。

测试用例

开发人员需要为修复的任何 bug 和添加的任何新功能创建测试用例。一些关于如何获得测试用例批准的提示

  • 所有功能和回归测试用例都添加到 llvm/test 目录中。应选择合适的子目录(有关详细信息,请参阅 测试指南)。

  • 测试用例应该使用 LLVM 汇编语言 编写。

  • 测试用例,尤其是回归测试用例,应尽可能地简化,通过 bugpoint 或手动方式。将整个失败的程序放入 llvm/test 中是不可接受的,因为这会给所有开发人员带来测试时间负担。请保持它们的简短。

  • 避免添加指向整个社区都无法访问的资源的链接,例如指向私有 bug 跟踪器、内部公司文档等的链接。相反,在测试中添加足够的注释以提供这些链接背后的上下文。

请注意,llvm/test 和 clang/test 仅用于回归和小型功能测试。更广泛的测试用例(例如,整个应用程序、基准测试等)应添加到 llvm-test 测试套件中。llvm-test 套件用于覆盖率(正确性、性能等)测试,而不是功能或回归测试。

发行说明

LLVM 中的许多项目通过发行说明向用户传达重要的更改,这些发行说明通常位于项目的 docs/ReleaseNotes.rst 中。对项目的用户端更改或用户可能希望了解的更改应根据作者或代码审查者的判断添加到项目的发布说明中,最好是在提交更改的提交的一部分。通常需要添加发行说明的更改示例(此列表并不详尽)

  • 添加、删除或修改命令行选项。

  • 添加、删除或重新分组诊断。

  • 修复可能对用户产生重大影响的 bug(请链接到 bug 数据库中修复的问题)。

  • 添加或删除对广泛影响或启用新编程范式的优化。

  • 修改 C 稳定 API。

  • 通知用户有关计划在未来版本中进行的可能具有破坏性的更改,例如删除弃用的功能。在这种情况下,应将发行说明添加到注释的 Potentially Breaking Changes 部分,并提供足够的信息和示例来演示潜在的破坏。此外,此部分的任何新条目都应在 Discourse 上的 公告 频道中公布。有关更多详细信息,请参阅 进行可能具有破坏性的更改

鼓励代码审查者在进行代码审查时,如果认为有必要,则要求添加发行说明。

质量

任何更改在提交到主开发分支之前必须满足的最低质量标准是

  1. 代码必须符合 LLVM 代码规范

  2. 代码必须至少在一个平台上干净地编译(没有错误,没有警告)。

  3. 错误修复和新功能应 包含测试用例,以便我们知道修复/功能将来是否会发生回归。

  4. 代码必须通过 llvm/test 测试套件。

  5. 代码不得导致 llvm-test 的合理子集发生回归,其中“合理”取决于贡献者的判断和更改的范围(更具侵入性的更改需要更多测试)。合理的子集可能是类似“llvm-test/MultiSource/Benchmarks”的内容。

  6. 确保源代码和测试文件中的链接指向公开可用的资源,并且主要用于添加其他信息,而不是提供关键上下文。周围的注释应足以提供这些链接背后的上下文。

此外,提交者负责解决将来发现的更改导致的任何问题。例如

  • 代码应在所有受支持的平台上干净地编译。

  • 更改不应导致 llvm-test 套件中的任何正确性回归,并且不得导致任何重大性能回归。

  • 更改集不应导致 LLVM 工具的性能或正确性回归。

  • 更改不应导致在所有适用目标上由 LLVM 编译的代码的性能或正确性回归。

  • 您需要解决因您的更改而产生的任何 GitHub 问题

我们希望在提交之前处理这些问题,但我们理解并非每次提交都可以测试所有这些问题。我们的构建机器人和夜间测试基础设施通常会发现这些问题。一个好的经验法则是检查更改后的第二天夜间测试人员是否存在回归。如果包含您的提交的一组提交导致失败,构建机器人将直接向您发送电子邮件。您需要检查构建机器人的消息,看看是否是您的错误,如果是,则修复该故障。

违反这些质量标准的提交(例如,非常糟糕)可能会被回滚。当更改阻止其他开发人员取得进展时,这是必要的。在问题得到修复后,开发人员可以重新提交更改。

提交消息

虽然我们不强制执行提交消息的格式,但我们更希望您遵循以下指南,以帮助进行审查、在日志中搜索、电子邮件格式化等。这些指南与其他开源项目使用的规则非常相似。

最重要的是,消息的内容应仔细编写,以传达更改的理由(无需过多详细说明)。它还应避免含糊不清或过于具体。例如,“位设置不正确”会让审阅者想知道哪些位以及为什么它们不正确,而“在 TargetInfo 中正确设置溢出位”则传达了更改的大部分内容。

以下是一些关于消息本身格式的指南

  • 将提交消息分成标题和正文,并用空行分隔。

  • 如果您不是原始作者,请确保提交的“作者”属性设置为原始作者,“提交者”属性设置为你自己。您可以使用类似于 git commit --amend --author="John Doe <[email protected]>" 的命令来更正作者属性,如果它不正确。有关更多信息,包括项目迁移到 git 之前我们使用的归属方法,请参阅 更改的归属

    在很少有情况下有多个作者时,请使用 git 标签“Co-authored-by:”列出其他作者

  • 标题应简洁。因为所有提交都将通过电子邮件发送到列表,并且第一行作为主题,所以不鼓励使用长标题。简短的标题在 git log 中也看起来更好。

  • 当更改仅限于代码的特定部分(例如后端或优化传递)时,习惯上在行的开头添加一个用方括号括起来的标签。例如,“[SCEV] …”或“[OpenMP] …”。这有助于电子邮件过滤器和提交后审查的搜索。

  • 正文(如果存在)应与标题用空行分隔。

  • 正文应简洁但具有说明性,包括完整的推理。除非需要理解更改,否则示例、代码片段和详细信息应保留在 bug 注释、网络审查或邮件列表中。

  • 文本格式和拼写应遵循与文档和代码内注释相同的规则,例如大写、句号等。

  • 如果提交是在最近提交的另一个补丁之上进行的错误修复,或者是对补丁的回滚或重新应用,请包含先前相关提交的 git 提交哈希。这可能很简单,例如“由于它导致了 PR#,因此回滚提交 NNNN”。

  • 如果补丁已过审查,请添加指向其审查页面的链接,如 此处 所示。如果补丁修复了 GitHub 问题中的 bug,我们鼓励添加对正在关闭的问题的引用,如 此处 所述。

  • 还可以将其他元数据添加到提交消息中以自动化流程,包括针对下游使用者。此元数据可以包含指向整个社区都无法访问的资源的链接。但是,此类链接和/或元数据不应替代使提交消息不言而喻。请注意,此类非公开链接不应包含在提交的代码中。

对于这些建议的轻微违规,社区通常更倾向于提醒贡献者此策略,而不是回滚。可以通过向提交邮件列表发送回复来处理轻微的更正和遗漏。

补丁回滚策略

作为一个社区,我们非常重视使树的顶端处于良好的状态,同时允许快速迭代开发。因此,与其他一些开源项目相比,我们倾向于更多地使用回滚来保持树的健康,并且我们的规范略有不同。

如果有人回滚了你的更改,你应该如何应对?

  • 请记住,补丁被回滚是正常且健康的。补丁被回滚并不一定意味着你做错了什么。

  • 我们鼓励明确感谢代表你完成此任务的回滚补丁的人。

  • 如果您需要更多信息来解决问题,请在包含回滚补丁的作者的原始提交线程中进行后续跟进。

您何时应该回滚自己的更改?

  • 任何时候,如果您了解到更改存在严重问题,都应该回滚它。我们强烈建议“回滚到绿色”,而不是“向前修复”。我们鼓励先回滚,然后离线调查,然后再应用已修复的补丁 - 如果有必要,可以在另一轮审查后进行。

  • 如果您以无法快速修复的方式破坏了构建机器人,请回滚。

  • 如果在提交线程中报告了演示问题的测试用例,请回滚并离线调查。

  • 如果您收到大量的 提交后审查 反馈,请回滚并在重新提交之前解决这些反馈。(可能在另一轮审查后。)

  • 如果其他贡献者要求你回退更改,请进行回退并线下讨论请求的理由(除非这样做会进一步破坏代码库的稳定性)。

什么时候应该回退其他人的更改?

  • 一般来说,如果作者本人会根据这些准则回退更改,我们鼓励其他贡献者出于对作者的礼貌这样做。这是我们的规范与其他项目存在差异的主要情况之一;我们通常认为回退是开发过程中的正常部分。我们不期望贡献者始终可用,并且保证有问题的补丁将被回退,我们可以在下次有机会时再处理它,这使得这种做法成为可能。

围绕回退有哪些期望?

  • 使用你的最佳判断。如果你不确定,请在提交线程上发起一封电子邮件寻求帮助。我们不是试图列举每种情况,而是提供一套指导原则。

  • 你应该确保回退更改可以提高代码库的稳定性。有时,回退一系列更改中的一个更改可能会使情况恶化而不是改善。我们期望做出合理的判断,以确保正在回退正确的补丁或一组补丁。

  • 回退提交的提交消息应解释为什么回退该补丁。

  • 通常的做法是回复原始提交邮件并提及回退。这既可以通知原始作者他们的补丁已被回退,也有助于其他关注 llvm-commits 的人跟踪上下文。

  • 理想情况下,你应该准备好一个公开可复现的测试用例以供共享。在可能的情况下,我们鼓励在提交线程或 PR 中共享测试用例。我们鼓励回退者尽量减少测试用例并尽可能地修剪依赖项。即使回退你自己的补丁也适用;为可能正在关注的其他人员记录原因至关重要。

  • 在没有至少承诺提供一种方法供补丁作者调试根本问题的情况下,回退被认为是不合理的。如果由于某种原因无法共享公共复现程序(例如,需要补丁作者无法访问的硬件,编译内部工作负载的编译时间急剧下降等),则回退者应积极主动地与补丁作者合作调试和测试候选补丁。

  • 回退应该及时进行。两小时前提交的更改可以在没有事先讨论的情况下进行回退。两年前提交的更改不应该回退。确切的过渡点很难说,但可能在代码库中停留几天左右。如果你不确定,我们鼓励你回复提交线程,给作者一些时间回复,然后如果作者似乎没有积极回复,则继续进行回退。

  • 重新应用已回退的补丁时,应更新提交消息以指示已解决的问题以及如何解决。

获取提交权限

我们授予提交权限给那些有提交高质量补丁记录的贡献者。如果你想要提交权限,请发送电子邮件到 Chris 并提供你的 GitHub 用户名。这适用于拥有 SVN 访问权限的先前贡献者以及新的贡献者。如果获得批准,将向你的 GitHub 帐户发送 GitHub 邀请。如果你没有收到 GitHub 的通知,请直接访问 邀请链接。接受邀请后,你将获得提交权限。

在获得提交权限之前,通常的做法是请求拥有提交权限的人员代表你提交。这样做时,请提供你想要在提交的作者属性中使用的姓名和电子邮件地址。

出于外部跟踪目的,提交的更改在提交完成后不久就会自动反映在提交邮件列表中(例如,llvm-commits)。请注意,这些邮件列表是经过审核的,大型提交通常需要版主批准电子邮件,因此如果提交没有立即出现在档案中,请不要担心。

如果你最近获得了提交权限,则这些策略适用

  1. 你被授予对 LLVM 所有部分的“提交后批准”权限。有关如何获得补丁批准的信息,请参阅 LLVM 代码审查政策和实践。获得批准后,你可以自己提交。

  2. 你可以提交你认为明显的补丁,无需批准。这显然是一个主观决定——我们只是期望你使用良好的判断力。例如:修复构建中断、回退明显错误的补丁、文档/注释更改、任何其他细微更改。避免在计划进行后续更改的代码之外提交仅格式或空白更改。此外,尝试将格式或空白更改与功能更改分开,方法是首先(理想情况下)或之后更正格式。此类更改应该高度本地化,并且提交消息应明确说明提交不打算更改功能,通常通过声明它是 NFC

  3. 你可以提交你贡献或维护的 LLVM 部分的补丁,无需批准(即,已被分配责任),前提是此类提交不得破坏构建。这是一种“信任但验证”的策略,并且此类提交将在提交后进行审查。

  4. 多次违反这些政策或一次严重违反可能会导致提交权限被撤销。

无论如何,你的更改仍然受 代码审查 约束(在提交之前或之后,具体取决于更改的性质)。我们也鼓励你审查其他人的补丁,但你没有义务这样做。

进行重大更改

当开发人员开始一个新的主要项目并打算将其贡献回 LLVM 时,他们应该尽可能地在 LLVM Discourse 论坛 上发布帖子以通知社区。这样做的原因是

  1. 使社区了解 LLVM 的未来更改,

  2. 避免重复工作,防止多方在不知情的情况下处理相同的事情,以及

  3. 确保在进行任何重大工作之前讨论并解决任何与拟议工作相关的技术问题。

LLVM 的设计经过精心控制,以确保所有部分都能很好地协同工作并尽可能保持一致。如果你计划对 LLVM 的工作方式进行重大更改或想要添加主要的新扩展,最好在开始工作之前与开发社区达成共识。

一旦新功能的设计最终确定,工作本身应该作为一系列 增量更改 来完成,而不是作为长期开发分支。

增量开发

在 LLVM 项目中,我们将所有重大更改都作为一系列增量补丁来完成。我们非常不喜欢巨大的更改或长期开发分支。长期开发分支有一些缺点

  1. 分支必须定期合并主线。如果分支开发和主线开发发生在代码的相同部分,解决合并冲突可能需要大量时间。

  2. 社区中的其他人倾向于忽略分支上的工作。

  3. 巨大的更改(在分支合并回主线时产生)极其难以进行 代码审查

  4. 我们的夜间测试基础设施不会定期测试分支。

  5. 作为单片大型更改开发的更改通常在完成所有更改集之前都无法工作。将其分解为一组较小的更改会增加任何工作被提交到主存储库的可能性。

为了解决这些问题,LLVM 使用增量开发风格,并且我们要求贡献者在进行大型/侵入性更改时遵循此实践。一些提示

  • 大型/侵入性更改通常需要在进行重大更改之前进行许多次要更改(例如,API 清理等)。这些类型的更改通常可以在进行重大更改之前完成,独立于该工作。

  • 如果可能,应将剩余的相互关联的工作分解为不相关的更改集。完成此操作后,定义第一个增量并就更改的最终目标达成共识。

  • 集合中的每个更改可以是独立的(例如,修复错误),或者是一系列计划的更改的一部分,这些更改朝着开发目标努力。

  • 每个更改都应尽可能小。这简化了你的工作(成为一个逻辑过程),简化了代码审查并减少了你获得对更改的负面反馈的机会。小的增量也有助于维护高质量的代码库。

  • 通常,重大更改的一个独立前奏是添加一个新的 API 并缓慢地迁移客户端以使用新的 API。每个使用新 API 的更改通常都是“明显的”,并且可以在没有审查的情况下提交。一旦新 API 就位并使用,替换 API 的底层实现就容易得多。此实现更改与 API 更改在逻辑上是分开的。

如果你有兴趣进行重大更改,并且这让你感到害怕,请务必首先 讨论更改/达成共识,然后询问有关进行更改的最佳方法。

更改的归属

当贡献者向 LLVM 项目提交补丁时,其他拥有提交权限的开发人员可能会在适当的时候(根据代码审查的进展等)为作者提交。这样做时,务必保留对贡献者贡献的正确归属。但是,我们不希望源代码中充斥着随机的归属“此代码由 J. Random Hacker 编写”(这很嘈杂且分散注意力)。实际上,版本控制系统会完美地记录谁更改了什么,并且 CREDITS.txt 文件描述了更高级别的贡献。如果你为其他人提交补丁,请按照 提交消息 部分概述的简单方式遵循更改的归属。总的来说,请不要在源代码中添加贡献者姓名。

此外,除非他们已将补丁提交到项目或你已被授权代表他们提交(你们一起工作并且你的公司授权你贡献补丁等),否则不要提交其他人编写的补丁。作者应首先将其提交到相关项目的提交列表、开发列表或 LLVM 错误跟踪器组件。如果有人私下向你发送补丁,请鼓励他们首先将其提交到相应的列表。

我们之前的版本控制系统(subversion)不像 git 那样区分作者和提交者。因此,较旧的提交使用了不同的归属机制。之前的方法是在提交消息的单独一行中包含“Patch by John Doe.”,并且有一些自动化流程依赖于此格式。

禁令

禁令的目的是保护社区中的人免于不得不与那些在 LLVM 项目空间中始终不尊重 LLVM 社区行为准则 的人互动。任何形式的贡献(拉取请求、问题报告、论坛帖子等)都需要与社区互动。因此,我们不接受任何形式的被禁个人的直接贡献。

间接贡献仅允许由完全拥有该贡献的人员进行,并且他们对与社区相关的与该贡献相关的所有互动负责。

如果您不确定在特定情况下如何行动,请联系 conduct@llvm.org 以获取建议。

IR 向后兼容性

当必须更改 IR 格式时,请记住我们尝试保持一定的向后兼容性。这些规则旨在平衡 LLVM 用户的便利性和不对 LLVM 开发人员造成很大负担。

  • 文本格式不向后兼容。我们不会太频繁地更改它,但没有具体的承诺。

  • 对 IR 的添加和更改应反映在 test/Bitcode/compatibility.ll 中。

  • 当前 LLVM 版本支持加载自 3.0 版以来的任何 bitcode。

  • 在每次 X.Y 版本发布后,必须将 compatibility.ll 复制到 compatibility-X.Y.ll。相应的 bitcode 文件应使用 X.Y 版本构建进行汇编,并作为 compatibility-X.Y.ll.bc 提交。

  • 较新的版本可以忽略旧版本的特性,但不能错误编译它们。例如,如果 nsw 以后被其他内容替换,则丢弃它将是升级 IR 的有效方法。

  • 调试元数据是特殊的,因为它在升级期间会被丢弃。

  • 非调试元数据被定义为可以安全地丢弃,因此升级它的有效方法是丢弃它。这不太友好,需要多花一些精力,但没有做出任何承诺。

C API 更改

  • 稳定性保证:一般来说,C API 对于稳定性来说是“尽力而为”。这意味着我们尽一切努力保持 C API 的稳定性,但这种稳定性将受到接口的抽象性和它包装的 C++ API 的稳定性的限制。在实践中,这意味着诸如“创建调试信息”或“创建这种类型的指令”之类的东西可能不如“获取此 IR 文件并为我的当前机器 JIT 它”稳定。

  • 发布稳定性:我们不会在发布分支上使用应用于该分支的补丁来破坏 C API,但例外情况是我们将修复意外的 C API 中断,这将使发布与前一个和下一个版本保持一致。

  • 测试:对 C API 的补丁需要像任何其他补丁一样附带测试。

  • 将新内容包含到 API 中:如果 LLVM 子组件已包含 C API,则扩展该 C API 是可以接受的。为当前没有 C API 的子组件添加 C API 需要在 LLVM Discourse 论坛 上进行讨论,以获取设计和可维护性反馈,然后再进行实施。

  • 文档:对 C API 的任何更改都需要在发行说明中进行记录,以便那些不关注该项目的外部用户清楚地了解 C API 的变化和发展。

更新工具链要求

随着时间的推移,我们打算要求使用更新的工具链。这意味着 LLVM 的代码库可以使用更新版本的 C++,因为它们已标准化。要求使用更新的工具链来构建 LLVM 对于构建 LLVM 的人来说可能会很痛苦;因此,这将仅通过以下流程进行

  • 总的目标是至少支持过去 3 年的 LLVM 和 GCC 版本。此基于时间的指南并不严格:我们可能会支持更旧的编译器,或者决定支持更少的版本。

  • LLVM Discourse 论坛 发送 RFC。

    • 详细说明版本提升的优势(例如,LLVM 应该使用哪些更新的 C++ 语言或库特性;避免在特定编译器版本中出现错误编译等)。

    • 详细说明在重要平台上的缺点(例如,Ubuntu LTS 状态)。

  • 一旦 RFC 达成共识,请更新 CMake 工具链版本检查以及 入门指南。这为编译 LLVM 的开发人员提供了一个更平滑的过渡路径,因为可以使用 CMake 标志将错误转换为警告。这是一个重要的步骤:LLVM 仍然没有需要新工具链的代码,但很快就会有。如果您编译了 LLVM 但没有阅读论坛,我们应该告诉您!

  • 确保至少一个 LLVM 版本已包含此软错误。并非所有开发人员都编译 LLVM 的最新版本。这些与版本绑定的开发人员也应该被告知即将发生的更改。

  • 在上述 LLVM 版本分支后,将软错误转换为硬错误。

  • 更新 编码标准 以允许我们在 RFC 中明确批准的新功能。

  • 开始在 LLVM 的代码库中使用新功能。

这是一个 示例 RFC相应的更改

使用 CI 系统

LLVM 项目的主要持续集成 (CI) 工具是 LLVM Buildbot。它使用不同的构建器来涵盖各种子项目和配置。构建在不同的工作节点上执行。构建器和工作节点由社区成员配置和提供。

Buildbot 跟踪主分支和发布分支上的提交。这意味着补丁在合并到这些分支后会被构建和测试(即合并后测试)。这也意味着偶尔破坏构建是可以的,因为期望贡献者使用所有可能的配置构建和测试他们的补丁是不合理的。

如果您的提交破坏了构建

  • 尽快修复构建,因为这可能会阻止其他贡献者或下游用户。

  • 如果您需要更多时间来分析和修复错误,请恢复您的更改以解除对其他人的阻塞。

如果其他人破坏了构建并且这阻止了您的工作

  • GitHub(如果可用)上的代码审查中发表评论或发送电子邮件给作者,说明问题以及这对您造成的影响。添加指向损坏构建和错误消息的链接,以便人们可以理解问题。

  • 如果这阻止了您的工作,请恢复提交,请参阅 恢复策略

如果构建/工作节点永久损坏

  • 第一步:联系工作节点的所有者。您可以在构建页面上的“工作节点”选项卡中找到工作节点管理员的姓名和联系信息

    _images/buildbot_worker_contact.png
  • 第二步:如果所有者没有回复或修复工作节点,请升级到 BuildBot 主机的维护者 Galina Kostanova。

  • 第三步:如果 Galina 无法帮助您,请升级到 基础设施工作组

将新组件引入 LLVM

LLVM 社区是一个充满活力和令人兴奋的地方,我们希望包容新项目并培养新社区,并增加跨行业和学术界的合作。

也就是说,我们需要在包容新想法和人员以及新代码所需的持续维护成本之间取得平衡。因此,我们有一个关于将主要新组件引入 LLVM 世界的一般 支持策略,具体取决于所需详细程度和责任。核心项目需要比外围项目更高的审查程度,后者可能存在其他差异。

但是,这实际上仅用于涵盖我们已经遇到的一些常见情况:不同的情况是不同的,我们也乐于讨论不寻常的情况 - 只需在 LLVM Discourse 论坛 上启动一个 RFC 线程。

添加新目标

LLVM 非常乐于接受新的目标,即使是实验性的目标,但在添加大量新代码时可能会出现一些问题,并且后端通常会批量添加。新目标需要与编译器的其他核心部分相同级别的支持,因此它们包含在我们 支持策略核心层中。

我们发现,先引入大量新代码,然后尝试在树中修复出现的错误是有问题的,原因有很多。出于这些原因,新目标始终作为实验性目标添加,直到它们被证明是稳定的,然后才能迁移到非实验性目标。

两类之间的区别在于

  • 默认情况下不构建实验性目标(需要在 CMake 时明确启用它们)。

  • 仅在启用实验性目标时出现的测试失败、错误和构建中断(由与目标无关的更改引起)由目标背后的社区负责修复。

将后端以实验性模式上游的基本规则是

  • 每个目标都必须有一个 代码所有者。在第一次合并时必须更新 CODE_OWNERS.TXT 文件。代码所有者确保对目标的更改得到审查,并指导整个工作。

  • 目标背后必须有一个活跃的社区。该社区将通过提供构建机器人、修复错误、回答 LLVM 社区的疑问并确保新目标不会破坏任何其他目标或通用代码来帮助维护目标。预计这种行为将在目标代码的整个生命周期中持续存在。

  • 代码必须没有争议性问题,例如,前端如何处理或应如何形成 IR 的重大更改,除非社区中的大多数人通过重构 (IR 标准) 在合并新目标更改之前达成一致,遵循 IR 向后兼容性

  • 代码符合本开发人员策略文档中列出的所有策略,包括许可证、专利和编码标准。

  • 目标应该有关于其工作原理(ISA、ABI 等)的合理文档或公开可用的模拟器/硬件(免费或足够便宜)——最好两者都有。这允许开发人员验证假设、理解约束并审查可能影响目标的代码。

此外,将后端提升到正式版本的规则是

  • 目标必须已满足所有其他最低要求,并在树中稳定至少 3 个月。此冷却期是为了确保后端和目标社区在可预见的未来能够承受持续的上游开发。

  • 目标的代码必须完全适应此策略以及编码标准。为进入实验模式而做出的任何例外情况必须在正式之前得到修复。

  • 测试覆盖率需要广泛且编写良好(测试用例小,文档齐全)。构建目标check-all必须在构建新目标后通过,并且在适用情况下,test-suite也必须至少在一个配置中通过且无错误(公开演示,例如,通过构建机器人)。

  • 需要创建并积极维护公共构建机器人,除非目标不需要额外的构建机器人(例如,check-all涵盖所有测试)。新目标的 CI 基础设施越相关和公开,LLVM 社区就越容易接受它。

继续作为受支持的官方目标

  • 维护人员必须在目标的整个生命周期中继续遵循这些规则。持续违反上述规则和策略可能导致目标从代码库中完全移除。

  • 支持、文档或测试覆盖率的下降将使目标成为其他目标的累赘,并被视为降级和最终移除的候选目标。

从本质上讲,这些规则对于目标获得和保持其状态是必要的,但也是定义代码腐烂的标记,并将用于清理树中未维护的目标。

希望向 LLVM 添加新目标的人员必须遵循以下步骤

  1. 阅读本节并确保您的目标符合所有要求。对于次要问题,您的社区将负责在初始合并后尽快进行所有必要的调整。

  2. LLVM Discourse 论坛发送变更请求 (RFC),描述您的目标以及它如何满足所有要求,以及为满足官方目标要求已完成和需要完成的工作。确保公开任何和所有有争议的问题、基础代码中所需的更改、表生成等。

  3. 一旦收到积极的回复,LLVM 社区就可以开始审查实际的补丁(但它们可以提前准备好,以支持 RFC)。创建一系列 N 个补丁,编号为“1/N”到“N/N”(确保 N 是一个实际数字,而不是字母“N”),这些补丁完成了目标的基本结构。

  4. 初始补丁应在 clang 和 LLVM 中添加文档、代码所有者和三元组支持。后续补丁添加 TableGen 基础设施来描述目标并将指令降低到汇编。最终补丁必须显示目标可以通过广泛的 LIT 测试(IR 到 MIR,MIR 到 ASM 等)正确降低。

  5. 一些补丁可能在其他补丁之前获得批准,但只有在所有补丁都获得批准后,才能一次性合并整个补丁集。这样做是为了保证所有更改作为一个整体都是好的。

  6. 初始合并后,目标社区可以停止对补丁进行编号,并开始异步处理目标以完成支持。他们仍然应该寻求参与初始阶段人员的审查,以确保进度仍然一致。

  7. 一旦满足所有官方要求(如上所述),代码所有者应通过向LLVM Discourse 论坛发送另一个 RFC 来请求默认启用目标。

将已建立的项目添加到 LLVM 单一代码库

LLVM 单一代码库是 LLVM 世界中开发的中心点,包含所有主要的 LLVM 组件,包括 LLVM 优化器和代码生成器、Clang、LLDB 等。通常的单一代码库很棒,因为它们允许对项目进行原子提交,简化 CI,并使子社区更容易协作。

与新目标一样,单一代码库中已存在的多数项目都被认为属于我们支持策略核心层。将内容添加到 LLVM 单一代码库的负担必须非常高——添加到此存储库的代码会被社区中的每个人检出。因此,我们对组件设置了与“官方目标”类似的高标准,它们

  • 必须与 LLVM 项目推进编译器、语言、工具、运行时等的使命大体一致。

  • 必须符合本开发人员策略文档中规定的所有策略,包括许可证、专利、编码标准和行为准则。

  • 必须有一个积极的社区来维护代码,包括已建立的代码所有者。

  • 应该有关于其工作原理的合理文档,包括高质量的 README 文件。

  • 应该有 CI 来捕获项目本身或由于底层 LLVM 依赖项而导致的故障。

  • 应该没有社区认为有争议的问题的代码,或者有明确的解决途径。

  • 必须通过 LLVM RFC 流程提出,并获得 LLVM 社区的批准——这最终调解了上述“应该”问题的解决。

如果您有一个您认为可以添加到 LLVM 单一代码库的项目,请在LLVM Discourse 论坛上发起 RFC 主题以开始讨论。此过程可能需要一些时间和迭代——请不要因此而气馁或畏惧!

如果您有一个您认为与 LLVM 一致的早期项目,请参阅“孵化新项目”部分。

孵化新项目

将新项目添加到 LLVM 单一代码库的负担有意设置得很高,但这可能会对新的和创新的项目产生阻碍作用。为了帮助培养这些类型的项目,LLVM 支持一个“孵化器”流程,该流程更容易上手。它为潜在的有价值的新顶级和子项目提供了空间,以便在它们拥有足够的代码来证明其效用并培养社区之前达到临界质量。这也允许已经在 LLVM 伞下拥有贡献权限的团队之间进行协作。

可以考虑纳入 LLVM 孵化器的项目符合以下标准

  • 必须与 LLVM 项目推进编译器、语言、工具、运行时等的使命大体一致。

  • 必须符合本开发人员策略文档中规定的许可证、专利和行为准则策略。

  • 必须有记录的章程和开发计划,例如以 README 文件、使命宣言和/或宣言的形式。

  • 应该符合编码标准、增量开发流程和其他期望。

  • 应该了解它希望最终培养的社区,并且应该有来自不同隶属关系/组织的成员的兴趣。

  • 应该有一条可行的路径,最终可以作为LLVM 单一代码库中的专用顶级或子项目毕业。

  • 应该包含一条通知(例如,在项目的 README 或网页中),说明该项目处于“孵化状态”,并且不包含在 LLVM 版本中(请参阅下面建议的措辞)。

  • 必须通过 LLVM RFC 流程提出,并获得 LLVM 社区的批准——这最终调解了上述“应该”问题的解决。

也就是说,项目不需要任何代码即可开始,也不需要有任何已建立的社区!此外,孵化项目可能会经历违反上述“应该”指南的瞬态状态,或者其他方面使其不适合直接包含在单一代码库中(例如,尚未适当地分解的依赖项、利用尚未上游的实验性组件或 API 等)。

批准后,llvm-admin 组可以授予新项目
  • LLVM Github 组织中的一个新存储库——但不是 LLVM 单一代码库。

  • 与其他 LLVM 论坛一起托管的新邮件列表、讨论论坛和/或 Discord 聊天。

  • 其他基础设施集成可以根据具体情况进行讨论。

毕业到单一代码库将遵循成为单一代码库中一流部分的现有流程和标准。类似地,孵化项目最终可能会被淘汰,但尚未为此制定流程。如果和何时出现这种情况,请在LLVM Discourse 论坛上发起 RFC 讨论。

此流程非常新——请预期细节会发生变化,始终可以在LLVM Discourse 论坛上询问此事。

项目 README 和主要项目网页的建议免责声明

This project is participating in the LLVM Incubator process: as such, it is
not part of any official LLVM release.  While incubation status is not
necessarily a reflection of the completeness or stability of the code, it
does indicate that the project is not yet endorsed as a component of LLVM.