在Linux上用Doxygen记录你的源代码

254 阅读8分钟

5 trends in open source documentation

当你试图熟悉别人的项目时,你通常会欣赏留下的评论,这些评论可以帮助你理解他们代码的含义。同样,无论何时你在编程时,无论是为自己还是为他人,对自己的代码进行注释都是很好的做法。所有的编程语言都提供了一种特殊的语法,可以将一个词、一行或整个部分标记为注释。在处理源代码时,这些区域会被编译器或解释器忽略。

注释并不能代替文档,但有一种方法可以使用你的注释来轻松制作文档。认识一下Doxygen,这是一个开源工具,可以根据代码中的注释生成HTML或LaTeX文档。Doxygen使你能够提供一个关于你的代码结构的全面概述,而无需额外的努力。虽然Doxygen主要用于记录C++,但你可以把它用于许多其他语言,如C、Objective-C、C#、PHP、Java、Python等等。

要使用Doxygen,你只需用Doxygen能读懂的语法注释你的源代码。然后,Doxygen会浏览你的源文件,并根据这些特殊注释创建HTML或LaTeX文档。下面的C++示例项目将说明如何对源代码进行注释,以及如何从中生成文档。这个例子可以在GitHub上找到,我还将包括对Doxygen手册和文档的不同部分的引用。

在Linux上安装Doxygen

在Fedora上,Doxygen可以作为一个软件包提供。打开一个终端并运行。

sudo dnf install doxygen

在基于Debian的系统上,你可以通过运行来安装它。

sudo apt-get install doxygen

使用方法

一旦安装,你所需要的就是一个与Doxygen兼容的注释的项目和一个Doxyfile,一个控制Doxygen行为的配置文件。

注意:如果你坚持使用GitHub上的相关示例项目,你可以省略下一步。

如果还没有Doxyfile ,你可以直接让Doxygen生成一个标准模板。要做到这一点,请导航到你的项目的根部,然后运行。

doxygen -g

-g ,代表生成。现在你应该注意到一个新创建的文件,叫做Doxyfile 。你可以通过简单的运行来调用Doxygen。

doxygen

现在你应该注意到两个新创建的文件夹。

  • html/
  • latex/

默认情况下,Doxygen会输出LaTeX格式的文档,以及基于HTML的文档。在这篇文章中,我将只关注基于HTML的文档。你可以在Doxygen官方文档中的 "入门"部分找到更多关于LaTeX输出的信息。

双击html/index.html ,打开实际的HTML文档。在一个空白配置下,它可能看起来像下面的截图。

A screenshot of a doxygen generated main page on Firefox. The content field under My Project Documentation is blank.

Image by: (Stephan Avenwedde, CC BY-SA 4.0)

现在是时候修改Doxyfile ,并在源代码中添加一些特殊的注释。

更多的Linux资源

Linux命令小抄

高级Linux命令小抄

免费在线课程。RHEL技术概述

Linux网络小抄

SELinux小抄

Linux常用命令小抄

什么是Linux容器?

我们最新的Linux文章

Doxyfile

Doxyfile 允许你定义大量的调整可能性,所以我将只描述一个非常小的子集。这些设置对应于示例项目的Doxyfile

第35行。项目名称

这里你可以指定项目名称,它将在标题行和浏览器标签中可见。

# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
# double-quotes, unless you are using Doxywizard) that should identify the
# project for which the documentation is generated. This name is used in the
# title of most generated pages and in a few other places.
# The default value is: My Project.

PROJECT_NAME           = "My Project"

第47行。项目简要说明

简要说明也将显示在页眉中,但字体较小。

# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
# quick idea about the purpose of the project. Keep the description short.

PROJECT_BRIEF          = "An example of using Doxygen in C++"

第926行。列入子目录

允许Doxygen在子目录中递归行走以寻找源文件和文档文件。

# The RECURSIVE tag can be used to specify whether or not subdirectories should
# be searched for input files as well.
# The default value is: NO.

RECURSIVE = YES

第1769行。禁用LaTeX输出

如果你只对HTML输出感兴趣,你可以用这个开关禁用LaTeX代码生成。

# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.

# The default value is: YES.

GENERATE_LATEX = NO

每次修改后,你可以再次运行Doxygen来检查你的修改是否产生了预期的效果。如果你只想检查一个现有的Doxyfile ,用-x 开关调用Doxygen。

A screenshot of the terminal showing the differences, Project Name, Project Brief, Recursive, and status of Generate Latex

图片由: (Stephan Avenwedde, CC BY-SA 4.0)

与命令diff ,Doxygen只显示实际的Doxy文件和模板之间的差异。

特别注释

Doxygen读取源文件并检查每个文件的特殊注释。基于这些注释和关键词,它建立了HTML文档。使用ByteStream类的头文件可以很好地解释特殊注释的结构,如上面链接的GitHub例子所示。

