Doxygen入门使用方法和最佳实践简介

一个ai生成的包含多个工具的工具箱图片

简介

Doxygen 是一种生成带注释的 C 语言源代码文档的实际标准工具。它也支持其他流行的编程语言,如 C、Objective-C、C#、PHP、Java、Python、IDL(Corba、Microsoft 和 UNO/OpenOffice 风格)、FORTRAN、VHDL,以及在一定程度上的 D 语言。

它可以根据程序本身的结构,处理规范注释的批注,并生成一个纯粹的参考手册。通过提取代码结构或利用自动生成的包含依赖图、继承图和协作图,可视化文档之间的关系。

主要功能包括:

1)从文档化的源文件(带有规范方式注释)生成 HTML 或离线的引用手册 LATEX。

2)支持生成 RTF(MS-Word)、PostScript、超链接 PDF、压缩 HTML 和 Unix man pages 的输出。

3)直接从源码获取文档,确保文档与源码保持一致。

Doxygen 可以配置从未记录的源文件中提取代码结构,这对于在大型源代码发行版中快速定位非常有用。它还能通过依赖图、继承图和协作图可视化各种元素之间的关系,这些图表都是自动生成的。

Doxygen 在 Mac OS X 和 Linux 下开发,但具有高度的可移植性。因此,它也能够在大多数其他 Unix 风格的系统上运行,并提供适用于 Windows 的可执行文件。

下载安装

Ubuntun 16.04版本上直接使用命令安装

apt install doxygen
doxygen -v
1.8.6

其他版本 https://sourceforge.net/projects/doxygen/files/

配置Doxygen

下图显示了工具之间的关系以及它们之间的信息流

image-20210611110054187

检查语言支持

默认支持 C, C++, Lex, C#, Objective-C, IDL, Java, VHDL, PHP, Python, Fortran and D.

其他语言需要特殊的配置来解决,不过同上以上就够用了。

建立配置文件

Doxygen 使用配置文件来判定所有的设置。每个项目都有一个配置文件。项目可以仅仅是一个源文件或者文件夹组成。

为了简化创建配置文件,先创建一个模板配置文件

doxygen -g <config-file>

image-20210611153741085

<config-file> 作为配置文件名称,默认Doxyfile 名称。 如果文件名使用减号,表示从标准输出中读取文件配置

配置文件格式,类似于Makefile 文件

TAGNAME = VALUE or
TAGNAME = VALUE1 VALUE2 ...

doxywizard 提供图形化的设置配置文件。

对于包含一些 C 和/或 C++ 源文件和头文件的小项目,您可以将 INPUT 标签留空,doxygen 将在当前目录中搜索源文件

如果您有一个包含源目录或树的较大项目,您应该将根目录或目录分配给 INPUT 标记,并将一个或多个文件模式添加到 FILE_PATTERNS 标记(例如 *.cpp *.h)。

只有匹配模式的文件才会被解析(如果模式被省略,典型模式列表用于doxygen 支持的文件类型)。 对于源树的递归解析,您必须将 RECURSIVE 标记设置为 YES。 为了进一步微调解析的文件列表,可以使用 EXCLUDE 和 EXCLUDE_PATTERNS 标签。 例如,要从源树中省略所有测试目录,可以使用:

