1# SPDX-License-Identifier: GPL-2.0-only 2# pylint: disable=C0103,C0209 3 4""" 5The Linux Kernel documentation build configuration file. 6""" 7 8import os 9import shutil 10import sys 11 12from textwrap import dedent 13 14import sphinx 15 16# If extensions (or modules to document with autodoc) are in another directory, 17# add these directories to sys.path here. If the directory is relative to the 18# documentation root, use os.path.abspath to make it absolute, like shown here. 19sys.path.insert(0, os.path.abspath("sphinx")) 20 21# Minimal supported version 22needs_sphinx = "3.4.3" 23 24# Get Sphinx version 25major, minor, patch = sphinx.version_info[:3] # pylint: disable=I1101 26 27# Include_patterns were added on Sphinx 5.1 28if (major < 5) or (major == 5 and minor < 1): 29 has_include_patterns = False 30else: 31 has_include_patterns = True 32 # Include patterns that don't contain directory names, in glob format 33 include_patterns = ["**.rst"] 34 35# Location of Documentation/ directory 36doctree = os.path.abspath(".") 37 38# Exclude of patterns that don't contain directory names, in glob format. 39exclude_patterns = [] 40 41# List of patterns that contain directory names in glob format. 42dyn_include_patterns = [] 43dyn_exclude_patterns = ["output"] 44 45# Currently, only netlink/specs has a parser for yaml. 46# Prefer using include patterns if available, as it is faster 47if has_include_patterns: 48 dyn_include_patterns.append("netlink/specs/*.yaml") 49else: 50 dyn_exclude_patterns.append("netlink/*.yaml") 51 dyn_exclude_patterns.append("devicetree/bindings/**.yaml") 52 dyn_exclude_patterns.append("core-api/kho/bindings/**.yaml") 53 54# Link to man pages 55manpages_url = 'https://man7.org/linux/man-pages/man{section}/{page}.{section}.html' 56 57# Properly handle directory patterns and LaTeX docs 58# ------------------------------------------------- 59 60def config_init(app, config): 61 """ 62 Initialize path-dependent variabled 63 64 On Sphinx, all directories are relative to what it is passed as 65 SOURCEDIR parameter for sphinx-build. Due to that, all patterns 66 that have directory names on it need to be dynamically set, after 67 converting them to a relative patch. 68 69 As Sphinx doesn't include any patterns outside SOURCEDIR, we should 70 exclude relative patterns that start with "../". 71 """ 72 73 # setup include_patterns dynamically 74 if has_include_patterns: 75 for p in dyn_include_patterns: 76 full = os.path.join(doctree, p) 77 78 rel_path = os.path.relpath(full, start=app.srcdir) 79 if rel_path.startswith("../"): 80 continue 81 82 config.include_patterns.append(rel_path) 83 84 # setup exclude_patterns dynamically 85 for p in dyn_exclude_patterns: 86 full = os.path.join(doctree, p) 87 88 rel_path = os.path.relpath(full, start=app.srcdir) 89 if rel_path.startswith("../"): 90 continue 91 92 config.exclude_patterns.append(rel_path) 93 94 # LaTeX and PDF output require a list of documents with are dependent 95 # of the app.srcdir. Add them here 96 97 # Handle the case where SPHINXDIRS is used 98 if not os.path.samefile(doctree, app.srcdir): 99 # Add a tag to mark that the build is actually a subproject 100 tags.add("subproject") 101 102 # get index.rst, if it exists 103 doc = os.path.basename(app.srcdir) 104 fname = "index" 105 if os.path.exists(os.path.join(app.srcdir, fname + ".rst")): 106 latex_documents.append((fname, doc + ".tex", 107 "Linux %s Documentation" % doc.capitalize(), 108 "The kernel development community", 109 "manual")) 110 return 111 112 # When building all docs, or when a main index.rst doesn't exist, seek 113 # for it on subdirectories 114 for doc in os.listdir(app.srcdir): 115 fname = os.path.join(doc, "index") 116 if not os.path.exists(os.path.join(app.srcdir, fname + ".rst")): 117 continue 118 119 has = False 120 for l in latex_documents: 121 if l[0] == fname: 122 has = True 123 break 124 125 if not has: 126 latex_documents.append((fname, doc + ".tex", 127 "Linux %s Documentation" % doc.capitalize(), 128 "The kernel development community", 129 "manual")) 130 131# helper 132# ------ 133 134 135def have_command(cmd): 136 """Search ``cmd`` in the ``PATH`` environment. 137 138 If found, return True. 139 If not found, return False. 140 """ 141 return shutil.which(cmd) is not None 142 143 144# -- General configuration ------------------------------------------------ 145 146# Add any Sphinx extensions in alphabetic order 147extensions = [ 148 "automarkup", 149 "kernel_abi", 150 "kerneldoc", 151 "kernel_feat", 152 "kernel_include", 153 "kfigure", 154 "maintainers_include", 155 "parser_yaml", 156 "rstFlatTable", 157 "sphinx.ext.autosectionlabel", 158 "sphinx.ext.ifconfig", 159 "translations", 160] 161# Since Sphinx version 3, the C function parser is more pedantic with regards 162# to type checking. Due to that, having macros at c:function cause problems. 163# Those needed to be escaped by using c_id_attributes[] array 164c_id_attributes = [ 165 # GCC Compiler types not parsed by Sphinx: 166 "__restrict__", 167 168 # include/linux/compiler_types.h: 169 "__iomem", 170 "__kernel", 171 "noinstr", 172 "notrace", 173 "__percpu", 174 "__rcu", 175 "__user", 176 "__force", 177 "__counted_by_le", 178 "__counted_by_be", 179 180 # include/linux/compiler_attributes.h: 181 "__alias", 182 "__aligned", 183 "__aligned_largest", 184 "__always_inline", 185 "__assume_aligned", 186 "__cold", 187 "__attribute_const__", 188 "__copy", 189 "__pure", 190 "__designated_init", 191 "__visible", 192 "__printf", 193 "__scanf", 194 "__gnu_inline", 195 "__malloc", 196 "__mode", 197 "__no_caller_saved_registers", 198 "__noclone", 199 "__nonstring", 200 "__noreturn", 201 "__packed", 202 "__pure", 203 "__section", 204 "__always_unused", 205 "__maybe_unused", 206 "__used", 207 "__weak", 208 "noinline", 209 "__fix_address", 210 "__counted_by", 211 212 # include/linux/memblock.h: 213 "__init_memblock", 214 "__meminit", 215 216 # include/linux/init.h: 217 "__init", 218 "__ref", 219 220 # include/linux/linkage.h: 221 "asmlinkage", 222 223 # include/linux/btf.h 224 "__bpf_kfunc", 225] 226 227# Ensure that autosectionlabel will produce unique names 228autosectionlabel_prefix_document = True 229autosectionlabel_maxdepth = 2 230 231# Load math renderer: 232# For html builder, load imgmath only when its dependencies are met. 233# mathjax is the default math renderer since Sphinx 1.8. 234have_latex = have_command("latex") 235have_dvipng = have_command("dvipng") 236load_imgmath = have_latex and have_dvipng 237 238# Respect SPHINX_IMGMATH (for html docs only) 239if "SPHINX_IMGMATH" in os.environ: 240 env_sphinx_imgmath = os.environ["SPHINX_IMGMATH"] 241 if "yes" in env_sphinx_imgmath: 242 load_imgmath = True 243 elif "no" in env_sphinx_imgmath: 244 load_imgmath = False 245 else: 246 sys.stderr.write("Unknown env SPHINX_IMGMATH=%s ignored.\n" % env_sphinx_imgmath) 247 248if load_imgmath: 249 extensions.append("sphinx.ext.imgmath") 250 math_renderer = "imgmath" 251else: 252 math_renderer = "mathjax" 253 254# Add any paths that contain templates here, relative to this directory. 255templates_path = ["sphinx/templates"] 256 257# The suffixes of source filenames that will be automatically parsed 258source_suffix = { 259 ".rst": "restructuredtext", 260 ".yaml": "yaml", 261} 262 263# The encoding of source files. 264# source_encoding = 'utf-8-sig' 265 266# The master toctree document. 267master_doc = "index" 268 269# General information about the project. 270project = "The Linux Kernel" 271copyright = "The kernel development community" # pylint: disable=W0622 272author = "The kernel development community" 273 274# The version info for the project you're documenting, acts as replacement for 275# |version| and |release|, also used in various other places throughout the 276# built documents. 277# 278# In a normal build, version and release are set to KERNELVERSION and 279# KERNELRELEASE, respectively, from the Makefile via Sphinx command line 280# arguments. 281# 282# The following code tries to extract the information by reading the Makefile, 283# when Sphinx is run directly (e.g. by Read the Docs). 284try: 285 makefile_version = None 286 makefile_patchlevel = None 287 with open("../Makefile", encoding="utf=8") as fp: 288 for line in fp: 289 key, val = [x.strip() for x in line.split("=", 2)] 290 if key == "VERSION": 291 makefile_version = val 292 elif key == "PATCHLEVEL": 293 makefile_patchlevel = val 294 if makefile_version and makefile_patchlevel: 295 break 296except Exception: 297 pass 298finally: 299 if makefile_version and makefile_patchlevel: 300 version = release = makefile_version + "." + makefile_patchlevel 301 else: 302 version = release = "unknown version" 303 304 305def get_cline_version(): 306 """ 307 HACK: There seems to be no easy way for us to get at the version and 308 release information passed in from the makefile...so go pawing through the 309 command-line options and find it for ourselves. 310 """ 311 312 c_version = c_release = "" 313 for arg in sys.argv: 314 if arg.startswith("version="): 315 c_version = arg[8:] 316 elif arg.startswith("release="): 317 c_release = arg[8:] 318 if c_version: 319 if c_release: 320 return c_version + "-" + c_release 321 return c_version 322 return version # Whatever we came up with before 323 324 325# The language for content autogenerated by Sphinx. Refer to documentation 326# for a list of supported languages. 327# 328# This is also used if you do content translation via gettext catalogs. 329# Usually you set "language" from the command line for these cases. 330language = "en" 331 332# There are two options for replacing |today|: either, you set today to some 333# non-false value, then it is used: 334# today = '' 335# Else, today_fmt is used as the format for a strftime call. 336# today_fmt = '%B %d, %Y' 337 338# The reST default role (used for this markup: `text`) to use for all 339# documents. 340# default_role = None 341 342# If true, '()' will be appended to :func: etc. cross-reference text. 343# add_function_parentheses = True 344 345# If true, the current module name will be prepended to all description 346# unit titles (such as .. function::). 347# add_module_names = True 348 349# If true, sectionauthor and moduleauthor directives will be shown in the 350# output. They are ignored by default. 351# show_authors = False 352 353# The name of the Pygments (syntax highlighting) style to use. 354pygments_style = "sphinx" 355 356# A list of ignored prefixes for module index sorting. 357# modindex_common_prefix = [] 358 359# If true, keep warnings as "system message" paragraphs in the built documents. 360# keep_warnings = False 361 362# If true, `todo` and `todoList` produce output, else they produce nothing. 363todo_include_todos = False 364 365primary_domain = "c" 366highlight_language = "none" 367 368# -- Options for HTML output ---------------------------------------------- 369 370# The theme to use for HTML and HTML Help pages. See the documentation for 371# a list of builtin themes. 372 373# Default theme 374html_theme = "alabaster" 375html_css_files = [] 376 377if "DOCS_THEME" in os.environ: 378 html_theme = os.environ["DOCS_THEME"] 379 380if html_theme in ["sphinx_rtd_theme", "sphinx_rtd_dark_mode"]: 381 # Read the Docs theme 382 try: 383 import sphinx_rtd_theme 384 385 html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] 386 387 # Add any paths that contain custom static files (such as style sheets) here, 388 # relative to this directory. They are copied after the builtin static files, 389 # so a file named "default.css" will overwrite the builtin "default.css". 390 html_css_files = [ 391 "theme_overrides.css", 392 ] 393 394 # Read the Docs dark mode override theme 395 if html_theme == "sphinx_rtd_dark_mode": 396 try: 397 import sphinx_rtd_dark_mode # pylint: disable=W0611 398 399 extensions.append("sphinx_rtd_dark_mode") 400 except ImportError: 401 html_theme = "sphinx_rtd_theme" 402 403 if html_theme == "sphinx_rtd_theme": 404 # Add color-specific RTD normal mode 405 html_css_files.append("theme_rtd_colors.css") 406 407 html_theme_options = { 408 "navigation_depth": -1, 409 } 410 411 except ImportError: 412 html_theme = "alabaster" 413 414if "DOCS_CSS" in os.environ: 415 css = os.environ["DOCS_CSS"].split(" ") 416 417 for l in css: 418 html_css_files.append(l) 419 420if html_theme == "alabaster": 421 html_theme_options = { 422 "description": get_cline_version(), 423 "page_width": "65em", 424 "sidebar_width": "15em", 425 "fixed_sidebar": "true", 426 "font_size": "inherit", 427 "font_family": "serif", 428 } 429 430sys.stderr.write("Using %s theme\n" % html_theme) 431 432# Add any paths that contain custom static files (such as style sheets) here, 433# relative to this directory. They are copied after the builtin static files, 434# so a file named "default.css" will overwrite the builtin "default.css". 435html_static_path = ["sphinx-static"] 436 437# If true, Docutils "smart quotes" will be used to convert quotes and dashes 438# to typographically correct entities. However, conversion of "--" to "—" 439# is not always what we want, so enable only quotes. 440smartquotes_action = "q" 441 442# Custom sidebar templates, maps document names to template names. 443# Note that the RTD theme ignores this 444html_sidebars = {"**": ["searchbox.html", 445 "kernel-toc.html", 446 "sourcelink.html"]} 447 448# about.html is available for alabaster theme. Add it at the front. 449if html_theme == "alabaster": 450 html_sidebars["**"].insert(0, "about.html") 451 452# The name of an image file (relative to this directory) to place at the top 453# of the sidebar. 454html_logo = "images/logo.svg" 455 456# Output file base name for HTML help builder. 457htmlhelp_basename = "TheLinuxKerneldoc" 458 459# -- Options for LaTeX output --------------------------------------------- 460 461latex_elements = { 462 # The paper size ('letterpaper' or 'a4paper'). 463 "papersize": "a4paper", 464 "passoptionstopackages": dedent(r""" 465 \PassOptionsToPackage{svgnames}{xcolor} 466 """), 467 # The font size ('10pt', '11pt' or '12pt'). 468 "pointsize": "11pt", 469 # Needed to generate a .ind file 470 "printindex": r"\footnotesize\raggedright\printindex", 471 # Latex figure (float) alignment 472 # 'figure_align': 'htbp', 473 # Don't mangle with UTF-8 chars 474 "fontenc": "", 475 "inputenc": "", 476 "utf8extra": "", 477 # Set document margins 478 "sphinxsetup": dedent(r""" 479 hmargin=0.5in, vmargin=1in, 480 parsedliteralwraps=true, 481 verbatimhintsturnover=false, 482 """), 483 # 484 # Some of our authors are fond of deep nesting; tell latex to 485 # cope. 486 # 487 "maxlistdepth": "10", 488 # For CJK One-half spacing, need to be in front of hyperref 489 "extrapackages": r"\usepackage{setspace}", 490 "fontpkg": dedent(r""" 491 \usepackage{fontspec} 492 \setmainfont{DejaVu Serif} 493 \setsansfont{DejaVu Sans} 494 \setmonofont{DejaVu Sans Mono} 495 \newfontfamily\headingfont{DejaVu Serif} 496 """), 497 "preamble": dedent(r""" 498 % Load kerneldoc specific LaTeX settings 499 \input{kerneldoc-preamble.sty} 500 """) 501} 502 503# This will be filled up by config-inited event 504latex_documents = [] 505 506# The name of an image file (relative to this directory) to place at the top of 507# the title page. 508# latex_logo = None 509 510# For "manual" documents, if this is true, then toplevel headings are parts, 511# not chapters. 512# latex_use_parts = False 513 514# If true, show page references after internal links. 515# latex_show_pagerefs = False 516 517# If true, show URL addresses after external links. 518# latex_show_urls = False 519 520# Documents to append as an appendix to all manuals. 521# latex_appendices = [] 522 523# If false, no module index is generated. 524# latex_domain_indices = True 525 526# Additional LaTeX stuff to be copied to build directory 527latex_additional_files = [ 528 "sphinx/kerneldoc-preamble.sty", 529] 530 531 532# -- Options for manual page output --------------------------------------- 533 534# One entry per manual page. List of tuples 535# (source start file, name, description, authors, manual section). 536man_pages = [ 537 (master_doc, "thelinuxkernel", "The Linux Kernel Documentation", [author], 1) 538] 539 540# If true, show URL addresses after external links. 541# man_show_urls = False 542 543 544# -- Options for Texinfo output ------------------------------------------- 545 546# Grouping the document tree into Texinfo files. List of tuples 547# (source start file, target name, title, author, 548# dir menu entry, description, category) 549texinfo_documents = [( 550 master_doc, 551 "TheLinuxKernel", 552 "The Linux Kernel Documentation", 553 author, 554 "TheLinuxKernel", 555 "One line description of project.", 556 "Miscellaneous", 557 ),] 558 559# -- Options for Epub output ---------------------------------------------- 560 561# Bibliographic Dublin Core info. 562epub_title = project 563epub_author = author 564epub_publisher = author 565epub_copyright = copyright 566 567# A list of files that should not be packed into the epub file. 568epub_exclude_files = ["search.html"] 569 570# ======= 571# rst2pdf 572# 573# Grouping the document tree into PDF files. List of tuples 574# (source start file, target name, title, author, options). 575# 576# See the Sphinx chapter of https://ralsina.me/static/manual.pdf 577# 578# FIXME: Do not add the index file here; the result will be too big. Adding 579# multiple PDF files here actually tries to get the cross-referencing right 580# *between* PDF files. 581pdf_documents = [ 582 ("kernel-documentation", "Kernel", "Kernel", "J. Random Bozo"), 583] 584 585# kernel-doc extension configuration for running Sphinx directly (e.g. by Read 586# the Docs). In a normal build, these are supplied from the Makefile via command 587# line arguments. 588kerneldoc_bin = "../scripts/kernel-doc.py" 589kerneldoc_srctree = ".." 590 591def setup(app): 592 """Patterns need to be updated at init time on older Sphinx versions""" 593 594 app.connect('config-inited', config_init) 595