Skip to content
 

Doxygen – stručný úvod

Tvorba dokumentácie patrí neoddiskutovateľne k najmenej obľúbeným činnostiam. Doxygen patrí k nástrojom, ktoré pomáhajú vytvoriť dokumentáciu k nášmu projektu a tým robia túto úlohu o niečo znesiteľnejšou.

Aby bolo jasné: Doxygen (a ani žiadny iný softvér) za vás nenapíše užívateľskú príručku. Doxygen slúži k zdokumentovaniu vášho projektu – funkcií, premenných, súborov. Pomáha:

  • dokumentovať vašu prácu pre vašich kolegov
  • dokumentovať vašu prácu pre vás, ak sa k projektu vrátite po nejakom čase
  • zprehľadniť váš projekt, ak nadobudne trochu väčšie rozmery

Používanie nástroja ako Doxygen má jeden zaujímavý vedľajší efekt – naučí vás písať zrozumiteľné komentáre. Zatiaľ čo nič nehovoriace komentáre v zdrojovom texte sú bežné, vo vytvorenej dokumentácii bijú do očí.

Používať Doxygen nie je zložité. Ukážme si teda – krok za krokom – ako sa rýchlo dopracovať k slušnej dokumentácii.

Konfigurácia

Skôr ako začneme musíme vyvoriť vytvoriť pre náš projekt konfiguračný súbor pre Doxygen. Tento súbor sa štandardne volá Doxyfile. Našťastie konfiguračný súbor si môžeme vygenerovať: štandardný konfiguračný súbor vytvoríme príkazom:

doxygen -g

Tento príkaz vygeneruje bohate okomentovaný konfiguračný súbor Doxyfile. Nájdeme a zmeníme v ňom niekoľko parametrov:

PROJECT_NAME           = "Hello world"
PROJECT_NUMBER         = 1.0

OUTPUT_DIRECTORY       = doc

GENERATE_HTML          = YES
GENERATE_LATEX         = YES

EXTRA_PACKAGES         = times

Prvými dvomi riadkami definujeme názov projektu a jeho verziu. Tretím parametrom definujeme adresár, do ktorého sa uloží vytvorená dokumentácia. Týmto nastavením definujeme, že sa dokumentácia bude vytvárať v podadresári doc.

Ďalšími dvomi parametrami určíme typy dokumentácie, ktorá sa majú vytvárať. My budeme vytvárať dokumentáciu vo formátoch HTML a PDF (PDF dokmentácia sa vytvára prostredníctvom LaTeX-u).

Posledný riadok je parameter pre LaTeX dokumentáciu – v podstate ním určíme, že LaTeX má použiť pre vytvorenie dokumentácie postscriptový font times.

Ak chceme generovať dokumentáciu v inom jazyku ako angličtine, nastavíme jazyk:

OUTPUT_LANGUAGE        = Slovak

Tým máme konfiguráciu nastavenú a môžeme začať pripravovať náš projekt.

Príprava zdrojových súborov

Ako prvý krok potrebujeme pridať do naších zdrojových súborov špeciálne komentáre, určené pre Doxygen. Pridajme na začiatok každého súboru komentár v tvare:

/**
@file
*/

Čo to znamená si povieme neskôr. Teraz môžeme vygenerovať dokumentáciu príkazom:

doxygen

HTML doumentácia je pripravená, stačí prehliadačom otvoriť súbor doc/html/index.html. PDF dokumentáciu musíme najprv vygenerovať – v adresári doc/latex spustíme príkaz:

make pdf

Tento príkaz vytvorí dokument s názvom refman.pdf.

Ako vyzerá výsledok v HTML si môžeme pozrieť tu, vytvorený pdf dokument si môžme pozrieť tu. Môžeme vidieť, že Doxygen dokázal zo zdrojových súborov získať pomerne veľa informácií, ale k dokumentácii to má stále ďaleko.

Doxygen komentáre

Doxygen komentár je komentár, obsahujúci informácie, ktoré sú zahrnuté do výslednej dokumentácie a súčasne aj riadiace informácie, ktoré upresňujú význam komentárov alebo riadia vzhľad výslednej dokumentácie.