EXCLUDE_PATTERNS = */test/*

Doxygen 根据文件的扩展名称,来设置解析文件方式,表格如下:

image-20210611111740134

任何未解析的扩展都可以通过将其添加到 FILE_PATTERNS 并设置适当的 EXTENSION_MAPPING 来设置。(其他的扩展文件可以通过设置添加解析方式)

运行Doxygen

doxygen <config-file>

、

执行后,默认生成的是HTML 文档和Latex 文档两个。

根据您的设置,doxygen 将在输出目录中创建 html、rtf、latex、xml、man 和/或 docbook 目录。顾名思义,这些目录包含生成的 HTML、RTF、XML、Unix-Man 页和 DocBook 格式的文档。 默认的输出目录是doxygen 启动的目录。可以使用 OUTPUT_DIRECTORY 更改写入输出的根目录。可以使用 HTML_OUTPUT、RTF_OUTPUT、LATEX_OUTPUT、XML_OUTPUT、MAN_OUTPUT 和 DOCBOOK_OUTPUT 选择输出目录中的特定格式目录。如果输出目录不存在,doxygen 将尝试为您创建它(但它不会尝试递归创建整个路径,就像 mkdir -p 所做的那样)。

注释代码

若配置文件中的 EXTRACT_ALL 选项设置为 NO(默认状态),doxygen 将仅为已注释的实体部分生成文档。那么如何标记这些内容呢?对于成员、类和命名空间,通常有两种选择:

1)在成员、类和命名空间之前放置特殊的注释,同时也允许直接在成员之后放置文档。

2)在其他位置(另一个文件或其他地方)放置一个特殊的文档块,并在文档块中使用结构命令。 结构命令将文档块链接到要记录的实体(如成员、类、命名空间或文件)。

需要注意的是:对于文件注释(即注释整个文件),只能使用第二种方式。在其他文件中放置特殊的文件块,但是文件内的函数等内容仍可以直接使用第一种方式进行注释。

方式一:写在代码中的注释

方式二:写在其他文件或者位置的代码我们忽略。

一个特殊的注释块是带有一些附加标记的 C 或 C++ 样式的注释块,因此 doxygen 知道它是需要在生成一段结构化文本。

对于 Python、VHDL 和 Fortran 代码,有不同的注释约定,可以分别在 Python 中的注释块、VHDL 中的注释块和 Fortran 中的注释块部分中找到。注释文档

对于代码中的每个实体,有两种(或在某些情况下为三种)类型的描述,它们共同构成了该实体的文档;简要说明详细说明,两者都是可选的。对于方法和函数,还有第三种类型的描述,即所谓的函数体内部描述,它由方法或函数主体内的所有注释块的串联组成。允许有多个简短或详细的描述(但不推荐,因为未指定描述的出现顺序)对于 HTML 输出,简要说明还用于在引用位置提供提示。

JAVA风格

/**
* ... text ...
*/

有些人喜欢让他们的注释块在文档中更明显。为此,您可以使用以下使用 JAVADOC_BANNER = YES然后可以使用

/********************************************//**
* ... text
***********************************************/
//注意 2 个斜线结束普通注释块并开始一个特殊的注释块

/////////////////////////////////////////////////
/// ... text ...
/////////////////////////////////////////////////

/************************************************
* ... text
***********************************************/

下面的例子就是一个好的JAVADOC 样式的代码模板。

/**
* A brief history of JavaDoc-style (C-style) comments.
*
* This is the typical JavaDoc-style C-style comment. It starts with two
* asterisks.
*
* @param theory Even if there is only one possible unified theory. it is just a
*               set of rules and equations.
*/
void cstyle( int theory );

/*******************************************************************************
* A brief history of JavaDoc-style (C-style) banner comments.
*
* This is the typical JavaDoc-style C-style "banner" comment. It starts with
* a forward slash followed by some number, n, of asterisks, where n > 2. It's
* written this way to be more "visible" to developers who are reading the
* source code.
*
* Often, developers are unaware that this is not (by default) a valid Doxygen
* comment block!
*
* However, as long as JAVADOC_BLOCK = YES is added to the Doxyfile, it will
* work as expected.
*
* This style of commenting behaves well with clang-format.
*
* @param theory Even if there is only one possible unified theory. it is just a
*               set of rules and equations.
******************************************************************************/
void javadocBanner( int theory );

/***************************************************************************//**
* A brief history of Doxygen-style banner comments.
*
* This is a Doxygen-style C-style "banner" comment. It starts with a "normal"
* comment and is then converted to a "special" comment block near the end of
* the first line. It is written this way to be more "visible" to developers
* who are reading the source code.
* This style of commenting behaves poorly with clang-format.
*
* @param theory Even if there is only one possible unified theory. it is just a
*               set of rules and equations.
******************************************************************************/
void doxygenBanner( int theory );

注意:有些的Doxygen C语言的注释文档中,\brief格式来写,这是QT样式的Doxygen 同样可以识别。可以理解为两种是一样的。

/*! \brief Brief description.
*         Brief description continued.
*
* Detailed description starts here.
*/
// 可以将 \brief 命令与上述注释块之一一起使用。此命令在段落末尾结束,因此在空行后添加详细说明

在配置文件中,如果 JAVADOC_AUTOBRIEF 设置为YES 。这种设置会自动的进行JAVADOC格式的auto brief 简述格式!

这是一个例子

/** Brief description which ends at this dot. Details follow
* here.
*/

/// Brief description which ends at this dot. Details follow
/// here.

