正文

學習用 doxygen 生成源碼文檔

(2010-12-21 20:44:54) 下一個

學習用 doxygen 生成源碼文檔

Arpan Sen, 資深工程師, Studio B Productions
Arpan Sen 是一位資深工程師,從事電子設計自動化行業的軟件開發。他花了好幾年研究多種風格的 UNIX,包括 Solaris、SunOS、HP-UX 和 IRIX,以及 Linux 和 Microsoft Windows。他主要對軟件性能優化技術、圖形理論和並行計算感興趣。Arpan 擁有軟件係統研究生學位。

簡介: 維護用 C/C++ 開發的遺留係統並添加新特性是一項艱難的任務。幸運的是,doxygen 可以幫助您完成這個任務。doxygen 是一種用於 C/C++、Java™、Python 和其他編程語言的文檔係統。本文在 C/C++ 項目的上下文中討論 doxygen 的特性,以及如何用 doxygen 定義的標記生成代碼文檔。

發布日期: 2008 年 10 月 13 日
級別: 中級 其他語言版本: 英文
訪問情況 2071 次瀏覽
建議: 

維護用 C/C++ 開發的遺留係統並添加新特性是一項艱難的任務。這涉及幾方麵的問題:理解現有的類層次結構和全局變量,不同的用戶定義類型,以及函數調用圖分析等等。本文在 C/C++ 項目的上下文中通過示例討論 doxygen 的幾個特性。但是,doxygen 非常靈活,也可用於用 Python、Java、PHP 和其他語言開發的軟件項目。本文的主要目的是幫助您從 C/C++ 源代碼提取出信息,但也簡要描述了如何用 doxygen 定義的標記生成代碼文檔。

安裝 doxygen

有兩種獲得 doxygen 的方法。可以下載預編譯的可執行文件,也可以從 SVN 存儲庫下載源代碼並自己編譯。清單 1 演示的是後一種方法。


清單 1. 安裝和構建 doxygen 源代碼
                bash-2.05$ svn co https://doxygen.svn.sourceforge.net/svnroot/doxygen/trunk doxygen-svnbash-2.05$ cd doxygen-svnbash-2.05$ ./configure –prefix=/home/user1/binbash-2.05$ makebash-2.05$ make install

注意,配置腳本把編譯的源代碼存儲在 /home/user1/bin 中(進行編譯後,會在 PATH 變量中添加這個目錄),因為並非每個 UNIX® 用戶都有寫 /usr 文件夾的權限。另外,需要用 svn 實用程序下載源代碼。


使用 doxygen 生成文檔

使用 doxygen 生成源代碼的文檔需要執行三個步驟。

生成配置文件

在 shell 提示上,輸入命令 doxygen -g 。這個命令在當前目錄中生成一個可編輯的配置文件 Doxyfile。可以改變這個文件名,在這種情況下,應該調用 doxygen -g <user-specified file name>,見 清單 2


清單 2. 生成默認的配置文件
                bash-2.05b$ doxygen -gConfiguration file 'Doxyfile' created.Now edit the configuration file and enter  doxygen Doxyfileto generate the documentation for your projectbash-2.05b$ ls DoxyfileDoxyfile

編輯配置文件

配置文件采用 = 這樣的結構,與 Make 文件格式相似。下麵是最重要的標記:

  • 必須在這裏提供一個目錄名,例如 /home/user1/documentation,這個目錄是放置生成的文檔文件的位置。如果提供一個不存在的目錄名,doxygen 會以這個名稱創建具有適當用戶權限的目錄。
  • 這個標記創建一個以空格分隔的所有目錄的列表,這個列表包含需要生成文檔的 C/C++ 源代碼文件和頭文件。例如,請考慮以下代碼片段:
    INPUT = /home/user1/project/kernel /home/user1/project/memory

    在這裏,doxygen 會從這兩個目錄讀取 C/C++ 源代碼。如果項目隻有一個源代碼根目錄,其中有多個子目錄,那麽隻需指定根目錄並把 標記設置為 Yes

  • 在默認情況下,doxygen 會搜索具有典型 C/C++ 擴展名的文件,比如 .c、.cc、.cpp、.h.hpp。如果 標記沒有相關聯的值,doxygen 就會這樣做。如果源代碼文件采用不同的命名約定,就應該相應地更新這個標記。例如,如果項目使用 .c86 作為 C 文件擴展名,就應該在 標記中添加這個擴展名。
  • 如果源代碼層次結構是嵌套的,而且需要為所有層次上的 C/C++ 文件生成文檔,就把這個標記設置為 Yes。例如,請考慮源代碼根目錄層次結構 /home/user1/project/kernel,其中有 /home/user1/project/kernel/vmm 和 /home/user1/project/kernel/asm 等子目錄。如果這個標記設置為 Yes,doxygen 就會遞歸地搜索整個層次結構並提取信息。
  • 這個標記告訴 doxygen,即使各個類或函數沒有文檔,也要提取信息。必須把這個標記設置為 Yes
  • 把這個標記設置為 Yes。否則,文檔不包含類的私有數據成員。
  • 把這個標記設置為 Yes。否則,文檔不包含文件的靜態成員(函數和變量)。

