LLVM 开发者政策

简介

本文档包含 LLVM 开发者政策,该政策定义了项目对开发者及其贡献的政策。本政策的目的是消除因 LLVM 开发的分布式特性可能引起的沟通不畅、返工和困惑。通过以清晰的措辞陈述政策,我们希望每位开发者都能预先知道在为 LLVM 做出贡献时会发生什么。本政策涵盖所有 llvm.org 子项目,包括 Clang、LLDB、libc++ 等。

本政策还旨在实现以下目标

  1. 吸引用户和开发者加入 LLVM 项目。

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

  3. 尽可能保持树顶的稳定。

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

本政策旨在面向 LLVM 的频繁贡献者。有兴趣贡献一次性补丁的人可以通过非正式的方式将其发送到llvm-commits 邮件列表,并与其他开发者合作完成整个流程。

开发者政策

本节包含与 LLVM 频繁开发者相关的政策。我们始终欢迎不经常为 LLVM 贡献的人员提交一次性补丁,但我们对频繁贡献者有更高的期望,以尽可能保持系统的效率。为了 LLVM 保持高质量标准,频繁的 LLVM 贡献者应满足以下要求。

保持信息灵通

开发者应通过阅读LLVM Discourse 论坛并订阅感兴趣的类别以获取通知,从而保持信息灵通。

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

对项目的贡献通过GitHub 拉取请求进行。您可以通过加入pr-subscribers-* GitHub 团队之一来订阅代码库区域的通知。此映射指示哪个团队与仓库中的特定路径关联。

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

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

请注意,所有公共 LLVM 邮件列表和 Discourse 论坛都是公开且存档的,并且保密或不公开声明将不被尊重。

制作和提交补丁

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

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

  2. 同样,补丁应在生成后尽快提交。如果补丁创建时间和应用时间之间的底层代码发生更改,则旧补丁可能无法正确应用。

  3. 创建补丁后,为其创建一个GitHub 拉取请求(或者在适用的情况下直接提交)。

提交补丁时,请不要在补丁本身中添加保密或不公开声明。这些声明与 LLVM 许可条款冲突,并可能导致您的贡献被排除在外。

电子邮件地址

LLVM 项目使用电子邮件在 GitHub 平台之外与贡献者沟通他们过去的贡献。主要而言,我们的 buildbot 基础设施使用电子邮件联系贡献者,告知构建和测试失败情况。

因此,LLVM 社区要求贡献者拥有与其 GitHub 提交关联的公共电子邮件地址,因此请确保在您的帐户设置中禁用“保持我的电子邮件地址私密”。

代码审查

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

做出可能破坏性的更改

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

警告

Phabricator 已弃用,并且以只读模式提供。对于新的代码贡献,请使用GitHub 拉取请求。本节包含需要更新的旧信息。

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

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

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

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

维护者

LLVM 项目的目标是快速发展功能,同时始终保持发布就绪状态。为了实现这一目标,项目需要志愿者愿意做那些不太光鲜的工作,以确保我们生产出稳健、高质量的产品。

维护者就是那些志愿者;他们是定期贡献者,他们自愿承担除代码贡献之外的额外社区责任。社区成员可以在各个项目根目录下的 Maintainers.rst 文件中找到项目的活跃和非活跃维护者。

维护者自愿承担项目领域内的以下共同责任

  • 确保提交获得高质量的审查,可以由维护者或其他人进行,

  • 帮助确认和评论问题,

  • 通过与其他维护者(和其他审查者)合作,调解代码审查分歧,以就如何最好地处理有争议的更改达成共识,

  • 积极参与相关的 RFC,

  • 协助发布经理进行向后移植和其他与发布相关的活动,

  • 成为需要帮助的贡献者的联络点(在 Discord/Discourse 上回答问题或主持办公时间)。

monorepo 中的每个顶级项目都将指定一个或多个首席维护者,他们负责确保满足该项目的社区需求。此角色与任何其他维护者角色类似,只是职责范围涵盖整个项目,而不是项目内的有限区域。如果您无法联系到维护者或不知道该联系哪个维护者,则首席维护者始终是联系的好选择。如果一个项目没有活跃的首席维护者,则该项目可能是从 monorepo 中删除的合理候选对象。应在 Discourse 上发起讨论,以寻找新的活跃首席维护者,或者是否应该停止该项目。

所有具有 LLVM 项目提交权限的贡献者都有资格成为维护者。但是,我们正在寻找能够承诺以下事项的人员

  • 在一个月的大部分时间里履行其职责,

  • 确保他们以及与他们互动的社区成员遵守 LLVM 社区行为准则,以及

  • 履行这些职责至少三个月。

我们认识到优先事项会发生变化、工作会变动、倦怠是真实存在的、长假是一种幸福,而且人们的生活通常很复杂。因此,我们希望尽可能减少某人成为维护者或辞去维护者职务的阻力。

