breathe-doc / breathe

ReStructuredText and Sphinx bridge to Doxygen
https://breathe-doc.org
Other
743 stars 198 forks source link

Is the breathe_show_include setting meant only for struct/class? #858

Open RaumZeit opened 2 years ago

RaumZeit commented 2 years ago

I'm in the process to transition our documentation of a large C project from doxygen to sphinx using the breathe bridge and have stumpled across some problems. In particular, I am missing the

#include <<headerfile.h>

entries for the function, typedef, macro, etc. documentation. The only place where I see that line is for struct documentation. In my conf.py I have the following setting:

breathe_show_include = True

and the corresponding doxygen.conf contains the flag:

SHOW_HEADERFILE        = YES

So I was wondering whether this is a limitation of breathe or whether I need some extra settings in my doxygen.conf.

Any help is appreciated!

Edit: Just wanted to be clear that the doxygen generated html output always contains the #include <headerfile.h> line for each of the documented symbols.

michaeljones commented 2 years ago

I've not super familiar with this part of the code but it looks like nodeDef.includes are handled in the sphinxrenderer.py file for union, class, namespace and the more generic compound but possibly not for function or typedef (and I can't see the macro support easily.). So it look like it is missing from Breathe at the moment and isn't just a config setting.

RaumZeit commented 2 years ago

Thanks for the detailed answer! I've also had a look into the code of both, breathe and doxygen in the past days. It seems that doxygen might be to blame here, since it only emits XML <includes> tags for struct for the C domain (for C++ it possibly emits these tags for class and namespace as well). When looking at the HTML output of doxygen, however, the #include <headerfile> lines that do show up in the descriptions of functions, typedef, etc. are hardcoded for that type of output. The XML output on the other hand stores the information on the file name/path that actually declares these symbols in the <location> tags.

So my hack for now is to render the node.location.file additionally to the description of function, typedef, and define nodes, something like:

    def visit_node():
            ....
            def content(contentnode) -> None:
                if self.app.env.config.breathe_show_decl_file_include:
                    if node.location and node.location.file:
                        text = "#include <" + node.location.file + ">"
                        contentnode += nodes.emphasis("", nodes.Text(text))

                contentnode.extend(self.description(node))

            nodes_ = self.handle_declaration(
                node, declaration, content_callback=content
            )
            ...

I've added a new config variable breathe_show_decl_file_include to switch-on this additional output for the above example and added a callback function similar to what is done for the node.include content elsewhere in the sphinxrenderer.py. If you are interested, I'm happy to share my hack as a PR.