學慣用 doxygen 產生源碼文檔

來源:互聯網
上載者:User

學慣用 doxygen 產生源碼文檔

瀏覽次數: 4 次 字型:[增加 減小] 類型:轉載
  維護用 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-svn
bash-2.05$ cd doxygen-svn
bash-2.05$ ./configure –prefix=/home/user1/bin
bash-2.05$ make
bash-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 -g
Configuration file 'Doxyfile' created.
Now edit the configuration file and enter
 doxygen Doxyfile
to generate the documentation for your project
bash-2.05b$ ls Doxyfile
Doxyfile

  編輯設定檔

  設定檔採用 <TAGNAME> = <VALUE> 這樣的結構,與 Make 檔案格式相似。下面是最重要的標記:

  <OUTPUT_DIRECTORY>:必須在這裡提供一個目錄名,例如 /home/user1/documentation,這個目錄是放置產生的文檔檔案的位置。如果提供一個不存在的目錄名,doxygen 會以這個名稱建立具有適當使用者權限的目錄。

  <INPUT>:這個標記建立一個以空格分隔的所有目錄的列表,這個列表包含需要產生文檔的 C/C++ 原始碼檔案和標頭檔。例如,請考慮以下程式碼片段:INPUT = /home/user1/project/kernel /home/user1/project/memory

  在這裡,doxygen 會從這兩個目錄讀取 C/C++ 原始碼。如果項目只有一個原始碼根目錄,其中有多個子目錄,那麼只需指定根目錄並把 <RECURSIVE> 標記設定為 Yes。

  <FILE_PATTERNS>:在預設情況下,doxygen 會搜尋具有典型 C/C++ 副檔名的檔案,比如 .c、.cc、.cpp、.h 和 .hpp。如果 <FILE_PATTERNS> 標記沒有相關聯的值,doxygen 就會這樣做。如果原始碼檔案採用不同的命名規範,就應該相應地更新這個標記。例如,如果項目使用 .c86 作為 C 副檔名,就應該在 <FILE_PATTERNS> 標記中添加這個副檔名。

  <RECURSIVE>:如果原始碼階層是嵌套的,而且需要為所有層次上的 C/C++ 檔案產生文檔,就把這個標記設定為 Yes。例如,請考慮原始碼根目錄階層 /home/user1/project/kernel,其中有 /home/user1/project/kernel/vmm 和 /home/user1/project/kernel/asm 等子目錄。如果這個標記設定為 Yes,doxygen 就會遞迴地搜尋整個階層並提取資訊。

  <EXTRACT_ALL>:這個標記告訴 doxygen,即使各個類或函數沒有文檔,也要提取資訊。必須把這個標記設定為 Yes。

  <EXTRACT_PRIVATE>:把這個標記設定為 Yes。否則,文檔不包含類的私人資料成員。

  <EXTRACT_STATIC>:把這個標記設定為 Yes。否則,文檔不包含檔案的靜態成員(函數和變數)。

  清單 3 給出一個 Do

xyfile 樣本。
  清單 3. 包含使用者提供的標記值的 doxyfile 樣本

OUTPUT_DIRECTORY = /home/user1/docs
EXTRACT_ALL = yes
EXTRACT_PRIVATE = yes
EXTRACT_STATIC = yes
INPUT = /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/.hpp
FILE_PATTERNS =
RECURSIVE = yes

  運行 doxygen

  在 shell 提示下輸入 doxygen Doxyfile(或者已為設定檔選擇的其他檔案名稱)運行 doxygen。在最終產生 Hypertext Markup Language(HTML)和 Latex 格式(預設)的文檔之前,doxygen 會顯示幾個訊息。在產生文檔期間,在 <OUTPUT_DIRECTORY> 標記指定的檔案夾中,會建立兩個子檔案夾 html 和 latex。清單 4 是一個 doxygen 作業記錄樣本。

  清單 4. doxygen 的日誌輸出

