I am using doxygen for documentation in a project written in C. In that project there is a lot of repeated code. Since I am limited to the use of pure C (no C++ allowed), I am using macros to reduce repetitions in the source files. In the code generated by the macros I am hoping to include functions and type declarations (they follow a pattern and the actual macros are fairly easy to write). I would really want these generated functions and types to appear in the doxygen documentations, since they are vital for the library API. However, I am struggling to make doxygen correctly expand the macros
Doxygen doesn't always expand the macros. E.g. in the same line of code, the same function-like macro, called twice, is expanded the first time but not the second.
I feel that the best way to explain this problem is by showing a MRE (you can download it from here)
Consider the following file singlefile.h
/** @file singlefile.h
@defgroup singlefile singlefile.h: Single File Example
Test file
@{
*/
#ifndef _SINGLE_FILE_H
#define _SINGLE_FILE_H
#define _CCONCAT(X, Y) X ## Y
#define _CONCAT(X, Y) _CCONCAT(X, Y)
#define CONCAT(X, Y) _CONCAT(X, Y)
#define MY_TYPE_FULL(MY_TYPE) CONCAT(My, MY_TYPE)
#define MY_TYPEDEF_H(MY_TYPE) typedef struct MY_TYPE_FULL(MY_TYPE) MY_TYPE_FULL(MY_TYPE);
MY_TYPEDEF_H(Account)
#endif
/** @} */
Expected output of the macro call MY_TYPEDEF_H(Account)
is the following type declaration
typedef struct MyAccount MyAccount;
This works as expected in a C preprcessor (also verified using https://godbolt.org/), but not in doxygen. The output of the doxygen preprcessor is
Preprocessing /home/<username>/Documents/doxygenmacroexpand/src/singlefile.h...
Preprocessor output (size: 296 bytes):
---------
00001 /** @file singlefile.h
00002 @defgroup singlefile singlefile.h: Single File Example
00003 Test file
00004 @{
00005 */
00006
00007
00008
00009
00010 #define _CCONCAT(X, Y)
00011 #define _CONCAT(X, Y)
00012 #define CONCAT(X, Y)
00013
00014 #define MY_TYPE_FULL(MY_TYPE)
00015 #define MY_TYPEDEF_H(MY_TYPE)
00016
00017 typedef struct MyAccount MY_TYPE_FULL( Account );
00018
00019
00020
00021 /** @} */
00022
---------
Macros accessible in this file:
---------
_CCONCAT _CONCAT MY_TYPE_FULL MY_TYPEDEF_H CONCAT
---------
Accordingly, the HTML documentation has the following type declaration
struct MyAccount MY_TYPE_FULL (Account)
This results in pure garbage documentation for my actual project, in which I have even more layers of macro calls.
What I find quite bizarre is that the same macro is expanded the first time but not the second.
I used a fresh Doxyfile generated with doxygen 1.8.17
. I set the following tags differently than default
INPUT = ./src
OUTPUT_DIRECTORY = ./doc
MACRO_EXPANSION = YES
OPTIMIZE_OUTPUT_FOR_C = YES
This is the directory structure (output of tree
)
.
├── Doxyfile
└── src
└── singlefile.h
How do I make doxygen properly expand all macros?
TL;DR. Some macros in the C source file are expanded by the doxygen preprocessor and some are not, even at the same call depth. This leads to partially generated documentation in the simplest cases and to complete garbage in my real project scenario.
Side note: this is my first posted question here on SO. Usually I find answers that allow me to solve my problems, but not his time. Anyway, I am open to feedback if you have any advice on how I should post a question
The version 1.8.17 is from December 27, 2019 and exhibits the problem shown. With doxygen version 1.8.18 (April 4, 2020) the problem is gone so it is with the current version 1.9.1. In all these cases I do see
00017 typedef struct MyAccount MyAccount ;
The advice is to update to version 1.9.1.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With