doxygen是一种从源代码生成文档的工具,支持多种语言。当然,源代码中需按一定的格式写注释,这些注释的格式也能帮助我们养成很好的注释习惯,可以尝试一下。





  使用doxygen生成文档的方法很简单:



**
  

    $ doxygen -g –s
  

  
  

    $ doxygen
  

</blockquote>



  只需两个简单命令就可以了。





  下面简单说明一下:





  1、在工程目录下输入doxygen –s –g doxyconfig,其中doxyconfig为生成配置的文件名称,可任意指定,如果不指定,默认生成的配置文件为Doxyfile。man手册中没有详细说明选项的意思,这里不妨猜测一下,-s为simple,-g为generate,如果不指定-s,则生成的配置文件大约为63KB,行数约1500左右;反之,则约成10KB,行数约250左右。——此处猜测便根据这些测试而来的。





  2、生成配置文件后,会出现提示信息,大意是说那个配置文件已经生成了,现在编辑它,之后输入doxygen Doxyfile(经实践证明,可以只输入doxygen命令)就可以产生工程的文档了。如果再次使用doxygen生产配置文件,则原来的就配置文件就变成了备份文件,添加后缀名.bak。





  3、根据doxygen要求的注释格式来编写代码的注释,这一步要求比较高,而且工作量比较大。我们在文章后面还要讲解的。





  下面介绍一下如何编辑生成的配置文件,我们以我们的串口程序为例子。





  &nbsp;





  doxygen的配置文件与大多数linux平台的配置文件类似,就是一些关键字与值,配置文件中的值以YES和NO居多。



<blockquote>
  

    DOXYFILE_ENCODING = UTF-8,默认编码为UTF-8,这样可以支持中文。
  

  
  

    PROJECT_NAME = “SerialPort”,项目名称,多个单词需要使用引号(“”)。
  

  
  

    PROJECT_NUMBER = “1.0 beta”,项目版本号。
  

  
  

    OUTPUT_DIRECTORY = serialport-html,输出文档的目录,如果为空,表示在当前目录,建议写上表示本工程的有意义的目录名称,比如我们就指定目录名称为serialport-html。
  

  
  

    OUTPUT_LANGUAGE = English,文档语言,可以指定为Chinese。
  

  
  

    IMAGE_PATH = image_dir,指定图片存放的目录,我们将图片放到当前目录下的image_dir目录中,因为我们的文档会出现测试图片示例。
  

  
  

    HTML_OUTPUT= . ,html输出目录名称,默认为html目录,如果为“.”则表明为上述OUTPUT_DIRECTORY目录。
  

  
  

    GENERATE_LATEX = NO,是否生成LaTeX,默认生成的,但我们不想生成。
  

  
  

    好了,我们需要修改的就这么多,使用上述第2步骤的命令就可以生成一个漂亮的文档了。此外还有一些常用的设置选项。
  

  
  

    INPUT =xxx,代码文件或目录,多个文件(目录)需要以空格隔开,如果不指定,表示当前目录,但是,如果指定目录且当前目录有代码文件的话,需要使用点号(“.”)表示当前目录。
  

  
  

    FILE_PATTERNS=xxx,指定各种文件,我们常用为*.cpp *.c *.h,等等。
  

</blockquote>



  上面基本就是我们常用的了,如果还想更深入了解,请移步到google网站。





  下面就是真正需要花费一定时间的工作:为我们的程序作特定格式的注释。





  doxygen支持多种注释风格,比如JavaDoc风格,它在C语言块注释开始处再添加一个星号(*)构成,如下:



<div>
  

    1.           /**
  

  
  

    2.            * … text …
  

  
  

    3.            */
  

</div>



  Qt风格:



<div>
  ```
1.           /*!
      
      ```
	2.            * ... text ...
  ```
3.            */
    </div>
    
    

      上面两种方式中间的星号(*)是可选的,不过,个人认为添加会更美观一些。
    

    
    

      C++风格的,——就是在C++注释后面再添加“/”:
    

    
    <div>
      ```
	1.           ///
  ```
2.           /// ... text ...
      
      ```
	3.           ///
</div>



  或者是这样:



