简介Doxygen

什么是Doxygen?

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

 对于未归档的源文件,也可以通过配置Doxygen来提取代码结构。或者借助自动生成的包含依赖图(includedependency graphs)、继承图(inheritance diagram)以及协作图(collaborationdiagram)来可视化文档之间的关系。Doxygen生成的帮助文档的格式可以是CHM、RTF、PostScript、PDF、HTML和Unixmanpage等。


一个好的程序设计师,在写程序时,都会在适当的地方加上合适的批注。如果,能够在撰写批注时,稍微符合某种格式,接着就可以透过一个工具程序依据程序结构及您的批注产生出漂亮的檔。这将令许多工作繁重的程序设计师有时间多喝几杯咖啡。

Doxygen 就是这样的一个工具。在您写批注时,稍微按照一些它所制订的规则。接着,他就可以帮您产生出漂亮的檔了。因此,Doxygen 的使用可分为两大部分。首先是特定格式的批注撰写,第二便是利用Doxygen的工具来产生檔。

目前Doxygen可处理的程序语言包含:

  • C/C++
  • Java
  • IDL (Corba, Microsoft及KDE-DCOP类型)

而可产生出来的檔格式有:

  • HTML
  • XML
  • LaTeX
  • RTF
  • Unix Man Page

而其中还可衍生出不少其它格式。如有了LaTeX 档后,就可以透过一些工具产生出PS或是PDF档案。

在多国语言的支持方面,Doxygen 目前可支持的约有2,30种。自Doxygen 1.2.16开始支持繁体中文(这正是小弟做的好事)。所以在目前一些Open Source 的程序文件产生器中,Doxygen 算是相当完整的一套。在程序语言处理上面,Doxygen也算是少数在Borland C++ Builder 的语法下还能够正常运作的工具之一(若非如此,小弟也不会推荐它)。

本文的目的是希望在经过仔细阅读本文之后能够给大家一个概略性的了解。以便可以很容易的上手使用Doxygen。至于Doxygen本身的详细使用,各位可以参考随着Doxygen 所附的檔。实际上,Doxygen 自己的使用手册就是使用Doxygen 产生的。您可以看到他实际上能够产生远比Reference Book更复杂的文件。

安装Doxygen

Doxygen 的安装可说十分的简单,本文仅介绍binary档案的安装,若您有兴趣从source code重新compile起来,请自行查阅参考手册。

首先,请您先至doxygen 的网站上面抓取最新版本的doxygen 回来。目前,只要您是Linux, Solaris, Mac OS X,HP-UX, 甚至是UnixWare,都有compile好的binary版本可以抓取。如果是Windows 95/98/ME/NT/2000/XP,甚至还有Setup的版本可以抓取。所以安装过程可说十分简单。只要给予正确的安装目录,相信一般在安装上是不会遇到什么问题的。

另外,如果您是Linux或是Windows,可以另外抓取Doxygen Wizard的程序。这是一个辅助工具,可以很快的帮您建立一个Doxygen 的组态档案。透过这个组态档案,您就可以很快的将檔产生出来。另外,若没有使用Doxygen Wizard,还是可以使用一般的文字编辑器将这个组态檔制作出来。

若安装成功,您应该可以看到doxygen 这个执行文件出现在您的系统中。若是Windows 平台,则可看到在程序集中有Doxygen 这个Folder出现。

设定Project的doxygen组态

Doxygen 产生檔可以分为三个步骤。一是为Project 建立组态文件,二是在程序代码中加上符合Doxygen所定义批注格式。三是使用Doxygen来产生批注。

因此,第一步就是为您的Project 制作Doxygen 的组态档案。这个所谓的组态档案,格式其实与很简单。就是一些Key 与值的设定。每个设定为一行。若第一行开头为"#" 表示该行为批注。Doxygen 会忽略它。每个设定行的格式有两种,分别如下:

TAG = value [value, ...]

TAG += value [value, ...]

第一种形式是最常见的,也就是要设定一个TAG (也就是一个Key ),他的值为右边所定义的部分。原则上每个值都是单一的英文字,如果您要定义的值有空格符包含在内,可使用双引号将它括住。如果要定义的值超过一个以上,可使用逗号","予以分隔开来。

如果您要定义的TAG 是属于表列型态的,也就是他会有很多的值分别以逗号隔开。在Doxygen 组态檔中允许您在不同的地方重复定义。只是后面的定义应使用上面所说的第二种形式。此种形式会将前后两个定义的值合并在一起。

知道这个基本格式后,剩下就是根据各个TAG 的意义来进行设定。关于TAG 的定义很多,此处我们仅针对必要用到的TAG 进行说明,剩下的部分请自行翻阅使用说明。

