Add documentation for using Doxygen
authorTeemu Murtola <teemu.murtola@gmail.com>
Sun, 9 Feb 2014 12:15:32 +0000 (14:15 +0200)
committerGerrit Code Review <gerrit@gerrit.gromacs.org>
Thu, 20 Feb 2014 05:11:29 +0000 (06:11 +0100)
- Add a page that provides guidelines and examples for using Doxygen.
  Hopefully, this would make simple examples easier to find, and help
  people write correct comments from the beginning.
- Remove unnecessary \addtopublicapi and \addtolibraryapi.

Once the contents are there, it is easy to enhance the documentation by
adding content whenever noticing things that are tricky.

Change-Id: I319e30452004998df73c249f46570cb2254daa87

13 files changed:
.gitattributes
doxygen/Doxyfile-common.cmakein
doxygen/Doxyfile-full.cmakein
doxygen/Doxyfile-lib.cmakein
doxygen/Doxyfile-user.cmakein
doxygen/doxygen.md [new file with mode: 0644]
doxygen/examples/doxygen-example-issues.cpp [new file with mode: 0644]
doxygen/examples/doxygen-example-module.cpp [new file with mode: 0644]
doxygen/examples/doxygen-example-scoping.cpp [new file with mode: 0644]
doxygen/examples/doxygen-example.c [new file with mode: 0644]
doxygen/examples/doxygen-example.cpp [new file with mode: 0644]
doxygen/mainpage.md
src/gromacs/utility/gmxassert.h

