8/04/2021

Sphinx 기반의 문서정리2 (Doxygen)

1. Sphinx 기본사용법 


Sphinx 기본설치 및 기본사용법 
문서를 처음 5월/6월에 작성했으나, 너무 길어져서 확장하여 8월 분할작성 

Sphinx기반의 ReadTheDoc Hosting
ReadTheDoc Hosting 및 관리가 쉬워서 개인이라면 이방법을 강력추천

Sphinx 와 Github를 연결해보고 사용하겠다고 여러방법으로 테스트 해봤지만, 
가장좋은 것은 현재 ReadtheDoc 사이트에서 Hosting하는게 가장편한 것으로 보인다.  

1.1 Sphinx extension 확장사용 

요즘 Markdown File이 대세이므로, RST파일과 Markdown를 동시에 같이 사용하도록 기능을 확장하도록하자. 
기존에는Markdown은 recommonmark기반으로 사용했다고 하는데, 
myst가 이를 호환해준다고 하고 Sphinx 사이트에서도 이걸로 거의 권장하는 것 같다. 
그리고, 가장 큰 이유는 Github와 호환성때문이다. 


  • markdown 과 mermaid 관련설치
myst_parser만 사용진행 (recommonmakr는 생략사용법은 생략)
(py38-sphinx) $ pip3 install myst_parser
(py38-sphinx) $ pip3 install sphinxcontrib-mermaid  // 옵션이며, extensions 씨 필요없다면 삭제  (간단한 diagram 사용) 

  • mermaid 기본사용법
Mermaid는 Diagram Tool로 오래전부터 Doxygen과 같이 많이 사용되어진  프로그램으로, 가장 많이 사용되는 Tool 이다. 
최근 Github에서도 지원가능하므로, 알아두도록하자 


  • Markdown 관련설정변경 
Markdown 기반으로 하기 위해서 아래와 같이 설정을 변경
(py38-sphinx) $ vi conf.py

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
        'sphinx.ext.autodoc',      # autodoc 안에 automodule 도 포함
        'sphinx.ext.autosummary',  # 현재미사용
        'myst_parser',            # Markdown을 위해서 사용
        'sphinxcontrib.mermaid',  # Mermaid Diagram을 위해서 사용  
]

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']

## 옵션으로 markdown 안에 ::: 되는 것을 동작되기 위해서 설정 RST와 같이 사용가능할것 같음 
## :::{note}
## And here's a note with a colon fence!
## :::
myst_enable_extensions = [
  "colon_fence",
]

## Source Suffix 설정 (rst,md) 
source_suffix = {
    '.rst': 'restructuredtext',
    '.txt': 'restructuredtext',
    '.md': 'markdown',
}


Sphinx-markdown 설치 및 설정 

  • Markdown 예제구성
일반 Markdown이 아닌 RST에서도 사용가능한 기능으로 확장 및 이외 diagram 추가
class에 warning/note/이외 다양한 rst directive 추가가능    
(py38-sphinx) $ vi test1.md
## TEST MD 

Markdown 에서 RST의 directive를 사용해보자  

```{admonition} Here's my note
:class: note

Here's my admonition content 
```

```{admonition} TEST Title
:class: warning

Here's my admonition content 
```

:::{note}
상위에서 설정한 colon fence! 기능 ㅋㅋㅋ
:::


mermaid 사용법임 아래 링크 참조
```{mermaid}
sequenceDiagram
  participant Alice
  participant Bob
  Alice->John: Hello John, how are you?
  loop Healthcheck
      John->John: Fight against hypochondria
  end
  Note right of John: Rational thoughts <br/>prevail...
  John-->Alice: Great!
  John->Bob: How about you?
  Bob-->John: Jolly good!
```
Markdown에서 상위 directive 사용법 

  • Markdown 관련 주의사항
  1. markdown의 # 와 ## 와 ###에 따라 계층이 나누어지므로 조심해서 사용
  2. markdown 외부 Link (http) 동작확인
  3. markdown 내부 Link는 동작확인 (HTML로 자동변경)
  4. markdown 내부 title 링크가 제대로 동작안됨 (*.md->*.html로 변경안됨)

  • index.rst의 재구성 (Markdown 사용)
