← Documents Documentation/conf.py GitHub 원문 ↗

Linux 6.18.37 · Documentation build

Linux 커널 문서 Sphinx 빌드 설정

Linux 커널 Documentation 트리의 Sphinx 확장, 동적 포함·제외 패턴, 버전 추출, HTML·LaTeX·man·Texinfo·EPUB·PDF 출력과 초기화 후크를 정의하는 중앙 설정 파일을 해설합니다.

Source pathDocumentation/conf.py
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

conf.py:1-596

Linux 커널 Documentation 트리의 Sphinx 확장, 동적 포함·제외 패턴, 버전 추출, HTML·LaTeX·man·Texinfo·EPUB·PDF 출력과 초기화 후크를 정의하는 중앙 설정 파일을 해설합니다.

최소 Sphinx 3.4.3을 지원하면서 5.1의 include_patterns 유무를 분기하고, `loadConfig(globals())`로 외부 설정을 적용한 뒤 `config-inited` 이벤트에서 실제 SOURCEDIR 기준 경로와 LaTeX 문서 목록을 완성합니다.

문서 빌드 설정 요약
Sphinx 버전·입력 패턴커널 확장·C 파서버전·프로젝트 메타데이터HTML·LaTeX·기타 출력loadConfig 재정의config_init 동적 경로

입력 선택부터 각 출력 형식과 초기화 이벤트까지의 상위 흐름입니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

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

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

부트스트랩, 동적 경로 패턴과 LaTeX 문서 목록

1-138

이 파일은 Linux 커널 `Documentation/` 트리를 Sphinx로 빌드하는 중앙 Python 설정입니다. GPL-2.0-only 라이선스와 pylint 예외를 선언한 뒤 표준 모듈, Sphinx, 커널 전용 `load_config`를 불러오며, `Documentation/sphinx`를 모듈 검색 경로 맨 앞에 추가합니다.

최소 지원 Sphinx 버전은 `3.4.3`입니다. Sphinx `5.1`부터 제공되는 `include_patterns` 지원 여부를 `sphinx.version_info`로 판단하고, 지원하는 경우 기본 RST 패턴 `**.rst`와 netlink YAML만 포함합니다. 이전 버전에서는 YAML 디렉터리를 동적 제외 목록으로 넣어 같은 결과를 우회합니다.

`config_init(app, config)`는 Sphinx의 `config-inited` 시점에 실제 `app.srcdir`을 알게 된 뒤 경로 의존 설정을 계산합니다. `doctree` 기준 패턴을 소스 디렉터리 상대 경로로 바꾸고 `../`로 시작해 현재 빌드 범위 밖에 있는 패턴은 건너뜁니다. 이어서 부분 문서 빌드와 전체 문서 빌드를 구분해 `latex_documents`를 채웁니다.

동적 패턴과 LaTeX 목록 초기화
config-initeddoctree 패턴을 app.srcdir 상대 경로로 변환../ 패턴 제외include_patterns / exclude_patterns 추가
SPHINXDIRS 부분 빌드현재 srcdir의 index.rst 확인단일 latex_documents 튜플 추가return
전체 빌드 또는 주 index 없음srcdir 하위 디렉터리 순회각 index.rst 확인중복 없는 latex_documents 튜플 추가

SOURCEDIR이 정해진 뒤 포함·제외 경로와 PDF용 문서 튜플을 실제 빌드 위치에 맞춥니다.

초기 import와 버전 설정
원문 줄심볼역할
1-6SPDX, pylint, 모듈 docstring라이선스, 이름·문자열 포맷 경고 비활성화, 빌드 설정 파일 목적을 선언
8-10`os`, `shutil`, `sys`경로·환경, 실행 파일 검색, 명령행과 표준 오류 처리
12`textwrap.dedent`여러 줄 LaTeX 문자열의 공통 들여쓰기 제거
14`sphinx`설치된 Sphinx 버전 확인
19`sys.path.insert(0, os.path.abspath("sphinx"))`커널 전용 확장 디렉터리를 우선 검색
21`loadConfig`외부 설정 병합 함수 import
24-35`needs_sphinx`, `major/minor/patch`, `has_include_patterns`최소 버전과 5.1 기능 분기, 기본 RST 포함 패턴 설정
38`doctree`현재 `Documentation/` 디렉터리의 절대 경로

원문 1-38줄의 모듈과 전역 기준값입니다.

포함·제외 패턴 호환성
조건동적 목록결과
공통`exclude_patterns=[]`, `dyn_exclude_patterns=["output"]`생성 출력 디렉터리를 문서 입력에서 제외
Sphinx 5.1 이상`dyn_include_patterns += netlink/specs/*.yaml`YAML 파서가 있는 netlink spec만 명시적으로 포함
Sphinx 5.1 미만`netlink/*.yaml` 제외지원하지 않는 netlink YAML을 제외
Sphinx 5.1 미만`devicetree/bindings/**.yaml` 제외방대한 DT binding YAML을 RST 빌드에서 제외
Sphinx 5.1 미만`core-api/kho/bindings/**.yaml` 제외KHO binding YAML을 제외