index 1e099235375a89d81893605945efaa2def6ad0a2..1aa10d59e37cac3f28bc12b1ec2bdd0b0824c5ef 100644 (file)
@@ -27,6 +27,8 @@ cmake/*.c                               !filter
 cmake/*.c.cmakein                       !filter
 doxygen/Doxyfile-*.cmakein              !filter
 doxygen/*.cpp                           !filter
 cmake/*.c.cmakein                       !filter
 doxygen/Doxyfile-*.cmakein              !filter
 doxygen/*.cpp                           !filter
+doxygen/examples/*.cpp                  filter=uncrustify_only
+doxygen/examples/*.c                    filter=uncrustify_only
 manual/UseLATEX.cmake                   !filter
 scripts/GMXRC.*                         !filter
 scripts/make_gromos_rtp.py              !filter
 manual/UseLATEX.cmake                   !filter
 scripts/GMXRC.*                         !filter
 scripts/make_gromos_rtp.py              !filter
index 57943473501f0a164a1acee34bd8e7396900a5ca..44a3a185dadd401dca769940cc50af4a45fa6487 100644 (file)
@@ -6,7 +6,8 @@ INPUT                  = @CMAKE_CURRENT_SOURCE_DIR@ \
                          @CMAKE_SOURCE_DIR@/share/template
 EXAMPLE_PATH           = @CMAKE_SOURCE_DIR@
 RECURSIVE              = YES
                          @CMAKE_SOURCE_DIR@/share/template
 EXAMPLE_PATH           = @CMAKE_SOURCE_DIR@
 RECURSIVE              = YES
-EXCLUDE                = @CMAKE_SOURCE_DIR@/src/contrib \
+EXCLUDE                = @CMAKE_SOURCE_DIR@/doxygen/examples \
+                         @CMAKE_SOURCE_DIR@/src/contrib \
                          @CMAKE_SOURCE_DIR@/src/external \
                          @CMAKE_SOURCE_DIR@/src/gromacs/legacyheaders/thread_mpi/atomic \
                          @CMAKE_SOURCE_DIR@/src/gromacs/selection/parser.cpp \
                          @CMAKE_SOURCE_DIR@/src/external \
                          @CMAKE_SOURCE_DIR@/src/gromacs/legacyheaders/thread_mpi/atomic \
                          @CMAKE_SOURCE_DIR@/src/gromacs/selection/parser.cpp \
@@ -43,6 +44,7 @@ GENERATE_LATEX         = NO
 # Setting this to NO has a side effect to hide undocumented headers from the
 # file list, which makes it generally look nicer.
 VERBATIM_HEADERS       = NO
 # Setting this to NO has a side effect to hide undocumented headers from the
 # file list, which makes it generally look nicer.
 VERBATIM_HEADERS       = NO
+STRIP_CODE_COMMENTS    = NO
 
 EXTRACT_LOCAL_CLASSES  = NO
 
 
 EXTRACT_LOCAL_CLASSES  = NO
 
index 8cf48a79a24c9476b3c5dc43b162f017ef825176..269b78783896921f6d42da931581836b5cdec8dd 100644 (file)
@@ -17,7 +17,5 @@ INLINE_INHERITED_MEMB  = NO  # Makes it easier to go through all documentation
 
 ALIASES               += inpublicapi="\ingroup group_publicapi"
 ALIASES               += inlibraryapi="\ingroup group_libraryapi"
 
 ALIASES               += inpublicapi="\ingroup group_publicapi"
 ALIASES               += inlibraryapi="\ingroup group_libraryapi"
-ALIASES               += addtopublicapi="\addtogroup group_publicapi"
-ALIASES               += addtolibraryapi="\addtogroup group_libraryapi"
 ALIASES               += libinternal=
 ALIASES               += endlibinternal=
 ALIASES               += libinternal=
 ALIASES               += endlibinternal=
index 3924070d579ea605c9626c476124a76574d40cea..497e358c1065df41bc372c52c06555893eb03d09 100644 (file)
@@ -8,7 +8,5 @@ HTML_OUTPUT            = html-lib
 
 ALIASES               += inpublicapi="\ingroup group_publicapi"
 ALIASES               += inlibraryapi="\ingroup group_libraryapi"
 
 ALIASES               += inpublicapi="\ingroup group_publicapi"
 ALIASES               += inlibraryapi="\ingroup group_libraryapi"
-ALIASES               += addtopublicapi="\addtogroup group_publicapi"
-ALIASES               += addtolibraryapi="\addtogroup group_libraryapi"
 ALIASES               += libinternal=
 ALIASES               += endlibinternal=
 ALIASES               += libinternal=
 ALIASES               += endlibinternal=
index 4e6750292944519619717e511ae5427154b1dece..da37fa9c4e11d83f8180614d8af735e06e7c7d4b 100644 (file)
@@ -4,6 +4,7 @@
 # exclude them from the generated file list
 EXCLUDE               += @CMAKE_SOURCE_DIR@/src/programs
 EXCLUDE               += @CMAKE_SOURCE_DIR@/src/testutils
 # exclude them from the generated file list
 EXCLUDE               += @CMAKE_SOURCE_DIR@/src/programs
 EXCLUDE               += @CMAKE_SOURCE_DIR@/src/testutils
+EXCLUDE               += @CMAKE_SOURCE_DIR@/doxygen/doxygen.md
 EXCLUDE               += @CMAKE_SOURCE_DIR@/doxygen/unittesting.md
 EXCLUDE               += @CMAKE_SOURCE_DIR@/doxygen/wrapperbinary.md
 
 EXCLUDE               += @CMAKE_SOURCE_DIR@/doxygen/unittesting.md
 EXCLUDE               += @CMAKE_SOURCE_DIR@/doxygen/wrapperbinary.md
 
@@ -15,7 +16,5 @@ HTML_OUTPUT            = html-user
 
 ALIASES               += inpublicapi="\ingroup group_publicapi"
 ALIASES               += inlibraryapi="\ingroup group_libraryapi"
 
 ALIASES               += inpublicapi="\ingroup group_publicapi"
 ALIASES               += inlibraryapi="\ingroup group_libraryapi"
-ALIASES               += addtopublicapi="\addtogroup group_publicapi"
-ALIASES               += addtolibraryapi="\addtogroup group_libraryapi"
 ALIASES               += libinternal="\internal"
 ALIASES               += endlibinternal="\endinternal"
 ALIASES               += libinternal="\internal"
 ALIASES               += endlibinternal="\endinternal"
diff --git a/doxygen/doxygen.md b/doxygen/doxygen.md
new file mode 100644 (file)
index 0000000..0bdea5e
--- /dev/null
@@ -0,0 +1,485 @@
+Using Doxygen {#page_doxygen}
+=============
+
+This page documents how Doxygen is set up in the \Gromacs source tree,
+as well as guidelines for adding new Doxygen comments.  Examples are included,
+as well as tips and tricks for avoiding Doxygen warnings.  The guidelines focus
+on C++ code and other new code that follows the new module layout.
+Parts of the guidelines are still applicable to documenting older code (e.g.,
+within `gmxlib/` or `mdlib/`), in particular the guidelines about formatting
+the Doxygen comments and the use of \c \\internal.
+\ref page_codelayout documents the overall structure of the documentation.
+
+To get started quickly, you only need to read the first two sections to
+understand the overall structure of the documentation, and take a look at the
+examples at the end.  The remaining sections provide the details for
+understanding why the examples are the way they are, and for more complex
+situations.  They are meant more as a reference to look up solutions for
+particular problems, rather than single-time reading.  To understand or find
+individual Doxygen commands, you should first look at Doxygen documentation
+(http://www.stack.nl/~dimitri/doxygen/manual/index.html).
+
+
+Documentation flavors
+=====================
+The \Gromacs source tree is set up to produce three different levels of Doxygen
+documentation:
+
+1. Public API documentation (suffix `-user`), which documents functions and
+   classes exported from the library and intended for use outside the \Gromacs
+   library.
+2. Library API documentation (suffix `-lib`), which additionally includes
+   functions and classes that are designed to be used from other parts of
+   \Gromacs, as well as some guidelines that are mostly of interest to
+   developers.
+3. Full documentation (suffix `-full`), which includes (nearly) all (documented)
+   functions and classes in the source tree.
+
+Each subsequent level of documentation includes all the documentation from the
+levels above it.  The suffixes above refer to the suffixes of Doxygen input and
+output files, as well as the name of the output directory.  When all the
+flavors have been built, the front pages of the documentation contain links to
+the other flavors, and explain the differences in more detail.
+
+As a general guideline, the public API documentation should be kept free of
+anything that a user linking against an unmodified \Gromacs does not see.
+In other words, the public API documentation should mainly document the
+contents of installed headers, and provide the necessary overview of using
+those.  Also, verbosity requirements for the public API documentation are
+higher: ideally, readers of the documentation could immediately start using the
+API based on the documentation, without any need to look at the implementation.
+
+Similarly, the library API documentation should not contain things that other
+modules in \Gromacs can or should never call.  In particular, anything declared
+locally in source files should be only available in the full documentation.
+Also, if something is documented, and is not identified to be in the library
+API, then it should not be necessary to call that function from outside its
+module.
+
+
+Building the documentation
+==========================
+
+If you simply want to see up-to-date documentation, you can go to
+http://jenkins.gromacs.org/job/Doxygen_Nightly_master/javadoc/html-lib/index.xhtml
+to see the documentation for the current development version.
+Jenkins also runs Doxygen for all changes pushed to Gerrit for master, and the
+resulting documentation can be viewed from the link posted by Jenkins.  The
+Doxygen build is marked as unstable if it introduces any Doxygen warnings.
+
+You may need to build the documentation locally if you want to check the
+results after adding/modifying a significant amount of comments.  This is
+recommended in particular if you do not have much experience with Doxygen.
+It is a good idea to build with all the different settings to see that the
+result is what you want, and that you do not produce any warnings.
+For local work, it is generally a good idea to set `GMX_COMPACT_DOXYGEN=ON`
+CMake option, which removes some large generated graphs from the documentation
+and speeds up the process significantly.
+
+All files related to Doxygen reside in the `doxygen/` subdirectory in the source
+and build trees.  In a freshly checked out source tree, this directory contains
+various `Doxyfile-*.cmakein` files.  When you run CMake, corresponding files
+`Doxyfile-user`, `Doxyfile-lib`, and `Doxyfile-full` are generated at the
+corresponding location in the build tree.  There is also a
+`Doxyfile-common.cmakein`, which is used to produce `Doxyfile-common`.
+This file contains settings that are shared between all the input files.
+`Doxyfile-compact` provides the extra settings for `GMX_COMPACT_DOXYGEN=ON`.
+
+You can run Doxygen directly with one of the generated files (all output will
+be produced under the current working directory), or build one of the
+`doc-user`, `doc-lib`, and `doc-full` targets.  The targets run Doxygen in a
+quieter mode and only show the warnings if there were any, and put the output
+under `doxygen/` in the build tree.  The `doc-all` target builds all three
+targets with less typing.
+
+The generated documentation is put under `html-user/`, `html-lib/`, and/or
+`html-full/` in the output directory.  Open `index.xhtml` file from one of
+these subdirectories to start browsing (for \Gromacs developers, the
+`html-lib/` is a reasonable starting point).  Log files with all Doxygen
+warnings are also produced as `doxygen-*.log`, so you can inspect them after
+the run.
+
+You will need Doxygen 1.8.5 to build the current documentation.  Other versions
+may work, but likely also produce warnings.  Additionally,
+[graphviz](http://www.graphviz.org) and
+[mscgen](http://www.mcternan.me.uk/mscgen/) are required for some graphs in
+the documentation, and `latex` for formulas.  Working versions are likely
+available through most package managers.  It is possible to build the
+documentation without these tools, but you will see some errors and the related
+figures will be missing from the documentation.
+
+
+General guidelines for Doxygen markup
+=====================================
+
+Doxygen provides quite a few different alternative styles for documenting the
+source code.  There are subtleties in how Doxygen treats the different types of
+comments, and this also depends somewhat on the Doxygen configuration.  It is
+possible to change the meaning of a comment by just changing the style of
+comment it is enclosed in.  To avoid such issues, and to avoid needing to
+manage all the alternatives, a single style throughout the source tree is
+preferable.  When it comes to treatment of styles, \Gromacs uses the default
+Doxygen configuration with one exception: `JAVADOC_AUTOBRIEF` is set ON to
+allow more convenient one-line brief descriptions in C code.
+
+Majority of existing comments in \Gromacs uses Qt-style comments (`/*!` and
+`//!` instead of `/*``*` and `///`, \c \\brief instead of \c \@brief etc.),
+so these should be used also for new documentation.  There is a single
+exception for brief comments in C code; see below.
+
+Similarly, existing comments use `/*!` for multiline comments in both C and
+C++ code, instead of using multiple `//!` lines for C++.  The rationale is that
+since the code will be a mixture of both languages for a long time, it is more
+uniform to use similar style in both.  Also, since files will likely transition
+from C to C++ gradually, rewriting the comments because of different style
+issues should not generally be necessary.  Finally, multi-line `//!` comments
+can work differently depending on Doxygen configuration, so it is better to
+avoid that ambiguity.
+
+When adding comments, ensure that a short brief description is always produced.
+This is used in various listings, and should briefly explain the purpose of the
+method without unnecessarily expanding those lists.
+The basic guideline is to start all comment blocks with \c \\brief (possibly
+after some other Doxygen commands).
+If you want to avoid the \c \\brief for one-liners, you can use `//!`, but the
+description must fit on a single line; otherwise, it is not interpreted as a
+brief comment.  Note in particular that a simple `/*!` without a \c \\brief
+does not produce a brief description.
+Also note that \c \\brief marks the whole following paragraph as a brief
+description, so you should insert an empty line after the intended brief
+description.
+
+In C code, `//` comments must be avoided because some compilers do not like
+them.  If you want to avoid the \c \\brief for one-liners in C code, use
+`/*``*` instead of `//!`.  If you do this, the brief description should not
+contain unescaped periods except at the end.  Because of this, you should
+prefer `//!` in C++ code.
+
+Put the documentation comments in the header file that contains the
+declaration, if such a header exists.
+Implementation-specific comments that do not influence how a method
+is used can go into the source file, just before the method definition, with an
+\c \\internal tag in the beginning of the comment block.  Doxygen-style comments
+within functions are not generally usable.
+
+At times, you may need to exclude some part of a header or a source file such
+that Doxygen does not see it at all.  In general, you should try to avoid this,
+but it may be necessary to remove some functions that you do not want to appear
+in the public API documentation, and which would generate warnings if left
+undocumented, or to avoid Doxygen warnings from code it does not understand.
+Prefer \c \\cond and \c \\endcond to do this.  If \c \\cond does not work for
+you, you can also use \c \#ifndef `DOXYGEN`.  If you exclude a class method in
+a header, you also need to exclude it in the source code to avoid warnings.
+
+
+\Gromacs specifics
+=================
+
+The general guidelines on the style of Doxygen comments were given above.
+This section introduces \Gromacs specific constructs currently used in Doxygen
+documentation, as well as how \Gromacs uses Doxygen groups to organize the
+documentation.
+
+Controlling documentation visibility
+------------------------------------
+
+To control in which level of documentation a certain function appears, three
+different mechanisms are used:
+* Global Doxygen configuration.  This is mainly used to include
+  declarations local to source files only in the full documentation.
+  You can find the details from the `Doxyfile-*.cmakein` files, and some of
+  them are also mentioned below on individual code constructs.
+* The standard Doxygen commands \c \\internal and \c \\endinternal mark the
+  documentation to be only extracted into the full documentation
+  (`INTERNAL_DOCS` is `ON` only for the full documentation).
+  In addition, \Gromacs specific custom Doxygen commands \c \\libinternal and
+  \c \\endlibinternal are provided, which only exclude the documentation from
+  the public API documentation.  These are implemented by expanding the
+  commands to either \c \\internal or to a no-op, depending on the
+  documentation level.
+* Doxygen commands \c \\if and \c \\cond can be used with section names
+  `libapi` and `internal` to only include the documentation in library API and
+  the full documentation, respectively.  `libapi` is also defined in the full
+  documentation.  These are declared using `ENABLED_SECTIONS` in the Doxygen
+  configuration files.
+
+Examples of locations where it is necessary to use these explicit commands are
+given below in the sections on individual code constructs.
+
+Modules as Doxygen groups
+-------------------------
+
+As described in \ref page_codelayout, each subdirectory under `src/gromacs/`
+represents a _module_, i.e., a somewhat coherent collection of routines.
+Doxygen cannot automatically generate a list of routines in a module; it only
+extracts various alphabetical indexes that contain more or less all documented
+functions and classes.  To help reading the documentation, the routines for a
+module should be visible in one place.
+
+\Gromacs uses Doxygen groups to achieve this: for each documented module, there
+is a \c \\defgroup definition for the module, and all the relevant classes and
+functions need to be manually added to this group using \c \\ingroup and
+\c \\addtogroup.
+The group page also provides a natural place for overview documentation about
+the module, and can be navigated to directly from the "Modules" tab in the
+generated documentation.
+
+Public API and library API groups
+---------------------------------
+
+In addition to the module groups, two fixed groups are provided:
+`group_publicapi` and `group_libraryapi`.  Classes and files can be added to
+these groups using \Gromacs specific custom \c \\inpublicapi and
+\c \\inlibraryapi commands.  The generated group documentation pages are not
+very useful, but annotated classes and files show the API definition under the
+name, making this information more easily accessible.  These commands in
+file-level comments are also used for some automatic intermodule dependency
+validation (see below).
+
+Note that functions, enumerations, and other entities that do not have a
+separate page in the generated documentation can only belong to one group;
+in such a case, the module group is preferred over the API group.
+
+Automatic dependency checking
+-----------------------------
+
+The build system provides three targets, `depcheck`, `doccheck`, and
+`depgraphs`, that depend on correct usage of the above commands, in particular
+the visibility and API definitions in file-level comments.
+These checks also provide some level of enforcement for rules about
+dependencies between the modules, but currently the checks are not run
+automatically.
+
+The `depcheck` target checks for issues that either completely or subtly break
+the installed headers: an installed header including a non-installed header, or
+an installed header installing another header using a path that does not
+resolve correctly when the headers are installed.  It also checks for
+consistent usage of
+\code
+#include "..." // This should be used for Gromacs headers
+\endcode
+versus
+\code
+#include <...> // This should be used for system and external headers.
+\endcode
+
+The `doccheck` target additionally checks that if an included file is
+documented, it is not used against the API definition specified in the
+file-level comment.  For example, including a file without any API definition
+from another module produces an error.  Another example of a check is that a
+non-installed header with public documentation triggers an error.
+
+The `depgraphs` target generates include dependency graphs.  One graph is
+produced that shows all the modules under `src/gromacs/`, and their include
+dependencies.  Additionally, a file-level graph is produced for each module,
+showing the include dependencies within that module.  Currently, these are
+mostly for eye candy, but they can also be used for analyzing problematic
+dependencies to clean up the architecture.  A legend for the graphs is
+currently included as comments in `admin/includedeps.py`.  The output is put in
+`doxygen/depgraphs/`.
+
+These targets require Python 2.7; the graph generation additionally requires
+`graphviz`.
+
+
+Documenting specific code constructs
+====================================
+
+This section describes the techical details and some tips and tricks for
+documenting specific code constructs such that useful documentation is
+produced.  If you are wondering where to document a certain piece of
+information, see the documentation structure section on \ref page_codelayout.
+The focus of the documentation should be on the overview content: Doxygen pages
+and the module documentation.  An experienced developer can relatively easily
+read and understand individual functions, but the documentation should help
+in getting the big picture.
+
+Doxygen pages
+-------------
+
+The pages that are accessible through navigation from the front page are
+written using Markdown and are located under `doxygen/`.  Each page should be
+placed in the page hierarchy by making it a subpage of another page, i.e., it
+should be referenced once using \c \\subpage.  `mainpage.md` is the root of the
+hierarchy.
+
+If you need to exclude a page from the public API docs, you need to add it to
+an exclude list in `Doxyfile-user.cmakein`, and ensure that there are no
+references to the page from public API documentation.  \c \\if `libapi` can be
+used to add references in content that is otherwise public.
+Generally, the pages should be on a high enough level and provide overview
+content that is useful enough such that it is not necessary to exclude them
+from the library API documentation.
+
+Modules
+-------
+
+For each module, decide on a header file that is the most important one for
+that module (if there is no self-evident header, it may be better to designate,
+e.g., module-doc.h for this purpose, but this is currently not done for any
+module).  This header should contain the \c \\defgroup definition for the
+module.  The name of the group should be `module_`<em>name</em>, where _name_
+is the name of the subdirectory that hosts the module.
+
+The module should be added to an appropriate group (see `doxygen/misc.cpp` for
+definitions) using \c \\ingroup to organize the "Modules" tab in the generated
+documentation.
+
+One or more contact persons who know about the contents of the module should be
+listed using \c \\author commands.  This provides a point of contact if one
+has questions.
+
+Classes/structs
+---------------
+
+Classes and structs in header files appear always in Doxygen documentation,
+even if their enclosing file is not documented.  So start the documentation
+blocks of classes that are not part of the public API with \c \\internal or
+\c \\libinternal.  Classes declared locally in source files or in unnamed
+namespaces only appear in the full documentation.
+
+If a whole class is not documented, this does not currently generate any
+warning.  The class is simply exluded from the documentation.  But if a member
+of a documented class is not documented, a warning is generated.  Guidelines for
+documenting free functions apply to methods of a class as well.
+
+For base classes, the API classification (\c \\inpublicapi or
+\c \\inlibraryapi) should be based on where the class is meant to be
+subclassed.  The visibility (\c \\internal or \c \\libinternal), in contrast,
+should reflect the API classification of derived classes such that the base
+class documentation is always generated together with the derived classes.
+
+For classes that are meant to be subclassed and have protected members, the
+protected members should only appear at the documentation level where the class
+is meant to be subclassed.  For example, if a class is meant to be subclassed
+only within a module, the protected members should only appear in the
+full documentation.  This can be accomplished using \c \\cond (note that you
+will need to add the \c \\cond command also to the source files to hide the
+same methods from Doxygen, otherwise you will get confusing warnings).
+
+Methods/functions/enums/macros
+------------------------------
+
+These items do not appear in the documentation unless their enclosing scope is
+documented.  For class members, the scope is the class; otherwise, it is the
+namespace if one exists, or the file.  An \c \\addtogroup can also define a
+scope if the group has higher visibility than the scope outside it.
+So if a function is not within a namespace (mostly applicable to C code) and
+has the same visibility as its enclosing file, it is not necessary to add a
+\c \\internal or \c \\libinternal.
+
+Static functions are currently extracted for all documentation flavors to allow
+headers to declare `static inline` functions (used in, for example, math code).
+Functions in anonymous namespaces are only extracted into the full
+documentation.  Together with the above rules, this means that you should avoid
+putting a `static` function within a documented namespace, even within source
+files, or it may inadvertently appear in the public API documentation.
+
+If you want to exclude an item from the documentation, you need to put in
+inside a \c \\cond block such that Doxygen does not see it.
+Otherwise, a warning for an undocumented function is generated.  You need to
+enclose both the declaration and the definition with \c \\cond.
+
+Files
+-----
+
+Each documented file should start with a documentation block (right after the
+copyright notice) that documents the file.  See the examples section for exact
+formatting.  Things to note:
+* Please do not specify the file name explicitly after \c \\file.  By default,
+  a file comment applies to the file it is contained in, and an explicit file
+  name only adds one more thing that can get out of date.
+* \c \\brief cannot appear on the same line as the \c \\file, but should be on
+  the next line.
+* \c \\internal or \c \\libinternal should indicate where the header is visible.
+  As a general guideline, all installed headers should appear in the public API
+  documentation, i.e., not contain these commands.  If nothing else, then to
+  document that it does not contain any public API functions.  Headers that
+  declare anything in the library API should be marked with \c \\libinternal,
+  and the rest with \c \\internal.
+* All source files, as well as most test files, should be documented with
+  \c \\internal, since they do not provide anything to public or library API,
+  and this avoids unintentionally extracting things from the file into those
+  documentations.  Shared test files used in tests from other modules should be
+  marked with \c \\libinternal.
+* \c \\inpublicapi or \c \\inlibraryapi should be used to indicate where the
+  header is meant to be directly included.
+* As with files, one or more contact persons should be listed with \c \\author.
+  If you make significant modifications or additions to a file, consider adding
+  an \c \\author line for yourself.
+
+Directories
+-----------
+
+Directory documentation does not typically contain useful information beyond a
+possible brief description, since they correspond very closely to modules, and
+the modules themselves are documented.  A brief description is still useful to
+provide a high-level overview of the source tree on the generated "Files" page.
+A reference to the module is typically sufficient as a brief description for a
+directory.  All directories are currently documented in
+`doxygen/directories.cpp`.
+
+
+Examples
+========
+
+Basic C++
+---------
+
+Here is an example of documenting a C++ class and its containing header file.
+Comments in the code and the actual documentation explain the used Doxygen
+constructs.
+
+\includelineno doxygen-example.cpp
+
+Basic C
+-------
+
+Here is another example of documenting a C header file (so avoiding all
+C++-style comments), and including free functions.  It also demonstrates the use
+of \c \\addtogroup to add multiple functions into a module group without repeated
+\c \\ingroup tags.
+
+\includelineno doxygen-example.c
+
+Scoping and visibility rules
+----------------------------
+
+The rules where Doxygen expects something to be documented, and when are
+commands like \c \\internal needed, can be complex.  The examples below
+describe some of the pitfalls.
+
+\includelineno doxygen-example-scoping.cpp
+
+Module documentation
+--------------------
+
+Documenting a new module should place a comment like this in a central header
+for the module, such that the "Modules" tab in the generated documentation can
+be used to navigate to the module.
+
+\includelineno doxygen-example-module.cpp
+
+Common mistakes
+---------------
+
+The most common mistake, in particular in C code, is to forget to document the
+file.  This causes Doxygen to ignore most of the comments in the file, so it
+does not validate the contents of the comments either, nor is it possible to
+actually check how the generated documentation looks like.
+
+The following example shows some other common mistakes that do not produce
+correct documentation.  The issues are explained in normal comments above each
+code fragment.
+
+\includelineno doxygen-example-issues.cpp
+
+Existing code
+-------------
+
+More examples you can find by looking at existing code in the source tree.  In
+particular new C++ code such as that in the `src/gromacs/analysisdata/` and
+`src/gromacs/options/` subdirectories contains a large amount of code
+documented mostly along these guidelines.  Some comments in
+`src/gromacs/selection/` (in particular, any C-like code) predate the
+introduction of these guidelines, so those are not the best examples.
diff --git a/doxygen/examples/doxygen-example-issues.cpp b/doxygen/examples/doxygen-example-issues.cpp
new file mode 100644 (file)
index 0000000..de1f300
--- /dev/null
@@ -0,0 +1,41 @@
+// The struct itself is not documented; other comments within the declaration
+// are ignored.
+
+struct t_struct {
+
+    // The comment tries to document both members at once, but it only
+    // applies to the first.  The second produces warnings about missing
+    // documentation (if the enclosing struct was documented).
+
+    //! Angle parameters.
+    double alpha, beta;
+};
+
+
+// This does not produce any brief documentation.
+// An explicit \brief is required, or //! (C++) or /** */ (C) should be used.
+
+/*! Brief comment. */
+int gmx_function();
+
+
+// This does not produce any documentation at all, since a ! is missing at
+// the beginning.
+
+/* \brief
+ * Brief description.
+ *
+ * More details.
+ */
+int gmx_function();
+
+
+// This puts the whole paragraph into the brief description.
+// A short description is preferable, separated by an empty line from the rest
+// of the text.
+
+/*! \brief
+ * Brief description. The description continues with all kinds of details about
+ * what the function does and how it should be called.
+ */
+int gmx_function();
diff --git a/doxygen/examples/doxygen-example-module.cpp b/doxygen/examples/doxygen-example-module.cpp
new file mode 100644 (file)
index 0000000..d94b442
--- /dev/null
@@ -0,0 +1,17 @@
+/*! \defgroup module_example "Example module (example)"
+ * \ingroup group_utilitymodules
+ * \brief
+ * Brief description for the module.
+ *
+ * Detailed description of the module.  Can link to a separate Doxygen page for
+ * overview, and/or describe the most important headers and/or classes in the
+ * module as part of this documentation.
+ *
+ * For modules not exposed publicly, \\libinternal can be added at the
+ * beginning (before \\defgroup).
+ *
+ * \author Author Name <author.name@email.com>
+ */
+
+// In other code, use \addtogroup module_example and \ingroup module_example to
+// add content (classes, functions, etc.) onto the module page.
diff --git a/doxygen/examples/doxygen-example-scoping.cpp b/doxygen/examples/doxygen-example-scoping.cpp
new file mode 100644 (file)
index 0000000..36c6ae9
--- /dev/null
@@ -0,0 +1,119 @@
+/*! \libinternal \file
+ * \brief
+ * ...
+ *
+ * The examples below assume that the file is documented like this:
+ * with an \\libinternal definition at the beginning, with an intent to not
+ * expose anything from the file in the public API.  Things work similarly for
+ * the full documentation if you replace \\libinternal with \\internal
+ * everywhere in the example.
+ *
+ * \ingroup module_example
+ */
+
+
+/*! \brief
+ * Brief description for a free function.
+ *
+ * A free function is not extracted into the documentation unless the enclosing
+ * scope (in this case, the file) is.  So a \\libinternal is not necessary.
+ */
+void gmx_function();
+
+// Assume that the module_example group is defined in the public API.
+
+//! \addtogroup module_example
+//! \{
+
+//! \cond libapi
+/*! \brief
+ * Brief description for a free function within \\addtogroup.
+ *
+ * In this case, the enclosing scope is actually the module_example group,
+ * which is documented, so the function needs to be explicitly excluded.
+ * \\libinternal does not work, since it would produce warnings about an
+ * undocumented function, so the whole declaration is hidden from Doxygen.
+ */
+void gmx_function();
+//! \endcond
+
+//! \}
+
+// For modules that are only declared in the library API, \addtogroup
+// cannot be used without an enclosing \cond.  Otherwise, it will create
+// a dummy module with the identifier as the name...
+
+//! \cond libapi
+//! \addtogroup module_libmodule
+//! \{
+
+/*! \brief
+ * Brief description.
+ *
+ * No \\libinternal is necessary here because of the enclosing \\cond.
+ */
+void gmx_function();
+
+//! \}
+//! \endcond
+
+/*! \libinternal \brief
+ * Brief description for a struct.
+ *
+ * Documented structs and classes from headers are always extracted into the
+ * documentation, so \\libinternal is necessary to exclude it.
+ * Currently, undocumented structs/classes do not produce warnings, so \\cond
+ * is not necessary.
+ */
+struct t_example
+{
+    int  member1; //!< Each non-private member should be documented.
+    bool member2; //!< Otherwise, Doxygen will produce warnings.
+};
+
+// This namespace is documented in the public API.
+namespace gmx
+{
+
+//! \cond libapi
+/*! \brief
+ * Brief description for a free function within a documented namespace.
+ *
+ * In this case, the enclosing scope is the documented namespace,
+ * so a \\cond is necessary to avoid warnings.
+ */
+void gmx_function();
+//! \endcond
+
+/*! \brief
+ * Class meant for subclassing only within the module, but the subclasses will
+ * be public.
+ *
+ * This base class still provides public methods that are visible through the
+ * subclasses, so it should appear in the public documentation.
+ * But it is not marked with \\inpublicapi.
+ */
+class BaseClass
+{
+    public:
+        /*! \brief
+         * A public method.
+         *
+         * This method also appears in the documentation of each subclass in
+         * the public and library API docs.
+         */
+        void method();
+
+    protected:
+        // The \cond is necessary to exlude this documentation from the public
+        // API, since the public API does not support subclassing.
+        //! \cond internal
+        //! A method that only subclasses inside the module see.
+        void methodForSubclassToCall();
+
+        //! A method that needs to be implemented by subclasses.
+        virtual void virtualMethodToImplement() = 0;
+        //! \endcond
+};
+
+} // namespace gmx
diff --git a/doxygen/examples/doxygen-example.c b/doxygen/examples/doxygen-example.c
new file mode 100644 (file)
index 0000000..900f464
--- /dev/null
@@ -0,0 +1,50 @@
+/*! \file
+ * \brief
+ * Declares a collection of functions for performing a certain task.
+ *
+ * More details can go here.
+ *
+ * \author Example Author <example@author.com>
+ * \inpublicapi
+ * \ingroup module_mymodule
+ */
+
+/*! \addtogroup module_mymodule */
+/*! \{ */
+
+/*! \brief
+ * Brief description for the data structure.
+ *
+ * More details.
+ *
+ * \inpublicapi
+ */
+typedef struct {
+    /** Brief description for member. */
+    int  member;
+    int  second; /**< Brief description for the second member. */
+    /*! \brief
+     * Brief description for the third member.
+     *
+     * Details.
+     */
+    int  third;
+} gmx_mystruct_t;
+
+/*! \brief
+ * Performs a simple operation.
+ *
+ * \param[in] value  Input value.
+ * \returns   Computed value.
+ *
+ * Detailed description.
+ * \\inpublicapi cannot be used here, because Doxygen only allows a single
+ * group for functions, and module_mymodule is the preferred group.
+ */
+int gmx_function(int value);
+
+/* Any . in the brief description should be escaped as \. */
+/** Brief description for this function. */
+int gmx_simple_function();
+
+/*! \} */
diff --git a/doxygen/examples/doxygen-example.cpp b/doxygen/examples/doxygen-example.cpp
new file mode 100644 (file)
index 0000000..159f90c
--- /dev/null
@@ -0,0 +1,71 @@
+/*! \libinternal \file
+ * \brief
+ * Declares gmx::MyClass.
+ *
+ * More details.  The documentation is still extracted for the class even if
+ * this whole comment block is missing.
+ *
+ * \author Example Author <example@author.com>
+ * \inlibraryapi
+ * \ingroup module_mymodule
+ */
+
+namespace gmx
+{
+
+/*! \libinternal
+ * \brief
+ * Brief description for the class.
+ *
+ * More details.  The \\libinternal tag is required for classes, since they are
+ * extracted into the documentation even in the absence of documentation for
+ * the enclosing scope.
+ * The \\libinternal tag is on a separate line because of a bug in Doxygen
+ * 1.8.5 (only affects \\internal, but for clarity it is also worked around
+ * here).
+ *
+ * \inlibraryapi
+ * \ingroup module_mymodule
+ */
+class MyClass
+{
+    public:
+        // Trivial constructors or destructors do not require documentation.
+        // But if a constructor takes parameters, it should be documented like
+        // methods below.
+        MyClass();
+        ~MyClass();
+
+        /*! \brief
+         * Brief description for the method.
+         *
+         * \param[in] param1  Description of the first parameter.
+         * \param[in] param2  Description of the second parameter.
+         * \returns   Description of the return value.
+         * \throws    std::bad_alloc if out of memory.
+         *
+         * More details describing the method.  It is not an error to put this
+         * above the parameter block, but most existing code has it here.
+         */
+        int myMethod(int param1, const char *param2) const;
+
+        //! Brief description for the accessor.
+        int simpleAccessor() const { return var_; }
+        /*! \brief
+         * Alternative, more verbose way of specifying a brief description.
+         */
+        int anotherAccessor() const;
+        /*! \brief
+         * Brief description for another accessor that is so long that it does
+         * not conveniently fit on a single line cannot be specified with //!.
+         */
+        int secondAccessor() const;
+
+    private:
+        // Private members (whether methods or variables) are currently ignored
+        // by Doxygen, so they don't need to be documented.  Documentation
+        // doesn't hurt, though.
+        int var_;
+};
+
+} // namespace gmx
index 4efaf5300be75d50589d5ffde9857054f93b792a..e395782212de2ea078f45660e51e6dd3e5941acf 100644 (file)
@@ -22,6 +22,8 @@ to be used outside a single module.
 \elseif libapi
 documentation of functions in the library intended for reuse within the
 library (a subset of these functions is also exposed as a public API).
 \elseif libapi
 documentation of functions in the library intended for reuse within the
 library (a subset of these functions is also exposed as a public API).