Markdown을 추가하여 index를 재구성한 후 다시 확인 
(py38-sphinx) $ vi index.rst
.. toctree::
   :maxdepth: 3
   :caption:  Table of Contents
   :numbered:
   
   intro
   test1.md   
   mytest/testa.md
   mytest/testb.md   

(py38-sphinx) $ make clean  //삭제 후 진행 
(py38-sphinx) $ make html   //_build/html/index.html 확인 

index.rst 의 toctree 설정구성 

  • Markdown 상위 결과확인 (Mermaid)
테스트 용으로 Github(Mermaid 지원) 일단 기본으로 동작확인




Github 기반으로 아래와 같이 구성 후 간단히 테스트만 해봤지만, Github의 docs/ 내부는 세부적으로 연결해줘야하는 것 같다.

(py38-sphinx) $ vi index.rst   //Github일 경우 아래 구성으로 구성후 기본테스트만함(불필요한 index 및 다 지움)
.. toctree::
   :maxdepth: 3
   :caption:  Table of Contents
   :numbered:
   
   README.md
              
(py38-sphinx) $ make clean  //삭제 후 진행 
(py38-sphinx) $ make html   //_build/html/index.html 확인 

1.2 Sphinx 의 Output 변경 (Latex/Others) 

HTML 이외의 Output은 구성은 어떻게 되는 지 궁금해서 일단 테스트 진행 
하지만 테스트 결과 HTML만 괜찮은 걸로 보임 

  • 관련 Tool 설치 
(py38-sphinx) $ sudo apt-get install -y latexmk //latexmk 필요   
(py38-sphinx) $ sudo apt-get install texlive-full  //texlive  필요   

  • Latex 설정변경 
Letex 관련설정하여 테스트만 해보고 괜찮게 나오는지만 파악 
(py38-sphinx) $ vi conf.py   // Latex 관련설정추가   

# -- Options for LaTeX output ------------------------------------------------
latex_engine = 'xelatex'
latex_elements = {
    # The paper size ('letterpaper' or 'a4paper').
    #
    'papersize': 'a4paper',

    # The font size ('10pt', '11pt' or '12pt').
    #
    'pointsize': '10pt',

    # Additional stuff for the LaTeX preamble.
    #
    'preamble': '',

    # Latex figure (float) alignment
    #
    'figure_align': 'htbp',


    # kotex config
    'figure_align': 'htbp',

    'fontpkg': r'''
\usepackage{kotex}
''',
} 

Sphinx Latex 관련설정 및 Font 설정 (출처)
  • Sphinx Builder 로 Output 변경 
(py38-sphinx) $ make latexpdf   // Latex로 출력  
(py38-sphinx) $ make epub   // epub로 출력  
(py38-sphinx) $ make man   // man로 출력  
(py38-sphinx) $ sphinx-build --help  //sphinx-build 사용법확인

일단 한글은 제대로 안되었는데, PDF 파일 뿐만 아니라 다른 Output도 구성이 너무 좋지 않음  

Sphinx의 다양한 output 지원
HTML를 빼고 Theme 및 구성이 제대로 되지 않아 거의 사용안할 듯 


2. Sphinx 와 doxygen 연결  

  • Sphinx 기반의 Doxygen 구성이해(필독)
Python Sphinx 기반의 Doxygen 구성분석 및 필요 Package들 파악 
toctree 예제 및 ESP-IDF이 구성을 자세히 이해할수가 있음 


2.1 ESP32의 Sphinx 와 doxygen 테스트

