当你试图熟悉别人的项目时,你通常会欣赏留下的评论,这些评论可以帮助你理解他们代码的含义。同样,无论何时你在编程时,无论是为自己还是为他人,对自己的代码进行注释都是很好的做法。所有的编程语言都提供了一种特殊的语法,可以将一个词、一行或整个部分标记为注释。在处理源代码时,这些区域会被编译器或解释器忽略。
注释并不能代替文档,但有一种方法可以使用你的注释来轻松制作文档。认识一下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文档。在一个空白配置下,它可能看起来像下面的截图。
Image by: (Stephan Avenwedde, CC BY-SA 4.0)
现在是时候修改Doxyfile
,并在源代码中添加一些特殊的注释。
更多的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。
图片由: (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
后面的句子将在紧凑型类概述中显示。
图片由: (Stephan Avenwedde, CC BY-SA 4.0)
在一个空行之后(空行被当作段落分隔符),构造函数的实际文档开始了。通过@param[in/out]
关键字,你可以标记传递给构造函数的参数,Doxygen会从中制作一个清晰的参数列表。
请注意,Doxygen会在注释中自动创建一个链接到提到的buffer()
和size()
方法。相比之下,析构器声明前的注释不会对Doxygen产生任何影响,因为它不被识别为特殊注释。
// Destructor
~ByteStream();
现在你已经看到了90%的魔法。通过对你的注释使用稍加修改的语法,你可以把它们转换成Doxygen可以读取的特殊注释。此外,通过使用一些关键词,你可以推进格式化。此外,Doxygen还有一些特殊的功能,我将在下一节强调这些功能。
特点
大部分的工作已经通过你对源代码的常规注释完成了。但通过一些调整,你可以很容易地增强Doxygen的输出。
标注
对于高级格式化,Doxygen支持Markdown语法和HTML命令。在opensource.com的下载区有一个Markdown的小抄。
主页面
除了你自定义的页眉之外,当你打开html/index.html
,你将得到一个大部分是空的页面。你可以通过使用特定的关键词在这个空白处添加一些有意义的内容。因为主页通常不是专门针对某个特定的源代码文件,你可以在项目的根目录下添加一个包含主页内容的普通文本文件。你可以在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。