如何帮助改进内核文档

文档是任何软件开发项目的重要组成部分。好的文档有助于吸引新的开发人员,并帮助已有的开发人员更有效地工作。如果没有高质量的文档,就会在代码逆向工程和避免不必要的错误上浪费大量时间。

不幸的是,内核的文档目前远未达到支持如此规模和重要性的项目所需的要求。

本指南适用于希望改善这种情况的贡献者。内核文档的改进可以由各种技能水平的开发人员完成;它们是学习内核流程的相对简单的方式,并且可以在社区中找到一席之地。以下大部分内容是文档维护者最迫切需要完成的任务列表。

文档待办事项列表

为了使我们的文档达到应有的水平,需要执行的任务数不胜数。此列表包含许多重要项目,但远非详尽无遗;如果您看到改进文档的不同方法,请不要退缩!

解决警告

文档构建目前会喷出数量惊人的警告。当您有那么多警告时,您可能根本没有警告;人们会忽略它们,并且永远不会注意到他们的工作何时添加了新的警告。因此,消除警告是文档待办事项列表中最高优先级的任务之一。任务本身相当简单,但必须以正确的方式进行才能成功。

C 代码的编译器发出的警告通常可以被认为是误报,从而导致旨在仅仅使编译器闭嘴的补丁。文档构建发出的警告几乎总是指向一个实际问题;要消除这些警告,需要了解问题并在其根源上解决问题。因此,修复文档警告的补丁可能不应在更改日志标题中说“修复警告”;它们应指出已修复的实际问题。

另一个重点是,文档警告通常是由 C 代码中 kerneldoc 注释的问题引起的。虽然文档维护者感谢收到这些警告修复的副本,但文档树通常不是实际执行这些修复的正确树;它们应发送给相关子系统的维护者。

例如,在文档构建中,我几乎随机抓取了一对警告

./drivers/devfreq/devfreq.c:1818: warning: bad line:
      - Resource-managed devfreq_register_notifier()
./drivers/devfreq/devfreq.c:1854: warning: bad line:
      - Resource-managed devfreq_unregister_notifier()

(为了便于阅读,这些行被拆分了)。

快速查看上面命名的源文件,发现了一些类似这样的 kerneldoc 注释

/**
 * devm_devfreq_register_notifier()
        - Resource-managed devfreq_register_notifier()
 * @dev:      The devfreq user device. (parent of devfreq)
 * @devfreq:  The devfreq object.
 * @nb:               The notifier block to be unregistered.
 * @list:     DEVFREQ_TRANSITION_NOTIFIER.
 */

问题在于缺少“*”,这混淆了构建系统对 C 注释块的简单理解。自从 2016 年添加该注释以来,这个问题就一直存在——整整四年。修复它只需要添加缺少的星号。快速查看该文件的历史记录,显示了主题行的正常格式,并且 scripts/get_maintainer.pl 告诉我应该接收它的人 (将您的补丁路径作为参数传递给 scripts/get_maintainer.pl)。生成的补丁如下所示

[PATCH] PM / devfreq: Fix two malformed kerneldoc comments

Two kerneldoc comments in devfreq.c fail to adhere to the required format,
resulting in these doc-build warnings:

  ./drivers/devfreq/devfreq.c:1818: warning: bad line:
        - Resource-managed devfreq_register_notifier()
  ./drivers/devfreq/devfreq.c:1854: warning: bad line:
        - Resource-managed devfreq_unregister_notifier()

Add a couple of missing asterisks and make kerneldoc a little happier.

