para fuente formato documentar como codigo c++ c documentation doxygen

c++ - fuente - ¿Los mejores consejos para documentar código usando doxygen?



documentar codigo android (20)

Mi equipo está empezando a documentar nuestro código C utilizando doxygen, prestando especial atención a nuestros encabezados API públicos. Parece que hay mucha flexibilidad y diferentes comandos especiales en doxygen, lo cual es genial, pero no está claro qué es bueno y qué es malo sin prueba y error.

¿Cuáles son tus formas favoritas de marcar tu código? ¿Qué DEBO HACER y NO HACER?
Proporcione sus mejores consejos, uno por respuesta para facilitar la votación.

Estoy buscando definir nuestro enfoque completo de la documentación de la API, incluida la provisión de una plantilla para comenzar el resto del equipo. Hasta ahora tengo algo como esto:

/** * @file example_action.h * @Author Me ([email protected]) * @date September, 2008 * @brief Brief description of file. * * Detailed description of file. */ /** * @name Example API Actions * @brief Example actions available. * @ingroup example * * This API provides certain actions as an example. * * @param [in] repeat Number of times to do nothing. * * @retval TRUE Successfully did nothing. * @retval FALSE Oops, did something. * * Example Usage: * @code * example_nada(3); // Do nothing 3 times. * @endcode */ boolean example(int repeat);


Si tiene errores en el código o encuentra errores, también puede etiquetar el código de esta manera:

/** @bug The text explaining the bug */

Cuando ejecutas doxygen, obtienes una lista de errores aparte junto a listas como Lista de tareas


Algunos comandos que uso en mi código:

  • /todo { paragraph describing what is to be done } Útil para realizar un seguimiento de todos, se creará una página en la documentación final que contiene su lista de tareas pendientes.
  • /c <word> Muestra el argumento usando una fuente de máquina de escribir. Use esto para referirse a una palabra de código. Lo usaría antes de "VERDADERO" y "FALSO" en su ejemplo.
  • /a , /warning , /see : vea http://www.stack.nl/~dimitri/doxygen/commands.html#cmdc para la descripción

Para proyectos complejos, puede ser útil tener un archivo separado para la gestión de módulos, que controla los grupos y subgrupos. Toda la jerarquía puede estar en un solo lugar y luego cada archivo simplemente puede rellenar los grupos secundarios. p.ej:

/** * @defgroup example Top Level Example Group * @brief The Example module. * * @{ */ /** * @defgroup example_child1 First Child of Example * @brief 1st of 2 example children. */ /** * @defgroup example_child2 Second Child of Example * @brief 2nd of 2 example children. */ // @}

Simplemente incluir la definición de un grupo dentro del {} de otro grupo lo convierte en un hijo de ese grupo. Luego, en el código y en los archivos de cabecera, las funciones solo pueden etiquetarse como parte del grupo en el que se encuentran y todo solo funciona en la documentación final. Hace que la refacturación de la documentación para que coincida con el código de refactorización sea mucho más fácil.


Si está seguro de que su equipo seguirá una plantilla tan pesada, bien, úselo como se muestra.

De lo contrario, parece JavaDoc. Una de las cosas buenas de Doxygen es cuán bueno es el trabajo que hace sin tener que usar un marcado tan fuerte. No necesita utilizar @name y con la configuración JAVADOC_AUTOBRIEF puede omitir @brief; solo asegúrese de que la primera línea del comentario sea una breve descripción razonable.

Prefiero los nombres descriptivos sobre la aplicación de la documentación y alentar a las personas a agregar comentarios solo cuando agreguen un valor significativo. De esta manera, los comentarios valiosos no son ahogados por todo el ruido.


Si tienes un proyecto realmente grande, lo suficientemente grande como para que Doxygen se ejecute en una hora, puedes dividirlo en varios módulos que Doxygen luego unirá utilizando archivos de etiquetas .

Por ejemplo, si tiene una gran solución de MSVC con veinte proyectos en ella, puede hacer que el directorio sea su propia ejecución de Doxygen, y luego usar archivos de etiquetas para unir la salida de la misma manera que un enlazador pega .libs para hacer un ejecutable .

Incluso puede tomar la metáfora de enlace más literalmente y hacer que cada archivo de configuración de Doxy corresponda a un archivo .vcproj, de modo que cada proyecto (por ejemplo, .lib o .dll) obtenga su propia salida Doxy.


Como me encuentro editando código en pantallas de mayor resolución, he pasado de usar la barra diagonal inversa al prefijo @ en los comandos de Doxygen. No tan ruidosa barra invertida se ha encontrado ahora demasiado malditamente difícil de distinguir los comandos de Doxygen.