清單 3 給出一個 Doxyfile 示例。


清單 3. 包含用戶提供的標記值的 doxyfile 示例
                OUTPUT_DIRECTORY = /home/user1/docsEXTRACT_ALL = yesEXTRACT_PRIVATE = yesEXTRACT_STATIC = yesINPUT = /home/user1/project/kernel#Do not add anything here unless you need to. Doxygen already covers all #common formats like .c/.cc/.cxx/.c++/.cpp/.inl/.h/.hppFILE_PATTERNS = RECURSIVE = yes

運行 doxygen

在 shell 提示下輸入 doxygen Doxyfile(或者已為配置文件選擇的其他文件名)運行 doxygen。在最終生成 Hypertext Markup Language(HTML)和 Latex 格式(默認)的文檔之前,doxygen 會顯示幾個消息。在生成文檔期間,在 標記指定的文件夾中,會創建兩個子文件夾 htmllatex清單 4 是一個 doxygen 運行日誌示例。


清單 4. doxygen 的日誌輸出
                Searching for include files...Searching for example files...Searching for images...Searching for dot files...Searching for files to excludeReading input files...Reading and parsing tag filesPreprocessing /home/user1/project/kernel/kernel.h…Read 12489207 bytesParsing input...Parsing file /project/user1/project/kernel/epico.cxx…Freeing input...Building group list.....Generating docs for compound MemoryManager::ProcessSpec…Generating docs for namespace stdGenerating group index...Generating example index...Generating file member index...Generating namespace member index...Generating page index...Generating graph info page...Generating search index...Generating style sheet...


文檔輸出格式

除了 HTML 之外,doxygen 還可以生成幾種輸出格式的文檔。可以讓 doxygen 生成以下格式的文檔:

  • UNIX 手冊頁: 標記設置為 Yes。在默認情況下,會在 指定的目錄中創建 man 子文件夾,生成的文檔放在這個文件夾中。必須把這個文件夾添加到 MANPATH 環境變量中。
  • Rich Text Format(RTF): 標記設置為 Yes。把 標記設置為希望放置 .rtf 文件的目錄;在默認情況下,文檔放在 OUTPUT_DIRECTORY 中的 rtf 子文件夾中。要想支持跨文檔瀏覽,應該把 標記設置為 Yes。如果設置這個標記,生成的 .rtf 文件會包含跨文檔鏈接。
  • Latex:在默認情況下,doxygen 生成 Latex 和 HTML 格式的文檔。在默認的 Doxyfile 中, 標記設置為 Yes。另外, 標記設置為 Latex,這意味著會在 OUTPUT_DIRECTORY 中創建 latex 子文件夾並在其中生成 Latex 文件。
  • Microsoft® Compiled HTML Help(CHM)格式: 標記設置為 Yes。因為在 UNIX 平台上不支持這種格式,doxygen 隻在保存 HTML 文件的文件夾中生成一個 index.hhp 文件。您必須通過 HTML 幫助編譯器把這個文件轉換為 .chm 文件。
  • Extensible Markup Language(XML)格式: 標記設置為 Yes。(注意,doxygen 開發團隊還在開發 XML 輸出)。

清單 5 提供的 Doxyfile 示例讓 doxygen 生成所有格式的文檔。


清單 5. 生成多種格式的文檔的 Doxyfile
                #for HTML GENERATE_HTML = YESHTML_FILE_EXTENSION = .htm#for CHM filesGENERATE_HTMLHELP = YES#for Latex outputGENERATE_LATEX = YESLATEX_OUTPUT = latex#for RTFGENERATE_RTF = YESRTF_OUTPUT = rtf RTF_HYPERLINKS = YES#for MAN pagesGENERATE_MAN = YESMAN_OUTPUT = man#for XMLGENERATE_XML = YES


doxygen 中的特殊標記

doxygen 包含幾個特殊標記。

C/C++ 代碼的預處理

