conf.py 18 KB

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