使用 Doxygen 制作 C 程序文档
目前,网上所能搜到 Doxygen 资料,大都是介绍 C++ 程序文档生成的,对于 C 程序的文档生成鲜有记述。由于我们的项目主要是采用 C 语言实现,这两天在学习使用 Doxygen 制作 C 程序文档时,摸索了一点东西出来,记之备忘。
关于 Doxygen
我们在写程序时,通常会在源码中适当之处添加合理的注释,以此来说明代码所能实现的功能、使用约定等信息。如果在撰写代码注释时,能够稍微遵从某种格式,然后采用某种工具,根据源码结构及注释自动生成排版美观的文档,这将大大减轻我们的工作量,使我们多一些时间享受生命。 Doxygen 就是这样一种工具。
关于 Doxygen 更为详尽的介绍,请阅读其官方主页。
安装 Doxygen
几乎所有的 GNU/Linux 发行版的软件仓库中都可以找到 Doxygen,有些发行版默认已经安装,安装前请检查一下。
如果你打算在 Windows 环境中使用 Doxygen,我会劝说你删除 Windows -> 安装一个 GNU/Linux -> 安装 Doxygen,如果你非要坚持在 Windows 环境中使用 Doxygen,那我只好告诉你:去 Doxygen 官方网站 下载一个 Win 版本的 Doxygen,然后双击所下载的安装文件,然后 Next … Next …
Doxygen 的工作过程
Doxygen 的工作过程可分为三个步骤:
- 配置 Doxygen 工作环境,生成 Doxygen 配置文件;
- 在程序源码中添加符合 Doxygen 可解析的注释格式;
- 使用 Doxygen 解析源码,输出格式化文档。
在 Doxygen 手册页上可以看到一份很详细的 Doxgen 工作流程图。对于我而言,仅仅需要 Doxygen 完成以下流程即可满足我的需求。
从一个具体而微的示例开始
为了更好的学习 Doxygen,构造了一个很小型的“项目”,为了叙述的方便,给它取个名字——“M2 List”,其内容是我从我们的项目中的双向链表模块抽取出来的。
M2 List 项目的目录结构如下图所示:
|---- src
| |
| |---- m2.h
| |---- m2-list.h
| |---- m2-list.c
|
|---- lib
|
|---- doc
|
|---- example
|
|---- test.c
M2 List 程序目录为 m2-list,src 目录用于放置程序源文档,example 用于放置测试程序,lib 用于放置最终生成的 M2 List 共享库文件。
下面讲述如何使用 Doxygen 为 M2 List 项目生成文档。
Step 1: 配置 Doxygen 工作环境
Doxygen 工作环境的配置貌似非常复杂,配置文件中的选项有数百项之多,不过其中的绝大多数不需理会,采用 Doxygen 配置文件模板中定义的默认值即可。
进入 m2-list 目录,使用 "doxygen -g" 命令生成 Doxygen 配置文件模板:
$ doxygen -g
默认生成的配置文件名为 "Doxyfile",也可以采用 "doxygen -g your-cfg-filename" 命令格式指定所生成的配置文件名。如无特殊需要,采用默认的配置文件名即可。
Doxyfile 文件内容非常多,大概 1000 多行,不过其中约 4/5 都是注释,每个配置选项都有一段详细的注释。日后,如果对 Doxygen 各配置选项的意义有一定了解,可以在生成配置文件的命令中添加 "-s" 选项,生成不含注释的配置文件,操作如下:
为实现本文目的,对默认生成的 Doxygen 配置文件需要有针对性的调整,使之适于 C 程序文档生成。下面给出我认为重要的几个配置选项及相应设置:
PROJECT_NAME = “M2 List”
# 文档版本号,可对应于项目版本号,譬如 svn、cvs 所生成的项目版本号
PROJECT_NUMBER = "1.0.0"
# 程序文档输出目录
OUTPUT_DIRECTORY = doc/
# 程序文档语言环境
OUTPUT_LANGUAGE = Chinese
# 如果是制作 C 程序文档,该选项必须设为 YES,否则默认生成 C++ 文档格式
OPTIMIZE_OUTPUT_FOR_C = YES
# 对于使用 typedef 定义的结构体、枚举、联合等数据类型,只按照 typedef 定义的类型名进行文档化
TYPEDEF_HIDES_STRUCT = YES
# 在 C++ 程序文档中,该值可以设置为 NO,而在 C 程序文档中,由于 C 语言没有所谓的域/名字空间这样的概念,所以此处设置为 YES
HIDE_SCOPE_NAMES = YES
# 让 doxygen 静悄悄地为你生成文档,只有出现警告或错误时,才在终端输出提示信息
QUIET = YES
# 只对头文件中的文档化信息生成程序文档
FILE_PATTERNS = *.h
# 递归遍历当前目录的子目录,寻找被文档化的程序源文件
RECURSIVE = YES
# 示例程序目录
EXAMPLE_PATH = example/
# 示例程序的头文档 (.h 文件) 与实现文档 (.c 文件) 都作为程序文档化对象
EXAMPLE_PATTERNS = *.c /
*.h
# 递归遍历示例程序目录的子目录,寻找被文档化的程序源文件
EXAMPLE_RECURSIVE = YES
# 允许程序文档中显示本文档化的函数相互调用关系
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES
REFERENCES_LINK_SOURCE = YES
# 不生成 latex 格式的程序文档
GENERATE_LATEX = NO
# 在程序文档中允许以图例形式显示函数调用关系,前提是你已经安装了 graphviz 软件包
HAVE_DOT = YES
CALL_GRAPH = YES
CALLER_GRAPH = YES
可以下载我的配置文档作为参考: My Doxyfile。
欲详知 Doxygen 各配置选项的作用,请阅读 doxygen 手册中的 config.html 页面 (通常位于 /usr/share/doc/doxygen*/html/config.html)。
Step 2: 程序源码文档化
准备好 Doxygen 的工作环境后,就需要根据 Doxygen 所定义的注释规则,对程序源码进行文档化。换句话说,就是在对程序源码添加注释时,要按照 Doxygen 的游戏规则来搞。
Doxygen 的注释类型可分为:
- 行间注释:注释语句不与程序源码出现在同一行,主要用于注释头文件中出现的结构体 (struct)、枚举 (enum)、联合 (uion) 等数据类型,以及程序接口的功能与使用约定;
- 行内注释:注释语句与程序源码出现在同一行内,主要用于代码的局部注释。
Doxygen 认可的行间注释标记见下例:
* 这是行间注释标记示例
*/
Doxygen 认可的行内注释标记见下例:
double coord[3]; /*!< 这是行内注释示例 */
}M2_3D_Point;
请仔细观察以上注释示例中所使用的注释标记。Doxygen 也允许使用其它类型的注释标记,但是我们通常没必要知道茴香豆的“茴”字有几种写法,只需要知道一种就可以了。
下面回顾一下 C 程序源码中的注释类型:
- 文件的注释:用于解释当前文件的用途、作者、创建及修改日期等信息;
- 数据类型的注释:用于解释数据类型的意义;
- 程序接口的注释:用于解释程序接口的功能、使用约定等信息;
- 还有,就是还有,我还没想出来……也许以后用着用着 doxygen,就想起来了,到时候再来这里添上新东西。
我总觉得自己在不停的说着废话,最直接了当的做法就是停下唠叨,参照 doxygen 手册中的 commands.html 页面,阅读下面的示例文档,它们都是 .h 文件。当然,在 .c 文件中也允许出现注释,但我认为它们不应该出现在程序文档中,使用 C 语言最重要的一个原则就是:.h 文件是用来声明的,类似于文章的目录或索引;而 .c 文件是用来实现的,类似文章的正文。
我的文档化后的程序源码:m2.h 下载|m2-list.h 下载。
Step 3: 程序文档生成
现在开始生成程序文档,将终端的工作目录定位在 m2-list 目录,然后键入:
your-cfg-filename 是 Step 1 中生成的 Doxygen 配置文件名,如果是使用 "doxygen -g" 生成的配置文件——Doxyfile,那么可以在终端里仅键入 "doxygen" 命令即可生成程序文档。
生成的文档位于 m2-list/doc/html 目录中,使用浏览器打开该目录中的 index.html 文件,即可看到自己的工作成果。
小结
本文仅仅是个很小很小的开始,许多我很想说的东西,由于拙于 & 懒于表达,都没有讲出来。如果这篇文章能够引起你对 Doxygen 的兴趣,并尝试在工作中使用它,我就心满意足了。实际上,Doxygen 给我的帮助不仅仅是生成程序文档,更重要的是它提示我应该怎样对程序进行良好的注释!
最后,要感谢 Doxygen 的开发者,说中文也许你们听不懂,那我 say 一句 “tks a lot”.
doxygen+VIM文档实用指南for C/C-liked Programmers
摘要:
文档撰写是一项十分繁琐而且费力的工作,相信已经有很多人对此深感头痛。文档生成工具的出现最大限度地帮助程序员解决了这个问题,这些工具通常可以从程序源代码自动生成文档,大大方便了文档工作。这篇小东西主要介绍了如何用VIM和doxygen来快速生成注释,并用最少的额外劳动来完成专业水准的程序文档的过程。仅供参考,如有雷同,纯属巧合。
关键字:
doxygen vim doxygentoolkit chm dot lex CLanuageScanner
补充:
本文一开始是为dylan同学准备的,后来有所扩展。本文不涉及doxygen注释的具体做法,因为可以在网上得到更多关于这方面的范例和资料。
什么是doxygen
什么是VIM
为什么要使用doxygen+VIM
需要做什么?
1) 准备工作
2) 添加注释
3) 配置并运行doxygen
4) 编译成chm
5) 一些配置选项
Dot图形扩展
doxygen方便扩展吗?
小结
什么是doxygen
doxygen是一个十分好用的自由软件,是一种文档生成器,其工作机制是利用注释中的有效信息来自动生成文档。目前doxygen的最新版是(1.5.1),从http://www.doxygen.org上可以下载最新版的doxygen。1.5.1版的doxygen可处理的语言包括:
l C/C++
l Java
l Python
l PHP
l Objective-C
l IDL (Corba, Microsoft及KDE-DCOP类型)
l C#
l D
它支持以下文档格式:
l HTML
l XML
l LaTeX
l RTF
l Unix Man Page
有了doxygen的支持后,从软件代码到项目文档的转化十分简单,直接执行doxygen可执行程序就可以了。此时doxygen会在当前目录下寻找默认的配置文Doxyfile(此文件可以手工编写,也可以借助于doxywizard生成),并从配置文件中读入待解析的文件列表和一些设置,最后生成相应格式的文档。而你所需要做的唯一工作,就是在软件代码中添加doxygen能够识别的注释。也就是说,只要在编辑代码的时候遵从doxygen的规范来添加注释,就毫不费劲地生成程序文档了。
和其他的一些注释工具相比,doxygen的优势在于它支持众多的文件类型,并能够生成十分漂亮的网页。一个典型的doxygen文档包含文件列表,函数列表,全局变量列表,结构体列表,为读者提供全局的信息。doxygen的自带的tag工具还可以帮助生成交叉索引,方便从一个函数跳转到另一个函数。这对于了解整个项目的结构和接口以及调用关系是十分有益的。
多说无益,下面给一个简单的范例,看看doxygen是如何工作的。(此部分代码也是用doxygen生成的)
view plaincopy to clipboardprint?
/**
* @file show.c
* @brief written to show the doxygen documentation tool.
* @author Clark ZHUO, zkk@mails.tsinghua.edu.cn
* @date 2006-11-09
*/
#include <stdio.h>
extern void printf(const char *format, ...);
extern void fprintf(FILE f, const char *format, ...);
/**
* @mainpage
* The page is showed to you!
*
* @defgroup macro
* @addtogroup macro
* simple macro
* @{ */
/** it is a macro
* the doxygen merge the message*/
#define MACRO1 1
/** @} */
/** @defgroup codes
* @addtogroup codes
* codes of this function
* @{*/
const char[] msg="Hello, doxygen!";
/**
* @brief @b invoke just invoke some example
*
* @param a first parameter
* @param b second paremeter
* @param operation selectable paremeter
*
* @return
* - MACRO1 if default operation is called
* - 0 if a or b is
* - -1 else
*/
int invoke(int a, int b, int operation=0)
{
printf(msg);
if (operation != 0) {
fprintf(2, "just a test.");
return MACRO1;
}
if ( (a==0) || (b==0)) return 0;
return -1;
}
/**
* @brief main the function for the program
*
* @param argc argument count for std C main
* @param argv argument value for std C main
*
* @return always return 0 to shell
*/
int main(int argc, char *argv[])
{
int val=1;
int valb=2;
printf("Program starts.../n");
/** <b> In function: </b> the main function called invoke*/
invoke(val, valb);
return 0;
}
/** @}*/
/**
* @file show.c
* @brief written to show the doxygen documentation tool.
* @author Clark ZHUO, zkk@mails.tsinghua.edu.cn
* @date 2006-11-09
*/
#include <stdio.h>
extern void printf(const char *format, ...);
extern void fprintf(FILE f, const char *format, ...);
/**
* @mainpage
* The page is showed to you!
*
* @defgroup macro
* @addtogroup macro
* simple macro
* @{ */
/** it is a macro
* the doxygen merge the message*/
#define MACRO1 1
/** @} */
/** @defgroup codes
* @addtogroup codes
* codes of this function
* @{*/
const char[] msg="Hello, doxygen!";
/**
* @brief @b invoke just invoke some example
*
* @param a first parameter
* @param b second paremeter
* @param operation selectable paremeter
*
* @return
* - MACRO1 if default operation is called
* - 0 if a or b is
* - -1 else
*/
int invoke(int a, int b, int operation=0)
{
printf(msg);
if (operation != 0) {
fprintf(2, "just a test.");
return MACRO1;
}
if ( (a==0) || (b==0)) return 0;
return -1;
}
/**
* @brief main the function for the program
*
* @param argc argument count for std C main
* @param argv argument value for std C main
*
* @return always return 0 to shell
*/
int main(int argc, char *argv[])
{
int val=1;
int valb=2;
printf("Program starts.../n");
/** <b> In function: </b> the main function called invoke*/
invoke(val, valb);
return 0;
}
/** @}*/
说明:以上例子主要演示了file, function, param, return等常用的doxygen标签,在doxygen帮助的“Special Commands”部分列出了所有的标签。
可以注意到,代码中所有的注释都以/**开头,这正是doxygen的一个标记,说明这段注释文本将被doxygen进行解释。事实上,doxygen同时支持好几种类型的注释风格,包括JavaDoc风格的/** */,QT风格的/*! */,和行注释风格的///和//!。
还可以注意到注释中有很多以@为前缀的语句,这些紧跟在@符号后面的标识符就是doxygen的关键字(也可以用’//’来替代’@’)。doxygen通过这些关键字来组织所生成的文档。例如,@file告诉doxygen后面的字符串是文件的名字,而@date则说明了文件的生成时间。
以下就是所生成的文档中函数列表中关于invoke的部分,效果还不错吧^_^(左侧是index页的模块列表,右侧是函数invoke的文档)
什么是VIM
这个问题就直接跳过了。作为最有名的编辑器之一,网上有铺天盖地的文章来介绍VIM的各种技巧。www.vim.org上面也有足够的信息和资源。你只用IDE?那你往下看看用VIM能不能给你带来更高的效率,如果值得,不妨只用IDE来编译和调试。
为什么要使用doxygen+VIM
从前文已知,doxygen确实是一种很不错的工具。但是为了帮助doxygen来生成文档,你需要在注释上花费更多的时间和精力。通常,这意味着你在写注释的时候需要更集中的注意力,和敲击更多的键盘。如果既想享受doxygen带来的便利,又不愿意在每次写注释的时候多写一大堆相似的,重复性的东西。这时候该怎么办呢?可以使用编辑器插件来最小化自己键入的字符。
作为世界上最著名的两大编辑器之一,VIM拥有众多的fans。和emacs不同,VIM的迷人之处在于其简约之美和强大的可扩展性。在随后的部分中我将向大家介绍doxygenToolkit.vim这个插件的基本用法。在安装这个插件之后,你只需要执行一个简单的操作,就可以完成doxygen风格的注释。它将使你的编码工作事半功倍。
doxygentoolkit.vim插件可以在www.vim.org上获取。
需要做什么?
以下将简要介绍VIM+doxygen的使用方法:
1) 准备工作
安装doxygen,安装gvim,下载doxygentoolkit.vim并将其安装到$VIMRUNTIME/plugin目录下。
之后,需要在VIM的配置文件中(windows下的_vimrc,linux下的vimrc或者~/.vimrc)为doxygentoolkit这个插件配置一些全局变量:
let g:doxygenToolkit_authorName="your name"
let g:doxygenToolkit_briefTag_funcName="yes"
其余的配置可以自己查阅doxygentoolkit的说明。这样,你就可以通过DoxAuthor,Dox,Doxb等几个命令来完成doxygen风格的文档了。当然,你可以用VIM的map功能来绑定这几个命令。我通常采用以下绑定:
map <F3>a :DoxAuthor
map <F3>f :Dox
map <F3>b :DoxBlock
map <F3>c O/** */<Left><Left>
2) 添加注释
在添加注释时,最常用的是:Dox,而每个文件同时也需要:DoxAuthor来添加文件头。
使用:Dox命令来为一个函数添加注释十分简单。你只需要把光标移动到函数声明或者定义所在行(函数原型所在行),然后执行:Dox就可以了。Dox会自动解析你的函数原型,并将相应的参数和返回值列出来。例如,当你对
int invoke(int a, int b, int operation=0)
添加注释时,Dox将生成如下代码
/**
* @brief invoke
*
* @param a
* @param b
* @param operation
*
* @return
*/
并将光标设知道invoke后面,方便你输入函数的简单描述。
:DoxAuthor则会自动将文件名,作者,时间等关键字自动填好,十分方便。
当然,你也可以按照自己的配置来修改doxygenToolkit.vim。
3) 配置并运行doxygen
doxygen的配置文件是一个文本文件,理论上你可以自己来直接修改。不过还有更省事的方法:doxygen为我们提供了doxywizard图形配置工具。doxywizard的功能十分直观,用起来很简单,在此不加赘述。进行配置之后,将配置文件存到工作目录下,运行doxygen。默认情况下,doxygen会产生html格式的文档,这些文件都会保存在工作目录的html子目录下面。之后,可以通过浏览器来打开html子目录下的index.html页面来查看为这个工程生成的文档。当然,如果你需要生成其他格式的文档,可以进行相应的配置。
doxygen配置文件的细节,我就不一一细述了,你可以去查阅更多的资料J
下图为Windows操作系统下doxygen的图形配置程序doxygenWizard:
4) 编译成chm
使用chm格式的文件来作为程序的文档可以使文档更加便于管理,现在也有越来越多的文档用chm格式发布。doxygen也可以支持编译生成chm格式的文件。这时候,你需要在doxygen的配置文件里设置以下选项(打开chm的支持,并配置htmlworkshop的位置):
GENERATE_HTMLHELP = YES
HHC_LOCATION = "C:/Program Files/HTML Help Workshop/hhc.exe" (如果hhc已经在系统的路径里,那么此处可以不填)
这样,doxygen在产生文档的时候会同时产生hhp后缀的文件,并自动运行HHC来帮你编译生成CHM的文件。当然,你也可以在Html Help Workshop里面用hhp文件来手动chm文件了。Html Help Workshop可以在各大软件站点上找到或者去微软的站点上下载:
5) 一些配置选项
我比较经常进行更改的doxyfile选项有:
INPUT = . ../include 项目的路径(用空格隔开,可以用引号括起来)
HIDE_UNDOC_MEMBERS = NO 是否需要隐藏未注释的成员
SOURCE_BROWSER = YES 是否显示源程序
GENERATE_HTML = YES 生成html格式的文档
GENERATE_HTMLHELP = YES 生成chm文件
CHM_FILE = show.chm chm文件的名字
HHC_LOCATION = "C:/Program Files/HTML Help Workshop/hhc.exe" hhc的路径
HAVE_DOT = YES 支持图形扩展
……
Dot图形扩展
在doxygen的配置中打开DOT选项后,doxygen可以帮你生成十分眩目的图形支持,使项目文档更加直观、易读。
为了能够使用Dot图形扩展,你需要首先安装graphviz,这是一个免费的图形库扩展,可以从http://graphviz.org 下载。下载完Dot并安装完毕之后,需要在doxygen文件中将以下选项打开:
HAVE_DOT = YES
进行相关DOT选项的设置之后,就可以生成带图形支持的文档了,这可以让你的文档增色不少。以下是一个函数调用关系图的范例(这是doxygen项目中的一个函数):
doxygen方便扩展吗?
尽管doxygen已经包含了许多最通用的文件类型的支持,你也许还希望能够让其为你自定义的某种语言生成文档,或者对某个功能进行调整。这时候,你可以添加一些额外的代码,并将源代码重新编译一遍。(当然,你也可以让作者添加对新语言的支持并发布新版本,呵呵)
doxygen项目的大部分代码是C++文件,大部分的代码解析工作是在*Scanner类里面进行的(目前包含CLanuageScanner和PythonLanuageScanner,前者处理所有类C的语言类型,后者是1.5新添加的针对python的类)。这些*Scanner是由lex语法解析器来自动生成的,可以通过修改scanner.l和pyscanner.l这两个文件来修改一些细节的处理。这些l文件中大量使用了lex的start condition,使所做修改不会轻易破坏已有的功能,比较方便。如果你所要添加的这种语言是类C结构的,也许只需要把这个文件类型添加到已有的C语言框架里就可以让一切正常工作。
修改完毕之后,将整个项目重新编译一遍,make程序将自动更新*Scanner类的内容,并将你所做的修改应用到doxygen程序上。调试之,就大功告成了。
小结
doxygen+VIM+doxygenToolkit.vim+Html Help Workshop = 注释->简单的文档解决方案
doxygen还有众多十分有用的关键字和其它的功能,有兴趣的朋友可以好好去发掘发掘。doxygen的主页上也有很多很有用的讨论,值得去好好看看。
对lex感兴趣的朋友可以去看看doxygen的scanner.l文件,肯定会有比较大的收获。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/clarkZHUO/archive/2006/12/31/1471573.aspx
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/AD_LI/archive/2009/08/23/4474878.aspx#
配置文件
每一个Doxygen工程都有一个后缀为.cfg的配置文件,用来保存所有的设置。配置文件的格式与autoexec.bat、config.sys等文件相似,是由名称/值对组成的ASCII码,会由doxygen命令来解析。为了简化创建和修改配置文件,Doxygen可以在命令行方式下加上参数-g自动创建模板文件。
doxygen -g <config-file>
忽略<config-file>将会生成一个名为Doxyfile的缺省文件,如果<config-file>已经存在,会被Doxygen改名为<config-file>.bak。
实际上,我们根本就不需要用一般的编辑器来编辑配置文件,Doxygen提供了一个辅助工具Doxywizard。Doxywizard是Doxygen的GUI前台,用户可以能过它来读写配置文件,省却了手工配置的麻烦。基本上,在Doxywizard中可以完成Doxygen的绝大多数工作,而且Doxygen也可以在由Doxywizard启动,这样就使得整个过程比较连贯。
虽然如此,我们还是要理解常见的各个Tag的含义。在Doxywizard中,可以看到这些Tag以自明的方式命名,我们大致可以从名称中看出其作用。这些Tag被Doxywizard大致分为几类,其中HTML到PerlMod是输出文件种类设置,Project是Doxygen工程设置,Build是编译类选项,Messages为出错或异常选项,Input为输入源选项,等等。