+Also overview documentation aimed at \Gromacs developers is included at this
+level.
 
 The main audience for this level of detail are users and developers who want to
 understand the \Gromacs code in general.
 
 The main audience for this level of detail are users and developers who want to
 understand the \Gromacs code in general.
@@ -38,7 +40,8 @@ preliminary, and subject to change.
 The main audience for this level of detail are users of \Gromacs who are
 interested in writing their own analysis tools that use \Gromacs as a library,
 as well as other developers who want to link against \Gromacs.
 The main audience for this level of detail are users of \Gromacs who are
 interested in writing their own analysis tools that use \Gromacs as a library,
 as well as other developers who want to link against \Gromacs.
-To understand the inner workings of \Gromacs, see the more detailed
+To understand the inner workings of \Gromacs, or if you want to contribute to
+\Gromacs, see the more detailed
 [library API documentation](../html-lib/index.xhtml) or
 [full documentation](../html-full/index.xhtml).
 \endif
 [library API documentation](../html-lib/index.xhtml) or
 [full documentation](../html-full/index.xhtml).
 \endif
@@ -56,6 +59,9 @@ give an overview of some of the topics that are documented:
    Provides general guidance for writing software that uses the \Gromacs
    library.
 \if libapi
    Provides general guidance for writing software that uses the \Gromacs
    library.
 \if libapi