由于Doxygen 的TAG 还算不少,为了方便使用,Doxygen 自身提供了一个方便的选项,可以帮您建立一份空白的Doxygen档案(Doxygen 是Doxygen 预设的组态檔名)。

> doxygen Doxygen


透过这个命令,您可以得到一个Doxygen 档案,接下来就可使用一般的文字编辑器来进行编辑。

下面将针对几个必要的TAG 进行说明:

PROJECT_NAME

Project 的名字,以一个单字为主,多个单字请使用双引号括住。

PROJECT_VERSION

Project的版本号码。

OUTPUT_DIRECTORY

输出路径。产生的文件会放在这个路径之下。如果没有填这个路径,将会以目前所在路径来作为输出路径。

OUTPUT_LANGUAGE

输出语言。预设为English。1.2.16 版后,您可以使用Chinese-Traditional 来输出中文繁体的格式。

INPUT

指定加载或找寻要处理的程序代码档案路径。这边是一个表列式的型态。并且可指定档案及路径。举例来说若您有a.c, b.c, c.c 三个档案。您可使用INPUT = a.c, b.c, c.c 的方式。若您给定一个目录,该目录下面所有档案都会被处理。

FILE_PATTERNS

如果您的INPUT Tag 中指定了目录。您可以透过这个Tag来要求Doxygen在处理时,只针对特定的档案进行动作。例如:您希望对目录下的扩展名为.c, .cpp及.h的档案作处理。您可设定FILE_PATTERNS = *.c, *.cpp, *.h。

RECURSIVE

这是一个布尔值的Tag,只接受YES或NO。当设定为YES时,INPUT所指定目录的所有子目录都会被处理。

EXCLUDE

如果您有某几个特定档案或是目录,不希望经过Doxygen处理。您可在这个Tag中指定。

EXCLUDE_PATTERNS

类似于FILE_PATTERNS的用法,只是这个Tag是供EXCLUDE所使用。

SOURCE_BROWSER

如果设定为YES,则Doxygen会产生出源文件的列表,以供查阅。

INLINE_SOURCES

如果设定为YES ,则程序代码也会被嵌入于说明文件中。

ALPHABETICAL_INDEX

如果设定为YES,则一个依照字母排序的列表会加入在产生的文件中。

GENERATE_HTML

若设定为YES ,就会产生HTML版本的说明檔。HTML檔是Doxygen预设产生的格式之一。

HTML_OUTPUT

HTML文件的输出目录。这是一个相对路径,所以实际的路径为OUTPUT_DIRECTORY加上HTML_OUTPUT。这个设定预设为html。

HTML_FILE_EXTENSION

HTML文件的扩展名。预设为.html。

HTML_HEADER

要使用在每一页HTML檔中的Header。如果没有指定,Doxygen会使用自己预设的Header。

HTML_FOOTER

要使用在每一页HTML檔中的Footer。如果没有指定,Doxygen会使用自己预设的Footer。

HTML_STYLESHEET

您可给定一个CSS 的设定,让HTML的输出结果更完美。

GENERATE_HTMLHELP

如设定为YES,Doxygen会产生一个索引文件。这个索引文件在您需要制作windows 上的HTML格式的HELP档案时会用的上。

GENERATE_TREEVIEW

若设定为YES,Doxygen会帮您产生一个树状结构,在画面左侧。这个树状结构是以JavaScript所写成。所以需要新版的Browser才能正确显示。

TREEVIEW_WIDTH

用来设定树状结构在画面上的宽度。

GENERATE_LATEX

设定为YES 时,会产生LaTeX 的文件。不过您的系统必需要有安装LaTeX 的相关工具。

LATEX_OUTPUT

LaTeX文件的输出目录,与HTML_OUTPUT用法相同,一样是指在OUTPUT_DIRECTORY之下的路径。预设为latex。

LATEX_CMD_NAME

LaTeX程序的命令名称及档案所在。预设为latex。

GENERATE_RTF

若设定为YES ,则会产生RTF 格式的说明檔。

RTF_OUTPUT

与HTML_OUTPUT 用法相同,用来指定RTF 输出档案路径。预设为rtf。

GENERATE_MAN

若设定为YES ,则会产生Unix Man Page 格式的说明檔。

MAN_OUTPUT

与HTML_OUTPUT 用法相同,用来指定Man Page的输出目录。预设为man。

GENERATE_XML

若设定为YES ,则会产生XML 格式的说明檔。

ENABLE_PREPROCESSING

若设定为YES ,则Doxygen 会启动C 的前置处理器来处理原始档。

PREDEFINED

