Documenting a Function

CMinx more or less copies your documentation comments verbatim to the resulting reST file. Strictly speaking this means you can put whatever you want in the comments; however, it is strongly recommended that you follow usual Python reST conventions so that you can get the most out of Sphinx’s parsing of the reST file. A good template is:

#[[[
# Short description. Runs up to the first blank line. So this is still the
# short description.
#
# Longer description goes here and includes all text and paragraphs from
# here forward that are not part of reST directives.
#
# The parameters, keywords, and their types will be pulled out of the longer
# description and placed in separate sections regardless of where they
# appear.
#
# :param name_of_param: Description of what `name_of_param` is used for
#
# The next line is a reST directive and will not be part of the longer
# description.
#
# .. note::
#
#    This is a note, it will show up using reST's native note section
#]]

The following sections describe the aspects of this template in more detail.

Basic Function Documentation

As an example consider the very simple CMake function say_hi_to defined as:

function(say_hi_to person)
    message("Hi ${person}")
endfunction()

say_hi_to takes one positional argument person which is the name of the person we want to say hi to. For documenting positional arguments it is recommended you use the :param: field like:

#[[[
# This function has very basic documentation.
#
# This function's description stays close to idealized formatting and does not
# do anything fancy.
#
# :param person: The person this function says hi to
# :type person: string
#]]
function(say_hi_to person)
    message("Hi ${person}")
endfunction()

Running CMinx on the documented code will generate:

.. function:: say_hi_to(person)

   This function has very basic documentation.
   
   This function's description stays close to idealized formatting and does not
   do anything fancy.
   
   :param person: The person this function says hi to
   :type person: string

Note

Since CMake is an interpreted language, it may not be obvious at first, but CMake does have types. In one context or another, native CMake distinguishes among: booleans, command names, file paths, floating-point numbers, integers, generator expressions, target names, strings, and lists. A list can contain any of the aforementioned types (including other lists) and all objects can be implicitly converted to stings.

The documentation comment has three parts:

# This function has very basic documentation.

is the short/brief description; it’s used to quickly summarize what the function does. The short description is often used when a user is trying to quickly ascertain what functionality a CMake module provides.

# This function's description stays close to idealized formatting and does not
# do anything fancy.

is the detailed description; it’s used to provide more in depth documentation beyond the brief description. Finally,

# :param person: The person this function says hi to
# :type person: string

documents the positional arguments to the function including how they are used and what their types.

Documenting Keyword Arguments

In modern CMake it is common practice for functions that accept many arguments, to accept those arguments as keyword arguments instead of positional arguments. As an example consider an “advanced” version of say_hi_to defined as:

function(advanced_say_hi_to me)
    cmake_parse_arguments(PARSE_ARGV 1 _asht "" "" "PERSONS;CATS")
    message("I, ${me}, want to say hi to the following ")
    message("people: ${_asht_PERSONS} and the following cats: ${_asht_CATS}")
endfunction()

Although not strictly necessary, most CMake function implementations handle keyword arguments by calling cmake_parse_arguments. The arguments to cmake_parse_arguments are the keywords the function recognizes; in this example the keyword arguments are PERSONS and CATS (see here for more details about cmake_parse_arguments).

Documenting keyword arguments is similar to documenting positional parameters except that instead of using the :param: field, one uses :keyword::

#[[[
# Variation of say_hi_to, which takes lists of people and cats to say hi to.
#
# This function is basically the same as ``say_hi_to``, but accounts for the
# fact that you may want to say hi to multiple people and maybe even a cat or
# two.
#
# :param me: The name of the person saying hi.
# :type me: string
#
# **Keyword Arguments**
#
# :keyword PERSONS: The person or persons to say hi to.
# :type PERSONS: list of strings
# :keyword CATS: The cat or cats to say hi to.
# :type CATS: list of strings
#]]
function(advanced_say_hi_to me)
    cmake_parse_arguments(PARSE_ARGV 1 _asht "" "" "PERSONS;CATS")
    message("I, ${me}, want to say hi to the following ")
    message("people: ${_asht_PERSONS} and the following cats: ${_asht_CATS}")
endfunction()

Running CMinx on this code generates:

.. function:: advanced_say_hi_to(me **kwargs)

   Variation of say_hi_to, which takes lists of people and cats to say hi to.
   
   This function is basically the same as ``say_hi_to``, but accounts for the
   fact that you may want to say hi to multiple people and maybe even a cat or
   two.
   
   :param me: The name of the person saying hi.
   :type me: string
   
   **Keyword Arguments**
   
   :keyword PERSONS: The person or persons to say hi to.
   :type PERSONS: list of strings
   :keyword CATS: The cat or cats to say hi to.
   :type CATS: list of strings

Notice how the function signature was automatically updated to include a **kwargs parameter. CMinx will do this for any function that calls cmake_parse_arguments or includes :keyword in its doc comment, the latter of which is configurable. If this is not desired, it can be turned off through the configuration file.

Note

While it is recommended that you document positional arguments differently than keyword arguments by using :param: vs. :keyword: the resulting HTML documentation may end up rendering the two the same. Thus, one should place a separator to clearly define which are keyword arguments.

CMake arguments can not only be keywords, where a value is supplied after the keyword, but can also be switches or options, where the keyword itself toggles the option and no subsequent value is passed. For these arguments, document them as part of the keyword arguments but set the type as option.