원문 40-55줄은 Sphinx 버전에 따라 YAML 처리 방식을 바꿉니다.

config_init(app, config)
구간동작세부
72-81동적 include 설정각 `dyn_include_patterns`를 절대 경로로 만든 뒤 `app.srcdir` 상대 경로로 변환하고 빌드 범위 안이면 추가
83-91동적 exclude 설정동일한 상대 경로 변환과 범위 검사를 거쳐 `config.exclude_patterns`에 추가
93-105부분 디렉터리 빌드`doctree`와 `app.srcdir`이 다르면 현재 디렉터리의 `index.rst`만 LaTeX manual 튜플로 추가
107-124전체·하위 디렉터리 빌드각 하위 `index.rst`를 찾고 기존 첫 필드와 중복되지 않을 때 `doc/index`, `doc.tex`, 제목, 저자, `manual` 튜플 추가

원문 59-124줄 함수의 두 책임을 순서대로 설명합니다.

have_command(cmd)
입력구현반환
명령 이름`shutil.which(cmd) is not None`PATH에서 찾으면 `True`, 없으면 `False`

원문 126-136줄의 작은 의존성 검사 도우미입니다.

Sphinx 확장, C 식별자 속성, 수학 렌더러와 소스 형식

139-262

일반 설정은 커널 문서용 확장 12개를 알파벳 순서로 등록합니다. Sphinx 3 이후 엄격해진 C 함수 파서가 커널 매크로를 형식 오류로 판단하지 않도록 `c_id_attributes`에 컴파일러·주소 공간·초기화·BTF 속성 47개를 허용합니다.

수학 렌더러는 `latex`와 `dvipng`가 모두 PATH에 있으면 HTML에서 `sphinx.ext.imgmath`를 추가하고 `imgmath`를 선택합니다. `SPHINX_IMGMATH` 환경 변수에 `yes`가 포함되면 강제로 활성화하고 `no`가 포함되면 비활성화하며, 다른 값은 표준 오류 경고 후 무시합니다. 조건이 충족되지 않으면 기본 `mathjax`를 사용합니다.

수학 렌더러 선택
latex 있음dvipng 있음load_imgmath=Truesphinx.ext.imgmath 추가math_renderer=imgmath
둘 중 하나 없음환경 재정의 없음load_imgmath=Falsemath_renderer=mathjax
SPHINX_IMGMATH=yes/noTrue/False 강제선택 결과 적용
알 수 없는 SPHINX_IMGMATHstderr 경고기존 자동 판정 유지

도구 가용성을 기본값으로 삼고 SPHINX_IMGMATH가 있으면 이를 우선 적용합니다.

등록된 확장 12개
범주확장용도
커널 마크업`automarkup`, `kernel_include`, `maintainers_include`, `translations`자동 링크, include 처리, MAINTAINERS 포함, 번역 지원
커널 인터페이스`kernel_abi`, `kerneldoc`, `kernel_feat`ABI, kernel-doc, feature 문서 생성
그림·표·YAML`kfigure`, `rstFlatTable`, `parser_yaml`도형, flat-table, YAML 소스 파싱
Sphinx 기본 확장`sphinx.ext.autosectionlabel`, `sphinx.ext.ifconfig`섹션 레이블과 조건부 문서

원문 141-155줄의 확장과 기능 범주입니다.

C 식별자 속성 47개
출처수량심볼
GCC compiler types1`__restrict__`
include/linux/compiler_types.h10`__iomem`, `__kernel`, `noinstr`, `notrace`, `__percpu`, `__rcu`, `__user`, `__force`, `__counted_by_le`, `__counted_by_be`
include/linux/compiler_attributes.h30`__alias`, `__aligned`, `__aligned_largest`, `__always_inline`, `__assume_aligned`, `__cold`, `__attribute_const__`, `__copy`, `__pure`, `__designated_init`, `__visible`, `__printf`, `__scanf`, `__gnu_inline`, `__malloc`, `__mode`, `__no_caller_saved_registers`, `__noclone`, `__nonstring`, `__noreturn`, `__packed`, `__pure`, `__section`, `__always_unused`, `__maybe_unused`, `__used`, `__weak`, `noinline`, `__fix_address`, `__counted_by`
include/linux/memblock.h2`__init_memblock`, `__meminit`
include/linux/init.h2`__init`, `__ref`
include/linux/linkage.h1`asmlinkage`
include/linux/btf.h1`__bpf_kfunc`

원문 156-220줄의 심볼을 원래 헤더 묶음별로 보존합니다. `__pure`는 원문 목록에 두 번 나타납니다.

