mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 09:20:13 -04:00
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>
This commit is contained in:
committed by
Jonathan Corbet
parent
0d9abc7627
commit
7e8a8143ec
@@ -53,7 +53,7 @@ ifeq ($(HAVE_SPHINX),0)
|
|||||||
else # HAVE_SPHINX
|
else # HAVE_SPHINX
|
||||||
|
|
||||||
# Common documentation targets
|
# Common documentation targets
|
||||||
infodocs texinfodocs latexdocs epubdocs xmldocs pdfdocs linkcheckdocs:
|
mandocs infodocs texinfodocs latexdocs epubdocs xmldocs pdfdocs linkcheckdocs:
|
||||||
$(Q)@$(srctree)/tools/docs/sphinx-pre-install --version-check
|
$(Q)@$(srctree)/tools/docs/sphinx-pre-install --version-check
|
||||||
+$(Q)$(PYTHON3) $(BUILD_WRAPPER) $@ \
|
+$(Q)$(PYTHON3) $(BUILD_WRAPPER) $@ \
|
||||||
--sphinxdirs="$(SPHINXDIRS)" --conf="$(SPHINX_CONF)" \
|
--sphinxdirs="$(SPHINXDIRS)" --conf="$(SPHINX_CONF)" \
|
||||||
@@ -108,6 +108,7 @@ dochelp:
|
|||||||
@echo ' htmldocs-redirects - generate HTML redirects for moved pages'
|
@echo ' htmldocs-redirects - generate HTML redirects for moved pages'
|
||||||
@echo ' texinfodocs - Texinfo'
|
@echo ' texinfodocs - Texinfo'
|
||||||
@echo ' infodocs - Info'
|
@echo ' infodocs - Info'
|
||||||
|
@echo ' mandocs - Man pages'
|
||||||
@echo ' latexdocs - LaTeX'
|
@echo ' latexdocs - LaTeX'
|
||||||
@echo ' pdfdocs - PDF'
|
@echo ' pdfdocs - PDF'
|
||||||
@echo ' epubdocs - EPUB'
|
@echo ' epubdocs - EPUB'
|
||||||
|
|||||||
@@ -579,20 +579,23 @@ source.
|
|||||||
How to use kernel-doc to generate man pages
|
How to use kernel-doc to generate man pages
|
||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
|
|
||||||
If you just want to use kernel-doc to generate man pages you can do this
|
To generate man pages for all files that contain kernel-doc markups, run::
|
||||||
from the kernel git tree::
|
|
||||||
|
|
||||||
$ scripts/kernel-doc -man \
|
$ make mandocs
|
||||||
$(git grep -l '/\*\*' -- :^Documentation :^tools) \
|
|
||||||
| scripts/split-man.pl /tmp/man
|
|
||||||
|
|
||||||
Some older versions of git do not support some of the variants of syntax for
|
Or calling ``script-build-wrapper`` directly::
|
||||||
path exclusion. One of the following commands may work for those versions::
|
|
||||||
|
|
||||||
$ scripts/kernel-doc -man \
|
$ ./tools/docs/sphinx-build-wrapper mandocs
|
||||||
$(git grep -l '/\*\*' -- . ':!Documentation' ':!tools') \
|
|
||||||
| scripts/split-man.pl /tmp/man
|
|
||||||
|
|
||||||
$ scripts/kernel-doc -man \
|
The output will be at ``/man`` directory inside the output directory
|
||||||
$(git grep -l '/\*\*' -- . ":(exclude)Documentation" ":(exclude)tools") \
|
(by default: ``Documentation/output``).
|
||||||
| scripts/split-man.pl /tmp/man
|
|
||||||
|
Optionally, it is possible to generate a partial set of man pages by
|
||||||
|
using SPHINXDIRS:
|
||||||
|
|
||||||
|
$ make SPHINXDIRS=driver-api/media mandocs
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
When SPHINXDIRS={subdir} is used, it will only generate man pages for
|
||||||
|
the files explicitly inside a ``Documentation/{subdir}/.../*.rst`` file.
|
||||||
|
|||||||
7
Makefile
7
Makefile
@@ -1799,9 +1799,10 @@ $(help-board-dirs): help-%:
|
|||||||
|
|
||||||
# Documentation targets
|
# Documentation targets
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
DOC_TARGETS := xmldocs latexdocs pdfdocs htmldocs htmldocs-redirects \
|
DOC_TARGETS := xmldocs latexdocs pdfdocs htmldocs epubdocs cleandocs \
|
||||||
epubdocs cleandocs linkcheckdocs dochelp refcheckdocs \
|
linkcheckdocs dochelp refcheckdocs texinfodocs infodocs mandocs \
|
||||||
texinfodocs infodocs
|
htmldocs-redirects
|
||||||
|
|
||||||
PHONY += $(DOC_TARGETS)
|
PHONY += $(DOC_TARGETS)
|
||||||
$(DOC_TARGETS):
|
$(DOC_TARGETS):
|
||||||
$(Q)$(MAKE) $(build)=Documentation $@
|
$(Q)$(MAKE) $(build)=Documentation $@
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
#!/usr/bin/env perl
|
|
||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
#
|
|
||||||
# Author: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
||||||
#
|
|
||||||
# Produce manpages from kernel-doc.
|
|
||||||
# See Documentation/doc-guide/kernel-doc.rst for instructions
|
|
||||||
|
|
||||||
if ($#ARGV < 0) {
|
|
||||||
die "where do I put the results?\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
mkdir $ARGV[0],0777;
|
|
||||||
$state = 0;
|
|
||||||
while (<STDIN>) {
|
|
||||||
if (/^\.TH \"[^\"]*\" 9 \"([^\"]*)\"/) {
|
|
||||||
if ($state == 1) { close OUT }
|
|
||||||
$state = 1;
|
|
||||||
$fn = "$ARGV[0]/$1.9";
|
|
||||||
print STDERR "Creating $fn\n";
|
|
||||||
open OUT, ">$fn" or die "can't open $fn: $!\n";
|
|
||||||
print OUT $_;
|
|
||||||
} elsif ($state != 0) {
|
|
||||||
print OUT $_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
close OUT;
|
|
||||||
@@ -47,12 +47,14 @@ the newer version.
|
|||||||
import argparse
|
import argparse
|
||||||
import locale
|
import locale
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import shlex
|
import shlex
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from concurrent import futures
|
from concurrent import futures
|
||||||
|
from glob import glob
|
||||||
|
|
||||||
from lib.python_version import PythonVersion
|
from lib.python_version import PythonVersion
|
||||||
from lib.latex_fonts import LatexFontChecker
|
from lib.latex_fonts import LatexFontChecker
|
||||||
@@ -77,6 +79,7 @@ TARGETS = {
|
|||||||
"epubdocs": { "builder": "epub", "out_dir": "epub" },
|
"epubdocs": { "builder": "epub", "out_dir": "epub" },
|
||||||
"texinfodocs": { "builder": "texinfo", "out_dir": "texinfo" },
|
"texinfodocs": { "builder": "texinfo", "out_dir": "texinfo" },
|
||||||
"infodocs": { "builder": "texinfo", "out_dir": "texinfo" },
|
"infodocs": { "builder": "texinfo", "out_dir": "texinfo" },
|
||||||
|
"mandocs": { "builder": "man", "out_dir": "man" },
|
||||||
"latexdocs": { "builder": "latex", "out_dir": "latex" },
|
"latexdocs": { "builder": "latex", "out_dir": "latex" },
|
||||||
"pdfdocs": { "builder": "latex", "out_dir": "latex" },
|
"pdfdocs": { "builder": "latex", "out_dir": "latex" },
|
||||||
"xmldocs": { "builder": "xml", "out_dir": "xml" },
|
"xmldocs": { "builder": "xml", "out_dir": "xml" },
|
||||||
@@ -503,6 +506,71 @@ class SphinxBuilder:
|
|||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
sys.exit(f"Error generating info docs: {e}")
|
sys.exit(f"Error generating info docs: {e}")
|
||||||
|
|
||||||
|
def handle_man(self, kerneldoc, docs_dir, src_dir, output_dir):
|
||||||
|
"""
|
||||||
|
Create man pages from kernel-doc output
|
||||||
|
"""
|
||||||
|
|
||||||
|
re_kernel_doc = re.compile(r"^\.\.\s+kernel-doc::\s*(\S+)")
|
||||||
|
re_man = re.compile(r'^\.TH "[^"]*" (\d+) "([^"]*)"')
|
||||||
|
|
||||||
|
if docs_dir == src_dir:
|
||||||
|
#
|
||||||
|
# Pick the entire set of kernel-doc markups from the entire tree
|
||||||
|
#
|
||||||
|
kdoc_files = set([self.srctree])
|
||||||
|
else:
|
||||||
|
kdoc_files = set()
|
||||||
|
|
||||||
|
for fname in glob(os.path.join(src_dir, "**"), recursive=True):
|
||||||
|
if os.path.isfile(fname) and fname.endswith(".rst"):
|
||||||
|
with open(fname, "r", encoding="utf-8") as in_fp:
|
||||||
|
data = in_fp.read()
|
||||||
|
|
||||||
|
for line in data.split("\n"):
|
||||||
|
match = re_kernel_doc.match(line)
|
||||||
|
if match:
|
||||||
|
if os.path.isfile(match.group(1)):
|
||||||
|
kdoc_files.add(match.group(1))
|
||||||
|
|
||||||
|
if not kdoc_files:
|
||||||
|
sys.exit(f"Directory {src_dir} doesn't contain kernel-doc tags")
|
||||||
|
|
||||||
|
cmd = [ kerneldoc, "-m" ] + sorted(kdoc_files)
|
||||||
|
try:
|
||||||
|
if self.verbose:
|
||||||
|
print(" ".join(cmd))
|
||||||
|
|
||||||
|
result = subprocess.run(cmd, stdout=subprocess.PIPE, text= True)
|
||||||
|
|
||||||
|
if result.returncode:
|
||||||
|
print(f"Warning: kernel-doc returned {result.returncode} warnings")
|
||||||
|
|
||||||
|
except (OSError, ValueError, subprocess.SubprocessError) as e:
|
||||||
|
sys.exit(f"Failed to create man pages for {src_dir}: {repr(e)}")
|
||||||
|
|
||||||
|
fp = None
|
||||||
|
try:
|
||||||
|
for line in result.stdout.split("\n"):
|
||||||
|
match = re_man.match(line)
|
||||||
|
if not match:
|
||||||
|
if fp:
|
||||||
|
fp.write(line + '\n')
|
||||||
|
continue
|
||||||
|
|
||||||
|
if fp:
|
||||||
|
fp.close()
|
||||||
|
|
||||||
|
fname = f"{output_dir}/{match.group(2)}.{match.group(1)}"
|
||||||
|
|
||||||
|
if self.verbose:
|
||||||
|
print(f"Creating {fname}")
|
||||||
|
fp = open(fname, "w", encoding="utf-8")
|
||||||
|
fp.write(line + '\n')
|
||||||
|
finally:
|
||||||
|
if fp:
|
||||||
|
fp.close()
|
||||||
|
|
||||||
def cleandocs(self, builder): # pylint: disable=W0613
|
def cleandocs(self, builder): # pylint: disable=W0613
|
||||||
"""Remove documentation output directory"""
|
"""Remove documentation output directory"""
|
||||||
shutil.rmtree(self.builddir, ignore_errors=True)
|
shutil.rmtree(self.builddir, ignore_errors=True)
|
||||||
@@ -531,7 +599,7 @@ class SphinxBuilder:
|
|||||||
# Other targets require sphinx-build, so check if it exists
|
# Other targets require sphinx-build, so check if it exists
|
||||||
#
|
#
|
||||||
sphinxbuild = shutil.which(self.sphinxbuild, path=self.env["PATH"])
|
sphinxbuild = shutil.which(self.sphinxbuild, path=self.env["PATH"])
|
||||||
if not sphinxbuild:
|
if not sphinxbuild and target != "mandocs":
|
||||||
sys.exit(f"Error: {self.sphinxbuild} not found in PATH.\n")
|
sys.exit(f"Error: {self.sphinxbuild} not found in PATH.\n")
|
||||||
|
|
||||||
if builder == "latex":
|
if builder == "latex":
|
||||||
@@ -619,10 +687,13 @@ class SphinxBuilder:
|
|||||||
output_dir,
|
output_dir,
|
||||||
]
|
]
|
||||||
|
|
||||||
try:
|
if target == "mandocs":
|
||||||
self.run_sphinx(sphinxbuild, build_args, env=self.env)
|
self.handle_man(kerneldoc, docs_dir, src_dir, output_dir)
|
||||||
except (OSError, ValueError, subprocess.SubprocessError) as e:
|
else:
|
||||||
sys.exit(f"Build failed: {repr(e)}")
|
try:
|
||||||
|
self.run_sphinx(sphinxbuild, build_args, env=self.env)
|
||||||
|
except (OSError, ValueError, subprocess.SubprocessError) as e:
|
||||||
|
sys.exit(f"Build failed: {repr(e)}")
|
||||||
|
|
||||||
#
|
#
|
||||||
# Ensure that each html/epub output will have needed static files
|
# Ensure that each html/epub output will have needed static files
|
||||||
|
|||||||
Reference in New Issue
Block a user