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