레이블·템플릿·소스 파서 설정
설정효과
autosectionlabel`prefix_document=True`, `maxdepth=2`문서명을 접두사로 붙여 상위 두 단계 섹션 레이블을 고유하게 생성
templates_path`sphinx/templates`커널 문서용 Jinja 템플릿 검색 경로
source_suffix`.rst: restructuredtext`, `.yaml: yaml`RST와 YAML을 각 파서에 연결
source_encoding주석 처리된 `utf-8-sig`현재는 Sphinx 기본 인코딩을 사용
master_doc`index`최상위 toctree 시작 문서

원문 222-262줄의 나머지 일반 설정입니다.

프로젝트 메타데이터, 커널 버전과 일반 문서 옵션

264-361

프로젝트 이름은 `The Linux Kernel`, 저자와 저작권 표시는 `The kernel development community`입니다. 일반 Makefile 기반 빌드에서는 명령행으로 `KERNELVERSION`과 `KERNELRELEASE`가 들어오지만, Sphinx를 직접 실행하는 환경을 위해 상위 `../Makefile`의 `VERSION`과 `PATCHLEVEL`도 읽습니다.

Makefile을 읽지 못하거나 두 값이 완성되지 않으면 `version`과 `release`를 `unknown version`으로 둡니다. `get_cline_version()`은 `sys.argv`에서 `version=`과 `release=`를 다시 찾아 둘 다 있으면 하이픈으로 결합하고, version만 있으면 그것만, 없으면 앞서 계산한 `version`을 반환합니다.

표시 버전 결정 우선순위
../Makefile VERSION + PATCHLEVELversion=release=VERSION.PATCHLEVEL
Makefile 추출 실패version=release=unknown version
sys.argv version= + release=get_cline_version -> version-release
sys.argv version=만 존재get_cline_version -> version
명령행 version 없음앞서 계산한 version 반환

직접 실행용 Makefile 추출값을 마련한 뒤 명령행 값이 있으면 HTML 설명에 우선 사용합니다.

버전 추출 코드
구간처리결과
279-290`../Makefile`을 열어 `VERSION`, `PATCHLEVEL` 검색두 값을 찾으면 조기 종료
291-297모든 예외를 무시한 뒤 finally에서 값 확인`major.patchlevel` 또는 `unknown version` 설정
300-312`get_cline_version()`이 모든 `sys.argv` 검사`version=`과 `release=` 문자열 분리
313-317반환 우선순위 적용`version-release` > `version` > 전역 `version`

원문 269-317줄의 예외 처리와 명령행 보완입니다.

일반 문서 옵션
설정현재 값의미
language`en`Sphinx 자동 생성 콘텐츠와 gettext 기본 언어
today/default_role/add_function_parentheses주석 처리기본 동작 사용
add_module_names/show_authors주석 처리기본 동작 사용
pygments_style`sphinx`구문 강조 스타일
keep_warnings주석 처리경고를 문서 시스템 메시지로 유지하지 않음
todo_include_todos`False`todo와 todoList 출력을 숨김
primary_domain`c`기본 도메인을 C로 설정
highlight_language`none`명시하지 않은 코드 블록의 자동 언어 강조를 끔

원문 320-361줄에서 실제 활성화된 값과 주석 예시를 구분합니다.

HTML 테마, CSS, 사이드바와 정적 자원

363-452

HTML 기본 테마는 `alabaster`이며 `DOCS_THEME` 환경 변수로 바꿀 수 있습니다. `sphinx_rtd_theme` 또는 `sphinx_rtd_dark_mode`를 요청하면 관련 모듈을 가져와 테마 경로와 CSS를 설정하고, import가 실패하면 `alabaster`로 되돌아갑니다.

`DOCS_CSS`는 공백으로 나눈 각 파일명을 `html_css_files`에 추가합니다. 최종 테마가 alabaster이면 커널 버전 설명, 페이지·사이드바 폭, 고정 사이드바, 글꼴 설정을 적용합니다. 선택된 테마는 표준 오류에 `Using ... theme`으로 기록됩니다.

HTML 테마 선택
기본html_theme=alabaster
DOCS_THEME요청 테마 적용
RTD 계열 요청sphinx_rtd_theme import 성공theme_overrides.cssdark 또는 normal 보정navigation_depth=-1
RTD import 실패alabaster로 복귀
sphinx_rtd_dark_mode import 실패sphinx_rtd_theme로 복귀theme_rtd_colors.css 추가

환경 변수와 Python 모듈 가용성에 따라 RTD 계열 또는 alabaster 설정으로 수렴합니다.

