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