How to document makefile templates and include *.mk file interfaces? - documentation

We have a number of makefile templates, that realize certain build actions by setting a few parameter makefile variables, and applying a makefile template via inclusion like
GENERIC_PARAM1-y := paramA
GENERIC_PARAM2-y := paramB
include $(MAKE_TOOLS)/doaction.mk
And files like doaction.mk contain make templates to generate standard rule definitions that are applied when just including the action make step.
Now we want to document these interfaces for the *.mk snippets using Doxygen like
## #file
## #brief doaction.mk is purposed to ...
##
## Some more detailed descriptions about rules applied ...
## #param GENERIC_PARAM1-y Parameter1 description ...
## #param GENERIC_PARAM2-y Parameter2 description ...
Is there a simple way to achieve this using any valid Doxygen syntax/configuration?

"Is there a simple way to achieve this using any valid doxygen syntax/configuration?"
Yes, you can use doxygen's INPUT_FILTER, FILE_PATTERNS and FILTER_SOURCE_FILES configuration settings as stolen from this blog post
Put these settings in your Doxyfile configuration
FILE_PATTERNS = *.mk
INPUT_FILTER = "sed -e 's|##|//!|'"
FILTER_SOURCE_FILES = YES
The INPUT_FILTER actually does the trick, the sed command is used by doxygen to open a pipe filtering the input files along the specified command.
Note:
The above mentioned command isn't embedded into a shell, thus chained command statements like
"grep '##' | sed -e 's|##|//!|'"
won't work.
Put your comments as proposed in the sample ## will expand for comments seen by doxygen
## #file
## #brief doaction.mk is purposed to ...
##
## Some more detailed descriptions about rules applied ...
## #param GENERIC_PARAM1-y Parameter1 description ...
## #param GENERIC_PARAM2-y Parameter2 description ...
Additionally you should put a
## #cond
...
## #endcond
around your makefile rules/templates code, to avoid doxygen parsing these parts.
The above sample should render as follows in the generated documentation HTML

Related

Standalone CMake script to cut off file contents by delimiters

I have a project where one repeatable task to do involves manipulating files' contents.
Until now I used a Python script for it, but recently I discovered I can use standalone CMake scripts ("standalone" here means they can be invoked outside of configure/build/test/etc. workflow). As my project already uses CMake for project management I concluded I can save others' problem of installing a Python interpreter (welcome Windows users!) and use CMake project-wide.
Part of my script needs to read a file and cut off everything that appears before "[START-HERE]" and after "[END-HERE]" lines. I am stuck with that part and don't know how to implement it. How can it be done?
You could combine file(READ) with if(MATCHES) to accompilish this. The former is used to read the file, the latter allows you to check for the occurance of a regular expression and to extract a capturing group:
foo.cmake
#[===[
Params:
INPUT_FILE : the path to the file to read
#]===]
file(READ "${INPUT_FILE}" FILE_CONTENTS)
if (FILE_CONTENTS MATCHES "(^|[\r\n])\\[START-HERE\\][\r\n]+(.*)[\r\n]+\\[END-HERE\\]")
# todo: use extracted match stored in CMAKE_MATCH_2 for your own logic
message("Content: '${CMAKE_MATCH_2}'")
else()
message(FATAL_ERROR "[START-HERE]...[END-HERE] doesn't occur in the input file '${INPUT_FILE}'")
endif()
foo.txt
Definetly not
[START-HERE]
working
[END-HERE]
Try again!
Output:
> cmake -D INPUT_FILE=foo.txt -P foo.cmake
Content: 'working'
For the part where you are stuck, here's one approach using the string, file, and math commands:
file(READ data.txt file_str)
string(FIND "${file_str}" "[START-HERE]" start_offset)
# message("${start_offset}")
math(EXPR start_offset "${start_offset}+12")
# message("${start_offset}")
string(FIND "${file_str}" "[END-HERE]" end_offset)
math(EXPR substr_len "${end_offset}-${start_offset}")
# message("${substr_len}")
string(SUBSTRING "${file_str}" "${start_offset}" "${substr_len}" trimmed_str)
# message("${trimmed_str}")
You could also probably do it by using the file(STRINGS) command, which reads lines of a file into an array, and then use the list(FIND) command. The approach shown above has the advantage of working if your delimiters are not on their own lines.
As #fabian shows in their answer post, you can also do this using a regular expression with if(MATCHES) like this:
file(READ "${INPUT_FILE}" FILE_CONTENTS)
if (FILE_CONTENTS MATCHES "(^|[\r\n])\\[START-HERE\\][\r\n]+(.*)[\r\n]+\\[END-HERE\\]")
# todo: use extracted match stored in CMAKE_MATCH_2 for your own logic
message("Content: '${CMAKE_MATCH_2}'")
else()
message(FATAL_ERROR "[START-HERE]...[END-HERE] doesn't occur in the input file '${INPUT_FILE}'")
endif()

Documenting CMake scripts

