# SPDX-License-Identifier: GPL-2.0-only1# pylint: disable=C0103,C020923"""4The Linux Kernel documentation build configuration file.5"""67import os8import shutil9import sys1011import sphinx1213# If extensions (or modules to document with autodoc) are in another directory,14# add these directories to sys.path here. If the directory is relative to the15# documentation root, use os.path.abspath to make it absolute, like shown here.16sys.path.insert(0, os.path.abspath("sphinx"))1718from load_config import loadConfig # pylint: disable=C0413,E04011920# Minimal supported version21needs_sphinx = "3.4.3"2223# Get Sphinx version24major, minor, patch = sphinx.version_info[:3] # pylint: disable=I11012526# Include_patterns were added on Sphinx 5.127if (major < 5) or (major == 5 and minor < 1):28has_include_patterns = False29else:30has_include_patterns = True31# Include patterns that don't contain directory names, in glob format32include_patterns = ["**.rst"]3334# Location of Documentation/ directory35doctree = os.path.abspath(".")3637# Exclude of patterns that don't contain directory names, in glob format.38exclude_patterns = []3940# List of patterns that contain directory names in glob format.41dyn_include_patterns = []42dyn_exclude_patterns = ["output"]4344# Properly handle include/exclude patterns45# ----------------------------------------4647def update_patterns(app, config):48"""49On Sphinx, all directories are relative to what it is passed as50SOURCEDIR parameter for sphinx-build. Due to that, all patterns51that have directory names on it need to be dynamically set, after52converting them to a relative patch.5354As Sphinx doesn't include any patterns outside SOURCEDIR, we should55exclude relative patterns that start with "../".56"""5758# setup include_patterns dynamically59if has_include_patterns:60for p in dyn_include_patterns:61full = os.path.join(doctree, p)6263rel_path = os.path.relpath(full, start=app.srcdir)64if rel_path.startswith("../"):65continue6667config.include_patterns.append(rel_path)6869# setup exclude_patterns dynamically70for p in dyn_exclude_patterns:71full = os.path.join(doctree, p)7273rel_path = os.path.relpath(full, start=app.srcdir)74if rel_path.startswith("../"):75continue7677config.exclude_patterns.append(rel_path)787980# helper81# ------828384def have_command(cmd):85"""Search ``cmd`` in the ``PATH`` environment.8687If found, return True.88If not found, return False.89"""90return shutil.which(cmd) is not None919293# -- General configuration ------------------------------------------------9495# Add any Sphinx extensions in alphabetic order96extensions = [97"automarkup",98"kernel_abi",99"kerneldoc",100"kernel_feat",101"kernel_include",102"kfigure",103"maintainers_include",104"rstFlatTable",105"sphinx.ext.autosectionlabel",106"sphinx.ext.ifconfig",107"translations",108]109110# Since Sphinx version 3, the C function parser is more pedantic with regards111# to type checking. Due to that, having macros at c:function cause problems.112# Those needed to be escaped by using c_id_attributes[] array113c_id_attributes = [114# GCC Compiler types not parsed by Sphinx:115"__restrict__",116117# include/linux/compiler_types.h:118"__iomem",119"__kernel",120"noinstr",121"notrace",122"__percpu",123"__rcu",124"__user",125"__force",126"__counted_by_le",127"__counted_by_be",128129# include/linux/compiler_attributes.h:130"__alias",131"__aligned",132"__aligned_largest",133"__always_inline",134"__assume_aligned",135"__cold",136"__attribute_const__",137"__copy",138"__pure",139"__designated_init",140"__visible",141"__printf",142"__scanf",143"__gnu_inline",144"__malloc",145"__mode",146"__no_caller_saved_registers",147"__noclone",148"__nonstring",149"__noreturn",150"__packed",151"__pure",152"__section",153"__always_unused",154"__maybe_unused",155"__used",156"__weak",157"noinline",158"__fix_address",159"__counted_by",160161# include/linux/memblock.h:162"__init_memblock",163"__meminit",164165# include/linux/init.h:166"__init",167"__ref",168169# include/linux/linkage.h:170"asmlinkage",171172# include/linux/btf.h173"__bpf_kfunc",174]175176# Ensure that autosectionlabel will produce unique names177autosectionlabel_prefix_document = True178autosectionlabel_maxdepth = 2179180# Load math renderer:181# For html builder, load imgmath only when its dependencies are met.182# mathjax is the default math renderer since Sphinx 1.8.183have_latex = have_command("latex")184have_dvipng = have_command("dvipng")185load_imgmath = have_latex and have_dvipng186187# Respect SPHINX_IMGMATH (for html docs only)188if "SPHINX_IMGMATH" in os.environ:189env_sphinx_imgmath = os.environ["SPHINX_IMGMATH"]190if "yes" in env_sphinx_imgmath:191load_imgmath = True192elif "no" in env_sphinx_imgmath:193load_imgmath = False194else:195sys.stderr.write("Unknown env SPHINX_IMGMATH=%s ignored.\n" % env_sphinx_imgmath)196197if load_imgmath:198extensions.append("sphinx.ext.imgmath")199math_renderer = "imgmath"200else:201math_renderer = "mathjax"202203# Add any paths that contain templates here, relative to this directory.204templates_path = ["sphinx/templates"]205206# The suffix(es) of source filenames.207# You can specify multiple suffix as a list of string:208# source_suffix = ['.rst', '.md']209source_suffix = '.rst'210211# The encoding of source files.212# source_encoding = 'utf-8-sig'213214# The master toctree document.215master_doc = "index"216217# General information about the project.218project = "The Linux Kernel"219copyright = "The kernel development community" # pylint: disable=W0622220author = "The kernel development community"221222# The version info for the project you're documenting, acts as replacement for223# |version| and |release|, also used in various other places throughout the224# built documents.225#226# In a normal build, version and release are are set to KERNELVERSION and227# KERNELRELEASE, respectively, from the Makefile via Sphinx command line228# arguments.229#230# The following code tries to extract the information by reading the Makefile,231# when Sphinx is run directly (e.g. by Read the Docs).232try:233makefile_version = None234makefile_patchlevel = None235with open("../Makefile", encoding="utf=8") as fp:236for line in fp:237key, val = [x.strip() for x in line.split("=", 2)]238if key == "VERSION":239makefile_version = val240elif key == "PATCHLEVEL":241makefile_patchlevel = val242if makefile_version and makefile_patchlevel:243break244except Exception:245pass246finally:247if makefile_version and makefile_patchlevel:248version = release = makefile_version + "." + makefile_patchlevel249else:250version = release = "unknown version"251252253def get_cline_version():254"""255HACK: There seems to be no easy way for us to get at the version and256release information passed in from the makefile...so go pawing through the257command-line options and find it for ourselves.258"""259260c_version = c_release = ""261for arg in sys.argv:262if arg.startswith("version="):263c_version = arg[8:]264elif arg.startswith("release="):265c_release = arg[8:]266if c_version:267if c_release:268return c_version + "-" + c_release269return c_version270return version # Whatever we came up with before271272273# The language for content autogenerated by Sphinx. Refer to documentation274# for a list of supported languages.275#276# This is also used if you do content translation via gettext catalogs.277# Usually you set "language" from the command line for these cases.278language = "en"279280# There are two options for replacing |today|: either, you set today to some281# non-false value, then it is used:282# today = ''283# Else, today_fmt is used as the format for a strftime call.284# today_fmt = '%B %d, %Y'285286# The reST default role (used for this markup: `text`) to use for all287# documents.288# default_role = None289290# If true, '()' will be appended to :func: etc. cross-reference text.291# add_function_parentheses = True292293# If true, the current module name will be prepended to all description294# unit titles (such as .. function::).295# add_module_names = True296297# If true, sectionauthor and moduleauthor directives will be shown in the298# output. They are ignored by default.299# show_authors = False300301# The name of the Pygments (syntax highlighting) style to use.302pygments_style = "sphinx"303304# A list of ignored prefixes for module index sorting.305# modindex_common_prefix = []306307# If true, keep warnings as "system message" paragraphs in the built documents.308# keep_warnings = False309310# If true, `todo` and `todoList` produce output, else they produce nothing.311todo_include_todos = False312313primary_domain = "c"314highlight_language = "none"315316# -- Options for HTML output ----------------------------------------------317318# The theme to use for HTML and HTML Help pages. See the documentation for319# a list of builtin themes.320321# Default theme322html_theme = "alabaster"323html_css_files = []324325if "DOCS_THEME" in os.environ:326html_theme = os.environ["DOCS_THEME"]327328if html_theme in ["sphinx_rtd_theme", "sphinx_rtd_dark_mode"]:329# Read the Docs theme330try:331import sphinx_rtd_theme332333html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]334335# Add any paths that contain custom static files (such as style sheets) here,336# relative to this directory. They are copied after the builtin static files,337# so a file named "default.css" will overwrite the builtin "default.css".338html_css_files = [339"theme_overrides.css",340]341342# Read the Docs dark mode override theme343if html_theme == "sphinx_rtd_dark_mode":344try:345import sphinx_rtd_dark_mode # pylint: disable=W0611346347extensions.append("sphinx_rtd_dark_mode")348except ImportError:349html_theme = "sphinx_rtd_theme"350351if html_theme == "sphinx_rtd_theme":352# Add color-specific RTD normal mode353html_css_files.append("theme_rtd_colors.css")354355html_theme_options = {356"navigation_depth": -1,357}358359except ImportError:360html_theme = "alabaster"361362if "DOCS_CSS" in os.environ:363css = os.environ["DOCS_CSS"].split(" ")364365for l in css:366html_css_files.append(l)367368if html_theme == "alabaster":369html_theme_options = {370"description": get_cline_version(),371"page_width": "65em",372"sidebar_width": "15em",373"fixed_sidebar": "true",374"font_size": "inherit",375"font_family": "serif",376}377378sys.stderr.write("Using %s theme\n" % html_theme)379380# Add any paths that contain custom static files (such as style sheets) here,381# relative to this directory. They are copied after the builtin static files,382# so a file named "default.css" will overwrite the builtin "default.css".383html_static_path = ["sphinx-static"]384385# If true, Docutils "smart quotes" will be used to convert quotes and dashes386# to typographically correct entities. However, conversion of "--" to "—"387# is not always what we want, so enable only quotes.388smartquotes_action = "q"389390# Custom sidebar templates, maps document names to template names.391# Note that the RTD theme ignores this392html_sidebars = {"**": ["searchbox.html",393"kernel-toc.html",394"sourcelink.html"]}395396# about.html is available for alabaster theme. Add it at the front.397if html_theme == "alabaster":398html_sidebars["**"].insert(0, "about.html")399400# The name of an image file (relative to this directory) to place at the top401# of the sidebar.402html_logo = "images/logo.svg"403404# Output file base name for HTML help builder.405htmlhelp_basename = "TheLinuxKerneldoc"406407# -- Options for LaTeX output ---------------------------------------------408409latex_elements = {410# The paper size ('letterpaper' or 'a4paper').411"papersize": "a4paper",412# The font size ('10pt', '11pt' or '12pt').413"pointsize": "11pt",414# Latex figure (float) alignment415# 'figure_align': 'htbp',416# Don't mangle with UTF-8 chars417"inputenc": "",418"utf8extra": "",419# Set document margins420"sphinxsetup": """421hmargin=0.5in, vmargin=1in,422parsedliteralwraps=true,423verbatimhintsturnover=false,424""",425#426# Some of our authors are fond of deep nesting; tell latex to427# cope.428#429"maxlistdepth": "10",430# For CJK One-half spacing, need to be in front of hyperref431"extrapackages": r"\usepackage{setspace}",432# Additional stuff for the LaTeX preamble.433"preamble": """434% Use some font with UTF-8 support with XeLaTeX435\\usepackage{fontspec}436\\setsansfont{DejaVu Sans}437\\setromanfont{DejaVu Serif}438\\setmonofont{DejaVu Sans Mono}439""",440}441442# Load kerneldoc specific LaTeX settings443latex_elements["preamble"] += """444% Load kerneldoc specific LaTeX settings445\\input{kerneldoc-preamble.sty}446"""447448# Grouping the document tree into LaTeX files. List of tuples449# (source start file, target name, title,450# author, documentclass [howto, manual, or own class]).451# Sorted in alphabetical order452latex_documents = []453454# Add all other index files from Documentation/ subdirectories455for fn in os.listdir("."):456doc = os.path.join(fn, "index")457if os.path.exists(doc + ".rst"):458has = False459for l in latex_documents:460if l[0] == doc:461has = True462break463if not has:464latex_documents.append(465(466doc,467fn + ".tex",468"Linux %s Documentation" % fn.capitalize(),469"The kernel development community",470"manual",471)472)473474# The name of an image file (relative to this directory) to place at the top of475# the title page.476# latex_logo = None477478# For "manual" documents, if this is true, then toplevel headings are parts,479# not chapters.480# latex_use_parts = False481482# If true, show page references after internal links.483# latex_show_pagerefs = False484485# If true, show URL addresses after external links.486# latex_show_urls = False487488# Documents to append as an appendix to all manuals.489# latex_appendices = []490491# If false, no module index is generated.492# latex_domain_indices = True493494# Additional LaTeX stuff to be copied to build directory495latex_additional_files = [496"sphinx/kerneldoc-preamble.sty",497]498499500# -- Options for manual page output ---------------------------------------501502# One entry per manual page. List of tuples503# (source start file, name, description, authors, manual section).504man_pages = [505(master_doc, "thelinuxkernel", "The Linux Kernel Documentation", [author], 1)506]507508# If true, show URL addresses after external links.509# man_show_urls = False510511512# -- Options for Texinfo output -------------------------------------------513514# Grouping the document tree into Texinfo files. List of tuples515# (source start file, target name, title, author,516# dir menu entry, description, category)517texinfo_documents = [(518master_doc,519"TheLinuxKernel",520"The Linux Kernel Documentation",521author,522"TheLinuxKernel",523"One line description of project.",524"Miscellaneous",525),]526527# -- Options for Epub output ----------------------------------------------528529# Bibliographic Dublin Core info.530epub_title = project531epub_author = author532epub_publisher = author533epub_copyright = copyright534535# A list of files that should not be packed into the epub file.536epub_exclude_files = ["search.html"]537538# =======539# rst2pdf540#541# Grouping the document tree into PDF files. List of tuples542# (source start file, target name, title, author, options).543#544# See the Sphinx chapter of https://ralsina.me/static/manual.pdf545#546# FIXME: Do not add the index file here; the result will be too big. Adding547# multiple PDF files here actually tries to get the cross-referencing right548# *between* PDF files.549pdf_documents = [550("kernel-documentation", "Kernel", "Kernel", "J. Random Bozo"),551]552553# kernel-doc extension configuration for running Sphinx directly (e.g. by Read554# the Docs). In a normal build, these are supplied from the Makefile via command555# line arguments.556kerneldoc_bin = "../scripts/kernel-doc.py"557kerneldoc_srctree = ".."558559# ------------------------------------------------------------------------------560# Since loadConfig overwrites settings from the global namespace, it has to be561# the last statement in the conf.py file562# ------------------------------------------------------------------------------563loadConfig(globals())564565566def setup(app):567"""Patterns need to be updated at init time on older Sphinx versions"""568569app.connect('config-inited', update_patterns)570571572