RTD 계열 분기
조건설정실패 시
`DOCS_THEME` 존재환경 변수 문자열을 `html_theme`에 대입후속 분기에서 처리
RTD 또는 RTD dark`sphinx_rtd_theme.get_html_theme_path()`와 `theme_overrides.css` 사용ImportError면 alabaster
RTD dark`sphinx_rtd_dark_mode` 확장을 추가ImportError면 일반 RTD
일반 RTD`theme_rtd_colors.css` 추가정상 모드 색상 보정
RTD 공통`navigation_depth=-1`전체 탐색 깊이 표시

원문 372-407줄의 import와 폴백 규칙입니다.

alabaster와 사용자 CSS
설정효과
DOCS_CSS공백 분리 후 각 항목 append빌드 호출자가 추가 CSS 목록 지정
description`get_cline_version()`사이드바에 커널 버전 표시
page_width/sidebar_width`65em` / `15em`본문과 사이드바 폭
fixed_sidebar문자열 `true`사이드바 고정
font_size/font_family`inherit` / `serif`상속 크기와 serif 계열

원문 409-425줄의 최종 CSS 및 테마 옵션입니다.

정적 파일과 사이드바
설정설명
html_static_path`sphinx-static`빌드에 복사할 정적 파일 디렉터리
smartquotes_action`q`따옴표만 스마트 변환하고 `--` 대시는 변환하지 않음
html_sidebars`searchbox.html`, `kernel-toc.html`, `sourcelink.html`모든 문서의 검색·목차·원문 링크
alabaster 추가`about.html`을 맨 앞에 삽입프로젝트 설명 사이드바 표시
html_logo`images/logo.svg`사이드바 상단 로고
htmlhelp_basename`TheLinuxKerneldoc`HTML Help 출력 기본 파일명

원문 427-452줄의 HTML 공통 출력 설정입니다.

LaTeX, man, Texinfo, EPUB, PDF와 최종 설정 연결

454-596

LaTeX 출력은 A4, 11pt, 좁은 수평 여백과 1인치 수직 여백, 최대 목록 깊이 10을 사용합니다. UTF-8 문자를 재인코딩하지 않도록 `fontenc`, `inputenc`, `utf8extra`를 비우고, `fontspec`으로 DejaVu Serif·Sans·Sans Mono를 지정하며 `kerneldoc-preamble.sty`를 불러옵니다.

`latex_documents`는 빈 목록으로 시작해 앞의 `config_init()`이 빌드 위치에 따라 채웁니다. man, Texinfo, EPUB, rst2pdf용 메타데이터도 각각 선언하며, Sphinx 직접 실행을 위해 `kerneldoc_bin=../scripts/kernel-doc.py`, `kerneldoc_srctree=..`를 기본값으로 제공합니다.

마지막 전역 호출 `loadConfig(globals())`는 명령행 또는 외부 설정으로 현재 전역값을 덮어써야 하므로 설정 선언 뒤에 놓입니다. `setup(app)`은 Sphinx `config-inited` 이벤트에 `config_init`을 연결해 구버전 Sphinx에서도 동적 패턴을 초기화합니다.

빌드 설정의 최종 적용 순서
Python 전역 기본값HTML·LaTeX·기타 백엔드 설정loadConfig(globals()) 재정의setup(app)config-initedconfig_init(app, config)

정적 기본값을 만든 뒤 외부 재정의를 적용하고 Sphinx 초기화 이벤트에서 경로 의존 값을 완성합니다.

latex_elements 핵심값
목적
papersize / pointsize`a4paper` / `11pt`용지와 기본 글자 크기
passoptionstopackagesxcolor에 `svgnames` 전달SVG 이름 색상 사용
printindexfootnotesize + raggedright + printindex`.ind` 색인 파일과 작은 왼쪽 정렬 색인
fontenc/inputenc/utf8extra빈 문자열UTF-8 문자 재가공 방지
sphinxsetup수평 0.5in, 수직 1in, parsed literal 줄바꿈문서 여백과 verbatim 동작
maxlistdepth`10`깊은 중첩 목록 허용
extrapackages`setspace`CJK one-half spacing 지원을 hyperref보다 먼저 로드
fontpkgDejaVu Serif/Sans/Sans Mono본문·산세리프·고정폭·제목 글꼴 지정
preamble`kerneldoc-preamble.sty` 입력커널 문서 전용 LaTeX 설정 로드

원문 456-496줄의 인쇄·글꼴·레이아웃 설정입니다.

LaTeX 문서와 보조 파일
설정현재 값설명
latex_documents빈 목록`config_init` 이벤트에서 index.rst 위치에 따라 채움
latex_logo주석 처리기본 제목 페이지 로고 동작
latex_use_parts/show_pagerefs/show_urls주석 처리Sphinx 기본값 사용
latex_appendices/domain_indices주석 처리부록과 도메인 색인 기본값 사용
latex_additional_files`sphinx/kerneldoc-preamble.sty`빌드 디렉터리에 전용 스타일 파일 복사

원문 498-524줄의 동적 목록과 주석 옵션입니다.

