Skip to content

Commit 7e8a814

Browse files
mchehabJonathan Corbet
authored andcommitted
docs: add support to build manpages from kerneldoc output
Generating man files currently requires running a separate script. The target also doesn't appear at the docs Makefile. Add support for mandocs at the Makefile, adding the build logic inside sphinx-build-wrapper, updating documentation and dropping the ancillary script. Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> Message-ID: <3d248d724e7f3154f6e3a227e5923d7360201de9.1758196090.git.mchehab+huawei@kernel.org> Signed-off-by: Jonathan Corbet <corbet@lwn.net>
1 parent 0d9abc7 commit 7e8a814

5 files changed

Lines changed: 98 additions & 50 deletions

File tree

Documentation/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ ifeq ($(HAVE_SPHINX),0)
5353
else # HAVE_SPHINX
5454

5555
# Common documentation targets
56-
infodocs texinfodocs latexdocs epubdocs xmldocs pdfdocs linkcheckdocs:
56+
mandocs infodocs texinfodocs latexdocs epubdocs xmldocs pdfdocs linkcheckdocs:
5757
$(Q)@$(srctree)/tools/docs/sphinx-pre-install --version-check
5858
+$(Q)$(PYTHON3) $(BUILD_WRAPPER) $@ \
5959
--sphinxdirs="$(SPHINXDIRS)" --conf="$(SPHINX_CONF)" \
@@ -108,6 +108,7 @@ dochelp:
108108
@echo ' htmldocs-redirects - generate HTML redirects for moved pages'
109109
@echo ' texinfodocs - Texinfo'
110110
@echo ' infodocs - Info'
111+
@echo ' mandocs - Man pages'
111112
@echo ' latexdocs - LaTeX'
112113
@echo ' pdfdocs - PDF'
113114
@echo ' epubdocs - EPUB'

Documentation/doc-guide/kernel-doc.rst

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -579,20 +579,23 @@ source.
579579
How to use kernel-doc to generate man pages
580580
-------------------------------------------
581581

582-
If you just want to use kernel-doc to generate man pages you can do this
583-
from the kernel git tree::
582+
To generate man pages for all files that contain kernel-doc markups, run::
584583

585-
$ scripts/kernel-doc -man \
586-
$(git grep -l '/\*\*' -- :^Documentation :^tools) \
587-
| scripts/split-man.pl /tmp/man
584+
$ make mandocs
588585

589-
Some older versions of git do not support some of the variants of syntax for
590-
path exclusion. One of the following commands may work for those versions::
586+
Or calling ``script-build-wrapper`` directly::
591587

592-
$ scripts/kernel-doc -man \
593-
$(git grep -l '/\*\*' -- . ':!Documentation' ':!tools') \
594-
| scripts/split-man.pl /tmp/man
588+
$ ./tools/docs/sphinx-build-wrapper mandocs
595589

