1###############################################################################
2# Build documentation
3###############################################################################
4option(BUILD_DOC "Build LAMMPS HTML documentation" OFF)
5
6if(BUILD_DOC)
7  # Sphinx 3.x requires at least Python 3.5
8  if(CMAKE_VERSION VERSION_LESS 3.12)
9    find_package(PythonInterp 3.5 REQUIRED)
10    set(VIRTUALENV ${PYTHON_EXECUTABLE} -m virtualenv -p ${PYTHON_EXECUTABLE})
11  else()
12    find_package(Python3 REQUIRED COMPONENTS Interpreter)
13    if(Python3_VERSION VERSION_LESS 3.5)
14      message(FATAL_ERROR "Python 3.5 and up is required to build the HTML documentation")
15    endif()
16    set(VIRTUALENV ${Python3_EXECUTABLE} -m virtualenv -p ${Python3_EXECUTABLE})
17  endif()
18  find_package(Doxygen 1.8.10 REQUIRED)
19
20  file(GLOB DOC_SOURCES ${LAMMPS_DOC_DIR}/src/[^.]*.rst)
21
22
23  add_custom_command(
24    OUTPUT docenv
25    COMMAND ${VIRTUALENV} docenv
26  )
27
28  set(DOCENV_BINARY_DIR ${CMAKE_BINARY_DIR}/docenv/bin)
29  set(DOCENV_REQUIREMENTS_FILE ${LAMMPS_DOC_DIR}/utils/requirements.txt)
30
31  set(SPHINX_CONFIG_DIR ${LAMMPS_DOC_DIR}/utils/sphinx-config)
32  set(SPHINX_CONFIG_FILE_TEMPLATE ${SPHINX_CONFIG_DIR}/conf.py.in)
33  set(SPHINX_STATIC_DIR  ${SPHINX_CONFIG_DIR}/_static)
34
35  # configuration and static files are copied to binary dir to avoid collisions with parallel builds
36  set(DOC_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/doc)
37  set(DOC_BUILD_CONFIG_FILE ${DOC_BUILD_DIR}/conf.py)
38  set(DOC_BUILD_STATIC_DIR ${DOC_BUILD_DIR}/_static)
39  set(DOXYGEN_BUILD_DIR ${DOC_BUILD_DIR}/doxygen)
40  set(DOXYGEN_XML_DIR ${DOXYGEN_BUILD_DIR}/xml)
41
42  # copy entire configuration folder to doc build directory
43  # files in _static are automatically copied during sphinx-build, so no need to copy them individually
44  file(COPY ${SPHINX_CONFIG_DIR}/ DESTINATION ${DOC_BUILD_DIR})
45
46  # configure paths in conf.py, since relative paths change when file is copied
47  configure_file(${SPHINX_CONFIG_FILE_TEMPLATE} ${DOC_BUILD_CONFIG_FILE})
48
49  add_custom_command(
50    OUTPUT ${DOC_BUILD_DIR}/requirements.txt
51    DEPENDS docenv ${DOCENV_REQUIREMENTS_FILE}
52    COMMAND ${CMAKE_COMMAND} -E copy ${DOCENV_REQUIREMENTS_FILE} ${DOC_BUILD_DIR}/requirements.txt
53    COMMAND ${DOCENV_BINARY_DIR}/pip $ENV{PIP_OPTIONS} install --upgrade pip
54    COMMAND ${DOCENV_BINARY_DIR}/pip $ENV{PIP_OPTIONS} install --upgrade ${LAMMPS_DOC_DIR}/utils/converters
55    COMMAND ${DOCENV_BINARY_DIR}/pip $ENV{PIP_OPTIONS} install -r ${DOC_BUILD_DIR}/requirements.txt --upgrade
56  )
57
58  set(MATHJAX_URL "https://github.com/mathjax/MathJax/archive/3.1.3.tar.gz" CACHE STRING "URL for MathJax tarball")
59  set(MATHJAX_MD5 "d1c98c746888bfd52ca8ebc10704f92f" CACHE STRING "MD5 checksum of MathJax tarball")
60  mark_as_advanced(MATHJAX_URL)
61
62  # download mathjax distribution and unpack to folder "mathjax"
63  if(NOT EXISTS ${DOC_BUILD_STATIC_DIR}/mathjax/es5)
64    file(DOWNLOAD ${MATHJAX_URL}
65      "${CMAKE_CURRENT_BINARY_DIR}/mathjax.tar.gz"
66      EXPECTED_MD5 ${MATHJAX_MD5})
67    execute_process(COMMAND ${CMAKE_COMMAND} -E tar xzf mathjax.tar.gz WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
68    file(GLOB MATHJAX_VERSION_DIR ${CMAKE_CURRENT_BINARY_DIR}/MathJax-*)
69    execute_process(COMMAND ${CMAKE_COMMAND} -E rename ${MATHJAX_VERSION_DIR} ${DOC_BUILD_STATIC_DIR}/mathjax)
70  endif()
71
72  # set up doxygen and add targets to run it
73  file(MAKE_DIRECTORY ${DOXYGEN_BUILD_DIR})
74  file(COPY ${LAMMPS_DOC_DIR}/doxygen/lammps-logo.png DESTINATION ${DOXYGEN_BUILD_DIR}/lammps-logo.png)
75  configure_file(${LAMMPS_DOC_DIR}/doxygen/Doxyfile.in ${DOXYGEN_BUILD_DIR}/Doxyfile)
76  get_target_property(LAMMPS_SOURCES lammps SOURCES)
77  add_custom_command(
78    OUTPUT ${DOXYGEN_XML_DIR}/index.xml
79    DEPENDS ${DOC_SOURCES} ${LAMMPS_SOURCES}
80    COMMAND Doxygen::doxygen ${DOXYGEN_BUILD_DIR}/Doxyfile WORKING_DIRECTORY ${DOXYGEN_BUILD_DIR}
81    COMMAND ${CMAKE_COMMAND} -E touch ${DOXYGEN_XML_DIR}/run.stamp
82  )
83
84  if(EXISTS ${DOXYGEN_XML_DIR}/run.stamp)
85    set(SPHINX_EXTRA_OPTS "-E")
86  else()
87    set(SPHINX_EXTRA_OPTS "")
88  endif()
89  add_custom_command(
90    OUTPUT html
91    DEPENDS ${DOC_SOURCES} docenv ${DOC_BUILD_DIR}/requirements.txt ${DOXYGEN_XML_DIR}/index.xml ${BUILD_DOC_CONFIG_FILE}
92    COMMAND ${DOCENV_BINARY_DIR}/sphinx-build ${SPHINX_EXTRA_OPTS} -b html -c ${DOC_BUILD_DIR} -d ${DOC_BUILD_DIR}/doctrees ${LAMMPS_DOC_DIR}/src ${DOC_BUILD_DIR}/html
93    COMMAND ${CMAKE_COMMAND} -E create_symlink Manual.html ${DOC_BUILD_DIR}/html/index.html
94    COMMAND ${CMAKE_COMMAND} -E copy_directory ${LAMMPS_DOC_DIR}/src/PDF ${DOC_BUILD_DIR}/html/PDF
95    COMMAND ${CMAKE_COMMAND} -E remove -f ${DOXYGEN_XML_DIR}/run.stamp
96  )
97
98  add_custom_target(
99    doc ALL
100    DEPENDS html ${DOC_BUILD_STATIC_DIR}/mathjax/es5
101    SOURCES ${LAMMPS_DOC_DIR}/utils/requirements.txt ${DOC_SOURCES}
102  )
103
104  install(DIRECTORY ${DOC_BUILD_DIR}/html DESTINATION ${CMAKE_INSTALL_DOCDIR})
105endif()
106