기타 출력 백엔드
백엔드설정출력 의미
man`(master_doc, thelinuxkernel, The Linux Kernel Documentation, [author], 1)`섹션 1 매뉴얼 페이지
TexinfoTheLinuxKernel 대상, Miscellaneous 범주dir 메뉴용 프로젝트 문서
EPUBproject/author/copyright 재사용, `search.html` 제외Dublin Core 메타데이터와 패키지 제외 목록
rst2pdf`kernel-documentation`, `Kernel`, `J. Random Bozo`단일 PDF 튜플; index 추가 시 지나치게 커진다는 FIXME 보존
kernel-doc`../scripts/kernel-doc.py`, srctree `..`Makefile 인수가 없는 직접 Sphinx 실행용 기본 경로

원문 527-584줄의 각 출력 형식과 튜플입니다.

최종 줄 좌표
원문 줄구성한국어 해설
454-496LaTeX 요소용지, 색상, 색인, 인코딩, 여백, 목록 깊이, 글꼴과 preamble을 설정합니다.
498-524LaTeX 문서·추가 파일동적 문서 목록과 `kerneldoc-preamble.sty` 복사를 선언합니다.
527-536man page한 개의 섹션 1 매뉴얼 페이지 튜플을 정의합니다.
539-552Texinfo문서 트리를 TheLinuxKernel Texinfo 대상으로 묶습니다.
554-563EPUB프로젝트 메타데이터와 `search.html` 제외를 설정합니다.
565-578rst2pdfPDF 상호 참조 관련 FIXME와 단일 PDF 문서를 정의합니다.
580-590kernel-doc와 loadConfig직접 빌드 경로를 제공하고 외부 설정을 마지막에 병합합니다.
593-596setup(app)`config-inited` 이벤트에 `config_init`을 연결합니다.

출력 백엔드와 설정 후크의 원문 범위입니다.

Linux v6.18.37 conf.py 원문 전체 보존

1-596
전체 원문 줄 좌표
원문 줄영역핵심 심볼
1-55부트스트랩과 입력 패턴`needs_sphinx`, `has_include_patterns`, `doctree`, `dyn_*_patterns`
56-124경로 의존 초기화`config_init`, `latex_documents`
126-136명령 검색`have_command`
139-220확장과 C 파서`extensions`, `c_id_attributes`
222-262레이블·수학·소스`autosectionlabel_*`, `SPHINX_IMGMATH`, `source_suffix`, `master_doc`
264-317프로젝트와 버전`project`, `version`, `release`, `get_cline_version`
320-361일반 출력`language`, `pygments_style`, `primary_domain`
363-452HTML`html_theme`, `DOCS_THEME`, `DOCS_CSS`, `html_sidebars`
454-524LaTeX`latex_elements`, `latex_documents`, `latex_additional_files`
527-578man·Texinfo·EPUB·PDF`man_pages`, `texinfo_documents`, `epub_*`, `pdf_documents`
580-596kernel-doc와 후크`kerneldoc_bin`, `loadConfig`, `setup`

596줄 파일의 상위 구성을 한눈에 확인하는 색인입니다.

아래 코드는 Linux v6.18.37 원문 1-596줄 전체입니다. 표시 안정성을 위해 탭만 여덟 칸으로 정규화했으며 Python 식별자, 문자열, 경로, 주석, docstring, LaTeX 원시 문자열, 환경 변수, 함수와 설정 순서는 변경하지 않았습니다.

# SPDX-License-Identifier: GPL-2.0-only
# pylint: disable=C0103,C0209

"""
The Linux Kernel documentation build configuration file.
"""

import os
import shutil
import sys

from  textwrap import dedent

import sphinx

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.insert(0, os.path.abspath("sphinx"))

from load_config import loadConfig               # pylint: disable=C0413,E0401

# Minimal supported version
needs_sphinx = "3.4.3"

# Get Sphinx version
major, minor, patch = sphinx.version_info[:3]          # pylint: disable=I1101

# Include_patterns were added on Sphinx 5.1
if (major < 5) or (major == 5 and minor < 1):
    has_include_patterns = False
else:
    has_include_patterns = True
    # Include patterns that don't contain directory names, in glob format
    include_patterns = ["**.rst"]

# Location of Documentation/ directory
doctree = os.path.abspath(".")

# Exclude of patterns that don't contain directory names, in glob format.
exclude_patterns = []

# List of patterns that contain directory names in glob format.
dyn_include_patterns = []
dyn_exclude_patterns = ["output"]

# Currently, only netlink/specs has a parser for yaml.
# Prefer using include patterns if available, as it is faster
if has_include_patterns:
    dyn_include_patterns.append("netlink/specs/*.yaml")
else:
    dyn_exclude_patterns.append("netlink/*.yaml")
    dyn_exclude_patterns.append("devicetree/bindings/**.yaml")
    dyn_exclude_patterns.append("core-api/kho/bindings/**.yaml")