Doxygen komentár je štandardný C komentár, ktorý začína sekvenciou /** (namiesto štandardnej sekvencie /*). V skutočnosti existuje viac variant komentárov – ale aby sme veci nekomplikovali, budeme používať iba túto variantu, o ostatných sa zmienime na záver.

Z dôvodu lepšieho zvýraznenia komentárov je možné riadky začínať hviezdičkou – tieto úvodné hviezdičky sú ignorované a v dokumentácii sa neobjavia.

Riadiace sekvencie v komentároch začínajú kľúčovým slovom: každé kľúčové slovo začína znakom „\“ alebo „@“ – obe možnosti sú rovnocenné. Napríklad kľúčové slová @file a \file sú úplne rovnocenné. V našich príkladoch budeme používať zavináčovú variantu – takéto kľúčové slová sú vizuálne výraznejšie.

Doxygen komentár sa zvyčajne umiestňuje pred prvok, ktorý popisujeme – pred deklaráciu alebo telo funkcie, pred premennú, triedu, makro. Pokiaľ chceme komentár umiestniť inde, musíme v komentári špecifikovať, ku ktorému prvku patrí. Typickým príkladom je súbor – keďže nie je možné umiestniť komentár pred súbor, v komentári musíme použiť kľúčové slovo @file <názov_súboru> (ak meno súboru vynecháme, vzťahuje sa na súbor, v ktorom sa komentár nachádza) – tak ako v komentári, ktorý sme pridali do všetkých súborov. Špeciálnym prípadom sú Doxygen komentáre v tele funkcie – tieto sa nevzťahujú k žiadnemu prvku ale stávajú sa súčasťou podrobného popisu funkcie.

Doxygen komentár môžeme umiestniť k deklarácii prvku (typicky v súbore .h) alebo pri definícii prvku. Doxygen komentáre skombinuje. Táto vlastnosť nám umožňuje napríklad uviesť krátky popis pri deklarácii v hlavičkovom súbore a podrobný popis pri definícii alebo implementácii funkcie.

V prípade popisovania premenných, makier, členov štruktúr, členov tried a parametrov funkcií je možné umiestniť Doxygen komentár za popisovaný prvok. Túto situáciu naznačíme znakom „<„ hneď za uvodnou sekvenciou, napríklad:

#define LNG_EN    0   /**< @brief Angličtina */

V zásade rozlišujeme tri typy komentárov:

  • krátky komentár – tento komentár sa používa na popis prvkov v rôznych zoznamoch. Krátky komentár musí byť uvedený kľúčovým slovom @brief a musí byť ukončený prázdnym riadkom (alebo riadkom obsahujúcim iba hviezdičku – hviezdičky na začatku sa ignorujú)
  • podrobný komentár – tento komentár sa používa na podrobný popis, vrátane popisu parametrov funkcií
  • komentár v tele funkcie – všetky komentáre v tele funkcie sa pospájajú a pridajú sa k podrobnému komentáru funkcie

Niekoľko príkladov komentárov:

/* Komentár pre makro je umiestnený za definíciou makra, obsahuje iba krátky komentár */

#define LNG_EN    0   /**< @brief Angličtina */

/* Komentár pre súbor, špecifikovaný kľúčovým slovom @file, obsahuje aj krátky aj podrobný komentár */

/**
* @file
*
* @brief Hlavný súbor aplikácie Hello world.
*
* V zdrojovom súbore hello.c sa nachádza vstupný bod aplikácie - funkcia main
*/

/* Komentár pre globálne premenné - prvá má komenár umiestnený pred sebou, druhá za sebou */
/*                                Oba komentáre obsahujú krátky aj podrobný popis */

/**
* @brief Globálny buffer, obsahujúci jazykovú mutáciu textu
*
* Tento bufer je statický bufer. Jeho obsah sa prepíše pri každom volaní funkcie GetString
*/
char StringBuffer[100];
bool DefaultLanguageUsed;        /**< @brief Globálna premenná, indikujúca použirtie preddefinovaného jazyka
*
* Premenná sa nastavuje po každom volaní funkcie GetString
*/

Zvláštnu pozornosť si zasluhuje popis parametrov funkcií. Parametre funkcie môžeme popísať Doxygen komentármi priamo v deklarácii funkcie. Môžeme použiť komentáre umiestnené pred parametrom alebo za parametrom. Avšak čo v prípade, že sa nám zdá takýto zápis neprehľadný? Našťastie máme ďalšiu možnosť – popis parametrov umiestniť do popisu funkcie ako takej a označiť ich kľúčovým slovom @param. Viac na príkladoch:

/* Popis parametrov priamo v hlavičke funkcie */
int
main (int n,     /**< [in] Počet parametrov */
char *c[]  /**< [in] Pole parametrov */
)
{
.
.
.
}

/* Popis parametrov v popise funkcie */
/**
*
* Funkcia vypíše reťazec, ktorý dostane ako parameter na terminál.
* Vypísaný reťazec je automaticky ukončený novým riadkom
*
* @param s [in] reťazec, ktorý sa má vypísať
*/
void out_string(const char *s)
{
.
.
.
}

