1# SPDX-License-Identifier: Apache-2.0
2
3cmake_minimum_required(VERSION 3.20.0)
4project(Zephyr-Kernel-Doc LANGUAGES)
5
6set(NO_BOILERPLATE TRUE)
7find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE} ..)
8
9file(TO_CMAKE_PATH "${ZEPHYR_BASE}" ZEPHYR_BASE)
10message(STATUS "Zephyr base: ${ZEPHYR_BASE}")
11
12#-------------------------------------------------------------------------------
13# Options
14
15set(SPHINXOPTS "-j auto" CACHE STRING "Default Sphinx Options")
16set(LATEXMKOPTS "-halt-on-error -no-shell-escape" CACHE STRING "Default latexmk options")
17set(DOC_TAG "development" CACHE STRING "Documentation tag")
18set(DTS_ROOTS "${ZEPHYR_BASE}" CACHE STRING "DT bindings root folders")
19
20separate_arguments(SPHINXOPTS)
21separate_arguments(LATEXMKOPTS)
22
23#-------------------------------------------------------------------------------
24# Dependencies
25
26find_package(Doxygen REQUIRED dot)
27
28find_program(SPHINXBUILD sphinx-build)
29if(NOT SPHINXBUILD)
30  message(FATAL_ERROR "The 'sphinx-build' command was not found")
31endif()
32
33find_package(LATEX COMPONENTS PDFLATEX)
34find_program(LATEXMK latexmk)
35if(NOT LATEX_PDFLATEX_FOUND OR NOT LATEXMK)
36  message(WARNING "LaTeX components not found. PDF build will not be available.")
37endif()
38
39include(${ZEPHYR_BASE}/cmake/python.cmake)
40
41# Find west to (optionally) process modules for Kconfig
42find_program(WEST west)
43
44#-------------------------------------------------------------------------------
45# Environment & Paths
46
47set(SPHINX_ENV
48  DOXYGEN_EXECUTABLE=${DOXYGEN_EXECUTABLE}
49  DOT_EXECUTABLE=${DOXYGEN_DOT_EXECUTABLE}
50)
51
52set(DOCS_CFG_DIR ${CMAKE_CURRENT_LIST_DIR})
53set(DOCS_DOCTREE_DIR ${CMAKE_CURRENT_BINARY_DIR}/doctrees)
54set(DOCS_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR})
55set(DOCS_SRC_DIR ${CMAKE_CURRENT_BINARY_DIR}/src)
56set(DOCS_HTML_DIR ${CMAKE_CURRENT_BINARY_DIR}/html)
57set(DOCS_LATEX_DIR ${CMAKE_CURRENT_BINARY_DIR}/latex)
58
59#-------------------------------------------------------------------------------
60# Functions
61
62# Create a custom doc target.
63#
64# This function has the same signature as `add_custom_target()`
65#
66# The function will create two targets for the doc build system.
67# - Target 1 named: `<name>`
68# - Target 2 named: `<name>-nodeps`
69#
70# Both targets will produce same result, but target 2 must have no dependencies.
71# This is useful to, e.g. re-run the Sphinx build without dependencies such as
72# devicetree or Kconfig generators.
73#
74function(add_doc_target name)
75  add_custom_target(${name} ${ARGN})
76  add_custom_target(${name}-nodeps ${ARGN})
77endfunction()
78
79#-------------------------------------------------------------------------------
80# Doxygen (standalone)
81
82set(DOXY_OUT ${CMAKE_CURRENT_BINARY_DIR}/doxygen)
83set(DOXYFILE_IN ${CMAKE_CURRENT_LIST_DIR}/zephyr.doxyfile.in)
84set(DOXYFILE_OUT ${CMAKE_CURRENT_BINARY_DIR}/zephyr.doxyfile)
85
86configure_file(${DOXYFILE_IN} ${DOXYFILE_OUT} @ONLY)
87
88add_custom_target(
89  doxygen
90  COMMAND
91    ${DOXYGEN_EXECUTABLE} ${DOXYFILE_OUT}
92  COMMENT "Running Doxygen..."
93)
94
95set_target_properties(
96  doxygen
97  PROPERTIES
98    ADDITIONAL_CLEAN_FILES "${DOXY_OUT}"
99)
100
101#-------------------------------------------------------------------------------
102# kconfig
103
104set(KCONFIG_BINARY_DIR ${CMAKE_BINARY_DIR}/Kconfig)
105list(INSERT MODULE_EXT_ROOT 0 ${ZEPHYR_BASE})
106file(MAKE_DIRECTORY ${KCONFIG_BINARY_DIR})
107
108include(${ZEPHYR_BASE}/cmake/extensions.cmake)
109include(${ZEPHYR_BASE}/cmake/zephyr_module.cmake)
110
111foreach(module_name ${ZEPHYR_MODULE_NAMES})
112  zephyr_string(SANITIZE TOUPPER MODULE_NAME_UPPER ${module_name})
113  list(APPEND
114       ZEPHYR_KCONFIG_MODULES
115       "ZEPHYR_${MODULE_NAME_UPPER}_MODULE_DIR=${ZEPHYR_${MODULE_NAME_UPPER}_MODULE_DIR}"
116  )
117
118  if(ZEPHYR_${MODULE_NAME_UPPER}_KCONFIG)
119    list(APPEND
120         ZEPHYR_KCONFIG_MODULES
121         "ZEPHYR_${MODULE_NAME_UPPER}_KCONFIG=${ZEPHYR_${MODULE_NAME_UPPER}_KCONFIG}"
122    )
123  endif()
124endforeach()
125
126if(WIN32)
127  set(SEP $<SEMICOLON>)
128else()
129  set(SEP :)
130endif()
131
132set(GEN_KCONFIG_REST_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/_scripts/gen_kconfig_rest.py)
133
134add_custom_target(
135  kconfig
136  COMMAND ${CMAKE_COMMAND} -E make_directory ${DOCS_SRC_DIR}/reference/kconfig
137  COMMAND ${CMAKE_COMMAND} -E env
138  PYTHONPATH=${ZEPHYR_BASE}/scripts/kconfig${SEP}$ENV{PYTHONPATH}
139  ZEPHYR_BASE=${ZEPHYR_BASE}
140  srctree=${ZEPHYR_BASE}
141  BOARD_DIR=boards/*/*
142  ARCH=*
143  ARCH_DIR=arch
144  SOC_DIR=soc
145  TOOLCHAIN_HAS_NEWLIB=y
146  KCONFIG_BINARY_DIR=${KCONFIG_BINARY_DIR}
147  KCONFIG_WARN_UNDEF=y
148  KCONFIG_TURBO_MODE=${KCONFIG_TURBO_MODE}
149  KCONFIG_DOC_MODE=1
150  ${ZEPHYR_KCONFIG_MODULES}
151    ${PYTHON_EXECUTABLE} ${GEN_KCONFIG_REST_SCRIPT} ${DOCS_SRC_DIR}/reference/kconfig/
152      --separate-all-index
153      --keep-module-paths
154      --modules Architecture,arch,${ZEPHYR_BASE}/arch
155                Driver,drivers,${ZEPHYR_BASE}/drivers
156                Kernel,kernel,${ZEPHYR_BASE}/kernel
157                Library,lib,${ZEPHYR_BASE}/lib
158                Subsystem,subsys,${ZEPHYR_BASE}/subsys
159                "External Module,modules,${ZEPHYR_BASE}/modules"
160
161  VERBATIM
162  COMMENT "Generating Kconfig documentation..."
163)
164
165set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${GEN_KCONFIG_REST_SCRIPT})
166
167#-------------------------------------------------------------------------------
168# devicetree
169
170set(GEN_DEVICETREE_REST_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/_scripts/gen_devicetree_rest.py)
171
172set(DTS_ROOT_ARGS)
173foreach(root ${DTS_ROOTS})
174  list(APPEND DTS_ROOT_ARGS --dts-root ${root})
175endforeach()
176
177add_custom_target(
178  devicetree
179  COMMAND ${CMAKE_COMMAND} -E env
180  PYTHONPATH=${ZEPHYR_BASE}/scripts/dts/python-devicetree/src${SEP}$ENV{PYTHONPATH}
181  ZEPHYR_BASE=${ZEPHYR_BASE}
182  ${PYTHON_EXECUTABLE} ${GEN_DEVICETREE_REST_SCRIPT}
183    --vendor-prefixes ${ZEPHYR_BASE}/dts/bindings/vendor-prefixes.txt
184    ${DTS_ROOT_ARGS}
185    ${DOCS_SRC_DIR}/reference/devicetree
186  VERBATIM
187  USES_TERMINAL
188  COMMENT "Generating Devicetree bindings documentation..."
189)
190
191set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${GEN_DEVICETREE_REST_SCRIPT})
192
193#-------------------------------------------------------------------------------
194# html
195
196add_doc_target(
197  html
198  COMMAND ${CMAKE_COMMAND} -E env ${SPHINX_ENV}
199  ${SPHINXBUILD}
200    -b html
201    -c ${DOCS_CFG_DIR}
202    -d ${DOCS_DOCTREE_DIR}
203    -w ${DOCS_BUILD_DIR}/html.log
204    -t ${DOC_TAG}
205    ${SPHINXOPTS}
206    ${DOCS_SRC_DIR}
207    ${DOCS_HTML_DIR}
208  USES_TERMINAL
209  COMMENT "Running Sphinx HTML build..."
210)
211
212set_target_properties(
213  html html-nodeps
214  PROPERTIES
215    ADDITIONAL_CLEAN_FILES "${DOCS_SRC_DIR};${DOCS_HTML_DIR};${DOCS_DOCTREE_DIR}"
216)
217
218add_dependencies(html devicetree kconfig)
219
220#-------------------------------------------------------------------------------
221# pdf
222
223add_doc_target(
224  latex
225  COMMAND ${CMAKE_COMMAND} -E env ${SPHINX_ENV}
226  ${SPHINXBUILD}
227    -b latex
228    -c ${DOCS_CFG_DIR}
229    -d ${DOCS_DOCTREE_DIR}
230    -w ${DOCS_BUILD_DIR}/latex.log
231    -t ${DOC_TAG}
232    -t svgconvert
233    ${SPHINXOPTS}
234    ${DOCS_SRC_DIR}
235    ${DOCS_LATEX_DIR}
236  USES_TERMINAL
237  COMMENT "Running Sphinx LaTeX build..."
238)
239
240set_target_properties(
241  latex latex-nodeps
242  PROPERTIES
243    ADDITIONAL_CLEAN_FILES "${DOCS_SRC_DIR};${DOCS_LATEX_DIR};${DOCS_DOCTREE_DIR}"
244)
245
246add_dependencies(latex kconfig devicetree)
247
248if(LATEX_PDFLATEX_FOUND AND LATEXMK)
249  if(WIN32)
250    set(PDF_BUILD_COMMAND "make.bat")
251  else()
252    find_program(MAKE make)
253    if(NOT MAKE)
254      message(FATAL_ERROR "The 'make' command was not found")
255    endif()
256    set(PDF_BUILD_COMMAND ${MAKE})
257  endif()
258
259  add_custom_target(
260    pdf
261    COMMAND ${CMAKE_COMMAND} -E env LATEXMKOPTS="${LATEXMKOPTS}"
262    ${PDF_BUILD_COMMAND}
263    WORKING_DIRECTORY ${DOCS_LATEX_DIR}
264    COMMENT "Building PDF file..."
265    USES_TERMINAL
266  )
267
268  add_dependencies(pdf latex)
269endif()
270
271#-------------------------------------------------------------------------------
272# others
273
274add_custom_target(
275  pristine
276  COMMAND ${CMAKE_COMMAND} -P ${ZEPHYR_BASE}/cmake/pristine.cmake
277)
278