Re: [PATCH v2 3/5] docs: sphinx-build-wrapper: prefer gmake
Mauro Carvalho Chehab <[email protected]>
| Newsgroups | org.kernel.vger.linux-doc,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
On Mon, 10 Aug 2026 22:33:07 +0800 Chen Miao <[email protected]> wrote: > Homebrew installs GNU Make as gmake on macOS, but the Sphinx build > wrapper invokes make directly when generating Info and Rust > documentation. This can make the dependency check succeed while those > documentation targets still use an incompatible make implementation. > > Honor MAKE when it names a compatible GNU Make. Otherwise check gmake > and then make, selecting the first GNU Make 4.0 or newer. This keeps the > wrapper's selection consistent with sphinx-pre-install. > > Signed-off-by: Chen Miao <[email protected]> > --- > tools/docs/sphinx-build-wrapper | 55 ++++++++++++++++++++++++++++----- > 1 file changed, 48 insertions(+), 7 deletions(-) > > diff --git a/tools/docs/sphinx-build-wrapper b/tools/docs/sphinx-build-wrapper > index 1bb962202..aa6a297db 100755 > --- a/tools/docs/sphinx-build-wrapper > +++ b/tools/docs/sphinx-build-wrapper > @@ -71,6 +71,7 @@ from jobserver import JobserverExec # pylint: disable=C0413,C0411,E0401 > # > VENV_DEFAULT = "sphinx_latest" > MIN_PYTHON_VERSION = PythonVersion("3.7").version > +MIN_MAKE_VERSION = PythonVersion("4.0").version > PAPER = ["", "a4", "letter"] > > TARGETS = { > @@ -97,6 +98,46 @@ class SphinxBuilder: > with the Kernel. > """ > > + @staticmethod > + def get_make_version(cmd): > + """Return the GNU Make version, or None for another make.""" > + if not cmd: > + return None > + > + try: > + result = subprocess.run( > + [cmd, "--version"], > + stdout=subprocess.PIPE, > + stderr=subprocess.PIPE, > + text=True, > + check=True, > + ) > + except (OSError, subprocess.CalledProcessError): > + return None > + > + match = re.search( > + r"^GNU Make\s+([0-9]+(?:\.[0-9]+)*)", result.stdout, re.MULTILINE > + ) > + if not match: > + return None > + > + return PythonVersion.parse_version(match.group(1)) > + > + def get_make(self): > + """Select the first GNU Make 4.0 or newer in preference order.""" > + candidates = [ > + self.env.get("MAKE"), > + shutil.which("gmake"), > + shutil.which("make"), > + ] > + > + for cmd in candidates: > + version = self.get_make_version(cmd) > + if version and version >= MIN_MAKE_VERSION: > + return cmd > + > + sys.exit("GNU Make 4.0 or newer is required") > + As the code here seems to be duplicated, please add it on a library to be used by both scripts, as this makes easier to maintain it. The doc tools libraries are located under tools/lib/python/kdoc. Both scripts are already prepared to use it. For instance: from kdoc.python_version import PythonVersion PythonVersion belongs to a common library. As make is unrelated, please create something like: tools/lib/python/kdoc/gmake_detect.py adding the code there, and then use from/import to pick the needed class or method. Regards, Mauro > def get_path(self, path, use_cwd=False, abs_path=False): > """ > Ancillary routine to handle patches the right way, as shell does. > @@ -569,9 +610,10 @@ class SphinxBuilder: > texinfo directory. > """ > > + make = self.get_make() > for output_dir in output_dirs: > try: > - subprocess.run(["make", "info"], cwd=output_dir, check=True) > + subprocess.run([make, "info"], cwd=output_dir, check=True) > except subprocess.CalledProcessError as e: > sys.exit(f"Error generating info docs: {e}") > > @@ -787,12 +829,11 @@ class SphinxBuilder: > > if rustdoc and target in ["htmldocs", "epubdocs"]: > print("Building rust docs") > - if "MAKE" in self.env: > - cmd = [self.env["MAKE"]] > - else: > - cmd = ["make", "LLVM=1"] > - > - cmd += [ "rustdoc"] > + make = self.get_make() > + cmd = [make] > + if make != self.env.get("MAKE"): > + cmd.append("LLVM=1") > + cmd.append("rustdoc") > if self.verbose: > print(" ".join(cmd)) > Thanks, Mauro