ESP의 Sphinx가 너무 잘 구현되어있어서, 그것을 그대로 한번 따라 해보려고 했는데, 
버전이 너무 낮아서 아래는 진행하지 않기로 했다. 
나와 같이 삽질하는 사람이 있을 거 같아 기록으로만 남김. 
  • ESP32 의 Sphinx 와 doxygen 사용
sphinx와 doxygen을 TEST을 위해서 기존의  ESP관련부분 참조 
(py38-sphinx) $ cp -a ~/esp/esp-idf/docs espdocs   //esp의 doc를 doxygen으로 만들예정 

(py38-sphinx) $ cd espdocs   //esp의 doc를 doxygen으로 만들예정 

(py38-sphinx) $ pip3 install breathe           //sphinx 와 doxygen 사이의 bridge 역할한다고 함

(py38-sphinx) $ cat requirements.txt 
# This is a list of python packages used to generate documentation. This file is used with pip:
# pip install --user -r requirements.txt
#
# matplotlib is currently required only by the script generate_chart.py
matplotlib==3.3.1 ; python_version>="3"
matplotlib==2.0.1 ; python_version=="2.7"
cairosvg==2.5.1 # required by sphinxcontrib-svg2pdfconverter[CairoSVG]
sphinx==2.3.1
breathe==4.14.1
sphinx-copybutton==0.3.0
sphinx-notfound-page
sphinxcontrib-blockdiag==2.0.0
sphinxcontrib-seqdiag==2.0.0
sphinxcontrib-actdiag==2.0.0
sphinxcontrib-nwdiag==2.0.0
sphinxcontrib-wavedrom==2.0.0
sphinxcontrib-svg2pdfconverter[CairoSVG]==1.1.0
nwdiag==2.0.0
recommonmark
future>=0.16.0 # for ../tools/gen_esp_err_to_name.py
sphinx_selective_exclude==1.0.3
sphinx_idf_theme==0.2.2

(py38-sphinx) $ pip3 install -r requirements.txt   //절대 실행하지 말자. 버전에 전부 너무 아래이며 오래된 package 사용 (venv 다시 설치, 젠장) 
(py38-sphinx) $ python3 build_docs.py   //확실히 기존의 sphinx 구조와 다르며 필요한 것은 다 직접구현 
IDF_PATH로 문제발생 

상위부분은 실패했으며, 분석해서 하려고 했으나 내가 원하는 방향하고 다른 것 같아 여기서 멈춘다 
상위 Sphinx는 ESP-IDF의 Sphinx인데, 너무 오래된 Version의 Sphinx를 사용하고 있다. 
그리고 부족한 부분들의 거의 직접구현하고 연결해서 사용하는 것으로 보인다. 

상위를 진행하면 전부 Version이 Downgrade 되므로 주의 
귀찮아서 기존의 venv를 지우고, 다시 venv 기반으로 sphinx 재설치
상위는 하지말도록하자. 

2.2  Doxygen 과 Sphinx를 Breath 연결구성 

  • ESP Exampel을 이용하여 Doxygen 생성 
일단 C소스가 필요하니, ESP Example을 가져와서 이 기반으로 doxygen을 생성하자. 
관련 package들은 우선 설치를 진행 
(py38-sphinx) $ sudo apt install doxygen     //doxygen 이 없어서 설치 
(py38-sphinx) $ sudo apt install doxygen-latex doxygen-doc  //doxygen 관련 package 설치
(py38-sphinx) $ doxygen-gui graphviz   //오래전부터 graphviz랑 같이사용 

(py38-sphinx) $ mkdir doxydocs   //venv로 이미 설치진행완료 

(py38-sphinx) $ cd doxydocs 

(py38-sphinx) $ cp -a ~/esp/esp-idf/examples  .    //esp32 examples 소스만 가져옴 

(py38-sphinx) $ cmake -version
cmake version 3.16.3

(py38-sphinx) $ doxygen -v
1.8.17 

(py38-sphinx) $ doxygen -g   //Doxyfile 생성 