<div>
  ```
1.           //!
      
      ```
	2.           //!... text ...
  ```
3.           //!
    </div>
    
    

      经测试,实际使用中,如果是单行注释的话,可以使用如下的格式:
    

    
    <div>
      ```
	1.           /** ... text ... */
  ```
2.           /**&lt; ... text ... */
    </div>
    
    

      这些格式会被doxygen文档化,如果不想让它文档化,可以“破坏”这些格式,比如可以使用“正宗”的C/C++注释:
    

    
    <div>
      ```
	1.           /* ... text ... */
  ```
2.           // ... text ...
    </div>
    
    

      上述风格来自doxygen的manual页面,具体地址为:
    

    
    

      [http://www.stack.nl/~dimitri/doxygen/docblocks.html](http://www.stack.nl/~dimitri/doxygen/docblocks.html)
    

    
    

      http://www.stack.nl/~dimitri/doxygen/index.html
    

    
    ```
# 自定义文档首页
# INPUT                  = README.md other_sources
# USE_MDFILE_AS_MAINPAGE = README.md
  下面介绍一下常用doxygen的命令,更多详细使用说明,请参考如下地址:





  [http://www.stack.nl/~dimitri/doxygen/commands.html#cmde](http://www.stack.nl/~dimitri/doxygen/commands.html#cmde)





  doxygen命令以@或开始,两种方式均可以。文中以@标记之。



<blockquote>
  

    @def 宏定义说明
  

  
  

    @fn 函数 函数说明
  

  
  

    @param 参数 参数说明
  

  
  

    @return 返回值说明(出错返回什么值,等等)
  

  
  

    @file 文件名
  

  
  

    @author 作者
  

  
  

    @version 程序版本
  

  
  

    @date 日期
  

  
  

    @note 注解(注意事项,等)
  

  
  

    @warning 警告信息
  

  
  

    @bug bug信息
  

  
  

    @test 测试示例、信息
  

  
  

    @todo 一些未完事宜
  

  
  

    (@bug、@test以及@todo等会出现链接页面)
  

  
  

    上面这样适合在函数、文件前面出现。
  

  
  

    下面为生成特殊字体的命令:
  

  
  

    @a @e @em:其后的单个字(word)表现为斜体,以强调作用。如有多个word的话,使用*xxx xxx*代替。
  

  
  

    @b:其后的word为粗体,多个则使用<b>xxx xxx**。
  

  
  

    @c @p:字体表现为打印机字体,多个则使用<tt>xxx xxx</tt>。
  

</blockquote>



  ` `





  `下面是一些具体的实例。 `





  `在文件开始处的版权声明及其它信息:`



**
  

    /**
  

  
  

    *                      Copyleft (C) 2010  Late Lee
  

  
  

    *        This program is tested on LINUX PLATFORM, WITH GCC 4.x.
  

  
  

    *        The program is distributed in the hope that it will be
  

  
  

    *        useful, but WITHOUT ANY WARRANTY. Please feel free to
  

  
  

    *        use the program, and I feel free to ignore the related
  

  
  

    *        issues. Any questions or suggestions, or bugs, please
  

  
  

    *        contact me at  or e-mail to
  

  
  

    *         if you want to do this.
  

  
  

    * @file   serialport.c
  

  
  

    * @author Late Lee
  

  
  

    * @date   Mon Jan 10 2011
  

  
  

    *
  

  
  

    * @brief  Some utils of the serial port, such as open the port, close
  

  
  

    *         the port and setup the port.
  

  
  

    * @note   This is a note.
  

  
  

    * @warning This is a warning.
  

  
  

    * @bug    This is a bug.
  

  
  

    */
  

</blockquote>



  &nbsp;





  在函数前的注释:





  &nbsp;



<blockquote>
  

    /**
  

  
  

    * open_port – Open a serial port
  

  
  

    *
  

  
  

    * @param port : The port number, eg, open_port(1) will open com1
  

  
  

    *
  

  
  

    * @return Return fd if success, otherwise will return -1 with some msg.
  

  
  

    */
  

</blockquote>



  定义宏使用的注释:



<blockquote>
  

    /**
  

  
  

    * @def error_exit
  

  
  

    * @brief A macro that prints the @a error msg and exit.
  

  
  

    */
  

  
  

    #define error_exit(error)
  

  
  

    do{
  

  
  

    fprintf(stderr, “%sn”, error);
  

  
  

    exit(0);
  

  
  

    } while(0)
  

</blockquote>



  &nbsp;





  &nbsp;





  或者你会说,这样的注释风格太麻烦了!不怕!现在有了跟emacs结合的doxymacs,在emacs中配置了doxymacs,这些注释是十分方便的!比如需要在文件前插入注释,按C-c d i即可,在函数前插入注释,按C-c d f即可,等等。具体的请移步到这里的文章:[http://www.latelee.org/embedded-linux/learning-elinux-4-my-emacs-ii](http://www.latelee.org/embedded-linux/learning-elinux-4-my-emacs-ii.html)及[http://www.latelee.org/embedded-linux/learning-elinux-4-my-emacs](http://www.latelee.org/embedded-linux/learning-elinux-4-my-emacs.html)。如果你使用的不是emacs,那Sorry,我也不太会,如果你懂,不妨分享一下。





  这个串口程序的文档已经放到网站上了,这里main.c文件参考页面地址:[http://www.latelee.org/yetanothertest/serialport-html-cn/main_8c.html](http://www.latelee.org/yetanothertest/serialport-html-cn/main_8c.html)





  此外,我们还测试生成中文文档,因此doxygen使用UTF8,因此只要将代码文件保存为utf8编码即可(使用Ultra Edit或notepad++等等编辑器很容易做到)。但这又引出一个问题,gcc并不支持utf8!经过google,发现gcc 4.4.0版本以后已经支持utf8了,因此,为了做这个测试,花了一个小时左右编译、安装高版本的gcc(我们使用4.4.5版本),结果,这个版本的gcc是支持utf8的。后来,又发现,如果使用“UTF-8 无BOM格式编码”格式保存源文件的话,在原来的gcc下也编译通过。因此如果想在程序中使用中文注释,建议以此格式保存,当然,在系统的locale不是中文的情况下看到的中文是乱码的。





  1、尽信书则不如无书,我们建议各位到实践中试一试,这样学到的知识才是我们自己的,比如,在指定源代码目录中,我的测试文件main.c放在当前目录下,如果不指定“.”的话,doxygen便不会处理该文件,这是网上很多资料没有说明的,因此需要实践才能了解。





  2、我们强烈建议各位到官方网站学习,因为其它地方绝大部分都出自官方网站,manual页面地址是:





  [http://www.stack.nl/~dimitri/doxygen/manual.html](http://www.stack.nl/~dimitri/doxygen/manual.html)

 

Doxygen是一种开源跨平台的,以类似JavaDoc风格描述的文档系统,完全支持C、C++、Java、Objective-C和IDL语言,部分支持PHP、C#。注释的语法与Qt-Doc、KDoc和JavaDoc兼容。Doxgen可以从一套归档源文件开始,生成HTML格式的在线类浏览器,或离线的LATEX、RTF参考手册。

Doxygen 是一个程序的文件产生工具,可将程序中的特定批注转换成为说明文件。通常我们在写程序时,或多或少都会写上批注,但是对于其它人而言,要直接探索程序里的批注,与打捞铁达尼号同样的辛苦。大部分有用的批注都是属于针对函式,类别等等的说明。所以,如果能依据程序本身的结构,将批注经过处理重新整理成为一个纯粹的参考手册,对于后面利用您的程序代码的人而言将会减少许多的负担。不过,反过来说,整理文件的工作对于您来说,就是沉重的负担。
Doxygen 就是在您写批注时,稍微按照一些它所制订的规则。接着,他就可以帮您产生出漂亮的文档了。

因此,Doxygen 的使用可分为两大部分。首先是特定格式的批注撰写,第二便是利用Doxygen的工具来产生文档。

 

 

1) 输出表格

`  &lt;span class="hljs-javadoc">/**
  * DSTATUS     | value| instruction
  * ------------| ---- | -----------------------
  * STA_NOINIT  | 0x01 | Drive not initialized
  * STA_NODISK  | 0x02 | No medium in the drive
  * STA_PROTECT | 0x04 | Write protected
  */&lt;/span>`

效果为:
这里写图片描述

(2) 参考其他函数注释:
@see
(3) module name:

`&lt;span class="hljs-javadoc">/**
  * &lt;span class="hljs-javadoctag"> @defgroup&lt;/span>  test_module_name
  * &lt;span class="hljs-javadoctag"> @brief&lt;/span>     module example.
  */&lt;/span>
&lt;span class="hljs-javadoc">/**
  * &lt;span class="hljs-javadoctag"> @ingroup&lt;/span>   test_module_name
  * &lt;span class="hljs-javadoctag"> @brief&lt;/span>     source file of module example.
  * &lt;span class="hljs-javadoctag"> @file&lt;/span>      test_module_name.c
  * &lt;span class="hljs-javadoctag"> @author&lt;/span>    test
  * &lt;span class="hljs-javadoctag"> @version&lt;/span>   1.0
  * &lt;span class="hljs-javadoctag"> @date&lt;/span>      2018/2/27
  * /&lt;/span>`

(4) <b> ** 以黑体显示字符,用法格式如下:

`&lt;span class="hljs-tag">&lt;&lt;span class="hljs-title">b&lt;/span>&gt;&lt;/span> multiple words &lt;span class="hljs-tag">&lt;/&lt;span class="hljs-title">b&lt;/span>&gt;&lt;/span>`

若要黑体显示像标题一样单独一行,可以在后面添加/n,如下图示例所示:
这里写图片描述
生成样式为:
这里写图片描述

 

**使用步骤**





1、第一次使用需要安装doxygen的程序

2、生成doxygen配置文件

3、编码时,按照某种格式编写注释 4、生成对应文档

1、安装doxygen及其相关程序

1.1Doxygen下载

http://sourceforge.net/projects/doxygen/?source=dlp 进行下载

本文使用的为Doxygen 1.8.3.1

安装,我们将在配置的时候使用doxywizard,Doxygen的GUI版本。

1.2HTML Help Workshop下载

如果你希望你的Doxygen自动生成chm,那么请下载HTML Help Workshop,我们将要使用当中的hcc.exe文件以及相关dll

http://www.microsoft.com/en-us/download/details.aspx?id=21138 进行下载

下载其中的htmlhelp.exe并安装,记住安装目录,我们将在Doxygen配置时使用。

1.3 Graphviz

graphviz 是一个由AT&T实验室启动的开源工具包,用于绘制DOT语言脚本描述的图形。Doxygen 使用 graphviz 自动生成类之间和文件之间的调用关系图,如不需要此功能可不安装该工具包。

安装并记录安装目录,同样我们一会需要配置Doxygen

2.配置Doxygen

2.1基本配置

在基本配置中,会介绍一些关于Doxygen的基本配置,例如各种乱码,输出内容等。

首先我们打开开始-》所有程序-》Doxygen-》doxywizard

第一步,选择你的工作目录(配置文件位置  D:\Doxygen),点击Select。

第二步,进行配置

Wizard选项卡:

首先修改Project name,选择扫描源代码的目录,Source code directory:,勾选Scan recursively  (递归扫描),之后选择输出目录,作为测试选择桌面进行查看。

在Wizard的Topics下的Mode,选择All Entities,可以输出相对完整的功能,是否包含源代码看你自身情况,在下面选择好你的语言。这里作者使用的是C#  所以选择Java or C#

在Output中,如果你需要输出chm格式,请勾选。

在Diagrams中选择使用GraphViz包,来输出UML

Expert选项卡:

说明:编码格式,UTF-8 是首选。如果需要显示中文则选择GB2312.

TAB_SIZE 主要是帮助文件中代码的缩进尺寸,譬如@code和@endcode段中代码的排版,建议设置成4。

Build页面,这个页面是生成帮助信息中比较关键的配置页面:

EXTRACT_ALL 表示:输出所有的函数,但是private和static函数不属于其管制。

EXTRACT_PRIVATE 表示:输出private函数。

EXTRACT_STATIC 表示:输出static函数。同时还有几个EXTRACT,相应查看文档即可。

SHOW_INCLUDE_FILES 表示:是否显示包含文件,如果开启,帮助中会专门生成一个页面,里面包含所有包含文件的列

表。

INLINE_INFO :如果开启,那么在帮助文档中,inline函数前面会有一个inline修饰词来标明。

SORT_MEMBER_DOCS :如果开启,那么在帮助文档列表显示的时候,函数名称会排序,否则按照解释的顺序显

示。

说明:INPUT_ENCODING (输入的源文件的编码),要与源文件的编码格式相同。如果源文件不是UTF-8编码最好转一下。

总结:我查看到我的代码文件是utf-8的(vs2013中打开文件 选另存为可看到编码格式)((VS2012的话):文件->高级保存选项)。

在Expert的HTML中,首先要看HHC_LOCATION选项,添加安装目录(注:作者目录为C:/Program Files (x86)/HTML Help Workshop/hhc.exe)

勾选CHM_INDEX_ENCODING,在你源代码中的字符集是什么就填写什么,

之后在Expert的Dot中勾选CLASS_DIAGRAMS,UML_LOOK

为了减少chm体积,在DOT_IMAGE_FORMAT中选择gif或者jpg,均可。





最后选择好DOT_PATH所输出的位置。





![](http://img.blog.csdn.net/20150426150054043?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYmlncHVkZGluZzI0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
点击 Run doxygen 按钮, Doxygen 就会从源代码中抓取符合规范的注释生成你定制的格式的文档。
几个错误:Error: When enabling GENERATE_HTMLHELP the search engine (SEARCHENGINE) should be disabled. I&#8217;ll do it for you.





warning: The selected output language &#8220;chinese&#8221; has not been updated





since release 1.8.2. As a result some sentences may appear in English.





解决:把HTML里面的SEARCHENGINE设置为NO
接下来的工作就是学习 doxygen 的注释规范了,参考 《doxygen 快速入门》第 2 节 “常用注释语法”。慢慢的就可以体会到 doxygen 的方便性。

 

3、doxygen 的注释规范

并非所有程序代码中的批注都会被Doxygen 所处理。您必需依照正确的格式撰写。原则上,Doxygen 仅处理与程序结构相关的批注,如
Function,Class ,档案的批注等。对于Function内部的批注则不做处理。Doxygen可处理下面几种类型的批注。

JavaDoc类型:

/**
* … 批注 …
*/

Qt类型:

/*!
* … 批注 …
*/

单行型式的批注:

/// … 批注 …

//! … 批注 …

要使用哪种型态完全看自己的喜好。以笔者自己来说,大范围的注解我会使用JavaDoc 型的。单行的批注则使用”///” 的类型。

此外,由于Doxygen 对于批注是视为在解释后面的程序代码。也就是说,任何一个批注都是在说明其后的程序代码。如果要批注前面的程
式码则需用下面格式的批注符号。

/*!< … 批注 … */
/**< … 批注 … */
//!< … 批注 …
///< … 批注 …

上面这个方式并不适用于任何地方,只能用在class 的member或是function的参数上。

举例来说,若我们有下面这样的class。
class MyClass {
public:
int member1 ;
int member2:
void member_function();
};

加上批注后,就变成这样:

/**
* 我的自订类别说明 …
*/
class MyClass {
public:
int member1 ; ///< 第一个member说明 …
int member2:  ///< 第二个member说明 …
int member_function(int a, int b);
};

/**
* 自订类别的member_funtion说明 …
*
* @param a 参数a的说明
* @param b 参数b的说明
*
* @return 传回a+b。
*/
int MyClass::member_function( int a, int b )
{
return a+b ;
}

当您使用Doxygen 产生说明文档时,Doxygen 会帮您parsing 您的程式码。并且依据程序结构建立对应的文件。然后再将您的批注,依据其位置套入于正确的地方。您可能已经注意到,除了一般文字说明外,还有一些其它特别的指令,像是@param及@return 等。这正是Doxygen 另外一个重要的部分,因为一个类别或是函式其实都有固定几个要说明的部分。为了让Doxygen 能够判断,所有我们就必需使用这些指令,来告诉Doxygen 后面的批注是在说明什么东西。Doxygen 在处理时,就会帮您把这些部分做特别的处理或是排版。甚至是制作参考连结。
首先,我们先说明在Doxygen 中对于类别或是函数批注的一个特定格式。
/**
* class或function的简易说明…
*
* class或function的详细说明…
* …
*/
上面这个例子要说的是,在Doxygen 处理一个class 或是function注解时,会先判断第一行为简易说明。这个简易说明将一直到空一行的出现。或是遇到第一个”.” 为止。之后的批注将会被视为详细说明。两者的差异在于Doxygen 在某些地方只会显示简易说明,而不显示详细说明。如:class 或function的列表。

另一种比较清楚的方式是指定@brief的指令。这将会明确的告诉Doxygen,何者是简易说明。例如:
/**
* @brief class或function的简易说明…
*
* class或function的详细说明…
* …
*/

除了这个class 及function外,Doxygen 也可针对档案做说明,条件是该批注需置于档案的前面。主要也是利用一些指令,通常这部分注解都会放在档案的开始地方。如:

/*! \file myfile.h
\brief 档案简易说明

详细说明.

\author 作者信息
*/

如您所见,档案批注约略格式如上,请别被”&#8221; 所搞混。其实,”&#8221; 与”@” 都是一样的,都是告诉Doxygen 后面是一个指令。两种在Doxygen 都可使用。笔者自己比较偏好使用”@”。
接着我们来针对一些常用的指令做说明:

<td valign="top">
  档案的批注说明。
</td>
<td valign="top">
  作者的信息
</td>
<td valign="top">
  用于class 或function的批注中,后面为class 或function的简易说明。
</td>
<td valign="top">
  格式为

  
  

    @param arg_name 参数说明
  

  
  

    主要用于函式说明中,后面接参数的名字,然后再接关于该参数的说明。</td> </tr> 
    
    <tr>
      <td valign="top">
        @return
      </td>
      
      <td valign="top">
        后面接函数传回值的说明。用于function的批注中。说明该函数的传回值。
      </td>
    </tr>
    
    <tr>
      <td valign="top">
        @retval
      </td>
      
      <td valign="top">
        格式为

        
        

          @retval value 传回值说明
        

        
        

          主要用于函式说明中,说明特定传回值的意义。所以后面要先接一个传回值。然后在放该传回值的说明。</td> </tr> </tbody> </table> 
          
          

            Doxygen 所支持的指令很多,有些甚至是关于输出排版的控制。您可从Doxygen的使用说明中找到详尽的说明。
          

          
          

            下面我们准备一组example.h 及example.cpp 来说明Doxygen 批注的使用方式:
          

          
          

            example.h:
          

          
          

            /**

* @file 本范例的include档案。 * * 这个档案只定义example这个class。 * * @author garylee@localhost */

            #define EXAMPLE_OK  0   ///< 定义EXAMPLE_OK的宏为0。
          

          
          

            /**

* @brief Example class的简易说明 * * 本范例说明Example class。 * 这是一个极为简单的范例。 * */ class Example { private: int var1 ; ///< 这是一个private的变数 public: int var2 ; ///< 这是一个public的变数成员。 int var3 ; ///< 这是另一个public的变数成员。 void ExFunc1(void); int ExFunc2(int a, char b); char *ExFunc3(char *c) ; };

            example.cpp:
          

          
          

            /**

* @file 本范例的程序代码档案。 * * 这个档案用来定义example这个class的 * member function。 * * @author garylee@localhost */

            /**

* @brief ExFunc1的简易说明 * * ExFunc1没有任何参数及传回值。 */ void Example::ExFunc1(void) { // empty funcion. }

            /**

* @brief ExFunc2的简易说明 * * ExFunc3()传回两个参数相加的值。 * * @param a 用来相加的参数。 * @param b 用来相加的参数。 * @return 传回两个参数相加的结果。 */ int ExFunc2(int a, char b) { return (a+b); }

            /**

* @brief ExFunc3的简易说明 * * ExFunc3()只传回参数输入的指标。 * * @param c 传进的字符指针。 * @retval NULL 空字符串。 * @retval !NULL 非空字符串。 */ char * ExFunc2(char * c) { return c; }

          # 附:我的配置文件

💬 评论

@file
@author
@brief
@param