I find myself in a situation where I would like to accurately document a host of custom CMake macros and functions and was wondering how to do it.
The first thing that comes to mind is simply using the built-in syntax and only document scripts, like so:
# -----------------------------
# [FUNCTION_NAME | MACRO_NAME]
# -----------------------------
# ... description ...
# -----------------------------
This is fine. However, I'd like to employ common doc generators, for instance doxygen, to also generate external documentation that can be read by anyone without looking at the implementation (which is a common scenario).
One way would be to write a simple parser that generates a corresponding C/C++ header with the appropriate signatures and documentation directly from the CMake script, which could the be processed by doxygen or comparable tools. One could also maintain such a header by hand - which is obviously tedious and error prone.
Is there any other way to employ a documentation generator with CMake scripts?
Here is the closest I could get. The following was tested with CMake 2.8.10. Currently, CMake 3.0 is under development which will get a new documentation system based on Sphinx and reStructuredText. I guess that this will bring new ways to document your modules.
CMake 2.8 can extract documentation from your modules, but only documentation at the beginning of the file is considered. All documentation is added as CMake comments, beginning with a single #. Double ## will be ignored (so you can add comments to your documentation). The end of documentation is marked by the first non-comment line (e.g. an empty line)
The first line gives a brief description of the module. It must start with - and end with a period . or a blank line.
# - My first documented CMake module.
# description
or
# - My first documented CMake module
#
# description
In HTML, lines starting with at two or more spaces (after the #) are formatted with monospace font.
Example:
# - My custom macros to do foo
#
# This module provides the macro foo().
# These macros serve to demonstrate the documentation capabilietes of CMake.
#
# FOO( [FILENAME <file>]
# [APPEND]
# [VAR <variable_name>]
# )
#
# The FOO() macro can be used to do foo or bar. If FILENAME is given,
# it even writes baz.
MACRO( FOO )
...
ENDMACRO()
To generate documentation for your custom modules only, call
cmake -DCMAKE_MODULE_PATH:STRING=. --help-custom-modules test.html
Setting CMAKE_MODULE_PATH allows you to define additional directories to search for modules. Otherwise, your modules need to be in the default CMake location. --help-custom-modules limits the documentation generation to custom, non-CMake-standar modules. If you give a filename, the documentation is written to the file, to stdout otherwise. If the filename has a recognized extension, the documentation is formatted accordingly.
The following formats are possible:
.html for HTML documentation
.1 to .9 for man page
.docbook for Docbook
anything else: plain text

Doxygen - Ini as a Text?

I am starting to dokumenting with doxygen and as far as it goes it seems quite easy and helpful !
There is just one file which gives me a headache, my config.ini .
This file has different comments, standards etc. .
I would like to load it as "code", so the page is not interpreted.
How can I achieve this ?
The following didn't work :
; /// #file config.ini
; /// #code
setting1
setting2
setting3
; /// #endcode
Your question is a little unclear but I assume from your question that you do want to see the contents of the .ini file in the documentation.
For what I think you need I'd suggest using #verbatim rather than #code.
If you are not seeing anything at all, then check that .ini is in the list of filename extensions that doxygen will parse? It's a setting in the doxyfile.
You can do what you want as follows:
Define a page that includes the .ini file, for instance test.dox as follows:
/** #page test_ini test.ini
* This is the configuration file:
* #verbinclude test.ini
*/
Then set EXAMPLE_PATH in doxygen's config file to the directory that contains test.ini and don't include .ini files in FILE_PATTERNS (so use the default).

What's the difference between --skip-stylesheets and --no-stylesheets

I wanted to generate scaffold without stylesheets, and I found these two flags: --skip-stylesheets, --no-stylesheets. What's the difference between them?
If you run rails g scaffold --help, it will show help information for that generator along with a list of options.
Some of the options have default values. For example, if you look at
-y, [--stylesheets] # Generate Stylesheets
# Default: true
You see it defaults to true. If you don't want to generate stylesheets, you can prefix the option with --no to disable that specific option.
The skip-stylesheets option is defined in the [Runtime options] section as follows:
-s, [--skip] # Skip files that already exist
So to answer your question:
--no-stylesheets doesn't generate stylesheets at all
--skip-stylesheets generates stylesheets but skips the ones that already exist.

Doxygen: Files having hash ( # ) in name

I have a problem with generating documentation for files with # in their names. I.e. :
Filename ab#cd.h starts with line:
/** #file ab#cd.h some description */
This description is missing in generated Doxygen HTML.
Also all links were wrong but they have been fixed by additional script which exchange # into %23. I'm thinking of another script for renaming file name before and after generation but maybe there is a possibility to deal with the issue in some other way?
Why # char influence Doxygen documentation generation?
Hashes in filenames are a recipe for problems, but in your example you could simply write
/** #file
* some description
*/
No need for the file name, and the description should be put on the next line.
Doxygen uses # for links. I believe you can escape a # with a \, but I'm not positive.