breathe
breathe copied to clipboard
Duplicate warning with breathe-apidoc
I use breathe-apidoc
as follows (I don't know if that is what was intended, I have not managed to find any documentation...):
python -m breathe.apidoc -p GooseFEM -o api _doxygen/xml
and that in my index.rst
.. toctree::
:caption: API
:maxdepth: 1
:glob:
api/*
Which works fine, accept that I'm getting a bunch of warnings such as
api/namespace/namespaceGooseFEM_1_1Tyings.rst:4: WARNING: Duplicate C++ declaration, also defined at api/class/classGooseFEM_1_1Tyings_1_1Control:4.
What can be done to prevent this?
I am getting the same warnings when generating documents for a tool I built in Java. I am using Doxygen and Breathe to generate Sphinx documentation to go with documentation for a JPype wrapper in Python. I am getting these warnings when using abstract class methods and I am overriding the method in the subclass. Breathe is complaining about a duplicate declaration for each of these abstract methods since they are in the superclass and subclass both. This should not be a warning and Breathe should understand proper inheritance and virtual methods.
I also created another issue related to this one for another error message when parsing abstract class methods and can be found at #778
I'm not sure if he issue is with what apidoc generates or with Breathe it self (or with Sphinx). If I remember correctly there are some duplicate-declaration problems when inheritance is involved. To be able to look more into this, it would be great if (both of) you can provide instructions for reproducing the problem, preferably in minimized example projects.
I think this is related to the xml
output from Doxygen. If you look carefully in the file you are going to see that Doxygen creates a <compound>
for every file inside of the INPUT
tag. If you are using C++
this means that you are creating a xml
file for the header *.h
and also for the source *.cpp
, which eventually would lead to a Duplication warning from the breathe-apidoc
.
There are some workaround to fix this warnings for C++
but I don't know how challenging would be to solve this problem from a Java
source code.
@Caelin I am a little curious, Java has already a very robust automated documentation, why do you do not use javadoc
?
Attach to this message I send an output of a index.xml
Doxygen file with the problem that I am describing
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<doxygenindex xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="index.xsd" version="1.8.17">
<compound refid="classImage" kind="class"><name>Image</name>
<member refid="classImage_1a5a9b26b4fb221248deb83abb666a1e21" kind="variable"><name>cols</name></member>
<member refid="classImage_1ad0238c887b63a1d9dedab2edeca64707" kind="variable"><name>rows</name></member>
<member refid="classImage_1aa06677ad88bf95e3ed87449786c681cb" kind="variable"><name>chan</name></member>
<member refid="classImage_1a8c885ded00fd35077e4df3be9cc1df95" kind="variable"><name>size</name></member>
<member refid="classImage_1ac707214a98f76a9bf7a268c10a4f16e1" kind="variable"><name>pixels</name></member>
<member refid="classImage_1a2999c972d3a441a0af7dfd52441b983d" kind="variable"><name>ppm_type</name></member>
<member refid="classImage_1a58edd1c45b4faeb5f789b0d036d02313" kind="function"><name>Image</name></member>
<member refid="classImage_1adc5d9e643b449f21aa5b0d0d7dd4b80f" kind="function"><name>Image</name></member>
<member refid="classImage_1ad480e22ff4c42487e72727de3417eb3d" kind="function"><name>Image</name></member>
<member refid="classImage_1a3ba117b81aff6aac412ebfb9496452f2" kind="function"><name>operator[]</name></member>
<member refid="classImage_1a0294f63700543e11c0f0da85601c7ae5" kind="function"><name>~Image</name></member>
</compound>
<compound refid="main_8cpp" kind="file"><name>main.cpp</name>
<member refid="main_8cpp_1a45ba202b05caf39795aeca91b0ae547e" kind="define"><name>TIMEOUT</name></member>
<member refid="main_8cpp_1a0ddf1224851353fc92bfbff6f499fa97" kind="function"><name>main</name></member>
</compound>
<compound refid="main__noHW_8cpp" kind="file"><name>main_noHW.cpp</name>
<member refid="main__noHW_8cpp_1a45ba202b05caf39795aeca91b0ae547e" kind="define"><name>TIMEOUT</name></member>
<member refid="main__noHW_8cpp_1a0ddf1224851353fc92bfbff6f499fa97" kind="function"><name>main</name></member>
</compound>
<compound refid="ppm_8cpp" kind="file"><name>ppm.cpp</name>
<member refid="ppm_8cpp_1ab4fa15fe08bc20636c72949eeeca24ce" kind="function"><name>getHexString</name></member>
<member refid="ppm_8cpp_1ab65a56f3b98ae30893a9e0c2dd42bf1d" kind="function"><name>readPPM</name></member>
<member refid="ppm_8cpp_1acc6448566403e47ccb3f02a4a65a6d2b" kind="function"><name>savePPM</name></member>
<member refid="ppm_8cpp_1acd6c96bf759e72c05352a64b1edc0e0f" kind="function"><name>savePixels</name></member>
</compound>
<compound refid="ppm_8h" kind="file"><name>ppm.h</name>
<member refid="ppm_8h_1aae9749d96e15ccb4f482dd5f55d98f9b" kind="typedef"><name>BYTE</name></member>
<member refid="ppm_8h_1ab65a56f3b98ae30893a9e0c2dd42bf1d" kind="function"><name>readPPM</name></member>
<member refid="ppm_8h_1acc6448566403e47ccb3f02a4a65a6d2b" kind="function"><name>savePPM</name></member>
<member refid="ppm_8h_1acd6c96bf759e72c05352a64b1edc0e0f" kind="function"><name>savePixels</name></member>
</compound>
<compound refid="serial_8cpp" kind="file"><name>serial.cpp</name>
<member refid="serial_8cpp_1ab4b19dfdf208fee18951d91c59d5009c" kind="function"><name>rgbToGrayscale</name></member>
<member refid="serial_8cpp_1ae55a803cd300fb3f3a7d5ff8be85f3c9" kind="function"><name>rgbToGrayscaleShift</name></member>
</compound>
<compound refid="serial_8h" kind="file"><name>serial.h</name>
<member refid="serial_8h_1ab4b19dfdf208fee18951d91c59d5009c" kind="function"><name>rgbToGrayscale</name></member>
<member refid="serial_8h_1ae55a803cd300fb3f3a7d5ff8be85f3c9" kind="function"><name>rgbToGrayscaleShift</name></member>
</compound>
<compound refid="dir_57e0317f685e46796bf0967b598c2df6" kind="dir"><name>/home/jairom/Documents/TUD_Projects/03_Semester/ESHO2/ESHO2/task_4/host/src/ppm</name>
</compound>
<compound refid="dir_ee75d340cb949c8d47b0901592a11d1b" kind="dir"><name>/home/jairom/Documents/TUD_Projects/03_Semester/ESHO2/ESHO2/task_4/host/src/serial</name>
</compound>
<compound refid="dir_68267d1309a1af8e8297ef4c3efbcdba" kind="dir"><name>/home/jairom/Documents/TUD_Projects/03_Semester/ESHO2/ESHO2/task_4/host/src</name>
</compound>
</doxygenindex>
Thanks. Just a comment the original question was about C++
Hi @tdegeus yes, I know. I point out the problem for a C++
implementation with the breathe-apidoc
. I tried to workaround the problem changing the Doxygen
file, but most of the options does not apply to the output of the XML.
It is necessary to update the code to not use the information from the *.cpp
files when there is already a .hpp
file with those same functions. If you see the message that I put in the file serial.cpp
has the same functions as serial.h
. However, as the code of breathe-apidoc
is right now, it cannot identify that those are the same implementation and shows the warning of Duplicate C++ declaration
.
@jakobandersen are you a collaborator from the breathe-apidoc
python file? I could help you but after some weeks because I have some deadlines to deal with in my work. If you are interested, please let me know.
There are so many possible levels where the true problem originates (from Doxygen through Breathe to Sphinx it self), that it is difficult to pinpoint without getting concrete. So I think a great starting point would be if one of you can create a small example project is that reproduces the problem. I.e., something with the minimal amount of source code and rst code.
Hi @jakobandersen
Attach to this message you will find a test_project
that has the problem related to this issue. The only thing that you need to do, if you want to see the directly the warning output messages is use the cmake
file that I use to build the documentation. Please be aware that the cmake
from the C++ project is independent from the cmake
in the folder docs
.
# Go to the project
cd docs
mkdir build && cd build
cmake .. && make
The output of the HTML is going to be located in the folder html
and the output from the breathe-apidoc
command is located in the folder src
inside of docs
.
I'm not really familiar with this specific use-case, but based on a bit of playing around with the example, it looks like there are two problems:
- Both
.hpp
and.cpp
files are processed by Doxygen (and thenbreathe-apidoc
). Changing theDoxyfile
to remove*.cpp
from theFILE_PATTERNS
setting will make it skip those files, so only the public interface is processed. - The more difficult problem is that you are generating two versions of the documentation: a file-oriented view, and a class-oriented view. For example, this gives the following error:
This is where you hit one of the big issues, where https://github.com/michaeljones/breathe/issues/321 may be a good root for diving into all the variations of the problem (see the issues that link back to it as well). Essentially: Sphinx needs to have exactly one place for the documentation of an entity (class, function, ...). So it by definition can't be documented both in a file-oriented page and a class-oriented page. The good news is that there is the/test_project/docs/src/file/ppm_8hpp.rst:4: WARNING: Duplicate C++ declaration, also defined at src/class/classImage:4. Declaration is '.. cpp:class:: Image'
cpp:alias
directive which can insert the signature of a entity somewhere, and link to it. The bad news is that we have not gotten to exploiting it in Breathe, yet.
Yes, the file+class conflict seems to be a particularly bad one. Even using .. doxygenfile::
multiple times seems to want to repeat the anchor for a namespace. From https://raw.githubusercontent.com/celeritas-project/celeritas/master/doc/api/corecel.rst I get numerous warnings:
/Users/seth/.local/src/celeritas-temp/doc/api/corecel.rst:22: WARNING: Duplicate C++ declaration, also defined at api/corecel:20.
Declaration is '.. cpp:type:: celeritas'.
/Users/seth/.local/src/celeritas-temp/doc/api/corecel.rst:10: CRITICAL: Duplicate ID: "d2/dd1/namespaceceleritas".
/Users/seth/.local/src/celeritas-temp/doc/api/corecel.rst:10: WARNING: Duplicate explicit target name: "d2/dd1/namespaceceleritas".
/Users/seth/.local/src/celeritas-temp/doc/api/corecel.rst:29: WARNING: Duplicate C++ declaration, also defined at api/corecel:20.
Since all the functions/macros/variables/etc. that I want to document are inside an innernamespace
I can't omit that section.
I think the duplicate declaration warning for namespaces is inevitable because they're mapped to cpp:type
: https://github.com/breathe-doc/breathe/blob/542ae9b9ed6e5bd5e92ba2360b094df8931ba756/breathe/renderer/sphinxrenderer.py#L251
It doesn't look like there is a Spinx entity for namespace
, the cpp:namespace
directive is actually for changing the current scope.
Maybe it would be better to instead just ensure the namespaces are merged into the entity names themselves?