Doxygen的基本使用

说到规范代码,良好的注释是一个必选项,那么怎么样才算有良好的注释呢?这个实际没有统一的标准,每个人都有自己的写作风格,但是对于函数定义注释,文件注释,宏定义注释这些是有一定的规范的,这个规范就是Doxygen给出的,写代码的时候如果严格遵守这个规范,那么Doxygen就额可以自动根据代码生成相应的文档,之前一直知道有这么个东西,但是一直都没能好好利用,这个借着代码翻新的机会,就好好说一下代码注释的一些事情。

Doxygen简介

Doxygen是一个可以从代码源文件的注释中提取必要信息生成代码文档的工具,充分利用可以有效的降低代码维护的工作量,为了便于工具识别,我们在编写代码注释的时候要遵守一定的规则,这样才能有效的实现代码文档的提取。

Doxygen支持多种平台,不过我只有windows和linux平台,这两个平台下面的安装方式:

# under linux
sudo apt install doxygen

Windows平台官方提供二进制包,不过下载比较慢,这里也提供一个镜像doxygen-1.8.15.windows.x64.bin.zip。将下载的zip文件解压之后,相应的目录添加到系统变量的PATH里面就可以了。

Doxygen基本使用

产生配置文件

Doxygen在使用上有点类似于make,首先需要通过命令doxygen -g产生一个配置文件,这个配置文件里面有很多配置信息可以更改,配置信息也有良好的说明,比如我们可以修改INPUT来指定代码源文件,通过修改PROJECT_NAME指定文档的名称等等。

基本格式

Doxygen是通过一定的格式识别那些注释要放到文档中的,比较常见的有以下几种注释:

首先是文件注释,文件注释是必不可少的,如果没有文件注释,Doxygen会直接忽略掉这个文件,即使后面有函数注释,所以如果一个文件没有被Doxygen识别,首先要看看文件注释是不是正确,doxygen的注释一般是/**或者/*!开始的,如果只有/*是会被认为普通注释而被直接忽略,一个典型的文件注释如下:

/** 
* @file         occs_drv.h
* @brief        This is driver define for OCCS module. 
* @details      This is the detail description. 
* @author       Major Lin
* @date         14/01/2019
* @version      1.0.0
* @par Copyright (c):  
*       Freescale Semiconductor
* @par History:          
*   version: author, date, desc\n 
*/  

头文件里面的宏定义一般也是要添加注释的,宏定义的注释比较简单,比如:

/** IRC 8M clock frequency in hz */
#define CLK_IRC_8M_FREQ             (8000000)

类似于宏定义,像是枚举变量,全局变量,全局数组等都可以用如下的定义方式:

/**
 * Enum define for all valid system clock
 * This is enum define for all valid system clock, the clock name is
 * used in clock enable, system clock switch, etc.
 */
typedef enum _occs_clk {
    CLK_IRC_8M,
    CLK_IRC_400K,
    CLK_IRC_200K,
    CLK_CRYSTAL,
    CLK_EXTAL,
    CLK_CLK_IN,
    CLK_IRC_48M,
    CLK_IRC48M_DIV,
    CLK_PLL
} occs_clk_t;

比较复杂的是函数定义的注释,因为我们要对函数的参数进行注释,所以有一些比较特别的语法:

/** clock output enable
 *  Set OCCS clock source route to external pin
 * @param[in] target    Target external pin, 0 for out0, 1 for out1
 * @param[in] clk       OCCS clock source
 * @param[in] div       Clock output divider
 * @retval  OK  success   
 * @retval  ERROR fail 
 */
int enable_clock_out(int target, occs_clk_t clk, int div);

上面函数注释中酒半酣了函数的基本说明信息和输入输出参数,其中[in]是可选的,可以用于表明函数参数的传递方向,对于返回值,虽然c函数只能有一个返回值,但是我们可以罗列出各种不同的返回值对应的具体含义,所以@retval是没有数量限制的。

分组

对于比较长的文件,里面可能有非常多的宏定义或者变量函数等等,为了方便查阅我们可以通过分组的方式简化生成的文档。Doxygen中分组之后默认只会显示分组的名称,而里面的具体变量和宏定义等都会被折叠起来,这样就很容易找到我们关心的变量或者宏定义,分组的实现方式如下:

/* ----------------------------------------------------------------------------
   -- Device Peripheral Access Layer
   ---------------------------------------------------------------------------- */

/*!
 * @addtogroup Peripheral_access_layer Device Peripheral Access Layer
 * @{
 */


/* ----------------------------------------------------------------------------
   -- ADC Peripheral Access Layer
   ---------------------------------------------------------------------------- */

/*!
 * @addtogroup ADC_Peripheral_Access_Layer ADC Peripheral Access Layer
 * @{
 */

......

/*!
 * @}
 */ /* end of group ADC_Peripheral_Access_Layer */

......

/*!
 * @}
 */ /* end of group Peripheral_access_layer */

编译输出结果

按照格式写好注释之后我们就可以通过doxygen命令输出文档,该命令默认会在当前文件夹下面搜索Doxyfile作为配置文件,并生成htmllatex两种格式的文档。


本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。

发表新评论