Searching for include files...
Searching for example files...
Searching for images...
Searching for dot files...
Searching for files to exclude
Reading input files...
Reading and parsing tag files
Preprocessing /home/user1/project/kernel/kernel.h

Read 12489207 bytes
Parsing input...
Parsing file /project/user1/project/kernel/epico.cxx

Freeing input...
Building group list...
..
Generating docs for compound MemoryManager::ProcessSpec

Generating docs for namespace std
Generating 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 手冊頁:把 <GENERATE_MAN> 標記設定為 Yes。在預設情況下,會在 <OUTPUT_DIRECTORY> 指定的目錄中建立 man 子檔案夾,產生的文檔放在這個檔案夾中。必須把這個檔案夾添加到 MANPATH 環境變數中。

  Rich Text Format(RTF):把 <GENERATE_RTF> 標記設定為 Yes。把 <RTF_OUTPUT> 標記設定為希望放置 .rtf 檔案的目錄;在預設情況下,文檔放在 OUTPUT_DIRECTORY 中的 rtf 子檔案夾中。要想支援跨文檔瀏覽,應該把 <RTF_HYPerlINKS> 標記設定為 Yes。如果設定這個標記,產生的 .rtf 檔案會包含跨文檔連結。

  Latex:在預設情況下,doxygen 產生 Latex 和 HTML 格式的文檔。在預設的 Doxyfile 中,<GENERATE_LATEX> 標記設定為 Yes。另外,<LATEX_OUTPUT> 標記設定為 Latex,這意味著會在 OUTPUT_DIRECTORY 中建立 latex 子檔案夾並在其中產生 Latex 檔案。

  Microsoft Compiled HTML Help(CHM)格式:把 <GENERATE_HTMLHELP> 標記設定為 Yes。因為在 UNIX 平台上不支援這種格式,doxygen 只在儲存 HTML 檔案的檔案夾中產生一個 index.hhp 檔案。您必須通過 HTML 協助編譯器把這個檔案轉換為 .chm 檔案。

  Extensible Markup Language(XML)格式:把 <GENERATE_XML> 標記設定為 Yes。(注意,doxy

gen Team Dev還在開發 XML 輸出)。
  清單 5 提供的 Doxyfile 樣本讓 doxygen 產生所有格式的文檔。

  清單 5. 產生多種格式的文檔的 Doxyfile

#for HTML
GENERATE_HTML = YES
HTML_FILE_EXTENSION = .htm
#for CHM files
GENERATE_HTMLHELP = YES
#for Latex output
GENERATE_LATEX = YES
LATEX_OUTPUT = latex
#for RTF
GENERATE_RTF = YES
RTF_OUTPUT = rtf
RTF_HYPERLINKS = YES
#for MAN pages
GENERATE_MAN = YES
MAN_OUTPUT = man
#for XML
GENERATE_XML = YES

  doxygen 中的特殊標記

  doxygen 包含幾個特殊標記。

  C/C++ 代碼的預先處理

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

  清單 6. 使用宏的 C++ 程式碼範例

#include <cstring>
#include <rope>
#define USE_ROPE
#ifdef USE_ROPE
 #define STRING std::rope
#else
 #define STRING std::string
#endif
static STRING name;

  通過原始碼中定義的 <USE_ROPE>,doxygen 產生的文檔如下:

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

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

        Defines
  #define USE_ROPE
  #define STRING std::string
Variables
  static std::rope name

  如果把 <ENABLE_PREPROCESSING> 標記設定為 No,前面原始碼的 doxygen 輸出就是:

        Variables
  static STRING name

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

  在文檔中,可能希望只展開特定的宏。為此,除了把 <ENABLE_PREPROCESSING> 和 <MACRO_EXPANSION> 標記設定為 Yes 之外,還必須把 <EXPAND_ONLY_PREDEF> 標記設定為 Yes(這個標記在預設情況下設定為 No),並在 <PREDEFINED> 或 <EXPAND_AS_DEFINED> 標記中提供宏的細節。請考慮 清單 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
