在 Linux 上用 Doxygen 生成源代碼文檔
在試著熟悉別人的代碼時(shí),你總希望他們留下的代碼注釋能對(duì)你理解代碼有所幫助。同理,無(wú)論為了自己還是其他人,編寫(xiě)代碼時(shí)寫(xiě)注釋是好習(xí)慣。所有編程語(yǔ)言都有專(zhuān)門(mén)的注釋語(yǔ)法,注釋可以是一個(gè)單詞、一行文字、甚至是一整段話(huà)。編譯器或解釋器處理源代碼時(shí)會(huì)忽略注釋。
注釋不能完全取代文檔,但是有方法可以使用注釋來(lái)生成文檔。Doxygen 是一個(gè)開(kāi)源的文檔生成工具,它能夠根據(jù)代碼注釋生成 HTML 或 LaTeX 格式的文檔。Doxygen 讓你在不用額外操作的情況下創(chuàng)建代碼結(jié)構(gòu)概覽。盡管 Doxygen 主要是用來(lái)給 C++ 生成文檔的,它對(duì)其它語(yǔ)言同樣適用,比如 C、Objective-C、 C#、 PHP、Java 和 Python 等。
要使用 Doxygen,你只需要在源代碼中使用 Doxygen 能夠識(shí)別的語(yǔ)法來(lái)寫(xiě)注釋。Doxygen 會(huì)掃描源碼文件,然后根據(jù)這些特殊注釋生成 HTML 或 LaTeX 文檔。下面的示例項(xiàng)目會(huì)演示如何使用 Doxygen 注釋?zhuān)约拔臋n是如通過(guò)注釋生成出來(lái)的。示例代碼可從 GitHub 上獲得,本文中也將引用 Doxygen 手冊(cè)及文檔 的相關(guān)章節(jié)。
在 Linux 上安裝 Doxygen
在 Fedora 上可以通過(guò)軟件包的形式安裝 Doxygen。打開(kāi)終端運(yùn)行命令:
sudo dnf install doxygen
在基于 Debian 的操作系統(tǒng)上,可以通過(guò)以下命令來(lái)安裝:
sudo apt-get install doxygen
使用
安裝完 Doxygen 后,你需要在項(xiàng)目中按 Doxygen 可以識(shí)別的格式來(lái)注釋代碼,還要提供一個(gè) Doxyfile 配置文件來(lái)控制 Doxygen 的一些行為。
注意:如果你用的是 GitHub 上的示例項(xiàng)目,你可以忽略下面一步。
如果 Doxyfile 文件不存在,你可以用 Doxygen 生成一個(gè)標(biāo)準(zhǔn) Doxyfile 模板文件。切換到項(xiàng)目根目錄下,運(yùn)行:
doxygen -g
參數(shù) -g
表示 生成generate。現(xiàn)在應(yīng)該會(huì)出現(xiàn)一個(gè)名為 Doxyfile
的新文件。通過(guò)命令調(diào)用 Doxygen:
doxygen
現(xiàn)在應(yīng)該能會(huì)有兩個(gè)新文件夾:
html/
latex/
默認(rèn)情況下,Doxygen 會(huì)同時(shí)輸出 LaTeX 和 HTML 格式的文檔。本文主要關(guān)注 HTML 文檔。你可以在 Doxygen 官方文檔的入門(mén)小節(jié)中找到關(guān)于 LaTeX 格式輸出的更多信息。
雙擊 html/index.html
打開(kāi) HTML 文件。用空的配置文件生成的文檔如下圖:
A screenshot of a doxygen generated main page on Firefox. The content field under My Project Documentation is blank.
現(xiàn)在我們?cè)囍薷?nbsp;Doxyfile
文件,并在源代碼中添加特殊注釋。
Doxyfile 文件
在 Doxyfile
文件中可以定義大量的可調(diào)選項(xiàng),本文通過(guò)介紹示例項(xiàng)目的 Doxyfile
文件我只能覆蓋其中很小的子集。
第 35 行:項(xiàng)目名稱(chēng)
你可以在這里指定項(xiàng)目名稱(chēng),它最終會(huì)顯示在頁(yè)眉header和瀏覽器標(biāo)簽上。
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
# double-quotes, unless you are using Doxywizard) that should identify the
# project for which the documentation is generated. This name is used in the
# title of most generated pages and in a few other places.
# The default value is: My Project.
PROJECT_NAME = "My Project"
第 47 行:項(xiàng)目簡(jiǎn)介
項(xiàng)目簡(jiǎn)介會(huì)以略小的字號(hào)顯示在頁(yè)眉上。
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
# quick idea about the purpose of the project. Keep the description short.
PROJECT_BRIEF = "An example of using Doxygen in C++"
第 926 行:包含子目錄
允許 Doxygen 查找源代碼和文檔文件時(shí)遞歸遍歷子目錄。
# The RECURSIVE tag can be used to specify whether or not subdirectories should
# be searched for input files as well.
# The default value is: NO.
RECURSIVE = YES
第 1769 行:禁用 LaTeX 輸出
如果你只想生成 HTML 文檔,可以通過(guò)這個(gè)開(kāi)關(guān)禁用 LaTeX 輸出。
# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
# The default value is: YES.
GENERATE_LATEX = NO
修改完成后,你可以再次運(yùn)行 Doxygen 來(lái)檢驗(yàn)修改是否生效了??梢栽谡{(diào)用 Doxygen 時(shí)使用 -x
選項(xiàng)來(lái)查看 Doxyfile
文件的變更項(xiàng):
A screenshot of the terminal showing the differences, Project Name, Project Brief, Recursive, and status of Generate Latex
通過(guò)調(diào)用 diff
命令,Doxygen 僅顯示當(dāng)前 Doxyfile 文件和模板文件的差異。
特殊注釋
Doxygen 通過(guò)掃描源代碼文件中的特殊注釋和關(guān)鍵字來(lái)生成 HTML 文檔。示例項(xiàng)目中的 ByteStream 類(lèi)的頭文件可以很好地解釋特殊注釋的用法。
下面用構(gòu)造函數(shù)和析構(gòu)函數(shù)作為示例:
/*! @brief Constructor which takes an external buffer to operate on
*
* The specified buffer already exist.
* Memory and size can be accessed by buffer() and size().
*
* @param[in] pBuf Pointer to existing buffer
* @param[in] size Size of the existing buffer
*/
ByteStream(char* pBuf, size_t size) noexcept;
特殊注釋塊有不同的格式風(fēng)格。我傾向于使用 /*!
開(kāi)頭(Qt 風(fēng)格),每行前添加 *
,以 */
結(jié)束注釋塊。你可以參考 Doxygen 手冊(cè)的文檔化代碼小節(jié),以大致了解不同的風(fēng)格選項(xiàng)。
Doxygen 注釋分兩個(gè)部分:簡(jiǎn)要描述和詳細(xì)描述。它們都是可選的。在上面的例子中的注釋塊是對(duì)緊跟其后的構(gòu)造函數(shù)聲明的描述。在 @brief
之后的文本會(huì)顯示在類(lèi)概覽小節(jié)中:
A screenshot of the C++ example of using Doxygen showing the Byte Stream Class Reference. The categories in the list are public member functions, writing (operators for writing to the stream), and reading (operators for reading from the stream)
A screenshot of the C++ example of using Doxygen showing the Byte Stream Class Reference. The categories in the list are public member functions, writing (operators for writing to the stream), and reading (operators for reading from the stream)
在空行(空行是段落分隔符)之后是構(gòu)造函數(shù)的實(shí)際文檔。用 @param[in/out]
關(guān)鍵字標(biāo)注傳遞給構(gòu)造函數(shù)的參數(shù),Doxygen 基于此生成參數(shù)列表:
Screenshot of the Doxygen example showing the parameters under ByteStream
Screenshot of the Doxygen example showing the parameters under ByteStream
值得注意的是 Doxygen 為 buffer()
和 size()
方法自動(dòng)生成了鏈接。相反,Doxygen 忽略了析構(gòu)函數(shù)前的注釋?zhuān)驗(yàn)樗](méi)有使用特殊注釋?zhuān)?/p>
// Destructor
~ByteStream();
現(xiàn)在你已經(jīng)看到 Doxygen 的絕大部分功能了。通過(guò)使用一種稍微改良的注釋格式,讓 Doxygen 能夠識(shí)別它們。通過(guò)使用一些關(guān)鍵字,你甚至可以進(jìn)一步控制格式化。在下一節(jié)中,我會(huì)進(jìn)一步介紹 Doxygen 的其它特性。
其它特性
現(xiàn)在幾乎所有的工作都可以通過(guò)對(duì)源代碼注釋的方式完成。通過(guò)一些微調(diào),你可以輕松地優(yōu)化 Doxygen 的輸出。
Markdown 格式
為了進(jìn)階的格式化,Doxygen 支持 Markdown 和 HTML 命令。Markdown 速查表可以在 這里 下載到。
項(xiàng)目主頁(yè)
除了自定義頁(yè)眉之外,html/index.html
幾乎沒(méi)有其它內(nèi)容了。你可以通過(guò)使用關(guān)鍵字向其中添加一些有意義的內(nèi)容。因?yàn)橹黜?yè)通常不是針對(duì)某個(gè)源代碼文件的,你可以將要顯示在主頁(yè)的內(nèi)容放到項(xiàng)目根目錄下的一個(gè)單獨(dú)文件中。示例項(xiàng)目中就是這樣做的,其輸出效果如下:
The Doxygen Example Documentation field now contains headings and documentation: Introduction, Running the example, System requirements, and Building the code, with step by step examples and code snippets (all can be found in the example on GitHub)
自動(dòng)鏈接生成
上面已將提到了,當(dāng)你引用代碼的其它部分時(shí),Doxygen 會(huì)自動(dòng)識(shí)別并生成相應(yīng)鏈接。但要注意,這要求被引用部分也有文檔才行。
更多信息可以在官方文檔的自動(dòng)鏈接生成中找到。
分組
ByteStream
類(lèi)重載overload 了的讀寫(xiě)流操作符 (<<
和 >>
)。在類(lèi)的概覽中可以發(fā)現(xiàn)操作符被分為讀和寫(xiě)兩組。分組是在 ByteStream
的頭文件中定義的。
分組的語(yǔ)法以標(biāo)記 @{
開(kāi)始,以 }@
結(jié)束。在標(biāo)記范圍中的內(nèi)容都屬于這個(gè)分組。在 ByteStream.h
中的實(shí)現(xiàn)如下:
/** @name Writing
* Operators for writing to the stream
* @{
*/
(...)
/** @}
* @name Reading
* Operators for reading from the stream
* @{
*/
(...)
/** @} */
你可以在官方文檔的分組中找到更多相關(guān)信息。
LLVM 支持
如果你用 Clang 構(gòu)建項(xiàng)目的話(huà),可以通過(guò)使用 -Wdocumentation
選項(xiàng)讓 Clang 對(duì)特殊注釋進(jìn)行檢查。想了解該特性的更多信息,可以參考 LLVM 用戶(hù)手冊(cè)和 Dmitri Gribenko 的展示報(bào)告,它們可以在 Clang 網(wǎng)站上找到。
誰(shuí)在用 Doxygen
Doxygen 是在 1997 年首次發(fā)布的。盡管有些年頭了,現(xiàn)在仍然有很多項(xiàng)目在使用 Doxygen。比如 NASA 的飛行軟件框架 F Prime、圖像處理庫(kù) OpenCV、包管理器 RPM。你還可以在其它領(lǐng)域發(fā)現(xiàn) Doxygen 語(yǔ)法標(biāo)記的身影,比如內(nèi)容管理平臺(tái) Drupal 的文檔標(biāo)準(zhǔn)中。
注意:Doxygen 輸出的 HTML 文檔風(fēng)格類(lèi)似于九十年代網(wǎng)頁(yè)。并且它也難以描繪元編程和模板編程架構(gòu)。在這些情況下,你應(yīng)該選擇 Sphinx 而不是 Doxygen。