1# SPDX-License-Identifier: Apache-2.0
2
3cmake_minimum_required(VERSION 3.20.0)
4project(Zephyr-Kernel-Doc LANGUAGES)
5
6set(MIN_WEST_VERSION 1.0.0)
7find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE} .. COMPONENTS doc)
8
9file(TO_CMAKE_PATH "${ZEPHYR_BASE}" ZEPHYR_BASE)
10message(STATUS "Zephyr base: ${ZEPHYR_BASE}")
11
12#-------------------------------------------------------------------------------
13# Options
14
15set(SPHINXOPTS "-j auto -W --keep-going -T" CACHE STRING "Default Sphinx Options")
16set(SPHINXOPTS_EXTRA "" CACHE STRING "Extra Sphinx Options (added to defaults)")
17set(LATEXMKOPTS "-halt-on-error -no-shell-escape" CACHE STRING "Default latexmk options")
18set(DT_TURBO_MODE OFF CACHE BOOL "Enable DT turbo mode")
19set(HW_FEATURES_TURBO_MODE OFF CACHE BOOL "Enable HW features turbo mode")
20set(DOC_TAG "development" CACHE STRING "Documentation tag")
21set(DTS_ROOTS "${ZEPHYR_BASE}" CACHE STRING "DT bindings root folders")
22
23separate_arguments(SPHINXOPTS)
24separate_arguments(SPHINXOPTS_EXTRA)
25separate_arguments(LATEXMKOPTS)
26
27#-------------------------------------------------------------------------------
28# Dependencies
29
30find_package(Doxygen REQUIRED dot)
31
32find_program(SPHINXBUILD sphinx-build)
33if(NOT SPHINXBUILD)
34  message(FATAL_ERROR "The 'sphinx-build' command was not found")
35endif()
36find_program(SPHINXAUTOBUILD sphinx-autobuild)
37
38find_package(LATEX COMPONENTS PDFLATEX)
39find_program(LATEXMK latexmk)
40if(NOT LATEX_PDFLATEX_FOUND OR NOT LATEXMK)
41  message(WARNING "LaTeX components not found. PDF build will not be available.")
42endif()
43
44#-------------------------------------------------------------------------------
45# Environment & Paths
46
47set(SPHINX_ENV
48  DOXYGEN_EXECUTABLE=${DOXYGEN_EXECUTABLE}
49  DOT_EXECUTABLE=${DOXYGEN_DOT_EXECUTABLE}
50  DOCS_HTML_DIR=${CMAKE_CURRENT_BINARY_DIR}/html
51)
52
53if(DEFINED ENV{ZEPHYR_DOXYGEN_OVERLAY})
54  if(EXISTS $ENV{ZEPHYR_DOXYGEN_OVERLAY})
55    set(INCLUDE_CUSTOM_FILE "@INCLUDE = $ENV{ZEPHYR_DOXYGEN_OVERLAY}")
56  else()
57    message(FATAL_ERROR "Zephyr Doxygen overlay $ENV{ZEPHYR_DOXYGEN_OVERLAY} does not exist!")
58  endif()
59else()
60  set(INCLUDE_CUSTOM_FILE "")
61endif()
62
63set(DOCS_CFG_DIR ${CMAKE_CURRENT_LIST_DIR})
64set(DOCS_DOCTREE_DIR ${CMAKE_CURRENT_BINARY_DIR}/doctrees)
65set(DOCS_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR})
66set(DOCS_SRC_DIR ${CMAKE_CURRENT_BINARY_DIR}/src)
67set(DOCS_HTML_DIR ${CMAKE_CURRENT_BINARY_DIR}/html)
68set(DOCS_LINKCHECK_DIR ${CMAKE_CURRENT_BINARY_DIR}/linkcheck)
69set(DOCS_LATEX_DIR ${CMAKE_CURRENT_BINARY_DIR}/latex)
70
71if(WIN32)
72  set(SEP $<SEMICOLON>)
73else()
74  set(SEP :)
75endif()
76
77#-------------------------------------------------------------------------------
78# Functions
79
80# Create a custom doc target.
81#
82# This function has the same signature as `add_custom_target()`
83#
84# The function will create two targets for the doc build system.
85# - Target 1 named: `<name>`
86# - Target 2 named: `<name>-nodeps`
87#
88# Both targets will produce same result, but target 2 must have no dependencies.
89# This is useful to, e.g. re-run the Sphinx build without dependencies such as
90# devicetree generator.
91#
92function(add_doc_target name)
93  add_custom_target(${name} ${ARGN})
94  add_custom_target(${name}-nodeps ${ARGN})
95endfunction()
96
97#-------------------------------------------------------------------------------
98# Doxygen (standalone)
99
100set(DOXY_OUT ${CMAKE_CURRENT_BINARY_DIR}/doxygen)
101set(DOXYFILE_IN ${CMAKE_CURRENT_LIST_DIR}/zephyr.doxyfile.in)
102set(DOXYFILE_OUT ${CMAKE_CURRENT_BINARY_DIR}/zephyr.doxyfile)
103set(ZEPHYR_VERSION "${Zephyr_VERSION}")
104
105configure_file(${DOXYFILE_IN} ${DOXYFILE_OUT} @ONLY)
106
107add_custom_target(
108  doxygen
109  COMMAND
110    ${DOXYGEN_EXECUTABLE} ${DOXYFILE_OUT}
111  COMMENT "Running Doxygen..."
112)
113
114set_target_properties(
115  doxygen
116  PROPERTIES
117    ADDITIONAL_CLEAN_FILES "${DOXY_OUT}"
118)
119
120#-------------------------------------------------------------------------------
121# devicetree
122
123set(GEN_DEVICETREE_REST_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/_scripts/gen_devicetree_rest.py)
124
125set(DTS_ARGS)
126foreach(root ${DTS_ROOTS})
127  list(APPEND DTS_ARGS --dts-root ${root})
128endforeach()
129
130if(DT_TURBO_MODE)
131  list(APPEND DTS_ARGS --turbo-mode)
132endif()
133
134add_custom_target(
135  devicetree
136  COMMAND ${CMAKE_COMMAND} -E env
137  PYTHONPATH=${ZEPHYR_BASE}/scripts/dts/python-devicetree/src${SEP}$ENV{PYTHONPATH}
138  ZEPHYR_BASE=${ZEPHYR_BASE}
139  ${PYTHON_EXECUTABLE} ${GEN_DEVICETREE_REST_SCRIPT}
140    --vendor-prefixes ${ZEPHYR_BASE}/dts/bindings/vendor-prefixes.txt
141    ${DTS_ARGS}
142    ${DOCS_SRC_DIR}/build/dts/api
143  VERBATIM
144  USES_TERMINAL
145  COMMENT "Generating Devicetree bindings documentation..."
146)
147
148set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${GEN_DEVICETREE_REST_SCRIPT})
149
150#-------------------------------------------------------------------------------
151# html
152
153set(SPHINX_TAGS "${DOC_TAG}")
154if(HW_FEATURES_TURBO_MODE)
155  list(APPEND SPHINX_TAGS "hw_features_turbo")
156endif()
157
158set(SPHINX_TAGS_ARGS "")
159foreach(tag ${SPHINX_TAGS})
160  list(APPEND SPHINX_TAGS_ARGS "-t" "${tag}")
161endforeach()
162
163add_doc_target(
164  html
165  COMMAND ${CMAKE_COMMAND} -E env ${SPHINX_ENV} OUTPUT_DIR=${DOCS_HTML_DIR}
166  ${SPHINXBUILD}
167    -b html
168    -c ${DOCS_CFG_DIR}
169    -d ${DOCS_DOCTREE_DIR}
170    -w ${DOCS_BUILD_DIR}/html.log
171    ${SPHINX_TAGS_ARGS}
172    ${SPHINXOPTS}
173    ${SPHINXOPTS_EXTRA}
174    ${DOCS_SRC_DIR}
175    ${DOCS_HTML_DIR}
176  USES_TERMINAL
177  COMMENT "Running Sphinx HTML build..."
178)
179
180set_target_properties(
181  html html-nodeps
182  PROPERTIES
183    ADDITIONAL_CLEAN_FILES "${DOCS_SRC_DIR};${DOCS_HTML_DIR};${DOCS_DOCTREE_DIR}"
184)
185
186add_dependencies(html devicetree)
187
188#-------------------------------------------------------------------------------
189# html-live
190
191add_doc_target(
192  html-live
193  COMMAND ${CMAKE_COMMAND} -E env ${SPHINX_ENV}
194  ${SPHINXAUTOBUILD}
195    --watch ${DOCS_CFG_DIR}
196    --ignore ${DOCS_BUILD_DIR}
197    -b html
198    -c ${DOCS_CFG_DIR}
199    -d ${DOCS_DOCTREE_DIR}
200    -w ${DOCS_BUILD_DIR}/html.log
201    ${SPHINX_TAGS_ARGS}
202    ${SPHINXOPTS}
203    ${SPHINXOPTS_EXTRA}
204    ${DOCS_SRC_DIR}
205    ${DOCS_HTML_DIR}
206  USES_TERMINAL
207  COMMENT "Running Sphinx HTML autobuild..."
208)
209
210set_target_properties(
211  html-live html-live-nodeps
212  PROPERTIES
213    ADDITIONAL_CLEAN_FILES "${DOCS_SRC_DIR};${DOCS_HTML_DIR};${DOCS_DOCTREE_DIR}"
214)
215
216add_dependencies(html-live devicetree)
217#-------------------------------------------------------------------------------
218# pdf
219
220add_doc_target(
221  latex
222  COMMAND ${CMAKE_COMMAND} -E env ${SPHINX_ENV} OUTPUT_DIR=${DOCS_LATEX_DIR}
223  ${SPHINXBUILD}
224    -b latex
225    -c ${DOCS_CFG_DIR}
226    -d ${DOCS_DOCTREE_DIR}
227    -w ${DOCS_BUILD_DIR}/latex.log
228    ${SPHINX_TAGS_ARGS}
229    -t convertimages
230    ${SPHINXOPTS}
231    ${SPHINXOPTS_EXTRA}
232    ${DOCS_SRC_DIR}
233    ${DOCS_LATEX_DIR}
234  USES_TERMINAL
235  COMMENT "Running Sphinx LaTeX build..."
236)
237
238set_target_properties(
239  latex latex-nodeps
240  PROPERTIES
241    ADDITIONAL_CLEAN_FILES "${DOCS_SRC_DIR};${DOCS_LATEX_DIR};${DOCS_DOCTREE_DIR}"
242)
243
244add_dependencies(latex devicetree)
245
246if(LATEX_PDFLATEX_FOUND AND LATEXMK)
247  if(WIN32)
248    set(PDF_BUILD_COMMAND "make.bat")
249  else()
250    find_program(MAKE make)
251    if(NOT MAKE)
252      message(FATAL_ERROR "The 'make' command was not found")
253    endif()
254    set(PDF_BUILD_COMMAND ${MAKE})
255  endif()
256
257  add_custom_target(
258    pdf
259    COMMAND ${CMAKE_COMMAND} -E env LATEXMKOPTS="${LATEXMKOPTS}"
260    ${PDF_BUILD_COMMAND}
261    WORKING_DIRECTORY ${DOCS_LATEX_DIR}
262    COMMENT "Building PDF file..."
263    USES_TERMINAL
264  )
265
266  add_dependencies(pdf latex)
267endif()
268
269#-------------------------------------------------------------------------------
270# linkcheck
271
272add_doc_target(
273  linkcheck
274  COMMAND ${CMAKE_COMMAND} -E env ${SPHINX_ENV} OUTPUT_DIR=${DOCS_LINKCHECK_DIR}
275  ${SPHINXBUILD}
276    -b linkcheck
277    -c ${DOCS_CFG_DIR}
278    -d ${DOCS_DOCTREE_DIR}
279    -w ${DOCS_BUILD_DIR}/linkcheck.log
280    ${SPHINX_TAGS_ARGS}
281    ${SPHINXOPTS}
282    ${SPHINXOPTS_EXTRA}
283    ${DOCS_SRC_DIR}
284    ${DOCS_LINKCHECK_DIR}
285  USES_TERMINAL
286  COMMENT "Running Sphinx link check..."
287)
288
289set_target_properties(
290  linkcheck linkcheck-nodeps
291  PROPERTIES
292    ADDITIONAL_CLEAN_FILES "${DOCS_SRC_DIR};${DOCS_LINKCHECK_DIR};${DOCS_DOCTREE_DIR}"
293)
294
295add_dependencies(linkcheck devicetree)
296
297#-------------------------------------------------------------------------------
298# others
299
300add_custom_target(
301  pristine
302  COMMAND ${CMAKE_COMMAND} -P ${ZEPHYR_BASE}/cmake/pristine.cmake
303)
304