Signed-off-by: Jonathan Corbet <[email protected]>
---
 drivers/devfreq/devfreq.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 57f6944d65a6..00c9b80b3d33 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -1814,7 +1814,7 @@ static void devm_devfreq_notifier_release(struct device *dev, void *res)

 /**
  * devm_devfreq_register_notifier()
-     - Resource-managed devfreq_register_notifier()
+ *   - Resource-managed devfreq_register_notifier()
  * @dev:     The devfreq user device. (parent of devfreq)
  * @devfreq: The devfreq object.
  * @nb:              The notifier block to be unregistered.
@@ -1850,7 +1850,7 @@ EXPORT_SYMBOL(devm_devfreq_register_notifier);

 /**
  * devm_devfreq_unregister_notifier()
-     - Resource-managed devfreq_unregister_notifier()
+ *   - Resource-managed devfreq_unregister_notifier()
  * @dev:     The devfreq user device. (parent of devfreq)
  * @devfreq: The devfreq object.
  * @nb:              The notifier block to be unregistered.
--
2.24.1

整个过程只花了幾分钟。当然,我随后发现有人在单独的树中修复了它,突出了另一个教训:在深入研究问题之前,始终检查 linux-next 是否已修复该问题。

其他修复将需要更长的时间,尤其是那些与缺少文档的结构成员或函数参数相关的修复。在这种情况下,有必要弄清楚这些成员或参数的角色并正确描述它们。总的来说,这项任务有时会有点乏味,但它非常重要。如果我们真的可以消除文档构建中的警告,那么我们就可以开始期望开发人员避免添加新的警告。

除了来自常规文档构建的警告之外,您还可以运行 make refcheckdocs 来查找对不存在的文档文件的引用。

被忽视的 kerneldoc 注释

鼓励开发人员为他们的代码编写 kerneldoc 注释,但是这些注释中的许多注释从未被提取到文档构建中。这使得此信息更难找到,例如,使 Sphinx 无法生成指向该文档的链接。向文档添加 kernel-doc 指令以引入这些注释可以帮助社区充分利用创建它们所做的工作。

可以使用 scripts/find-unused-docs.sh 工具来查找这些被忽略的注释。

请注意,最大的价值来自于引入导出的函数和数据结构的文档。许多子系统也有供内部使用的 kerneldoc 注释;除非它们放置在专门针对在相关子系统中工作的开发人员的文档中,否则不应将其引入文档构建。

拼写错误修复

修复文档中的拼写错误或格式错误是了解如何创建和发送补丁的一种快速方法,并且是一项有用的服务。我总是愿意接受这样的补丁。也就是说,在您修复了一些拼写错误后,请考虑继续执行更高级的任务,为下一个初学者留下一些拼写错误需要解决。

请注意,某些内容不是拼写错误,不应“修复”

  • 内核文档中允许使用美式英语和英式英语的拼写。无需通过将一种拼写替换为另一种拼写来修复其中一种。

  • 句点后应跟一个空格还是两个空格的问题,不应在内核文档的上下文中进行讨论。其他存在合理分歧的领域,例如“牛津逗号”,在这里也是题外话。

与对任何项目的任何补丁一样,请考虑您的更改是否真的会使事情变得更好。

过时的文档

一些内核文档是当前、维护且有用的。一些文档则不是。陈旧、过时且不准确的文档可能会误导读者,并使人们对我们的整体文档产生怀疑。任何可以解决这些问题的事情都非常受欢迎。

每当您使用文档时,请考虑它是否是最新的、是否需要更新,或者是否应该完全删除。这里有一些您可以注意的警告信号

  • 引用 2.x 内核

  • 指向 SourceForge 存储库的指针

  • 在过去的几年中,历史记录中只有拼写错误修复

  • 讨论 Git 之前的工作流程

当然,最好的做法是使文档保持最新,添加所需的任何信息。当然,这种工作通常需要熟悉相关子系统的开发人员的合作。当被礼貌地询问,并且他们的回答被倾听并付诸行动时,开发人员通常非常愿意与那些致力于改进文档的人员合作。

一些文档超出了希望;例如,我们偶尔会发现引用很久以前从内核中删除的代码的文档。对于删除过时的文档存在令人惊讶的阻力,但我们还是应该这样做。我们文档中的额外垃圾对任何人都没有帮助。

在某些情况下,过时的文档中可能有一些有用的信息,而您又无法更新它,那么最好的办法可能是在开头添加警告。建议使用以下文本

.. warning ::
      This document is outdated and in need of attention.  Please use
      this information with caution, and please consider sending patches
      to update it.

这样,至少我们长期受苦的读者已经被警告该文档可能会误导他们。

文档一致性

这里的老人会记得 1990 年代出现在书架上的 Linux 书籍。它们只是从网络上各个位置搜集来的文档文件的集合。此后,书籍(大部分)得到了改进,但内核的文档仍然主要基于该模型构建。它由数千个文件组成,几乎每个文件都是与其他所有文件隔离编写的。我们没有连贯的内核文档体系;我们有数千个单独的文档。

我们一直在尝试通过创建一组针对特定读者的“书籍”来改善这种情况。这些包括

以及这本关于文档本身的指南。

将文档移动到适当的书籍中是一项重要的任务,需要继续进行。但是,这项工作存在一些挑战。移动文档文件会给使用这些文件的人员带来短期痛苦;他们对这种变化感到不热情,这是可以理解的。通常可以将文档移动一次;但是,我们真的不想继续将它们到处移动。

但是,即使所有文档都放在正确的位置,我们也只是设法将一大堆文档变成了一组较小的文档。尝试将所有这些文档编织成一个整体的工作尚未开始。如果您对我们如何在这方面取得进展有很好的想法,我们将非常乐意听取您的意见。

样式表改进

随着 Sphinx 的采用,我们获得了比以前更好看的 HTML 输出。但是它仍然可以进行很多改进;Donald Knuth 和 Edward Tufte 会对此印象不佳。这需要调整我们的样式表,以创建更符合排版、可访问和可读的输出。

请注意:如果您承担这项任务,您将进入典型的自行车棚领域。即使是相对明显的更改,也可能会收到很多意见和讨论。唉,这就是我们生活的世界的本质。

非 LaTeX PDF 构建

对于具有大量时间和 Python 技能的人来说,这是一项非常重要的任务。Sphinx 工具链相对较小且包含在内;易于添加到开发系统。但是构建 PDF 或 EPUB 输出需要安装 LaTeX,LaTeX 绝不是小型的或包含在内的。消除它会是一件好事。

最初的期望是使用 rst2pdf 工具 (https://rst2pdf.org/) 生成 PDF,但事实证明它无法胜任这项任务。不过,最近 rst2pdf 的开发工作似乎又重新活跃起来,这是一个充满希望的迹象。如果一位有足够动力的开发者能够与该项目合作,使 rst2pdf 能够用于内核文档构建,那么全世界都会对他感激不尽。

编写更多文档

自然地,内核的许多部分都严重缺乏文档。如果您掌握了文档化特定内核子系统的知识,并且有编写文档的意愿,请不要犹豫,立即开始编写并将结果贡献给内核。无数的内核开发者和用户将会感谢您。