# Properly handle directory patterns and LaTeX docs
# -------------------------------------------------

def config_init(app, config):
    """
    Initialize path-dependent variabled

    On Sphinx, all directories are relative to what it is passed as
    SOURCEDIR parameter for sphinx-build. Due to that, all patterns
    that have directory names on it need to be dynamically set, after
    converting them to a relative patch.

    As Sphinx doesn't include any patterns outside SOURCEDIR, we should
    exclude relative patterns that start with "../".
    """

    # setup include_patterns dynamically
    if has_include_patterns:
        for p in dyn_include_patterns:
            full = os.path.join(doctree, p)

            rel_path = os.path.relpath(full, start=app.srcdir)
            if rel_path.startswith("../"):
                continue

            config.include_patterns.append(rel_path)

    # setup exclude_patterns dynamically
    for p in dyn_exclude_patterns:
        full = os.path.join(doctree, p)

        rel_path = os.path.relpath(full, start=app.srcdir)
        if rel_path.startswith("../"):
            continue

        config.exclude_patterns.append(rel_path)

    # LaTeX and PDF output require a list of documents with are dependent
    # of the app.srcdir. Add them here

    # When SPHINXDIRS is used, we just need to get index.rst, if it exists
    if not os.path.samefile(doctree, app.srcdir):
        doc = os.path.basename(app.srcdir)
        fname = "index"
        if os.path.exists(os.path.join(app.srcdir, fname + ".rst")):
            latex_documents.append((fname, doc + ".tex",
                                    "Linux %s Documentation" % doc.capitalize(),
                                    "The kernel development community",
                                    "manual"))
            return

    # When building all docs, or when a main index.rst doesn't exist, seek
    # for it on subdirectories
    for doc in os.listdir(app.srcdir):
        fname = os.path.join(doc, "index")
        if not os.path.exists(os.path.join(app.srcdir, fname + ".rst")):
            continue

        has = False
        for l in latex_documents:
            if l[0] == fname:
                has = True
                break

        if not has:
            latex_documents.append((fname, doc + ".tex",
                                    "Linux %s Documentation" % doc.capitalize(),
                                    "The kernel development community",
                                    "manual"))

# helper
# ------


def have_command(cmd):
    """Search ``cmd`` in the ``PATH`` environment.

    If found, return True.
    If not found, return False.
    """
    return shutil.which(cmd) is not None


# -- General configuration ------------------------------------------------

# Add any Sphinx extensions in alphabetic order
extensions = [
    "automarkup",
    "kernel_abi",
    "kerneldoc",
    "kernel_feat",
    "kernel_include",
    "kfigure",
    "maintainers_include",
    "parser_yaml",
    "rstFlatTable",
    "sphinx.ext.autosectionlabel",
    "sphinx.ext.ifconfig",
    "translations",
]
# Since Sphinx version 3, the C function parser is more pedantic with regards
# to type checking. Due to that, having macros at c:function cause problems.
# Those needed to be escaped by using c_id_attributes[] array
c_id_attributes = [
    # GCC Compiler types not parsed by Sphinx:
    "__restrict__",

    # include/linux/compiler_types.h:
    "__iomem",
    "__kernel",
    "noinstr",
    "notrace",
    "__percpu",
    "__rcu",
    "__user",
    "__force",
    "__counted_by_le",
    "__counted_by_be",

    # include/linux/compiler_attributes.h:
    "__alias",
    "__aligned",
    "__aligned_largest",
    "__always_inline",
    "__assume_aligned",
    "__cold",
    "__attribute_const__",
    "__copy",
    "__pure",
    "__designated_init",
    "__visible",
    "__printf",
    "__scanf",
    "__gnu_inline",
    "__malloc",
    "__mode",
    "__no_caller_saved_registers",
    "__noclone",
    "__nonstring",
    "__noreturn",
    "__packed",
    "__pure",
    "__section",
    "__always_unused",
    "__maybe_unused",
    "__used",
    "__weak",
    "noinline",
    "__fix_address",
    "__counted_by",

    # include/linux/memblock.h:
    "__init_memblock",
    "__meminit",

    # include/linux/init.h:
    "__init",
    "__ref",

    # include/linux/linkage.h:
    "asmlinkage",

    # include/linux/btf.h
    "__bpf_kfunc",
]

# Ensure that autosectionlabel will produce unique names
autosectionlabel_prefix_document = True
autosectionlabel_maxdepth = 2

# Load math renderer:
# For html builder, load imgmath only when its dependencies are met.
# mathjax is the default math renderer since Sphinx 1.8.
have_latex = have_command("latex")
have_dvipng = have_command("dvipng")
load_imgmath = have_latex and have_dvipng