要成为新的维护者,您可以自愿发布一个 PR,将自己添加到您自愿服务的区域。或者,现有维护者可以通过发布 PR 来提名您,但被提名人必须明确接受 PR,以便明确他们同意在提议的区域内志愿服务。只要同一项目中至少有一位维护者认可他们履行职责的能力,并且社区没有提出明确反对意见,PR 就会被接受。

要辞去维护者职务,您可以将您的名字移至项目 Maintainers.rst 文件的“非活跃维护者”部分,或者完全删除您的名字;无需 PR 审查。此外,任何在较长时间内未积极履行其职责的维护者都可以由该项目中的另一位活跃维护者,并在征得该项目中另一位活跃维护者的同意后,将其移至“非活跃维护者”部分。如果一个项目只有一个活跃维护者,请在 Discourse 上发帖,征求更广泛的社区对删除和项目未来方向的反馈。但是,在删除之前,请与非活跃维护者讨论情况,以避免意外的沟通失误。如果无法联系到非活跃维护者,则无需与他们讨论。辞去或被移除维护者职务是正常的,并且不会阻止某人在将来恢复其作为维护者的活动。

要恢复作为维护者的活动,您可以发布一个 PR,将您的名字从 Maintainers.rst 文件的“非活跃维护者”部分移至活跃维护者列表。由于该志愿者之前已被接受,因此只要同一项目中至少有一位维护者批准该 PR,并且社区没有提出明确反对意见,他们将被重新接受。

测试用例

开发者需要为修复的任何错误和添加的任何新功能创建测试用例。以下是一些让您的测试用例获得批准的技巧

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

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

  • 测试用例,尤其是针对回归的测试用例,应尽可能减少,可以使用 bugpoint 或手动进行。将整个失败的程序放入 llvm/test 中是不可接受的,因为这会给所有开发者带来 测试时间 负担。请保持测试用例简短。

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

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

发行说明

LLVM 中的许多项目通过发行说明向用户传达重要的更改,通常在项目的 docs/ReleaseNotes.rst 中找到。项目的面向用户的更改或用户可能希望了解的更改应添加到项目的发行说明中,由作者或代码审查员酌情决定,最好作为提交更改的一部分。通常需要添加发行说明的更改示例(此列表并非详尽无遗)

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

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

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

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

  • 修改 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 <jdoe@llvm.org>" 的命令来更正作者属性。有关更多信息,包括在项目迁移到 git 之前我们用于归属的方法,请参阅更改的归属

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

  • 标题应简洁。由于所有提交都通过电子邮件发送到列表,并且第一行作为主题,因此不赞成长标题。短标题在 git log 中也看起来更好。

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

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

  • 正文应简洁但具有解释性,包括完整的推理。除非需要理解更改,否则示例、代码片段和血腥细节应留给错误注释、Web 审查或邮件列表。

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

  • 如果提交是对另一个最近提交的补丁的错误修复,或者是补丁的回退或重新应用,请包含先前相关提交的 git 提交哈希值。这可以像“Revert commit NNNN because it caused PR#”一样简单。

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

  • 也可以在提交消息中添加其他元数据以自动化流程,包括下游消费者。此元数据可以包括指向整个社区无法访问的资源的链接。但是,此类链接和/或元数据不应用于代替使提交消息具有自解释性。请注意,此类非公开链接不应包含在提交的代码中。

对于轻微违反这些建议的情况,社区通常倾向于提醒贡献者该政策,而不是回退。轻微的更正和遗漏可以通过回复提交邮件列表来处理。

补丁回退政策

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

如果有人回退了您的更改,您应该如何回应?

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

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

  • 如果您需要更多信息来解决问题,请在原始提交线程中与回退补丁的作者联系。

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

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

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

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

  • 如果您收到大量的提交后审查反馈,请在重新提交之前回退并处理所述反馈。(可能在另一轮审查之后。)

  • 如果另一位贡献者要求您回退,请回退并在离线状态下讨论请求的优点(除非这样做会进一步破坏树顶的稳定性)。

您应该在何时回退其他人的更改?

  • 一般来说,如果作者自己会根据这些准则回退更改,我们鼓励其他贡献者这样做,以示对作者的礼貌。这是我们的规范与其他规范不同的主要情况之一;我们通常认为回退是开发的正常部分。我们不期望贡献者始终可用,并且保证有问题的补丁将被回退,并且我们可以在下次有机会时返回它,从而实现这一点。

围绕回退有哪些期望?

  • 请使用您最好的判断力。如果您不确定,请在提交线程上发送电子邮件寻求帮助。我们不是试图枚举每种情况,而是给出一些准则。

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

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

  • 习惯上回复原始提交电子邮件,提及回退。这既可以作为原始作者的补丁已被回退的通知,也可以帮助其他关注 llvm-commits 的人跟踪上下文。

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

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

  • 回退应具有合理的及时性。两小时前提交的更改可以无需事先讨论即可回退。两年前提交的更改不应回退。确切的过渡点很难说,但可能在树中几天之内。如果您不确定,我们建议您回复提交线程,给作者一些时间回复,然后如果作者似乎没有积极回复,则继续回退。

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

