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