Len na okraj, všimnime komentár k funkcii out_string – komentár neobsahuje krátky popis. Krátky popis sa nachádza pri deklarácii:

/**
* @brief Výstupná funkcia
*
*/
extern void out_string(const char *s);

Ako vyzerá dokumentácia po pridaní Doxygen komentárov: HTML a PDF

Formátovanie komentárov a krížové referencie

Ak chceme text popisu rozdeliť na odstavce, musíme oddeliť jednotlivé odstavce prázdnym riadkom. Ak chceme zvýrazniť text, môžme použiť jednoducjé HTML kódy, ako <b></b> alebo <i></i>. Pri generovaní iných formátov ako HTML Doxygen tieto kódy rozlíši a nahradí ich príslušnými konštrukciami. Pre číslované alebo nečíslované zoznamy je možné použíť HTML konštrukcie <ol></ol> alebo <ul></ul>. Iná varianta zoznamov je jednoduchý zoznam, kde položky začínajú znakom „-„ (nečíslovaný zoznam) alebo znakmi „-#“ (číslovaný zoznam). Úroveň vnorenia je daná odsadením jednotlivých položíek. Pre úplný a presný zoznam možností formátovania konzultujte dokumentáciu.

Doxygen vie automaticky generovať krížové referencie. Pokiaľ nájde v popise zmienku o nejakom prvku v správnom formáte, automaticky vytvorí referenciu na podrobnú dokumentáciu. Rozlíši názvy súborov, názvy funkcií v tvare fcia(), názvy globálnych premenných ak ich uvedieme vo formáte ::premenna. Takisto môžme Doxygen donútiť vytvoriť krížovú referenciu použitím kľúčového slova @ref <meno>. Viac podrobností sa nachádza v manuáli – vymenovanie všetkých možností presahuje rámec tohoto úvodu.
Pozrite si komentáre pre funkciu main. V nej sú uvedené rôzne spôsoby vytvárania krížových referencií a niekoľko možností formátovania.

Zdrojové súbory v dokumentácii

Keď si v kapitole alebo záložke súbory pozrieme zoznam súborov, zbadáme, že do dokumentácie bol zahrnutý aj obsah hlavičkových súborov, avšak nie je tam zahrnutý obsah zdrojových textov. Pokiaľ by sme chceli do dokumentácie zahrnúť aj zdrojové texty, musíme v konfiguračnom súbore Doxygen zmeniť parametre:

SOURCE_BROWSER = YES
LATEX_SOURCE_CODE = YES

Pridaním zdrojových textov sa pri každom prvku objaví aj odvolávka do zdrojového textu. Zdrojové texty sú farebne zvýraznené a takisto obsahujú odvolávky na dokumentáciu. Zo zdrojových textov boli odstránené všetky Doxygen komentáre, avšak štandardné komentáre sú ponechané. Pokiaľ by sme chceli Doxygen komentáre zahrnúť do zdrojových textov, musíme zmeniť konfiguračný parameter

STRIP_CODE_COMMENTS=NO

Ak nám táto forma prezentácie nestačí, môžme zahrnúť fragmenty kódu priamo do textu dokumentácie. Umožní nám to nastavenie konfiguračného parametra:

INLINE_SOURCES=YES

Výsledná dokumentácia po pridaní zdrojových textov: HTML a PDF

Pokiaľ v dokumentácii nechceme zdrojové texty a ani obsah hlavičkových súborov, nastavíme v súbore Doxyfile parameter:

VERBATIM_HEADERS = NO

Samozrejme, všetky vyššie zmienené parametre nastavíme tiež na NO

Trochu diagramov

Ak máme nainštalovaný balík graphwiz a naša inštalácia Doxygen s ním dokáže pracovať (Doxygen bol kompilovaný s touto voľbou), máme možnosť zahrnúť do dokumentácie zaujímavé štrukturálne diagramy. Všetko, čo potrebujeme, je v konfiguračnom súbore Doxyfile povoliť použitie programu dot (ktorý, ako súčasť balíka graphwiz slúži na vytváranie grafov a diagramov):

HAVE_DOT = YES

Implicitne sú povolené všetky typy typy diagramov, s výnimkou diagramov volania funkcií – diagramy, zobrazujúce ktoré funkcie volá tá-ktorá funkcia alebo diagramy zobrazujúce odkiaľ je predmetná funkcia volaná. Dôvod je prostý – u rozsiahlejších projektov môže vytváranie takýchto diagramov trvať pomerne dlho.