(py38-sphinx) $ vi Doxyfile    //생성된 Doxyfile 의 설정들을 변경해주자 (소스위치/XML/기타등등)
PROJECT_NAME           = "ESP Sample"
INPUT                  = ./examples 
RECURSIVE              = YES
GENERATE_XML           = YES

(py38-sphinx) $ doxygen       //Doxyfile 기준으로 Doxygen 실행  

(py38-sphinx) $ ls    //html 와 xml 생성확인 HTML을 우선확인해보자  
Doxyfile  examples  html  latex   xml

  • 생성된 Doxygen 구성확인 
  1. 상위 HTML에서 쉽게 생성된 Doxygen 파일 확인 가능 (index.html)
  2. Latex에서는 PDF 파일 확인가능 
  3. XML은 breathe를 위해 사용예정 

나의 경우 Doxygen 자료가 없어서 ESP의 Sample 이용 



  • Sphinx 와 Breathe 기반으로 Doxygen 연결 
Breathe를 기반으로 Doxygen XML을 이용하여 Sphinx 와 연결 

(py38-sphinx) $ mkdir docs
(py38-sphinx) $ cd docs

(py38-sphinx) $ pip3 install breathe           //sphinx 와 doxygen 사이의 bridge 역할한다고 함

(py38-sphinx) $ sphinx-quickstart     //sphinx start 실행  

(py38-sphinx) $ vi conf.py 
## Extension을 위해서 설정 
import os
import sys
sys.path.insert(0, os.path.abspath('.'))

## 만약 Shell Script 형식으로 사용하고자 하면 사용 
#import subprocess
#subprocess.call('make clean', shell=True)
#subprocess.call('cd ../../doxygen ; doxygen', shell=True)

## breathe 설정으로 상위생성된 XML 연결  
breathe_projects = { "ESP Sample": "../xml/" }
breathe_default_project = "ESP Sample"


## Extension에 breathe 추가 및 기타 추가 (필요 없다면 빼자) 
extensions = [
    'sphinx.ext.autodoc',
    'sphinx.ext.doctest',
    'sphinx.ext.mathjax',
    'sphinx.ext.viewcode',
    'sphinx.ext.imgmath',
    'sphinx.ext.todo',
    'breathe',
]

html_theme = 'sphinx_rtd_theme'

(py38-sphinx) $ vi index.rst      // 아래와 같이 설정하면 시간 엄청 오래걸리며 이상하게 생성됨  
.. toctree::
   :maxdepth: 2
   :caption: Contents:

.. doxygenindex::
.. doxygenfunction::
.. doxygenstruct::
.. doxygenenum::
.. doxygentypedef::
.. doxygenclass::

(py38-sphinx) $ make html

  • 결과확인 
비록 ESP의 Sample을 가지고 했지만, 아래와 같이 Doxygen 형태로 나옴




(py38-sphinx) $ vi test0.rst      // @breif 가 있는 함수를 찾아 함수명으로 추출  
C  Functions
-------------

.. doxygenfunction:: ws2812_rmt_adapter

(py38-sphinx) $ vi index.rst      // 확인  
.. toctree::
   :maxdepth: 2
   :caption: Contents:

   test0   
   
(py38-sphinx) $ make html

breathe 기본사용법 


2.3 기타 Doxygen 테스트 

  • Cmake 와 Doxygen 설치 및 확인 

$ cmake -version
cmake version 3.16.3

$ sudo apt install doxygen
$ sudo apt install doxygen-latex doxygen-doc doxygen-gui graphviz 
$ sudo apt install xapian-tools

$ doxygen -v
1.8.17 

https://github.com/jacking75/examples_CMake
git clone https://github.com/ttroy50/cmake-examples.git
//git clone https://github.com/sinairv/Cpp-Tutorial-Samples.git
//$ git clone https://github.com/googleapis/google-cloud-cpp
//$ git clone https://github.com/GoogleCloudPlatform/cpp-samples