596-
$ scripts/kernel-doc -man \
597-
$(git grep -l '/\*\*' -- . ":(exclude)Documentation" ":(exclude)tools") \
598-
| scripts/split-man.pl /tmp/man
590+
The output will be at ``/man`` directory inside the output directory
591+
(by default: ``Documentation/output``).
592+
593+
Optionally, it is possible to generate a partial set of man pages by
594+
using SPHINXDIRS:
595+
596+
$ make SPHINXDIRS=driver-api/media mandocs
597+
598+
.. note::
599+
600+
When SPHINXDIRS={subdir} is used, it will only generate man pages for
601+
the files explicitly inside a ``Documentation/{subdir}/.../*.rst`` file.

Makefile

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1799,9 +1799,10 @@ $(help-board-dirs): help-%:
17991799

18001800
# Documentation targets
18011801
# ---------------------------------------------------------------------------
1802-
DOC_TARGETS := xmldocs latexdocs pdfdocs htmldocs htmldocs-redirects \
1803-
epubdocs cleandocs linkcheckdocs dochelp refcheckdocs \
1804-
texinfodocs infodocs
1802+
DOC_TARGETS := xmldocs latexdocs pdfdocs htmldocs epubdocs cleandocs \
1803+
linkcheckdocs dochelp refcheckdocs texinfodocs infodocs mandocs \
1804+
htmldocs-redirects
1805+
18051806
PHONY += $(DOC_TARGETS)
18061807
$(DOC_TARGETS):
18071808
$(Q)$(MAKE) $(build)=Documentation $@

scripts/split-man.pl

Lines changed: 0 additions & 28 deletions
This file was deleted.

tools/docs/sphinx-build-wrapper

Lines changed: 76 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,14 @@ the newer version.
4747
import argparse
4848
import locale
4949
import os
50+
import re
5051
import shlex
5152
import shutil
5253
import subprocess
5354
import sys
5455

5556
from concurrent import futures
57+
from glob import glob
5658

5759
from lib.python_version import PythonVersion
5860
from lib.latex_fonts import LatexFontChecker
@@ -77,6 +79,7 @@ TARGETS = {
7779
"epubdocs": { "builder": "epub", "out_dir": "epub" },
7880
"texinfodocs": { "builder": "texinfo", "out_dir": "texinfo" },
7981
"infodocs": { "builder": "texinfo", "out_dir": "texinfo" },
82+
"mandocs": { "builder": "man", "out_dir": "man" },
8083
"latexdocs": { "builder": "latex", "out_dir": "latex" },
8184
"pdfdocs": { "builder": "latex", "out_dir": "latex" },
8285
"xmldocs": { "builder": "xml", "out_dir": "xml" },
@@ -503,6 +506,71 @@ class SphinxBuilder:
503506
except subprocess.CalledProcessError as e:
504507
sys.exit(f"Error generating info docs: {e}")
505508

509+
def handle_man(self, kerneldoc, docs_dir, src_dir, output_dir):
510+
"""
511+
Create man pages from kernel-doc output
512+
"""
513+
514+
re_kernel_doc = re.compile(r"^\.\.\s+kernel-doc::\s*(\S+)")
515+
re_man = re.compile(r'^\.TH "[^"]*" (\d+) "([^"]*)"')
516+
517+
if docs_dir == src_dir:
518+
#
519+
# Pick the entire set of kernel-doc markups from the entire tree
520+
#
521+
kdoc_files = set([self.srctree])
522+
else:
523+
kdoc_files = set()
524+
525+
for fname in glob(os.path.join(src_dir, "**"), recursive=True):
526+
if os.path.isfile(fname) and fname.endswith(".rst"):
527+
with open(fname, "r", encoding="utf-8") as in_fp:
528+
data = in_fp.read()
529+
530+
for line in data.split("\n"):
531+
match = re_kernel_doc.match(line)
532+
if match:
533+
if os.path.isfile(match.group(1)):
534+
kdoc_files.add(match.group(1))
535+
536+
if not kdoc_files:
537+
sys.exit(f"Directory {src_dir} doesn't contain kernel-doc tags")
538+
539+
cmd = [ kerneldoc, "-m" ] + sorted(kdoc_files)
540+
try:
541+
if self.verbose:
542+
print(" ".join(cmd))
543+
544+
result = subprocess.run(cmd, stdout=subprocess.PIPE, text= True)
545+
546+
if result.returncode:
547+
print(f"Warning: kernel-doc returned {result.returncode} warnings")
548+
549+
except (OSError, ValueError, subprocess.SubprocessError) as e:
550+
sys.exit(f"Failed to create man pages for {src_dir}: {repr(e)}")
551+
552+
fp = None
553+
try:
554+
for line in result.stdout.split("\n"):
555+
match = re_man.match(line)
556+
if not match:
557+
if fp:
558+
fp.write(line + '\n')
559+
continue
560+
561+
if fp:
562+
fp.close()
563+
564+
fname = f"{output_dir}/{match.group(2)}.{match.group(1)}"
565+
566+
if self.verbose:
567+
print(f"Creating {fname}")
568+
fp = open(fname, "w", encoding="utf-8")
569+
fp.write(line + '\n')
570+
finally:
571+
if fp:
572+
fp.close()
573+
506574
def cleandocs(self, builder): # pylint: disable=W0613
507575
"""Remove documentation output directory"""
508576
shutil.rmtree(self.builddir, ignore_errors=True)
@@ -531,7 +599,7 @@ class SphinxBuilder:
531599
# Other targets require sphinx-build, so check if it exists
532600
#
533601
sphinxbuild = shutil.which(self.sphinxbuild, path=self.env["PATH"])
534-
if not sphinxbuild:
602+
if not sphinxbuild and target != "mandocs":
535603
sys.exit(f"Error: {self.sphinxbuild} not found in PATH.\n")
536604

537605
if builder == "latex":
@@ -619,10 +687,13 @@ class SphinxBuilder:
619687
output_dir,
620688
]
621689

622-
try:
623-
self.run_sphinx(sphinxbuild, build_args, env=self.env)
624-
except (OSError, ValueError, subprocess.SubprocessError) as e:
625-
sys.exit(f"Build failed: {repr(e)}")
690+
if target == "mandocs":
691+
self.handle_man(kerneldoc, docs_dir, src_dir, output_dir)
692+
else:
693+
try:
694+
self.run_sphinx(sphinxbuild, build_args, env=self.env)
695+
except (OSError, ValueError, subprocess.SubprocessError) as e:
696+
sys.exit(f"Build failed: {repr(e)}")
626697

627698
#
628699
# Ensure that each html/epub output will have needed static files

0 commit comments

Comments
 (0)