為了提取信息,doxygen 必須對 C/C++ 代碼進行預處理。但是,在默認情況下,它隻進行部分預處理 —— 計算條件編譯語句(#if…#endif),但是不執行宏展開。請考慮 清單 6 中的代碼。


清單 6. 使用宏的 C++ 代碼示例
                #include #include #define USE_ROPE#ifdef USE_ROPE  #define STRING std::rope#else  #define STRING std::string#endifstatic STRING name;

通過源代碼中定義的 ,doxygen 生成的文檔如下:

                Defines    #define USE_ROPE    #define STRING std::ropeVariables    static STRING name

在這裏可以看到 doxygen 執行了條件編譯,但是沒有對 STRING 執行宏展開。Doxyfile 中的 標記在默認情況下設置為 Yes。為了執行宏展開,還應該把 標記設置為 Yes。這會使 doxygen 產生以下輸出:

                Defines   #define USE_ROPE    #define STRING std::stringVariables    static std::rope name

如果把 標記設置為 No,前麵源代碼的 doxygen 輸出就是:

                Variables    static STRING name

注意,文檔現在沒有定義,而且不可能推導出 STRING 的類型。因此,總是應該把 標記設置為 Yes

在文檔中,可能希望隻展開特定的宏。為此,除了把 標記設置為 Yes 之外,還必須把 標記設置為 Yes(這個標記在默認情況下設置為 No),並在 標記中提供宏的細節。請考慮 清單 7 中的代碼,這裏隻希望展開宏 CONTAINER


清單 7. 包含多個宏的 C++ 源代碼
                #ifdef USE_ROPE  #define STRING std::rope#else  #define STRING std::string#endif#if ALLOW_RANDOM_ACCESS == 1  #define CONTAINER std::vector#else  #define CONTAINER std::list#endifstatic STRING name;static CONTAINER gList;

清單 8 給出配置文件。


清單 8. 允許有選擇地展開宏的 Doxyfile
                ENABLE_PREPROCESSING = YESMACRO_EXPANSION = YESEXPAND_ONLY_PREDEF = YESEXPAND_AS_DEFINED = CONTAINER…

下麵的 doxygen 輸出隻展開了 CONTAINER

                Defines#define STRING   std::string #define CONTAINER   std::listVariablesstatic STRING namestatic std::list gList

注意,隻有 CONTAINER 宏被展開了。在 都設置為 Yes 的情況下, 標記隻選擇展開等號操作符右邊列出的宏。

對於預處理過程,要注意的最後一個標記是 。就像用 -D 開關向 C++ 編譯器傳遞預處理器定義一樣,使用這個標記定義宏。請考慮 清單 9 中的 Doxyfile。


清單 9. 定義了宏展開標記的 Doxyfile
                ENABLE_PREPROCESSING = YESMACRO_EXPANSION = YESEXPAND_ONLY_PREDEF = YESEXPAND_AS_DEFINED = PREDEFINED = USE_ROPE=                              ALLOW_RANDOM_ACCESS=1

下麵是 doxygen 生成的輸出:

                Defines#define USE_CROPE #define STRING   std::rope #define CONTAINER   std::vectorVariablesstatic std::rope name static std::vector gList

在使用 標記時,宏應該定義為 <macro name>=<value> 形式。如果不提供值,比如簡單的 #define,那麽隻使用 <macro name>=<spaces> 即可。多個宏定義以空格或反斜杠()分隔。

從文檔生成過程中排除特定文件或目錄

在 Doxyfile 中的 標記中,添加不應該為其生成文檔的文件或目錄(以空格分隔)。因此,如果提供了源代碼層次結構的根,並要跳過某些子目錄,這將非常有用。例如,如果層次結構的根是 src_root,希望在文檔生成過程中跳過 examples/ 和 test/memoryleaks 文件夾,Doxyfile 應該像 清單 10 這樣。


清單 10. 使用 EXCLUDE 標記的 Doxyfile
                INPUT = /home/user1/src_rootEXCLUDE = /home/user1/src_root/examples /home/user1/src_root/test/memoryleaks…


生成圖形和圖表

在默認情況下,Doxyfile 把 標記設置為 Yes。這個標記用來生成類層次結構圖。要想生成更好的視圖,可以從 Graphviz 下載站點 下載 dot 工具。Doxyfile 中的以下標記用來生成圖表:

  • 在 Doxyfile 中這個標記默認設置為 Yes。如果這個標記設置為 No,就不生成繼承層次結構圖。
  • 如果這個標記設置為 Yes,doxygen 就使用 dot 工具生成更強大的圖形,比如幫助理解類成員及其數據結構的協作圖。注意,如果這個標記設置為 Yes 標記就無效了。
  • 如果 標記和這個標記同時設置為 Yes,就使用 dot 生成繼承層次結構圖,而且其外觀比隻使用 時更豐富。
  • 如果 標記和這個標記同時設置為 Yes,doxygen 會生成協作圖(還有繼承圖),顯示各個類成員(即包含)及其繼承層次結構。

清單 11 提供一個使用一些數據結構的示例。注意,在配置文件中 標記都設置為 Yes


清單 11. C++ 類和結構示例
                struct D {  int d;};class A {  int a;};class B : public A {  int b;};class C : public B {  int c;  D d;};

圖 1 給出 doxygen 的輸出。


圖 1. 使用 dot 工具生成的類繼承圖和協作圖
類繼承圖

代碼文檔樣式

到目前為止,我們都是使用 doxygen 從原本沒有文檔的代碼中提取信息。但是,doxygen 也鼓勵使用文檔樣式和語法,這有助於生成更詳細的文檔。本節討論 doxygen 鼓勵在 C/C++ 代碼中使用的一些常用標記。更多信息參見 參考資料

每個代碼元素有兩種描述:簡短的和詳細的。簡短描述通常是單行的。函數和類方法還有第三種描述體內描述(in-body description),這種描述把在函數體中找到的所有注釋塊集中在一起。比較常用的一些 doxygen 標記和注釋樣式如下:

  • 簡短描述:使用單行的 C++ 注釋,或使用 標記。
  • 詳細描述:使用 JavaDoc 式的注釋 /** … test … */(注意開頭的兩個星號 [*])或 Qt 式的注釋 /*! … text … */
  • 體內描述:類、結構、聯合體和名稱空間等 C++ 元素都有自己的標記,比如

為了為全局函數、變量和枚舉類型生成文檔,必須先對對應的文件使用 標記。清單 12 給出的示例包含用於四種元素的標記:函數標記()、函數參數標記()、變量名標記()、用於 #define 的標記()以及用來表示與一個代碼片段相關的問題的標記()。


清單 12. 典型的 doxygen 標記及其使用方法
                /*! file globaldecls.h      brief Place to look for global variables, enums, functions           and macro definitions  *//** var const int fileSize      brief Default size of the file on disk  */const int fileSize = 1048576;/** def SHIFT(value, length)      brief Left shift value by length in bits  */#define SHIFT(value, length) ((value) << (length))/** fn bool check_for_io_errors(FILE* fp)      brief Checks if a file is corrupted or not      param fp Pointer to an already opened file      warning Not thread safe!  */bool check_for_io_errors(FILE* fp);

下麵是生成的文檔:

                Defines#define SHIFT(value, length)   ((value) << (length))               Left shift value by length in bits.Functionsbool check_for_io_errors (FILE *fp)          Checks if a file is corrupted or not.Variablesconst int fileSize = 1048576;Function Documentationbool check_for_io_errors (FILE* fp)Checks if a file is corrupted or not.Parameters              fp: Pointer to an already opened fileWarningNot thread safe! 


結束語

本文討論如何用 doxygen 從遺留的 C/C++ 代碼提取出大量相關信息。如果用 doxygen 標記生成代碼文檔,doxygen 會以容易閱讀的格式生成輸出。隻要以適當的方式使用,doxygen 就可以幫助任何開發人員維護和管理遺留係統。


參考資料

學習

  • 您可以參閱本文在 developerWorks 全球站點上的 英文原文

  • doxygen 站點 包含關於 doxygen 的非常有價值的手冊和幾篇文章。

  • 下載 dot 實用程序

  • AIX and UNIX 專區:developerWorks 的“AIX and UNIX 專區”提供了大量與 AIX 係統管理的所有方麵相關的信息,您可以利用它們來擴展自己的 UNIX 技能。

  • AIX and UNIX 新手入門:訪問“AIX and UNIX 新手入門”頁麵可了解更多關於 AIX 和 UNIX 的內容。

  • AIX and UNIX 專題匯總:AIX and UNIX 專區已經為您推出了很多的技術專題,為您總結了很多熱門的知識點。我們在後麵還會繼續推出很多相關的熱門專題給您,為了方便您的訪問,我們在這裏為您把本專區的所有專題進行匯總,讓您更方便的找到您需要的內容。

  • developerWorks 技術活動和網絡廣播:隨時關注 developerWorks 技術活動和網絡廣播。

  • Podcasts:收聽 IBM 技術專家的訪談錄。

獲得產品和技術

  • 下載 doxygen。

  • IBM 試用軟件:使用可從 developerWorks 直接下載的軟件構建您的下一個開發項目。

討論

關於作者

Arpan Sen 是一位資深工程師,從事電子設計自動化行業的軟件開發。他花了好幾年研究多種風格的 UNIX,包括 Solaris、SunOS、HP-UX 和 IRIX,以及 Linux 和 Microsoft Windows。他主要對軟件性能優化技術、圖形理論和並行計算感興趣。Arpan 擁有軟件係統研究生學位。

[ 打印 ]
閱讀 ()評論 (1)
評論
目前還沒有任何評論
登錄後才可評論.