• Sphinx 找不到 Doxygen 导出的 xml 中的内容的解决方法


    Sphinx + Breathe + Doxygen + CMake 的教程看这个就够了

    https://devblogs.microsoft.com/cppblog/clear-functional-c-documentation-with-sphinx-breathe-doxygen-cmake/

    但是他还是少写了一些东西,所以还是有一些小坑的

    这些坑会导致 Sphinx 找不到 Doxygen 导出的 xml 中的内容,或者是报错

    第一个是 conf.py 可能一直找不到 sphinx_rtd_theme 这个 module,即使你更新了 pip,重新下载了 sphinx_rtd_theme 好多遍,也没有办法

    这个原因很简单,就是因为他没有找到你的 python 下载包的路径

    我的 cmake 配置如下,主要是设置了一个虚拟环境,放在输出目录中,这样我们就可以不污染主机的 python 环境,也可以清楚地知道自己的包下载到哪里了

    projectRoot/CMakeLists.txt

    ...
    
    # Docs only available if this is the main app
    find_package(Doxygen)
    if(Doxygen_FOUND)
        message(STATUS "Found Doxygen, building docs")
        add_subdirectory(docs)
    else()
        message(STATUS "Doxygen not found, not building docs")
    endif()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    projectRoot/docs/CMakeLists.txt

    option(BUILD_DOCS_USE_VENV "Generate Python virtual environment" ON)
    
    find_package(Python COMPONENTS Interpreter REQUIRED)
    if (BUILD_DOCS_USE_VENV)
        set(DOCS_VENV "${CMAKE_CURRENT_BINARY_DIR}/venv")
        message(STATUS "Creating Python venv at ${DOCS_VENV}")
        execute_process(COMMAND ${Python_EXECUTABLE} -m venv ${DOCS_VENV})
        set(ENV{VIRTUAL_ENV} ${DOCS_VENV})
        set(Python_FIND_VIRTUALENV FIRST)
        unset(Python_EXECUTABLE)
        find_package(Python COMPONENTS Interpreter REQUIRED)
    
        execute_process(
            COMMAND ${Python_EXECUTABLE} -m pip install --no-cache wheel
            WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
            COMMAND_ERROR_IS_FATAL ANY
        )
        execute_process(
            COMMAND ${Python_EXECUTABLE} -m pip install --no-cache -r requirements.txt
            WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
            COMMAND_ERROR_IS_FATAL ANY
        )
    endif()
    
    execute_process(
        COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../helper/req_check.py requirements.txt
        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
        COMMAND_ERROR_IS_FATAL ANY
    )
    
    find_program(SPHINX_EXECUTABLE sphinx-build HINTS ${DOCS_VENV}/Scripts ${DOCS_VENV}/bin REQUIRED)
    message(STATUS "Found Sphinx: ${SPHINX_EXECUTABLE}")
    
    # Find all the public headers from runtime
    get_target_property(RUNTIME_PUBLIC_HEADER_DIR ${RUNTIME_NAME} INTERFACE_INCLUDE_DIRECTORIES)
    file(GLOB_RECURSE RUNTIME_PUBLIC_HEADERS CONFIGURE_DEPENDS ${RUNTIME_PUBLIC_HEADER_DIR}/*.h)
    
    # Find all the public headers from editor
    get_target_property(EDITOR_PUBLIC_HEADER_DIR ${EDITOR_NAME} INTERFACE_INCLUDE_DIRECTORIES)
    file(GLOB_RECURSE EDITOR_PUBLIC_HEADERS CONFIGURE_DEPENDS ${EDITOR_PUBLIC_HEADER_DIR}/*.h)
    
    message(--------------)
    message(STATUS "${RUNTIME_PUBLIC_HEADERS}")
    message(STATUS "${EDITOR_PUBLIC_HEADERS}")
    message(--------------)
    
    set(DOXYGEN_INPUT_DIR ${PROJECT_SOURCE_DIR}/src)
    set(DOXYGEN_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/doxygen)
    set(DOXYGEN_INDEX_FILE ${DOXYGEN_OUTPUT_DIR}/xml/index.xml)
    set(DOXYFILE_IN ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in)
    set(DOXYFILE_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
    
    # Replace variables inside @@ with the current values
    configure_file(${DOXYFILE_IN} ${DOXYFILE_OUT} @ONLY)
    
    # Doxygen won't create this for us
    file(MAKE_DIRECTORY ${DOXYGEN_OUTPUT_DIR})
    
    # Only regenerate Doxygen when the Doxyfile or public headers change
    add_custom_command(OUTPUT ${DOXYGEN_INDEX_FILE}
                       DEPENDS ${RUNTIME_PUBLIC_HEADERS} ${EDITOR_PUBLIC_HEADERS}
                       COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYFILE_OUT}
                       MAIN_DEPENDENCY ${DOXYFILE_OUT} ${DOXYFILE_IN}
                       COMMENT "Generating docs"
                       VERBATIM)
    
    # Nice named target so we can run the job easily
    add_custom_target(Doxygen ALL DEPENDS ${DOXYGEN_INDEX_FILE})
    
    set(SPHINX_SOURCE ${CMAKE_CURRENT_SOURCE_DIR})
    set(SPHINX_BUILD ${CMAKE_CURRENT_BINARY_DIR}/sphinx)
    set(SPHINX_INDEX_FILE ${SPHINX_BUILD}/index.html)
    
    # Only regenerate Sphinx when:
    # - Doxygen has rerun
    # - Our doc files have been updated
    # - The Sphinx config has been updated
    add_custom_command(OUTPUT ${SPHINX_INDEX_FILE}
                       COMMAND 
                         ${SPHINX_EXECUTABLE} -b html
                         # Tell Breathe where to find the Doxygen output
                         -Dbreathe_projects.MeowEngine=${DOXYGEN_OUTPUT_DIR}/xml
                       ${SPHINX_SOURCE} ${SPHINX_BUILD}
                       WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
                       DEPENDS
                       # Other docs files you want to track should go here (or in some variable)
                       ${CMAKE_CURRENT_SOURCE_DIR}/index.rst
                       ${DOXYGEN_INDEX_FILE}
                       MAIN_DEPENDENCY ${SPHINX_SOURCE}/conf.py
                       COMMENT "Generating documentation with Sphinx")
    
    # Nice named target so we can run the job easily
    add_custom_target(Sphinx ALL DEPENDS ${SPHINX_INDEX_FILE})
    
    # Add an install target to install the docs
    include(GNUInstallDirs)
    install(DIRECTORY ${SPHINX_BUILD}
    DESTINATION ${CMAKE_INSTALL_DOCDIR})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98

    其中,获取 Doxygen 所需要的头文件那里,那里是我自己的项目的情况,一个 runtime 一个 engine,这个具体实现因项目而异

    然后我们现在已经知道自己下载的包在哪里了,我们就在 conf.py 中直接把这个路径写进去

    projectRoot/docs/conf.py

    import sys
    from pathlib import Path
    
    sys.path.insert(0, str(Path('../build/docs/venv/Lib/site-packages/').resolve()))
    
    • 1
    • 2
    • 3
    • 4

    然后还有一点坑的就是,在 conf.py 中我们要写明 breathe 的项目的名称和对应的 doxygen 输出的 xml 的位置:

    projectRoot/docs/conf.py

    breathe_projects = {
        "MeowEngine": "../build/docs/doxygen/xml"
    }
    
    • 1
    • 2
    • 3

    完整的 conf.py

    projectRoot/docs/conf.py

    # Configuration file for the Sphinx documentation builder.
    #
    # For the full list of built-in configuration values, see the documentation:
    # https://www.sphinx-doc.org/en/master/usage/configuration.html
    
    # -- Project information -----------------------------------------------------
    # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
    
    import sys
    from pathlib import Path
    
    sys.path.insert(0, str(Path('../build/docs/venv/Lib/site-packages/').resolve()))
    
    import sphinx_rtd_theme
    
    project = 'MeowEngine'
    copyright = '2023, CheapMeow'
    author = 'CheapMeow'
    
    # -- General configuration ---------------------------------------------------
    # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
    
    extensions = ['sphinx_rtd_theme', 'breathe']
    
    breathe_projects = {
        "MeowEngine": "../build/docs/doxygen/xml"
    }
    
    templates_path = ['_templates']
    exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
    
    # -- Options for HTML output -------------------------------------------------
    # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
    
    html_theme = 'sphinx_rtd_theme'
    html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
    html_static_path = ['_static']
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    如果现在 sphinx 还是没有办法找到你的类的话,可能是你没有写明命名空间

    projectRoot/docs/index.rst

    .. doxygenclass:: Meow::MeowEngine
       :project: MeowEngine
       :members:
    
    • 1
    • 2
    • 3

    因为你可以看到 xml 里面的输出是带着命名空间的

    projectRoot/build/docs/doxygen/xml/class_meow_1_1_meow_engine.xml

      <compounddef id="class_meow_1_1_meow_engine" kind="class" language="C++" prot="public">
        <compoundname>Meow::MeowEnginecompoundname>
    
    • 1
    • 2
  • 相关阅读:
    SLAM_语义SLAM相关论文
    分页操作系统
    【牛客-剑指offer-数据结构篇】JZ23 链表中环的入口结点 两种实现 Java实现
    opencv4笔记
    C++ ——vector数组笔记
    2023年计算机毕设选题推荐
    『现学现忘』Git基础 — 17、Commit对象
    PDF文件无密码,如何解密?
    使用cpolar发布树莓派网页(cpolar隧道的完善)
    物联网设备通信
  • 原文地址:https://blog.csdn.net/hijackedbycsdn/article/details/132679827