https://github.com/GoogleCloudPlatform/python-docs-samples
https://github.com/GoogleCloudPlatform/nodejs-docs-samples
https://github.com/GoogleCloudPlatform/ai-platform-samples


https://breathe.readthedocs.io/en/latest/directives.html#doxygenstruct

$ mkdir docs
$ cd docs
$ doxygen -g   //Doxyfile 생성 

$ vi Doxyfile
PROJECT_NAME           = "Google CPP Sample"
INPUT                  = ../cpp-samples
RECURSIVE              = YES

$ doxygen         // 생성확인


$ cd ..
$ ls 
cpp-samples  docs  py38-sphinx

$ find . -name CMakeLists.txt
./cpp-samples/gcs-fast-transfers/CMakeLists.txt
./cpp-samples/iot/mqtt-ciotc/CMakeLists.txt
./cpp-samples/cloud-run-hello-world/CMakeLists.txt
./cpp-samples/populate-bucket/CMakeLists.txt
./cpp-samples/speech/api/CMakeLists.txt
./cpp-samples/gcs-indexer/CMakeLists.txt


$ vi CMakeLists.txt
cmake_minimum_required (VERSION 3.8)
project ("Sphinx Example")
add_subdirectory ("Cpp-Tutorial-Samples")
add_subdirectory ("docs")

$ vi docs/CMakeLists.txt
find_package(Doxygen REQUIRED)

#This will be the main output of our command
set(DOXYGEN_INDEX_FILE ${CMAKE_CURRENT_SOURCE_DIR}/html/index.html)

add_custom_command(OUTPUT ${DOXYGEN_INDEX_FILE}
                   DEPENDS ${CAT_CUTIFIER_PUBLIC_HEADERS}
                   COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
                   WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
                   MAIN_DEPENDENCY Doxyfile
                   COMMENT "Generating docs")

add_custom_target(Doxygen ALL DEPENDS ${DOXYGEN_INDEX_FILE})

$ vi docs/Doxyfile.in
#...
INPUT = "@DOXYGEN_INPUT_DIR@"
#...
OUTPUT_DIRECTORY = "@DOXYGEN_OUTPUT_DIR@"
#...

$ vi docs/CMakeLists.txt
find_package(Doxygen REQUIRED)

set(DOXYGEN_INPUT_DIR ${PROJECT_SOURCE_DIR}/cpp-samples)
set(DOXYGEN_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/docs/doxygen)
set(DOXYGEN_INDEX_FILE ${DOXYGEN_OUTPUT_DIR}/html/index.html)
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)

file(MAKE_DIRECTORY ${DOXYGEN_OUTPUT_DIR}) #Doxygen won't create this for us
add_custom_command(OUTPUT ${DOXYGEN_INDEX_FILE}
                   DEPENDS ${CAT_CUTIFIER_PUBLIC_HEADERS}
                   COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYFILE_OUT}
                   MAIN_DEPENDENCY ${DOXYFILE_OUT} ${DOXYFILE_IN}
                   COMMENT "Generating docs")

add_custom_target(Doxygen ALL DEPENDS ${DOXYGEN_INDEX_FILE})

$ cmake -Btest
$ cmkae --build test
$ cmake CMakeLists.txt

$ vi cpp-samples/CMakeLists.txt
cmake_minimum_required (VERSION 3.8)
project ("Google Sample")

add_subdirectory ("gcs-fast-transfers")
add_subdirectory ("iot/mqtt-ciotc")
add_subdirectory ("cloud-run-hello-world")
add_subdirectory ("populate-bucket")
add_subdirectory ("speech/api")
add_subdirectory ("gcs-indexer")



$ sudo apt-get install lynx    // HTML viewer로 설치했으나, 너무 좋지않아 필요없음 


bazel 사용법


Github Page 설정관련 (Web 관련부분)

RST 와 Markdown

Github 기반으로 Technical 관련문서를 만드는 사이트 

Github기반으로 Sphinx로 이용하여 문서만드는 예제 


댓글 없음 :