C++ 风格的简单描述结合详细注释

/// Brief description.
/** Detailed description. */

或者, JAVADOC_AUTOBRIEF 设置为NO。

//! Brief description.

//! Detailed description
//! starts here.

多个详细描述,会进行自动的进行连接

//! Brief description, which is
//! really a detailed description since it spans multiple lines.
/*! Another detailed description!
*/

与大部分文档不同,Doxygen 成员的定义前放置注释,包括全局函数。这样注释可以放在源文件中而不是头文件中。这使头文件保持紧凑,并允许成员的实现者更加直接地访问文档。

可以将简要说明放在声明之前,将详细说明放在成员定义之前。在成员之后放置注释内容

如果想注释结构体成员,类成员或者 枚举成员,Union 联合成员。 需要将注释放在成员的后面,但是必须添加“<” 符号

int var; /*!< Detailed description after the member */
或者
int var; /**< Detailed description after the member */

int var; ///< Detailed description after the member
        ///<

如果放置简单描述

int var; //!< Brief description after the member

int var; ///< Brief description after the member

函数参数的内联文档

void foo(int v /**< [in] docs for input parameter v. */);

[in], [out], [in,out] 表示参数的方向

请注意,这些块与上一节中的特殊注释块具有相同的结构和含义,只是 < 表示该成员位于块的前面而不是块的后面。

例子

/*! A test class */

class Afterdoc_Test
{
 public:
   /** An enum type.
    * The documentation block cannot be put after the enum!
    */
   enum EnumType
  {
     int EVal1,     /**< enum value 1 */
     int EVal2      /**< enum value 2 */
  };
   void member();   //!< a member function.
   
 protected:
   int value;       /*!< an integer value */
};

工作模板

在设计的使用中,使用这个模板,就可以写好注释文档

开启: JAVADOC_AUTOBRIEF 设置成YES ,这是javaDOC方式注解方式。

If JAVADOC_AUTOBRIEF is set to YES in the configuration file, then using Javadoc style comment blocks will automatically start a brief description which ends at the first dot followed by a space or new line.

/**
* A test class. A more elaborate class description.
*/

class Javadoc_Test
{
 public:

   /**
    * An enum.
    * More detailed enum description.
    */

   enum TEnum {
         TVal1, /**< enum value TVal1. */  
         TVal2, /**< enum value TVal2. */  
         TVal3  /**< enum value TVal3. */  
        }
      *enumPtr, /**< enum pointer. Details. */
      enumVar;  /**< enum variable. Details. */
     
     /**
      * A constructor.
      * A more elaborate description of the constructor.
      */
     Javadoc_Test();

     /**
      * A destructor.
      * A more elaborate description of the destructor.
      */
    ~Javadoc_Test();
   
     /**
      * a normal member taking two arguments and returning an integer value.
      * @param a an integer argument.
      * @param s a constant character pointer.
      * @see Javadoc_Test()
      * @see ~Javadoc_Test()
      * @see testMeToo()
      * @see publicVar()
      * @return The test results
      */
      int testMe(int a,const char *s);
     
     /**
      * A pure virtual member.
      * @see testMe()
      * @param c1 the first argument.
      * @param c2 the second argument.
      */
      virtual void testMeToo(char c1,char c2) = 0;
 
     /**
      * a public variable.
      * Details.
      */
      int publicVar;
     
     /**
      * a function variable.
      * Details.
      */
      int (*handler)(int a,int b);
};

一个注释模板基本上就够用了。直接在头文件中写注释就好了;

一般同样的我们会在代码开头方注释模板

/**
* @file        
* @brief This is a brief description.
* @details   This is the detail description.
* @author author
* @date   date
* @version   v1.0
* @par Copyright(c): abc corporation
* @par History:        
* version: author, date, desc\n
*/

自动生成符合Doxygen 格式的文档的插件工具

输入/** +Enter键,会自动生成对应的格式!

VSCode 提示插件Doxygen Documentation Generator 查看下面的基础的几个演示用法!

至于插件的安装,这里就不说明了!

image-20231130175904910

安装:点击扩展按钮,然后点击插件安装即可

image-20231130180048575

参考文档

[1] Doxygen 学习

[2] https://www.doxygen.nl/manual/docblocks.html#cppblock

[3] https://www.doxygen.nl/manual/docblocks.html#cppblock

[4] https://www.doxygen.nl/manual/index.html



发表评论

1 评论