获取提交权限

一旦您有 3 个或更多合并的拉取请求,您可以使用此链接 <https://github.com/llvm/llvm-project/issues/new?title=Request%20Commit%20Access%20For%20%3Cuser%3E&body=%23%23%23%20Why%20Are%20you%20requesting%20commit%20access%20?>`_ 提交问题并请求提交权限。将标题中的 <user> 字符串替换为您的 GitHub 用户名,并在问题描述中解释您请求提交权限的原因。创建问题后,您需要获得两位当前贡献者的支持才能获得提交权限。

您提交的补丁的审查者将在创建问题时自动抄送。最常见的是,这些审查者将提供必要的批准,但来自其他 LLVM 提交者的批准也是可以接受的。审查应用程序的人员正在确认您确实已提交了三个补丁,并且基于在这些审查以及 LLVM 社区其他地方的互动,他们不担心您遵守我们的开发者政策和行为准则。

如果获得批准,GitHub 邀请将发送到您的 GitHub 帐户。如果您没有收到来自 GitHub 的通知,请直接转到邀请链接。一旦您接受邀请,您将获得提交权限。

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

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

如果您最近被授予提交权限,则以下政策适用

  1. 您被授予对 LLVM 所有部分进行 commit-after-approval 的权限。有关如何获得补丁批准的信息,请参阅 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。它使用不同的构建器来覆盖各种子项目和配置。构建在不同的worker上执行。构建器和 worker 由社区成员配置和提供。

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

如果您的提交破坏了构建:

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

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

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

  • GitHub 的代码审查中评论(如果可用)或通过电子邮件联系作者,解释问题以及这如何影响您。添加指向损坏的构建和错误消息的链接,以便人们可以理解问题。

  • 如果这阻止了您的工作,请回退提交,请参阅 revert_policy

如果构建/worker 永久损坏:

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

    _images/buildbot_worker_contact.png
  • 第二步:如果所有者没有回应或修复 worker,请升级上报给 BuildBot master 的维护者 Galina Kostanova。

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

将新组件引入 LLVM

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

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

但是,这实际上仅旨在涵盖我们看到出现的常见情况:不同的情况是不同的,我们也对讨论不寻常的情况持开放态度 - 只需在 LLVM Discourse 论坛上启动 RFC 线程即可。

添加新目标

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

我们发现,先提交大量新代码,然后在树内尝试修复突发问题,出于多种原因是有问题的。出于这些原因,新目标始终实验性方式添加,直到它们被证明稳定,然后再移动到非实验性。

两类之间的区别在于:

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

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

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

  • 每个目标必须至少有一个维护者Maintainers.rst 文件必须作为首次合并的一部分进行更新。这些维护者确保对目标的更改得到审查,并指导整体工作。

  • 目标背后必须有一个活跃的社区。这个社区将通过提供构建机器人、修复错误、回答 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 Monorepo

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

与新目标一样,monorepo 中已经存在的大多数项目都被认为是我们的支持政策核心层。向 LLVM monorepo 添加内容的负担需要非常高 - 添加到此存储库的代码会被社区中的每个人检出。因此,我们将组件保持在与“官方目标”相似的高标准,它们:

  • 必须在总体上符合 LLVM 项目的使命,即推进编译器、语言、工具、运行时等。

  • 必须符合本开发者政策文件中列出的所有政策,包括许可证、专利、编码标准和行为准则。

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

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

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

  • 应该有代码,代码中没有社区认为有争议的问题,或者正在明确地解决这些问题。

  • 必须通过 LLVM RFC 流程提出,并且其添加必须获得 LLVM 社区的批准 - 这最终调解了上述“应该”关注点的解决。

如果您有一个您认为添加到 LLVM monorepo 中有意义的项目,请在 LLVM Discourse 论坛上启动 RFC 主题,以开始讨论。此过程可能需要一些时间和迭代 - 请不要因此而气馁或感到害怕!

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

孵化新项目

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

可以考虑用于 LLVM 孵化器的项目符合以下标准:

  • 必须在总体上符合 LLVM 项目的使命,即推进编译器、语言、工具、运行时等。

  • 必须符合本开发者政策文件中列出的许可证、专利和行为准则政策。

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

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

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

  • 应该有一条可行的路径,最终作为 LLVM monorepo 内的专用顶级或子项目毕业。

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

  • 必须通过 LLVM RFC 流程提出,并且其添加必须获得 LLVM 社区的批准 - 这最终调解了上述“应该”关注点的解决。

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

获得批准后,llvm-admin 组可以授予新项目:
  • LLVM Github 组织中的新存储库 - 但不是 LLVM monorepo。

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

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

毕业到 mono-repo 将遵循现有的流程和标准,成为 monorepo 的一流部分。同样,孵化项目最终可能会被淘汰,但尚未为此建立任何流程。如果并且当这种情况出现时,请在 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.