#endif
static STRING name;
static CONTAINER gList;

  清單 8 給出設定檔。

  清單 8. 允許有選擇地展開宏的 Doxyfile

ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES

EXPAND_ONLY_PREDEF = YES
EXPAND_AS_DEFINED = CONTAINER

  下面的 doxygen 輸出只展開了 CONTAINER:

        Defines
#define STRING  std::string
#define CONTAINER  std::list
Variables
static STRING name
static std::list gList

  注意,只有 CONTAINER 宏被展開了。在 <MACRO_EXPANSION> 和 <EXPAND_ONLY_PREDEF> 都設定為 Yes 的情況下,<EXPAND_AS_DEFINED> 標記只選擇展開等號操作符右邊列出的宏。

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

  清單 9. 定義了宏展開標記的 Doxyfile

ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
EXPAND_AS_DEFINED =
PREDEFINED = USE_ROPE=
               ALLOW_RANDOM_Access=1

  下面是 doxygen 產生的輸出:

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

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

  從文檔產生過程中排除特定檔案或目錄

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

  清單 10. 使用 EXCLUDE 標記的 Doxyfile

INPUT = /home/user1/src_root
EXCLUDE = /home/user1/src_root/examples /home/user1/src_root/test/memoryleaks

  產生圖形和圖表

  在預設情況下,Doxyfile 把 <CLASS_DIAGRAMS> 標記設定為 Yes。這個標記用來產生類階層圖。要想產生更好的視圖,可以從 Graphviz 下載網站 下載 dot 工具。Doxyfile 中的以下標記用來組建圖表:

  <CLASS_DIAGRAMS>:在 Doxyfile 中這個標記預設設定為 Yes。如果這個標記設定為 No,就不產生繼承階層圖。

  <HAVE_DOT>:如果這個標記設定為 Yes,doxygen 就使用 dot 工具產生更強大的圖形,比如協助理解類成員及其資料結構的共同作業圖表。注意,如果這個標記設定為 Yes,<CLASS_DIAGRAMS> 標記就無效了。

  <CLASS_GRAPH>:如果 <HAVE_DOT> 標記和這個標記同時設定為 Yes,就使用 dot 產生繼承階層圖,而且其外觀比只使用 <CLASS_DIAGRAMS> 時更豐富。

  <COLLABORATION_GRAPH>:如果 <HAVE_DOT> 標記和這個標記同時設定為 Yes,doxygen 會產生共同作業圖表(還有繼承圖),顯示各個類成員(即包含)及其繼承階層。

  清單 11 提供一個使用一些資料結構的樣本。注意,在設定檔中 <HAVE_DOT>、<CLASS_GRAPH> 和 <COLLABORATION_GRAPH> 標記都設定為 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++ 注釋,或使用 <brief> 標記。

  詳細描述:使用 JavaDoc 式的注釋 /** … test … */(注意開頭的兩個星號 [*])或 Qt 式的注釋 /*! … text … */。

  體內描述:類、結構、聯合體和名稱空間等 C++ 元素都有自己的標記,比如 <class>、<struct>、<union> 和 <namespace>。

  為了為全域函數、變數和枚舉類型產生文檔,必須先對對應的檔案使用 <file> 標記。清單 12 給出的樣本包含用於四種元素的標記:函數標記(<fn>)、函數參數標記(<param>)、變數名標記(<var>)、用於 #define 的標記(<def>)以及用來表示與一個程式碼片段相關的問題的標記(<warning>)。

  清單 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.
Functions
bool check_for_io_errors (FILE *fp) 
    Checks if a file is corrupted or not.
Variables
const int fileSize = 1048576;
Function Documentation
bool check_for_io_errors (FILE* fp)
Checks if a file is corrupted or not.
Parameters
       fp: Pointer to an already opened file
Warning
Not thread safe!

  結束語

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.