https://cedar-renjun.github.io/2014/03/21/learn-doxygen-in-10-minutes/
綜述
本文試圖在10分鐘內,幫助您瞭解文檔生成工具Doxygen的基本概念,並熟悉Doxygen的使用規則,同時給予深入學習的一些方向性建議。
因爲本文僅僅是幫助初學者入門,所以選例方面較爲簡單,缺乏廣度和深度。後期會編寫一些深度學習Doxygen的文章,敬請關注
【佔位符:文章結構整體描述】
Doxygen是什麼東西?
Doxygen是一款文檔生成工具,它可以從代碼中提取出相應的文檔,並組織,輸出成各種漂亮的文檔(如HTML,PDF,RTF等)
有了Doxygen工具,程序員便可以在寫代碼的時候,直接內嵌文檔,再也不需要爲某個功能代碼單獨寫文檔,從而最大程度的保持了文檔和代碼的統一性
另外,Doxygen 1.8.x版本中增加對markdown的支持,也支持內嵌部分HTML標籤,從而極大的簡化了文檔編寫難度,甚至,您可以用Doxygen生成一個靜態的網站。
目前Doxygen支持C/C++,Objective-C, C#,PHP等語言,支持多平臺(Mac OS, Linux, Windows),更多信息,請參考Doxygen官方介紹
Doxygen適合什麼人?
適合對代碼文檔有一定要求的程序員
PS:能看到這裏的程序員,一定是位有追求,有理想的工程獅,哈哈,就你了,go on please
開始學習Doxygen
注:在繼續閱讀之前,請確保您:
- 知道如何在windows環境下調出命令窗口
如果您初次接觸命令窗口,請參考附錄中關於CMD的內容 - 具有簡單的編程基礎
下載和安裝
doxygen最新版爲1.8.6版本,下載鏈接如下
http://sourceforge.net/projects/doxygen/files/latest/download?source=files
下載完成後,雙擊安裝,採用默認設置就ok,這裏不做過多介紹
準備源文件
這裏準備了三個簡單的C語言源代碼
main.c // 演示如何調用Dev中的設備接口
dev.c // Dev設備的實現代碼
dev.h // Dev設備的操作接口
具體代碼如下:
main.cview raw
|
|
dev.cview raw
|
|
dev.hview raw
|
|
將這3個源文件放在某個文件夾內,這裏以GettingStart文件夾爲例,其目錄組織結構如下所示
GettingStart
|-- dev.c
|-- dev.h
|-- main.c
第一次嘗試
接下來,我們看看,不編寫任何註釋的情況下,Doxygen會怎麼生成文檔
打開命令行(powershell)窗口,並CD到GettingStart目錄下,輸入下面命令
doxygen -g
Powershell的返回信息如下,同時,我們的GettingStart目錄下增加了一個名叫Doxyfile的文件(注意第21行)
注:如果您初次接觸命令窗口,請參考附錄中關於CMD的內容
|
|
注:上面使用的是win7的powershell,它支持很多傳統CMD不支持的命令,比如ls
,如果您使用的是傳統的CMD窗口,這裏請用dir
來代替ls
這個Doxyfile就是Doxygen工程的配置文件,裏面含有一些配置信息
接下來我們做一些修改
在默認情況下,Doxygen會輸出HTML和LATEX形式文檔,LATEX主要用於生成PDF,這裏暫時不需要,所以我們禁用LATEX輸出
在Doxyfile中將下面一行
GENERATE_LATEX = YES
修改爲
GENERATE_LATEX = NO
接下來,我們修改HTML的顯示方式,將下面兩行代碼
DISABLE_INDEX = NO
GENERATE_TREEVIEW = NO
修改爲
DISABLE_INDEX = YES
GENERATE_TREEVIEW = YES
至於爲什麼修改,暫時不用深究,我們後期再討論
現在我們就可以輸出文檔了,在命令行(powershell)下輸入
doxygen .\Doxyfile
注:這個命令稱爲編譯,下文直接用編譯來代替表示這個指令
這時,Doxygen會從我們的代碼中提取相應的文檔,並生成HTML文件,進入GettingStart
文件夾內,雙擊打開HTML文件夾下的index.html文件
點擊這裏查看
可以看到,當Doxygen對沒有任何註釋的代碼,也可以生成對應的文檔框架,不過,僅僅是框架而已,沒有太大作用。Doxygen針對這種情況,專門設置了一個選項EXTRACT_ALL
,默認情況下爲NO
狀態,手工設置爲YES後,Doxygen會盡可以的從代碼中提取信息,這裏我們將Doxyfile中的
EXTRACT_ALL = NO
改爲
EXTRACT_ALL = YES
然後再次編譯,前後輸出結果,對比如下:
注:請點擊這裏查看EXTRACT_ALL = YES
的輸出結果
最終效果展示
接下來,我們爲代碼中增加對應的描述信息
Doxygen制定了一套註釋規範,在保證正確輸出文檔的同時,也兼顧了良好的可讀性。對編程人員來說,只需在編寫註釋的時候,稍微注意格式,即可生成非常優秀的文檔,額外增加的工作量可忽略不計。
下面就是某個函數的Doxygen註釋
|
|
我們可以看到,程序代碼可讀性非常好,即便沒有生成單獨的文檔,任何具有一定英文基礎的同學都可以
輕鬆的瞭解到函數的用法和入口參數,注意事項等信息。
接下來,我們採用Doxygen語法爲main.c dev.c dev.h添加註釋信息,完成後的效果如下所示:
main.cview raw
|
|
dev.cview raw
|
|
dev.hview raw
|
|
用Doxygen編譯後,生成的HTML文檔如下所示:
注:請點擊這裏查看詳細的輸出文檔。
Doxygen把代碼中的文件,例子,函數,宏等信息提取出來,一目瞭然
這裏要說一下,如果沒有Doxygen,我們該怎麼做呢?
很多人會用SourceInsight這個代碼閱讀工具來輔助閱讀,功能非常強大,但你電腦上必須裝SI,否則沒法閱讀,這就限制了使用範圍,從這裏可以看到Doxygen的優勢所在:提取代碼文檔,並將所有部分鏈接起來,形成統一整體
也許還有人會說,SI也可以生成繼承圖,調用圖等圖標,Doxygen可以嗎?完全可以的,藉助於Dot工具,Doxygen可以生成各種關係圖表
注:Doxygen配合Dot工具生成圖表以及Dot工具的用法,後期專門寫一篇文章來介紹
一步一步跟我學Doxygen
現在讓我們開始從0開始,一步步爲代碼添加註釋信息,最終生成上面所看到的效果
首先爲函數添加註釋信息,這是必須要做的。這裏有個選擇性問題,添加到哪裏呢?.c文件?.h文件?
一般來說:
- .h文件代表模塊對外的接口最小信息,面向模塊使用者
- .c文件代表模塊的實現代碼,面向的是開發者
在實際編程中,事先約定各個模塊間的接口,然後將不同的模塊分配給不同的開發者,與此同時,測試人員根據接口要求,編寫測試代碼,這就完全保證了併發編程和白盒測試要求。
這裏我們可以看到,文檔主要是用來描述接口信息的,所以,我對代碼的註釋規定如下:
- 模塊對外接口,僅在.h中提供註釋信息
- 模塊內部輔助函數,全部用static設爲私有函數,同時僅在.c中保留註釋信息
當然,您也可以同時爲.c .h的接口函數編寫兩份完全一樣的註釋信息,但這麼做,您會同時維護兩份信息,出錯的概率會更大些。
確定了註釋位置,下一步考慮一個函數需要哪些信息
一般來說,需要函數功能,入口參數,返回值,注意事項,某些時候還需要說明上下文環境,從而保證函數能正確執行
比如這個函數
extern int Dev_PrintInt(int number);
它的功能就是打印一個整形數據,傳入參數爲整數,返回的是成功打印的數據長度(字節爲單位),同時呢,我們在調用這個函數之前,必須要先初始化Dev設備
ok,這就是所有接口信息,稍微規範一下,就變成了下面的樣子
// 函數功能:打印整數
// 入口參數:number爲一個整數類型
// 返回結構:返回的是成功打印的數據長度(字節爲單位)
// 注意事項:
// 1:在調用本函數前,請確保已經調用Dev_Init初始化設備
// 2:請注意函數返回值,如果該值爲0,則說明函數執行失敗
extern int Dev_PrintInt(int number);
用英文來書寫呢,則變成下面的樣子
//***************************************************************************************
//
// brief : Print Int number to terimal device.
//
// param : number is the data you want to print.
// retval : the number of print information, in bytes. return zero indicate print error !
//
// Note:
// * Be sure you have called \ref Dev_Init function before call this fuction.
// * Remember to check return value.
//
//***************************************************************************************
extern int Dev_PrintInt(int number);
註釋信息寫完了,一般來說,函數能達到這種信息程度就ok了,但既然要生成文檔,就不得不考慮一個問題
如果你是Doxygen作者,怎麼從上面的註釋裏面提取信息呢,信息那麼多,有*
號,有各種文字信息。
你可以將所有的註釋信息都輸出出來,但這麼做,等於沒有分類整理,同時也包含了雜亂信息,比如一排*
另外一個解決方法是:設置某些特殊字符,比如function
表示,一旦檢測到這個特殊標記,則認爲是接下來
的一行是函數功能描述。但這麼做,萬一用戶的註釋裏面出現很多個function,你怎麼識別哪個是普通文本,
哪個是特殊標記?
也許你會說了,可以採用$FUNCTION$這種形式啊,恩,這麼做是可行的,可以確保識別出來特殊標記
接下來,還有一個問題,我們上面的註釋中,有很多*
號,僅僅起到美觀和格式化的作用,當然不希望在
輸出文檔中顯示這些東西,問題是你怎麼識別這些符號,並不顯示呢?也許你會說,可以強制規定註釋的
格式,不讓用戶在代碼中寫很多*
,ok,假設用戶同意這麼做。那接下來呢,如果我希望在代碼中寫某些話
,但是不希望輸出到文檔中,比如“XX是2B”等等,你又該怎麼做呢?
正向思考遇到問題時,不妨反向考慮,這是誰的問題:是我設計思路的問題還是用戶用法的問題?
困難重重,肯定是設計思路的問題
如果設計一個標記符,將普通註釋和要生成的文檔註釋區分開來,就能解決問題了。
Doxygen的用法,說白了,就是爲了解決上面提到的兩個問題:
怎麼區分普通註釋和輸出註釋
怎麼在輸出註釋裏面,識別特殊標記和普通文本
ok,講到這裏,基本把Doxygen的機制給解釋清楚了,如果您還不理解,最簡單的方法就是把你假設爲Doxygen
作者,重新推演一遍。
下面咱們看看Doxygen怎麼解決這兩個問題的
區分普通註釋和特殊註釋
對於C/C++語言來說,註釋形式有兩種
//
/* */
Doxygen通過在這裏增加*
,/
,!
來作爲特殊標記,比如
對於/* */
這種註釋來說,正常註釋爲
/*
* 正常註釋
*/
Doxygen在註釋第一個*
後,設置*
或!
作爲標誌,如果檢測到有這些,
就將接下來的註釋作爲導出文檔來解釋
/**
* 要輸出成文檔的註釋
*/
或者
/*!
* 要輸出成文檔的註釋
*/
同時,中間的*
號可以省略,像這樣
/**
要輸出成文檔的註釋
*/
或者
/*!
要輸出成文檔的註釋
*/
對於//
這種類型的註釋,Doxygen在第二個/
後,增加!
或/
作爲區分標誌,如果檢測到有這些,
就將接下來的註釋作爲導出文檔來解釋
/// 要輸出成文檔的註釋
或者
//! 要輸出成文檔的註釋
對於這種呢,有一個潛在的問題,很多時候,我們需要在把註釋放到後面,比如下面這種
#define DEV_ON ((int)(1)) //! Simple device is power on.
#define DEV_OFF ((int)(0)) //! Simple device is power off.
如果真要這麼寫的話,Doxygen會把//! Simple device is power on.
當做DEV_OFF
的註釋,這
當然不是我們所希望的! 怎麼辦呢,只好再加一個特殊標記了,Doxygen針對這種情況,需要在!
後
再增加一個<
標誌符,如果檢測到這個,則認爲這個註釋是爲前面代碼準備的,所以,上面的註釋應該
這麼寫
#define DEV_ON ((int)(1)) //!< Simple device is power on.
#define DEV_OFF ((int)(0)) //!< Simple device is power off.
做到這裏,Doxygen就可以正確區分普通註釋和特殊註釋了,^_^
更詳細的信息,請參考Doxygen註釋規範
區分特殊標記符和普通文本
ok,現在可以識別出了普通註釋和特殊註釋,接下來,Doxygen是怎麼從特殊註釋裏面提取信息的呢
比如
注意左邊導航欄,Doxygen怎麼識別出這是一個函數/宏呢?答案還是採用特殊標記
注:提到特殊標記,其實吧,編程語言非常常用,比如HTML就是典型的markup語言,一堆一堆的括號,看着就頭疼
Doxygen採用\
和@
作爲特殊標記符,當在特殊註釋裏面檢測到了特殊標記符,則接下來檢測緊跟單詞是不是Doxygen
事先規定好的,如果是,則將按照特定的規則來解釋緊跟着的註釋;如果不是呢,則將\
和@
解釋爲普通文本,聰明吧
可能有點拗口,下面給你個例子
//***************************************************************************************
//
//! \brief Print Int number to terimal device.
//!
//! \param [in] number is the data you want to print.
//! \retval the number of print information, in bytes. return zero indicate print error !.
//!
//! \note
//! * Be sure you have called \ref Dev_Init function before call this fuction.
//! * Remember to check return value.
//
//***************************************************************************************
extern int Dev_PrintInt(int number);
看到了吧,這裏的\brief
和\param
都是特殊符號,表示簡要描述和參數。萬一你小手一抖,把\param
寫成了\parame
,那就悲劇了,因爲Doxygen不認識parame
,所以它會把這句話當做是普通文本來處理
其實,上面的\
換成@
也是ok的,如下所示
//***************************************************************************************
//
//! @brief Print Int number to terimal device.
//!
//! @param [in] number is the data you want to print.
//! @retval the number of print information, in bytes. return zero indicate print error !.
//!
//! @note
//! * Be sure you have called \ref Dev_Init function before call this fuction.
//! * Remember to check return value.
//
//***************************************************************************************
extern int Dev_PrintInt(int number);
相信某些玩過ARM芯片的,對這類註釋非常熟悉,官方庫都是採用Doxygen語法規則註釋的
那麼,我們怎麼知道Doxygen認識哪些符號呢,參考Doxygen自帶手冊啊,Special Commands章節
授之於魚,不如授之於漁,該說的都介紹完了,至於具體的指令含義和用法,自己慢慢看手冊唄
注:點擊這裏下載GettingStart的壓縮包,包含源碼,HTML輸出文檔,配置腳本
如果在看腳本的時候遇到問題,請參考這裏
深入研究
不好意思,文章有點長,估計過了10分鐘,so bad,o(╯□╰)o
根據20/80原則,一個軟件,常用的僅僅是20%的功能,其餘80%功能是極少用到的
上面僅僅介紹了Doxygen的設計思想和學習範例,抓住了綱領,相信您通過研究代碼和幫助手冊,很快就能學會使用Doxygen
如果您想深入研究Doxygen,比如markdown和代碼無縫交互,插入HTML代碼,定製HTML網頁,CSS等功能,
請參考Doxygen幫助手冊,裏面有詳細說明,如果學習過程中,遇到問題,歡迎和我交流,互相學習
Do one thing and do it well
CedarQQ:819280802
參考資料
https://blog.csdn.net/Candy1232009/article/details/80786179
Doxygen配置 界面
Doxygen產生文檔可以分爲三個步驟,一是在程序代碼中加上符合Doxygen所定義註釋格式;二是使用Doxywizard進行配置;三是使用Doxygen來產生註釋文檔。現在我們假定電腦中已經安裝了Doxygen並且代碼中的註釋已經符合Doxygen規範,下面我們來通過設置配置來生成註釋文檔。
————————————————
版權聲明:本文爲CSDN博主「開心笑」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/Candy1232009/article/details/80786179