Utilizo un enlace post-commit de subversión para extraer los directorios que han cambiado, los escribo en un archivo y luego todas las noches vuelvo a generar automáticamente el html doxygen en nuestro servidor web para que siempre tengamos docco actualizados.

Todos los proyectos que deseo documentados tienen un pequeño archivo project.doxy que contiene la configuración por proyecto y una inclusión en la configuración principal de doxygen, por ejemplo:

PROJECT_NAME = "AlertServer" PROJECT_NUMBER = 8.1.2 INPUT = "C:/Dev/src/8.1.2/Common/AlertServer" HTML_OUTPUT = "AlertServer" @INCLUDE = "c:/dev/CommonConfig.doxy"

Para el servidor SVN de Windows, use el gancho:

@echo off for /F "eol=¬ delims=¬" %%A in (''svnlook dirs-changed %1 -r %2'') do echo %%A >> c:/svn_exports/export.txt

y luego corre esta noche:

@echo off rem --------------- rem remove duplicates. type nul> %TEMP%./TEMP.txt for /F "eol=¬ delims=¬" %%a in (c:/svn_exports/export.txt) do ( findstr /L /C:"%%a" < %TEMP%./TEMP.txt > nul if errorlevel=1 echo %%a>> %TEMP%./TEMP.txt ) copy /y %TEMP%./TEMP.txt export_uniq.cmd >nul if exist %TEMP%./TEMP.txt del %TEMP%./TEMP.txt rem --------------- rem fetch all the recently changed directories into the svn_exports directory for /F "eol=¬ delims=¬" %%A in (c:/svn_exports/export_uniq.cmd) do ( svn export "file:///d:/repos/MyRepo/%%A" "c:/svn_exports/%%A" --force ) rem --------------- rem search through all dirs for any config files, if found run doxygen for /R c:/svn_exports %%i in (*.doxy) do c:/tools/doxygen/bin/doxygen.exe "%i" rem --------------- rem now remove the directories to be generated. del /F c:/svn_exports

esto elimina las entradas duplicadas, encuentra todos los proyectos que tienen un archivo de proyecto .doxy y ejecuta doxygen en ellos. Voila: código completamente documentado y siempre actualizado en un servidor web.


Una buena "mejor práctica" (aunque no siempre alcanzable) es proporcionar ejemplos breves y prácticos para cada API, y llevarlos a la ayuda utilizando / includelineno (o / include para ningún número de línea). Estas pueden ser pruebas unitarias, si están escritas para que los usuarios puedan entenderlas (es decir, que no estén conectadas a un arnés de prueba más grande). Como un buen efecto secundario, los cambios en la API romperán las muestras, por lo que deben mantenerse actualizados.

Puede describir una API en palabras, pero no hay nada como ver el código real para entender cómo usarlo.


Agrupe las funciones y campos de sus miembros si tiene sentido hacerlo con / defgroup. Esto es muy útil, incluso si no dices mucho.


Siempre incluya una descripción con sus clases. Trate de decir cómo se usa una clase, o por qué se usa, no solo qué es (lo que generalmente solo refleja el nombre de todos modos).


Utiliza muchos y muchos enlaces. Esto se puede hacer usando también los enlaces (/ see o @see si lo prefiere), y asegurándose de usar referencias a otros nombres de clase en la documentación por su nombre de clase correcto. Por ejemplo, si se refiere a la clase FUZZYObject como un "objeto", escriba inmediatamente después el nombre de la clase (por ejemplo, "frazzle the objects (FUZZYObject)").


Cree y publique su documentación automáticamente. Como parte de la construcción automática de la documentación, preste atención a las advertencias, es muy fácil escribir comentarios doxygen de estructura incorrecta.


Use /example todo lo que pueda. Vincula automáticamente elementos API a código de ejemplo.


No te molestes con @author o @date (@date se mencionó en otra publicación). Ambos son manejados por un sistema de control de revisiones.


Para proyectos más grandes que requieren 5 + min para generar, me pareció útil poder generar doxygen para un solo archivo y verlo en un navegador web.

Si bien las referencias a cualquier cosa que esté fuera del archivo no se resolverán, aún puede ser útil ver que el formato básico es correcto.

Esta secuencia de comandos toma un único archivo y la configuración de doxy de los proyectos y ejecuta doxygen. Lo configuré para ejecutarlo desde mi IDE.

#!/usr/bin/env python3 """ This script takes 2-3 args: [--browse] <Doxyfile> <sourcefile> --browse will open the resulting docs in a web browser. """ import sys import os import subprocess import tempfile doxyfile, sourcefile = sys.argv[-2:] tempfile = tempfile.NamedTemporaryFile(mode=''w+b'') doxyfile_tmp = tempfile.name tempfile.write(open(doxyfile, "r+b").read()) tempfile.write(b''/n/n'') tempfile.write(b''INPUT='' + os.fsencode(sourcefile) + b''/n'') tempfile.flush() subprocess.call(("doxygen", doxyfile_tmp)) del tempfile # Maybe handy, but also annoying as default. if "--browse" in sys.argv: import webbrowser webbrowser.open("html/files.html")