# Respect SPHINX_IMGMATH (for html docs only)
if "SPHINX_IMGMATH" in os.environ:
    env_sphinx_imgmath = os.environ["SPHINX_IMGMATH"]
    if "yes" in env_sphinx_imgmath:
        load_imgmath = True
    elif "no" in env_sphinx_imgmath:
        load_imgmath = False
    else:
        sys.stderr.write("Unknown env SPHINX_IMGMATH=%s ignored.\n" % env_sphinx_imgmath)

if load_imgmath:
    extensions.append("sphinx.ext.imgmath")
    math_renderer = "imgmath"
else:
    math_renderer = "mathjax"

# Add any paths that contain templates here, relative to this directory.
templates_path = ["sphinx/templates"]

# The suffixes of source filenames that will be automatically parsed
source_suffix = {
    ".rst": "restructuredtext",
    ".yaml": "yaml",
}

# The encoding of source files.
# source_encoding = 'utf-8-sig'

# The master toctree document.
master_doc = "index"

# General information about the project.
project = "The Linux Kernel"
copyright = "The kernel development community"         # pylint: disable=W0622
author = "The kernel development community"

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# In a normal build, version and release are set to KERNELVERSION and
# KERNELRELEASE, respectively, from the Makefile via Sphinx command line
# arguments.
#
# The following code tries to extract the information by reading the Makefile,
# when Sphinx is run directly (e.g. by Read the Docs).
try:
    makefile_version = None
    makefile_patchlevel = None
    with open("../Makefile", encoding="utf=8") as fp:
        for line in fp:
            key, val = [x.strip() for x in line.split("=", 2)]
            if key == "VERSION":
                makefile_version = val
            elif key == "PATCHLEVEL":
                makefile_patchlevel = val
            if makefile_version and makefile_patchlevel:
                break
except Exception:
    pass
finally:
    if makefile_version and makefile_patchlevel:
        version = release = makefile_version + "." + makefile_patchlevel
    else:
        version = release = "unknown version"


def get_cline_version():
    """
    HACK: There seems to be no easy way for us to get at the version and
    release information passed in from the makefile...so go pawing through the
    command-line options and find it for ourselves.
    """

    c_version = c_release = ""
    for arg in sys.argv:
        if arg.startswith("version="):
            c_version = arg[8:]
        elif arg.startswith("release="):
            c_release = arg[8:]
    if c_version:
        if c_release:
            return c_version + "-" + c_release
        return c_version
    return version  # Whatever we came up with before


# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = "en"

# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
# today = ''
# Else, today_fmt is used as the format for a strftime call.
# today_fmt = '%B %d, %Y'

# The reST default role (used for this markup: `text`) to use for all
# documents.
# default_role = None

# If true, '()' will be appended to :func: etc. cross-reference text.
# add_function_parentheses = True

# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
# add_module_names = True

# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
# show_authors = False

# The name of the Pygments (syntax highlighting) style to use.
pygments_style = "sphinx"

# A list of ignored prefixes for module index sorting.
# modindex_common_prefix = []

# If true, keep warnings as "system message" paragraphs in the built documents.
# keep_warnings = False

# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False

primary_domain = "c"
highlight_language = "none"

# -- Options for HTML output ----------------------------------------------

# The theme to use for HTML and HTML Help pages.  See the documentation for
# a list of builtin themes.

# Default theme
html_theme = "alabaster"
html_css_files = []

if "DOCS_THEME" in os.environ:
    html_theme = os.environ["DOCS_THEME"]

if html_theme in ["sphinx_rtd_theme", "sphinx_rtd_dark_mode"]:
    # Read the Docs theme
    try:
        import sphinx_rtd_theme

        html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]

        # Add any paths that contain custom static files (such as style sheets) here,
        # relative to this directory. They are copied after the builtin static files,
        # so a file named "default.css" will overwrite the builtin "default.css".
        html_css_files = [
            "theme_overrides.css",
        ]

        # Read the Docs dark mode override theme
        if html_theme == "sphinx_rtd_dark_mode":
            try:
                import sphinx_rtd_dark_mode            # pylint: disable=W0611

                extensions.append("sphinx_rtd_dark_mode")
            except ImportError:
                html_theme = "sphinx_rtd_theme"

        if html_theme == "sphinx_rtd_theme":
            # Add color-specific RTD normal mode
            html_css_files.append("theme_rtd_colors.css")

        html_theme_options = {
            "navigation_depth": -1,
        }

    except ImportError:
        html_theme = "alabaster"

if "DOCS_CSS" in os.environ:
    css = os.environ["DOCS_CSS"].split(" ")

    for l in css:
        html_css_files.append(l)

if html_theme == "alabaster":
    html_theme_options = {
        "description": get_cline_version(),
        "page_width": "65em",
        "sidebar_width": "15em",
        "fixed_sidebar": "true",
        "font_size": "inherit",
        "font_family": "serif",
    }