+ - \subpage page_doxygen <br/>
+   Provides an overview and some instructions for using Doxygen to document the
+   source code.
  - \subpage page_unittesting <br/>
    Provides an overview of unit testing in \Gromacs.
  - \subpage page_wrapperbinary <br/>
  - \subpage page_unittesting <br/>
    Provides an overview of unit testing in \Gromacs.
  - \subpage page_wrapperbinary <br/>
index 432473b938034ee33c107496b5302b4b7576f3a9..0259b611f14a354b6b2bed1d9f8a6e6410d4eed5 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2011,2012,2013, by the GROMACS development team, led by
+ * Copyright (c) 2011,2012,2013,2014, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -46,9 +46,8 @@
 #include <boost/current_function.hpp>
 #include <boost/exception/detail/attribute_noreturn.hpp>
 
 #include <boost/current_function.hpp>
 #include <boost/exception/detail/attribute_noreturn.hpp>
 
-/*! \addtopublicapi
- * \{
- */
+//! \addtogroup module_utility
+//! \{
 
 /*! \def GMX_RELEASE_ASSERT
  * \brief
 
 /*! \def GMX_RELEASE_ASSERT
  * \brief
@@ -84,7 +83,7 @@
 #define GMX_ASSERT(condition, msg) GMX_RELEASE_ASSERT(condition, msg)
 #endif
 
 #define GMX_ASSERT(condition, msg) GMX_RELEASE_ASSERT(condition, msg)
 #endif
 
-/*!\}*/
+//! \}
 
 namespace gmx
 {
 
 namespace gmx
 {