可以让您自行定义一些宏。类似于gcc 中的-D选项。


若上面这些基本的Tag 都设定正确,接下来就是将您的Source Code 批注修改成为正确的格式。若您觉得用一般文字编辑器来编辑组态檔很麻烦,建议您可以使用Doxygen Wizard这个工具程序。他可以很快的建构出您所需要的Doxygen档案。

撰写正确格式的批注

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

JavaDoc类型:

/**
* ... 批注 ...
*/

Qt类型:

/*!
* ... 批注 ...
*/


单行型式的批注:

/// ... 批注 ...

//! ... 批注 ...

要使用哪种型态完全看自己的喜好。以笔者自己来说,大范围的注解我会使用JavaDoc 型的。单行的批注则使用"///" 的类型。此外,由于Doxygen 对于批注是视为在解释后面的程序代码。也就是说,任何一个批注都是在说明其后的程序代码。如果要批注前面的程式码则需用下面格式的批注符号。

/*!< ... 批注 ... */
/**< ... 批注 ... */
//!< ... 批注 ...
///< ... 批注 ...


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

举例来说,若我们有下面这样的class。


class MyClass {
public:
int member1;
int member2:
voidmember_function();
};

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

/**
* 我的自订类别说明 ...
*/
class MyClass {
public:
int member1; ///< 第一个member说明 ...
intmember2:///< 第二个member说明 ...
intmember_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 作者信息
*/

如您所见,档案批注约略格式如上,请别被"\" 所搞混。其实,"\" 与"@" 都是一样的,都是告诉Doxygen 后面是一个指令。两种在Doxygen 都可使用。笔者自己比较偏好使用"@"。

接着我们来针对一些常用的指令做说明:

@file

档案的批注说明。

@author

作者的信息

@brief

用于class 或function的批注中,后面为class 或function的简易说明。

@param

格式为

@param arg_name 参数说明

主要用于函式说明中,后面接参数的名字,然后再接关于该参数的说明。

@return

后面接函数传回值的说明。用于function的批注中。说明该函数的传回值。

@retval

格式为

@retval value 传回值说明

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


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的变数成员。
voidExFunc1(void);
intExFunc2(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;
}

上面这两个档案很简单的说明了Doxygen 批注的使用方式。您可依照此要领在你自己的程序代码中加上对应的批注。其实,无论您有无使用Doxygen ,都不妨依照他的格式将批注写入,一方面是依照他的格式,并不会干扰您程序的运作。另一方面,Doxygen 所定义的都是基本程序批注应当要有的东西。撰写清楚的批注是好的程序设计师应当的工作。

制作说明文件

当您前面所有的步骤都正确无误执行后,只需要执行下面的命令就可建立出您要的文件了:

> doxygen Doxygen


如果有错误产生,请检查您的Doxygen 组态檔设定是否有误,目录的存取权限是否足够。如果输出的结果不正确,请检查您的批注是否符合格式。批注的位置是否正确。举例来说,您不可在说明class 的批注与class 本身插入其它的程序代码或宣告。否则Doxygen 就无法将批注与该class对应起来。

如果您使用Doxygen Wizard,可直接使用上面的Run的按钮或选单项目来制作说明文件。如果是产生HTML檔,在HTML_OUTPUT所指定的目录中的index.html将是您说明文件的首页。

在中文繁体方面,目前我仅成功制作出HTML与RTF 格式的说明檔。其它格式的过程比较复杂,需要搭配其它工具,有待各位自行尝试。

附:注释的书写

  注释应该怎么写,写多还是写少。过多的注释甚至会干扰对代码的阅读。写注释的一个总的原则就是注释应该尽量用来表明作者的 意图,至少也应该是对一部分代码的总结,而不应该是对代码的重复或者解释。对代码的重复或者解释的代码,看代码可能更容易理解。反映作者意图的注释解释代码的目的,从解决问题的层次上进行注释,而代码总结性注释则是从问题的解答的层次上进行注释。

推荐的写注释的过程是首先使用注释勾勒出代码的主要框架,然后根据注释撰写相应的代码。对各种主要的数据结构、输出的函数、多个函数公用的变量进行详细地注释。对代码中控制结构,单一目的的语句集进行注释。下面是一些写注释时需要注意的要点:

  避免对单独语句进行注释;

  通过注释解释为什么这么做、或者要做什么,使代码的读者可以只阅读注释理解代码;

  对读者可能会有疑问的地方进行注释;

  对数据定义进行注释,而不是对其使用过程进行注释;

  对于难于理解的代码,进行改写,而不要试图通过注释加以说明;

  对关键的控制结构进行注释;

  对数据和函数的边界、使用前提等进行注释;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值