sys.stderr.write("Using %s theme\n" % html_theme)

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["sphinx-static"]

# If true, Docutils "smart quotes" will be used to convert quotes and dashes
# to typographically correct entities.  However, conversion of "--" to "—"
# is not always what we want, so enable only quotes.
smartquotes_action = "q"

# Custom sidebar templates, maps document names to template names.
# Note that the RTD theme ignores this
html_sidebars = {"**": ["searchbox.html",
                        "kernel-toc.html",
                        "sourcelink.html"]}

# about.html is available for alabaster theme. Add it at the front.
if html_theme == "alabaster":
    html_sidebars["**"].insert(0, "about.html")

# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
html_logo = "images/logo.svg"

# Output file base name for HTML help builder.
htmlhelp_basename = "TheLinuxKerneldoc"

# -- Options for LaTeX output ---------------------------------------------

latex_elements = {
    # The paper size ('letterpaper' or 'a4paper').
    "papersize": "a4paper",
    "passoptionstopackages": dedent(r"""
        \PassOptionsToPackage{svgnames}{xcolor}
    """),
    # The font size ('10pt', '11pt' or '12pt').
    "pointsize": "11pt",
    # Needed to generate a .ind file
    "printindex": r"\footnotesize\raggedright\printindex",
    # Latex figure (float) alignment
    # 'figure_align': 'htbp',
    # Don't mangle with UTF-8 chars
    "fontenc": "",
    "inputenc": "",
    "utf8extra": "",
    # Set document margins
    "sphinxsetup": dedent(r"""
        hmargin=0.5in, vmargin=1in,
        parsedliteralwraps=true,
        verbatimhintsturnover=false,
    """),
    #
    # Some of our authors are fond of deep nesting; tell latex to
    # cope.
    #
    "maxlistdepth": "10",
    # For CJK One-half spacing, need to be in front of hyperref
    "extrapackages": r"\usepackage{setspace}",
    "fontpkg": dedent(r"""
        \usepackage{fontspec}
        \setmainfont{DejaVu Serif}
        \setsansfont{DejaVu Sans}
        \setmonofont{DejaVu Sans Mono}
        \newfontfamily\headingfont{DejaVu Serif}
    """),
    "preamble": dedent(r"""
        % Load kerneldoc specific LaTeX settings
        \input{kerneldoc-preamble.sty}
    """)
}

# This will be filled up by config-inited event
latex_documents = []

# The name of an image file (relative to this directory) to place at the top of
# the title page.
# latex_logo = None

# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
# latex_use_parts = False

# If true, show page references after internal links.
# latex_show_pagerefs = False

# If true, show URL addresses after external links.
# latex_show_urls = False

# Documents to append as an appendix to all manuals.
# latex_appendices = []

# If false, no module index is generated.
# latex_domain_indices = True

# Additional LaTeX stuff to be copied to build directory
latex_additional_files = [
    "sphinx/kerneldoc-preamble.sty",
]


# -- Options for manual page output ---------------------------------------

# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
    (master_doc, "thelinuxkernel", "The Linux Kernel Documentation", [author], 1)
]

# If true, show URL addresses after external links.
# man_show_urls = False


# -- Options for Texinfo output -------------------------------------------

# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
#  dir menu entry, description, category)
texinfo_documents = [(
        master_doc,
        "TheLinuxKernel",
        "The Linux Kernel Documentation",
        author,
        "TheLinuxKernel",
        "One line description of project.",
        "Miscellaneous",
    ),]

# -- Options for Epub output ----------------------------------------------

# Bibliographic Dublin Core info.
epub_title = project
epub_author = author
epub_publisher = author
epub_copyright = copyright

# A list of files that should not be packed into the epub file.
epub_exclude_files = ["search.html"]

# =======
# rst2pdf
#
# Grouping the document tree into PDF files. List of tuples
# (source start file, target name, title, author, options).
#
# See the Sphinx chapter of https://ralsina.me/static/manual.pdf
#
# FIXME: Do not add the index file here; the result will be too big. Adding
# multiple PDF files here actually tries to get the cross-referencing right
# *between* PDF files.
pdf_documents = [
    ("kernel-documentation", "Kernel", "Kernel", "J. Random Bozo"),
]

# kernel-doc extension configuration for running Sphinx directly (e.g. by Read
# the Docs). In a normal build, these are supplied from the Makefile via command
# line arguments.
kerneldoc_bin = "../scripts/kernel-doc.py"
kerneldoc_srctree = ".."

# ------------------------------------------------------------------------------
# Since loadConfig overwrites settings from the global namespace, it has to be
# the last statement in the conf.py file
# ------------------------------------------------------------------------------
loadConfig(globals())


def setup(app):
    """Patterns need to be updated at init time on older Sphinx versions"""

    app.connect('config-inited', config_init)