To však neplatí pre náš malý projektík, a tak obidva typy diagramov zobrazujúce štruktúru volania funkcií globálne povolíme:

CALL_GRAPH = YES
CALLER_GRAPH =YES

Pokiaľ nám globálne povolenie týchto diagramov spôsobí problémy, máme možnosť tieto voľby vypnúť a povoliť generovanie diagramov pomocou kľúčových slov @callgraph a @callergraph v komentári popisujúcom funkciu, u ktorej chceme mať diagramy zobrazené.

A takto vyzerá dokumentácia obohatená o diagramy: HTML a PDF

Triedenie do skupín

Dokumentácia, ktorú sme doteraz vytvorili, dokumentuje súbory – zdrojové aj hlavičkové. Avšak našej dokumentácii chýba istá štrukturovanosť – napríklad rozdelenie funkcií do kategórií alebo prehľadné zoznamy obsahujúce prvky z viacerých súborov.

Doxygen nám túto možnosť dáva. Umožňuje zadeliť jednotlivé prvky do hierarchicky usporiadaných skupín. Skupinu zadefinujeme pomocou Doxygen komentára obsahujúceho príkaz @defgroup. Príkaz @defgroup má dva parametre – identifikátor skupiny a názov skupiny. Doxygen komentár definujúci skupinu môže obsahovať krátky aj podrobný popis. Skupiny sa zaradia pod záložku „Moduly“.

Dokumentovaný prvok zaradíme do skupiny príkazom @ingroup <groupid>. kde groupid je identifikátor skupiny. Každý prvok môže byť v jednej alebo viacerých skupinách (alebo žiadnej). Pokiaľ príkaz @ingroup použijeme v definícii skupiny, vytvoríme hierarchickú štruktúru skupín.

Pokiaľ chceme viac prvkov zaradiť do skupiny naraz, môžeme ich obkolesiť špeciálnymi zátvorkami: @{ a @}. Všetky prvky obkolesené týmito zátvorkami budú zaradené do skupiny identifikovanej posledným príkazom @ingroup. Táto možnosť je obzvlášť užitočná pri premenných a makrách. Makrá a premenné v súbore lang.h sú zaradené do skupín týmto spôsobom.

Najlepšie príklad:

/**
* @defgroup top Skupina
* @brief Hlavná skupina
*/

/**
* @ingroup top
* @defgroup sub Podskupina
*
* @brief Podskupina
*/

/**
* @ingroup sub
* @brief Funkcia v podskupine
*/
void fcia(void);
/**
* @ingroup sub
* @brief Skupina premenných v podskupine
* @{
*/
int i;
int j;
/** @} */

Otázkou je, kam vložiť definície skupín. V zásade ich môžeme vložiť do ktoréhokoľvek zdrojového súboru. Toto riešenie nie je najlepšie – údržba dokumentácie sa zneprehľadní.

Lepším riešením je vytvoriť nezávislý súbor, ktorý bude obsahovať definície a štruktúru skupín. Nazvime ho napríklad groups.dox. Aby doxygen vedel spracovať súbory s koncovkou dox, musíme zmeniť konfiguračný parameter:

FILE_PATTERNS = *.c *.h *.dox

Súbor groups.dox nájdete v priloženom súbore v príklade doxy4. Výsledná dokumentácia so skupinami vyzerá takto: HTML a PDF

Vylepšenia vzhľadu

Vytvorená dokumentácia má drobné chybičky:

  • záložku Moduly, ktorej by viac svedčil názov Kategórie
  • rozmiestnenie informácií na stránkach kategórií, kde by podrobný popis mohol predchádzať zoznamu prvkov.
  • zbytočné diagramy na stránkach kategóríí

Príkazom

doxygen -l

sa vytvorí súbor popisujúci rozloženie informácií DoxygenLayout.xml, ktorý neskôr mierne upravíme. Aby Doxygen používal tento súbor, musíme nastaviť konfiguračný parameter:

LAYOUT_FILE = DoxygenLayout.xml

Najprv zmeníme názov záložky. V bloku <navindex> zmeníme názov kategórie nasledovne:

<navindex>
.
.
.
<tab type="modules" visible="yes" title="Kategórie"/>

Ďalej presunieme riadok detaileddescription (nachádzajúci sa medzi </memberdecl> a <memberdef>) za groupgraph a samotný riadok groupgraph zapoznámkujeme. Na záver premenujeme vnorené kategórie:

<group>
<briefdescription visible="yes"/>
<!--    <groupgraph visible="$GROUP_GRAPHS"/> -->
<detaileddescription title=""/>
.
.
.
<memberdecl>
.
.
.
<nestedgroups visible="yes" title="Podkategórie"/>

Modifikovanú dokumentáciu nájdete tu: HTML. Je to lepšie, aj keď nie dokonalé.

Problém je, že niektoré nastavenia – ako napríklad premenovanie modulov na kategórie – fungujú iba pre HTML výstup. Názvy kapitol pre PDF dokumentáciu sú pevne zakódované. Snáď sa to zmení v ďalších verziách.

Dodatočná dokumentácia

Našej dokumentácii chýba posledná vec, a to rôzne popisy, návody a podobne. Doxygen nazýva túto dokumentáciu stránkami (pages).

Stránky nie sú generované automaticky. Stránky musíme napísať od A do Z. Popis stránky je komentárový blok, obsahujúci kľúčové slovo @page <ident> <nadpis>. ident je jednoznačný identifikátor stránky, nasledovaný voliteľným nadpisom. Tento komentárový blok môže obsahovať ako krátky tak aj detailný popis.

Opäť musíme rozhodnúť, kam tieto informácie umiestniť. Podobne ako u definície skupín môžeme popisy stránok umiestniť kamkoľvek. Ale najlepším riešením je umiestniť ich do samostatných súborov. Keďže sme si už zadefinovali, aby Doxygen spracovával súbory s koncovkou dox, nazvime tento súbor pages.dox.

Stránky môžu byť hierarchicky usporiadané. Použitím príkazu @subpage <ident> zaradíme do stránky odkaz na ďalšiu stránku a táto stránka sa automaticky stane podstránkou aktuálnej stránky.

Špeciálnu úlohu hrá hlavná stránka. Táto stránka je označená príkazom @mainpage (namiesto obvyklého @page). Hlavná stránka je prvou stránkou vo vytvorenej dokumentácii.

Ale dosť slov, najlepšie si to ukážeme na príklade:

/**
@mainpage

Hlavná stránka

- @subpage prva
- @subpage druha

Toto je hlavná stránka
*/

/**
@page prva Prvá stránka

@brief Prvá stránka

Toto je prvá stránka
*/

/**
@page druha Druhá stránka

@brief Druhá stránka

Toto je druhá stránka
*/

A takto vyzerá konečná verzia dokumentácie: HTML a PDF

Alternatívne formáty komentárov

Keďže Doxygen sa inšpiroval viacerými dokumentačnými nástrojmi, akceptuje viac štýlov komentárov.

V našom článku sme používali takzvaný Javadoc formát:

/**
* @brief Krátky komentár
*
* Podrobný komentár
*/

Podobný, s drobnou zmenou, je Qt formát:

/*!
* @brief Krátky komentár
*
* Podrobný komentár
*/

Pre C++ (alebo ak náš kompilátor akceptuje C++ komentáre) môžme použiť nasledujúci štýl (Javadoc formát):

///
/// @brief Krátky komentár
///
/// Podrobný komentár
///

Alebo Qt formát:

//!
//! @brief Krátky komentár
//!
//! Podrobný komentár
//!

Tento typ komentáru vyžaduje, aby sa vyskytoval aspoň na dvoch po sebe nasledujúcich riadkoch. Všetky po sebe idúce komentáre tvoria jeden komentárový blok. Pokiaľ potrebujeme bloky oddeliť, musia byť oddelené aspoň jedným riadkom bez Doxygen komentára tohoto typu. Pokiaľ je takýto komentár osamotený, tak je automaticky považovaný za za krátky komentár, aj keď neuvedieme kľúčové slovo @brief. Takže predošlý príklad môže vyzerať takto:

/// Krátky komentár

/// Podrobný komentár
///

Samozrejme, môžeme ho skombinovať s klasickým C komentárom:

/// Krátky komentár
/**
*  Podrobný komentár
*/

Je úplne jedno, pre ktorý štýl komentárov sa rozhodnete. Iba odporúčam používať jednotný štýl v celom projekte.

Kam ísť ďalej

Úvod máme za sebou. Ak chcete od Doxygen získať viac, odporúčam preštudovať komentovaný konfiguračný súbor – je v ňom obrovské množstvo nastavení, ktoré môžu zmeniť spôsob vytvárania dokumentácie. A snáď netreba zdôrazňovať, že preštudovanie príručky k Doxygen by malo byť samozrejmosťou.

Všetky príklady si môžete stiahnuť tu.

Print Friendly, PDF & Email
17 291 zobrazení