Si encuentra que la directiva de configuración INLINE_SOURCES pone demasiados códigos en la documentación, puede citar manualmente partes específicas del código con el comando / snippet .

/** * Requirment XYZ is implemented by the following code. * * /snippet file.c CODE_LABEL */ int D() { //[CODE_LABEL] if( A ) { B= C(); } //[CODE_LABEL] }

Nota: snippet obtiene sus archivos de EXAMPLE_PATH , no donde está la ruta de origen. Deberá colocar la misma lista de archivos y rutas desde la directiva INPUT en la directiva EXAMPLE_PATH .


Si le preocupa que algunos miembros del equipo eviten la documentación o si solo desea un conjunto mínimo de documentación que funcione, puede habilitarlos en su configuración doxygen.

WARNINGS = YES WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES

Como parte de su proceso de creación de doxygen, guarde las advertencias en un archivo y trate de obtener y mantener el conteo de advertencia lo más bajo posible (0 si es razonable). Si haces esto, cada miembro público y protegido de la clase necesitará al menos un @brief, @param para cada argumento de función y un @return. Esto es lo suficientemente bueno para describir la mayoría de las API y no demasiado para gravar otras bases de código de vida.

Por supuesto, debe alentar a las personas a documentar todo lo que consideren necesario caso por caso, siempre que cumplan con los estándares mínimos del proyecto. No establezca el mínimo demasiado alto, sin embargo, puede que al final no obtenga documentación útil.

Por ejemplo, en nuestro proyecto, todo lo que otro codificador pueda tocar debería documentarse. Habilitar las advertencias permite ver qué tan cerca estamos de ese objetivo. También tratamos de utilizar @internal para describir qué / por qué hacemos lo que hacemos con algunos de nuestros miembros privados.


Escriba una página de inicio descriptiva usando @mainpage (en un archivo de encabezado separado solo para este propósito). Considere, como se muestra en mi ejemplo, convertirlo en una guía para sus principales clases / funciones y módulos.

Otra muestra

Mientras estaba volviendo en línea el contenido de doxígeno de oofile principal anteriormente vinculado, aquí hay un ejemplo de algunos trabajos actuales del cliente que usan formato Markdown. Usando Markdown puede referirse a una página principal en el marcado (en la configuración de Doxygen) que es ideal para el archivo típico readme.md incluido en proyectos de código abierto.

Lingopal ======== Developer Documentation started when Andy Dent took over support in May 2014. There are a number of pages in Markdown format which explain key aspects: - @ref doc/LingopalBuilding.md - @ref doc/LingopalSigning.md - @ref doc/LingopalDatabases.md - @ref doc/LingopalExternals.md See the <a href="pages.html">Related Pages list for more.</a> ------------- _Note_ These pages, whilst readable by themselves, are designed to be run through the [Doxygen](http://www.doxygen.com) code documentation engine which builds an entire local cross-referenced set of docs. It uses a minor [extension of Markdown formatting.](http://www.stack.nl/~dimitri/doxygen/manual/markdown.html) The settings to generate the documentation are `Lingopal.doxy` and `LingopalDocOnly.doxy`. The latter is used for quick re-generation of just these additional pages.


No necesita ni debe escribir el nombre del archivo en la directiva @file, doxygen lee el nombre del archivo automáticamente. El problema al escribir el nombre del archivo es que cuando cambie el nombre del archivo también tendrá que cambiar la directiva @file .

Proporcionar información @author y @date también es inútil la mayor parte del tiempo, ya que el sistema de control de origen lo hace mucho mejor que alguien editando los archivos manualmente.

Tampoco tiene que escribir @brief si usa la siguiente sintaxis de Doxygen y habilita JAVADOC_AUTOBRIEF en la configuración de doxygen:

/*! Short Description on the first line Detailed description... ... */ void foo(void) {}

La directiva @name para funciones también es 100% redundante la mayor parte del tiempo y completamente inútil. Solo genera errores cuando alguien modifica el nombre de la función y no el doxygen @name .


Use Grupos para organizar su código en módulos.

Recuerde que puede colocar casi todo en múltiples grupos para que se puedan usar para proporcionar un etiquetado semántico como las etiquetas en Desbordamiento de pila. Por ejemplo, puede etiquetar las cosas como específicas para una plataforma determinada.

También puede usar grupos para hacer coincidir una jerarquía de carpetas dentro de un IDE , como se muestra en mi salida de muestra RB2Doxy.

Los grupos funcionan bien cuando están anidados: tengo un gran ejemplo para la fuente OOFILE .