Uploaded image for project: 'Data Management'
  1. Data Management
  2. DM-22500

Trial generating C++ documentation for pipelines.lsst.io using "exhale"

    XMLWordPrintable

    Details

      Description

      To bridge Doxygen-generated C++ reference documentation into pipelines.lsst.io, a Sphinx-based site, we know we want to use Breathe. However, we don't know the best way to build out the API reference site. We don't want a monolithic page with all APIs, instead, we want one-page-per-API, like we do the Python docs.

      One approach to building out this page hierarchy is with exhale, an additional Sphinx extension that builds generates doxygen-like namespace browsing of a C++ API. This ticket is to demo that approach and see if it's an appropriate solution for the LSST Science Pipelines documentation.

        Attachments

          Issue Links

            Activity

            Hide
            jsick Jonathan Sick added a comment -

            Krzysztof Findeisen, I have a prototype build of the Science Pipelines documentation that includes a C++ reference: https://pipelines.lsst.io/v/DM-22500/index.html

            This is using mostly off-the-shelf tooling (Doxygen, breathe, and exhale), along with a Doxygen build that's driven by Documenteer itself, rather than sconsUtils and lsstDoxygen.

            There are limitations in this presentation of the C++ API reference, but our main question right now is:

            Is this API reference sufficient to replace our standalone Doxygen HTML site for the purpose of providing a C++ API reference?

            The main page that exhale generates is at https://pipelines.lsst.io/v/DM-22500/cpp-api/index.html

            There are standalone pages for namespaces (e.g. https://pipelines.lsst.io/v/DM-22500/cpp-api/namespace_lsst__afw__table.html#namespace-lsst-afw-table) and things like classes (https://pipelines.lsst.io/v/DM-22500/cpp-api/classlsst_1_1afw_1_1table_1_1_schema.html#exhale-class-classlsst-1-1afw-1-1table-1-1-schema).

            There are also pages for each header file, though they currently aren't linking properly in the upload to LSST the Docs.

            Another oddity is that cross-links go to this page https://pipelines.lsst.io/v/DM-22500/cpp-api/namespace/namespacelsst.html rather than the individual standalone pages. This means that API definitions are being duplicated.

            Finally, I had to exclude include/lsst/afw/geom/SpanSet.h and include/lsst/afw/geom/SpanSetFunctorGetters.h from the Doxygen build because they're causing Sphinx failures related to https://github.com/svenevs/exhale/issues/51

            Show
            jsick Jonathan Sick added a comment - Krzysztof Findeisen , I have a prototype build of the Science Pipelines documentation that includes a C++ reference: https://pipelines.lsst.io/v/DM-22500/index.html This is using mostly off-the-shelf tooling (Doxygen, breathe, and exhale), along with a Doxygen build that's driven by Documenteer itself, rather than sconsUtils and lsstDoxygen . There are limitations in this presentation of the C++ API reference, but our main question right now is: Is this API reference sufficient to replace our standalone Doxygen HTML site for the purpose of providing a C++ API reference? The main page that exhale generates is at https://pipelines.lsst.io/v/DM-22500/cpp-api/index.html There are standalone pages for namespaces (e.g. https://pipelines.lsst.io/v/DM-22500/cpp-api/namespace_lsst__afw__table.html#namespace-lsst-afw-table ) and things like classes ( https://pipelines.lsst.io/v/DM-22500/cpp-api/classlsst_1_1afw_1_1table_1_1_schema.html#exhale-class-classlsst-1-1afw-1-1table-1-1-schema ). There are also pages for each header file, though they currently aren't linking properly in the upload to LSST the Docs. Another oddity is that cross-links go to this page https://pipelines.lsst.io/v/DM-22500/cpp-api/namespace/namespacelsst.html rather than the individual standalone pages. This means that API definitions are being duplicated. Finally, I had to exclude include/lsst/afw/geom/SpanSet.h and include/lsst/afw/geom/SpanSetFunctorGetters.h from the Doxygen build because they're causing Sphinx failures related to https://github.com/svenevs/exhale/issues/51
            Hide
            krzys Krzysztof Findeisen added a comment - - edited

            I'm not sure I'd call it "sufficient"; at best, it's very hard to use. Things I've noticed:

            • I can't search for C++ classes; I assume that's a limitation of the demo. Our experience with Doxygen shows that search quality makes or breaks the usability of an API reference, so we should test that when we can. People avoided using Doxygen if they thought the namespace index was the only way to find a class, and they'll do the same here.
            • Some information is not provided, like whether a class is inheritable or not, or whether nested types are public, protected, or private (shouldn't even be in here!)
              • Correction: Doxygen also doesn't distinguish public and protected nested types, though it excludes private ones; compare the one reference to VisitorWrapper in Doxygen to the three references in exhale
            • I found at least one case where the class description is garbled (still readable in this case, but possibly not others). Compare the exhale documentation for afw::typehandling::GenericMap, the Doxygen version, and the source code.
            • Some classes, like afw::typehandling::Storable, are not documented; I'm not sure if that is one of the deliberate exclusions you mentioned.
            • Once you get onto namespacelsst.html you're stuck, because that page only provides a class description. Compare the namespacelsst entry for afw::geom::Transform and the class page. Transform's entry has one link that goes to the class page, but that appears to be a fluke of it using a CRTP base class.
            • Some cross-links don't go to namespacelsst.html, such as the link to meas::base::FluxResultKey on DipoleFluxAlgorithm's page. This is the behavior we want, but the inconsistency, combined with the previous issue, may be confusing and frustrating for users.

            It would help if you included lsst::geom in future demos; IIRC those classes are both thoroughly documented and use some more C++11 features, so they'd be a good contrasting case to some of the older code in afw.

            Show
            krzys Krzysztof Findeisen added a comment - - edited I'm not sure I'd call it "sufficient"; at best, it's very hard to use. Things I've noticed: I can't search for C++ classes; I assume that's a limitation of the demo. Our experience with Doxygen shows that search quality makes or breaks the usability of an API reference, so we should test that when we can. People avoided using Doxygen if they thought the namespace index was the only way to find a class, and they'll do the same here. Some information is not provided, like whether a class is inheritable or not, or whether nested types are public, protected, or private (shouldn't even be in here!) Correction: Doxygen also doesn't distinguish public and protected nested types, though it excludes private ones; compare the one reference to VisitorWrapper in Doxygen to the three references in exhale I found at least one case where the class description is garbled (still readable in this case, but possibly not others). Compare the exhale documentation for afw::typehandling::GenericMap , the Doxygen version , and the source code . Some classes, like afw::typehandling::Storable , are not documented; I'm not sure if that is one of the deliberate exclusions you mentioned. Once you get onto namespacelsst.html you're stuck, because that page only provides a class description. Compare the namespacelsst entry for afw::geom::Transform and the class page . Transform 's entry has one link that goes to the class page, but that appears to be a fluke of it using a CRTP base class. Some cross-links don't go to namespacelsst.html , such as the link to meas::base::FluxResultKey on DipoleFluxAlgorithm's page . This is the behavior we want, but the inconsistency, combined with the previous issue, may be confusing and frustrating for users. It would help if you included lsst::geom in future demos; IIRC those classes are both thoroughly documented and use some more C++11 features, so they'd be a good contrasting case to some of the older code in afw .
            Hide
            jsick Jonathan Sick added a comment -

            Thanks Krzysztof Findeisen, that's great feedback. I agree this probably isn't yet better than what we have and warrants more work. (cc Frossie Economou, John Swinbank).

            I appreciate your comments about search. For the cases when you are browsing, or at least, are looking at a landing page for the API, are you most interested in the namespace hierachy or in a header-file based grouping?

            Going forward, I'm thinking that our options are:

            1. Build a customized version of exhale. After all, exhale is only generating rst files with stubs for automodapi. If we know exactly what we want, I can possibly build a simpler extension that avoids exhale's issues.
            2. Look into autodoxy (something I found embedded in a project called simgrid), which might be another good basis.
            3. Use Documenteer's newfound ability to drive the Doxygen build, and use that embed the Doxygen HTML into the pipelines.lsst.io side and use an extension like doxylink to link to the Doxygen site.
            Show
            jsick Jonathan Sick added a comment - Thanks Krzysztof Findeisen , that's great feedback. I agree this probably isn't yet better than what we have and warrants more work. (cc Frossie Economou , John Swinbank ). I appreciate your comments about search. For the cases when you are browsing, or at least, are looking at a landing page for the API, are you most interested in the namespace hierachy or in a header-file based grouping? Going forward, I'm thinking that our options are: Build a customized version of exhale. After all, exhale is only generating rst files with stubs for automodapi. If we know exactly what we want, I can possibly build a simpler extension that avoids exhale's issues. Look into autodoxy  (something I found embedded in a project called simgrid), which might be another good basis. Use Documenteer's newfound ability to drive the Doxygen build, and use that embed the Doxygen HTML into the pipelines.lsst.io side and use an extension like doxylink to link to the Doxygen site.
            Hide
            krzys Krzysztof Findeisen added a comment - - edited

            For the cases when you are browsing, or at least, are looking at a landing page for the API, are you most interested in the namespace hierachy or in a header-file based grouping?

            Usually I already have an object of a particular class (and can figure out its namespace from context) and want to know more about its methods, so the former. But I'm not sure my perspective is the typical one. Maybe ask John Parejko for a second opinion, as a C++ developer who thinks Pythonically?

            I should add that the package-level index used in the Sphinx Python docs is easier to navigate than the hierarchical tree used by Doxygen and exhale, not least because it involves less clicking.

            Going forward, I'm thinking that our options are:

            What about DM-22499?

            Show
            krzys Krzysztof Findeisen added a comment - - edited For the cases when you are browsing, or at least, are looking at a landing page for the API, are you most interested in the namespace hierachy or in a header-file based grouping? Usually I already have an object of a particular class (and can figure out its namespace from context) and want to know more about its methods, so the former. But I'm not sure my perspective is the typical one. Maybe ask John Parejko for a second opinion, as a C++ developer who thinks Pythonically? I should add that the package-level index used in the Sphinx Python docs is easier to navigate than the hierarchical tree used by Doxygen and exhale, not least because it involves less clicking. Going forward, I'm thinking that our options are: What about DM-22499 ?
            Hide
            Parejkoj John Parejko added a comment -

            Catching up on this: I personally barely think about files at all when visualizing an API and only think about the class and namespace hierarchy. Granted the structure is more rigid in our C++ code than in our python code, but as Krzysztof knows, when I go to our doxygen, I go straight to either the namespace or class heirarchy.

            Show
            Parejkoj John Parejko added a comment - Catching up on this: I personally barely think about files at all when visualizing an API and only think about the class and namespace hierarchy. Granted the structure is more rigid in our C++ code than in our python code, but as Krzysztof knows, when I go to our doxygen, I go straight to either the namespace or class heirarchy.
            Hide
            jsick Jonathan Sick added a comment -

            I'm marking this ticket as "Done" as we've proved that exhale is suitable for the pipelines.lsst.io project. Going forward, we're focussing on the Doxygen HTML build + Doxylink approach (DM-23094).

            For archival purposes, I've attached Git patches of the additions to https://github.com/lsst/pipelines_lsst_io and https://github.com/lsst-sqre/documenteer associated with the exhale proof-of-concept. The draft PIpelines documentation build is still available at https://pipelines.lsst.io/v/DM-22500

            Show
            jsick Jonathan Sick added a comment - I'm marking this ticket as "Done" as we've proved that exhale is suitable for the pipelines.lsst.io project. Going forward, we're focussing on the Doxygen HTML build + Doxylink approach ( DM-23094 ). For archival purposes, I've attached Git patches of the additions to https://github.com/lsst/pipelines_lsst_io and https://github.com/lsst-sqre/documenteer associated with the exhale proof-of-concept. The draft PIpelines documentation build is still available at https://pipelines.lsst.io/v/DM-22500

              People

              Assignee:
              jsick Jonathan Sick
              Reporter:
              jsick Jonathan Sick
              Watchers:
              John Parejko, Jonathan Sick, Krzysztof Findeisen
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved:

                  Jenkins

                  No builds found.