我将以构造函数和析构函数为例进行分析。

/*! @brief Constructor which takes an external buffer to operate on
*
* The specified buffer already exist.
* Memory and size can be accessed by buffer() and size().
*
* @param[in] pBuf Pointer to existing buffer
* @param[in] size Size of the existing buffer
*/

ByteStream(char* pBuf, size_t size) noexcept;

对于特殊注释块的格式,有不同的味道。我更喜欢用Qt风格的注释开始(/*!),并在每一行前加一个星号(*)。然后,该块以星号和正斜杠结尾(*/)。要了解不同风格选项的概况,请参考Doxygen手册中的记录代码部分。

Doxygen中的注释分为两个部分,一个是简要描述,一个是详细描述。这两个部分都是可选的。在上面的代码示例中,注释块指的是下面一行代码,即一个构造函数的声明。@brief 后面的句子将在紧凑型类概述中显示。

A screenshot of the C++ example of using Doxygen showing the Byte Stream Class Reference. The categories in the list are public member functions, writing (operators for writing to the stream), and reading (operators for reading from the stream)

图片由: (Stephan Avenwedde, CC BY-SA 4.0)

在一个空行之后(空行被当作段落分隔符),构造函数的实际文档开始了。通过@param[in/out] 关键字,你可以标记传递给构造函数的参数,Doxygen会从中制作一个清晰的参数列表。

Screenshot of the Doxygen example showing the parameters under ByteStream

请注意,Doxygen会在注释中自动创建一个链接到提到的buffer()size() 方法。相比之下,析构器声明前的注释不会对Doxygen产生任何影响,因为它不被识别为特殊注释。

// Destructor
~ByteStream();

现在你已经看到了90%的魔法。通过对你的注释使用稍加修改的语法,你可以把它们转换成Doxygen可以读取的特殊注释。此外,通过使用一些关键词,你可以推进格式化。此外,Doxygen还有一些特殊的功能,我将在下一节强调这些功能。

特点

大部分的工作已经通过你对源代码的常规注释完成了。但通过一些调整,你可以很容易地增强Doxygen的输出。

标注

对于高级格式化,Doxygen支持Markdown语法和HTML命令。在opensource.com的下载区有一个Markdown的小抄。

主页面

除了你自定义的页眉之外,当你打开html/index.html ,你将得到一个大部分是空的页面。你可以通过使用特定的关键词在这个空白处添加一些有意义的内容。因为主页通常不是专门针对某个特定的源代码文件,你可以在项目的根目录下添加一个包含主页内容的普通文本文件。你可以在GitHub上的例子中看到这一点。其中的注释产生了以下输出。

The Doxygen Example Documentation field now contains headings and documentation: Introduction, Running the example, System requirements, and Building the code, with step by step examples and code snippets (all can be found in the example on GitHub)

自动生成链接

如上所述,Doxygen会自动计算出你所引用的是代码的一个现有部分,并创建一个指向相关文档的链接。请注意,只有当您引用的部分也有文档时,自动链接创建才会起作用。

更多的信息可以在官方文档的自动链接生成下找到。

群体

ByteStream类有重载的流操作符,用于写 (<<) 和读 (>>)。在上面特殊注释部分的类概述中,你可以看到操作符的声明被分组为。这些组是在ByteStream头文件中定义和命名的。

分组是用一种特殊的语法完成的。你用@{ 开始一个组,用}@ 结束它。这些标记内的所有成员都属于这个组。在头文件ByteStream.h ,它的实现方式如下。

/** @name Writing
* Operators for writing to the stream
* @{
*/

(...)

/** @}
* @name Reading
* Operators for reading from the stream
* @{
*/

(...)

/** @} */

你可以在Doxygen文档中的分组下找到更多关于分组的信息。

LLVM支持

如果你用Clang构建,你可以在构建过程中应用标志-Wdocumentation ,让Clang检查你的特殊注释。你可以在LLVM用户手册或Dmitri Gribenko的演讲中找到更多关于这个功能的信息,这两个网站都在Clang网站上。

Doxygen的使用范围

Doxygen于1997年首次发布,所以它已经存在了一些年头。尽管它年代久远,许多项目都使用Doxygen来创建他们的文档。一些例子是NASA的F Prime飞行软件框架,图像处理库OpenCV,以及软件包管理器RPM。你还可以在其他领域找到Doxygen语法,比如在内容管理平台Drupal的文档标准中。

注意事项:使用Doxygen的一个缺点是,它输出的HTML文档具有90年代网页的外观和感觉。使用Doxygen也很难描绘出元和模板编程的架构。对于这些情况,你可能会选择Sphinx而不是Doxygen。