From nobody Fri Oct 3 19:11:52 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4912934F48D; Tue, 26 Aug 2025 13:49:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756216159; cv=none; b=GR1aPBSWwI9Sk+g/YVlFFZg2NexGvdjfBUdmk9e7Mx5esam0KP2WId1VhR6kz0uRffNRH/24e1efhTaKGTO6vmuFM7nVP7t03mNBzM5e/IkX2MyxBpFmUI9ycwviWUilwqO59UKDPF+bd47KDf/Mi0qmuMCzU+oYarwcF/asLp4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756216159; c=relaxed/simple; bh=rDrE2LuCwBUXw/qV6662Y0R+FHQHPqF/g7vGGsTqNTI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=p+n9B21oKGqDLr8DsyVqzV+WFAwJNHqW02n+dEgVoeiMN1ZWUXOB9wwo6uPd4StbGoh5R5c2A2NkDbP+t8gffgrLt3MfwfYYX2S0yefEejr2NhClQAFCyTrsU0Y2W1xhzR9D79+lJsc6LbLg3jSJOMd2VLS5BFM50tFVhtbYed0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hMQkK2lt; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="hMQkK2lt" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DDEB0C113D0; Tue, 26 Aug 2025 13:49:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756216158; bh=rDrE2LuCwBUXw/qV6662Y0R+FHQHPqF/g7vGGsTqNTI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hMQkK2ltqDxzk200ymufi2QORcOKf2CoqCrNbBkhP3ehZW8d0qRQATQHIuJl/1Pn3 0G1acvsoAq4xIIsHHbd+2GyqaV3HWWt3r9E4jEBMfV8BYYnAqpCoXjkQl+EHACiNB1 JK9GIdyRUukB0/v6xn6KA3YKcCsjakrW6qV4nxAlntCk23Ysnk/rFR2ZYPgzteybSK vWqu1Srb763+C26NJGXhmfaATmw1oxFP1NaCoVIXMPp7a4iNpOCv0MGjOYeZP9p2Fs BHAzLx1yhtNnPXfSddI5rupI3Q/greVVl3PU2HyQh7fMQiz6N8Z6RKkOnQ6lT8ZDsM xgKRaO/Uzcy4A== Received: from mchehab by mail.kernel.org with local (Exim 4.98.2) (envelope-from ) id 1uqu31-00000000Fat-0obV; Tue, 26 Aug 2025 15:49:15 +0200 From: Mauro Carvalho Chehab To: Linux Doc Mailing List Cc: Mauro Carvalho Chehab , "Jonathan Corbet" , "Mauro Carvalho Chehab" , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , Alice Ryhl , Masahiro Yamada , Miguel Ojeda , Nathan Chancellor , Nicolas Schier , Randy Dunlap , Tamir Duberstein , linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/1] docs: add support to build manpages from kerneldoc output Date: Tue, 26 Aug 2025 15:49:04 +0200 Message-ID: <423d8460d5fa040d2499b5a5af341e2dc1377881.1756215924.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.51.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Content-Type: text/plain; charset="utf-8" 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 --- Documentation/Makefile | 3 +- Documentation/doc-guide/kernel-doc.rst | 19 ++----- Makefile | 2 +- scripts/split-man.pl | 28 ---------- tools/docs/sphinx-build-wrapper | 77 ++++++++++++++++++++++++-- 5 files changed, 80 insertions(+), 49 deletions(-) delete mode 100755 scripts/split-man.pl diff --git a/Documentation/Makefile b/Documentation/Makefile index 3e1cb44a5fbb..22e39e5ed07d 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -53,7 +53,7 @@ ifeq ($(HAVE_SPHINX),0) else # HAVE_SPHINX =20 # Common documentation targets -infodocs texinfodocs latexdocs epubdocs xmldocs pdfdocs linkcheckdocs: +mandocs infodocs texinfodocs latexdocs epubdocs xmldocs pdfdocs linkcheckd= ocs: $(Q)@$(srctree)/tools/docs/sphinx-pre-install --version-check +$(Q)$(PYTHON3) $(BUILD_WRAPPER) $@ \ --sphinxdirs=3D"$(SPHINXDIRS)" --conf=3D$(SPHINX_CONF) \ @@ -104,6 +104,7 @@ dochelp: @echo ' htmldocs - HTML' @echo ' texinfodocs - Texinfo' @echo ' infodocs - Info' + @echo ' mandocs - Man pages' @echo ' latexdocs - LaTeX' @echo ' pdfdocs - PDF' @echo ' epubdocs - EPUB' diff --git a/Documentation/doc-guide/kernel-doc.rst b/Documentation/doc-gui= de/kernel-doc.rst index af9697e60165..d85dcb08c87d 100644 --- a/Documentation/doc-guide/kernel-doc.rst +++ b/Documentation/doc-guide/kernel-doc.rst @@ -579,20 +579,9 @@ source. How to use kernel-doc to generate man pages ------------------------------------------- =20 -If you just want to use kernel-doc to generate man pages you can do this -from the kernel git tree:: +Generating man pages is a makefile target. Just run:: =20 - $ scripts/kernel-doc -man \ - $(git grep -l '/\*\*' -- :^Documentation :^tools) \ - | scripts/split-man.pl /tmp/man + $ make mandocs =20 -Some older versions of git do not support some of the variants of syntax f= or -path exclusion. One of the following commands may work for those versions= :: - - $ scripts/kernel-doc -man \ - $(git grep -l '/\*\*' -- . ':!Documentation' ':!tools') \ - | scripts/split-man.pl /tmp/man - - $ scripts/kernel-doc -man \ - $(git grep -l '/\*\*' -- . ":(exclude)Documentation" ":(exclude)tools"= ) \ - | scripts/split-man.pl /tmp/man +The output will be at ``/man`` directory inside the output directory +(by default: ``Documentation/output``). diff --git a/Makefile b/Makefile index 6bfe776bf3c5..9bd44afeda26 100644 --- a/Makefile +++ b/Makefile @@ -1800,7 +1800,7 @@ $(help-board-dirs): help-%: # Documentation targets # ------------------------------------------------------------------------= --- DOC_TARGETS :=3D xmldocs latexdocs pdfdocs htmldocs epubdocs cleandocs \ - linkcheckdocs dochelp refcheckdocs texinfodocs infodocs + linkcheckdocs dochelp refcheckdocs texinfodocs infodocs mandocs PHONY +=3D $(DOC_TARGETS) $(DOC_TARGETS): $(Q)$(MAKE) $(build)=3DDocumentation $@ diff --git a/scripts/split-man.pl b/scripts/split-man.pl deleted file mode 100755 index 96bd99dc977a..000000000000 --- a/scripts/split-man.pl +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env perl -# SPDX-License-Identifier: GPL-2.0 -# -# Author: Mauro Carvalho Chehab -# -# 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 =3D 0; -while () { - if (/^\.TH \"[^\"]*\" 9 \"([^\"]*)\"/) { - if ($state =3D=3D 1) { close OUT } - $state =3D 1; - $fn =3D "$ARGV[0]/$1.9"; - print STDERR "Creating $fn\n"; - open OUT, ">$fn" or die "can't open $fn: $!\n"; - print OUT $_; - } elsif ($state !=3D 0) { - print OUT $_; - } -} - -close OUT; diff --git a/tools/docs/sphinx-build-wrapper b/tools/docs/sphinx-build-wrap= per index eaca0900bd5c..2f06df744e27 100755 --- a/tools/docs/sphinx-build-wrapper +++ b/tools/docs/sphinx-build-wrapper @@ -79,6 +79,7 @@ TARGETS =3D { "epubdocs": { "builder": "epub", "out_dir": "epub" }, "texinfodocs": { "builder": "texinfo", "out_dir": "texinfo" }, "infodocs": { "builder": "texinfo", "out_dir": "texinfo" }, + "mandocs": { "builder": "man", "out_dir": "man" }, "latexdocs": { "builder": "latex", "out_dir": "latex" }, "pdfdocs": { "builder": "latex", "out_dir": "latex" }, "xmldocs": { "builder": "xml", "out_dir": "xml" }, @@ -458,6 +459,71 @@ class SphinxBuilder: except subprocess.CalledProcessError as e: sys.exit(f"Error generating info docs: {e}") =20 + def handle_man(self, kerneldoc, docs_dir, src_dir, output_dir): + """ + Create man pages from kernel-doc output + """ + + re_kernel_doc =3D re.compile(r"^\.\.\s+kernel-doc::\s*(\S+)") + re_man =3D re.compile(r'^\.TH "[^"]*" (\d+) "([^"]*)"') + + if docs_dir =3D=3D src_dir: + # + # Pick the entire set of kernel-doc markups from the entire tr= ee + # + kdoc_files =3D set([self.srctree]) + else: + kdoc_files =3D set() + + for fname in glob(os.path.join(src_dir, "**"), recursive=3DTru= e): + if os.path.isfile(fname) and fname.endswith(".rst"): + with open(fname, "r", encoding=3D"utf-8") as in_fp: + data =3D in_fp.read() + + for line in data.split("\n"): + match =3D 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 =3D [ kerneldoc, "-m" ] + sorted(kdoc_files) + try: + if self.verbose: + print(" ".join(cmd)) + + result =3D subprocess.run(cmd, stdout=3Dsubprocess.PIPE, text= =3D True) + + if result.returncode: + print(f"Warning: kernel-doc returned {result.returncode} w= arnings") + + except (OSError, ValueError, subprocess.SubprocessError) as e: + sys.exit(f"Failed to create man pages for {src_dir}: {repr(e)}= ") + + fp =3D None + try: + for line in result.stdout.split("\n"): + match =3D re_man.match(line) + if not match: + if fp: + fp.write(line + '\n') + continue + + if fp: + fp.close() + + fname =3D f"{output_dir}/{match.group(2)}.{match.group(1)}" + + if self.verbose: + print(f"Creating {fname}") + fp =3D open(fname, "w", encoding=3D"utf-8") + fp.write(line + '\n') + finally: + if fp: + fp.close() + def cleandocs(self, builder): =20 shutil.rmtree(self.builddir, ignore_errors=3DTrue) @@ -574,10 +640,13 @@ class SphinxBuilder: output_dir, ] =20 - try: - self.run_sphinx(sphinxbuild, build_args, env=3Dself.env) - except (OSError, ValueError, subprocess.SubprocessError) as e: - sys.exit(f"Build failed: {repr(e)}") + if target =3D=3D "mandocs": + self.handle_man(kerneldoc, docs_dir, src_dir, output_dir) + else: + try: + self.run_sphinx(sphinxbuild, build_args, env=3Dself.en= v) + except (OSError, ValueError, subprocess.SubprocessError) a= s e: + sys.exit(f"Build failed: {repr(e)}") =20 # # Ensure that each html/epub output will have needed static fi= les --=20 2.51.0