Re: [PATCH v3 2/6] docs: sphinx-pre-install: add macOS Homebrew support
Mauro Carvalho Chehab <[email protected]>
| Newsgroups | org.kernel.vger.linux-doc,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
On Thu, 13 Aug 2026 02:23:19 +0800 Chen Miao <[email protected]> wrote: > The dependency checker currently reports an unknown distribution on macOS > and cannot provide installation hints. > > Detect macOS and include its product version in the status output. Use > Homebrew for formula dependencies and install the command-line-only MacTeX > cask without sudo. Only require Homebrew when dependencies need to be > installed, install the DejaVu and Noto CJK fonts needed for PDF output, and > explain how to refresh PATH after installing MacTeX. > > Keep PyYAML in the virtualenv requirements because Homebrew does not > provide a PyYAML formula. Check the module even on macOS: it is required by > the parser_yaml extension regardless of how Sphinx is installed. When it is > missing, direct users to the default virtualenv mode. > > Signed-off-by: Chen Miao <[email protected]> I can't comment on macOS specifics, but the logic looks sane on my eyes. Acked-by: Mauro Carvalho Chehab <[email protected]> > --- > Documentation/doc-guide/sphinx.rst | 18 +++++ > tools/docs/sphinx-pre-install | 110 +++++++++++++++++++++++++++++ > 2 files changed, 128 insertions(+) > > diff --git a/Documentation/doc-guide/sphinx.rst b/Documentation/doc-guide/sphinx.rst > index 51c370260..1e105542a 100644 > --- a/Documentation/doc-guide/sphinx.rst > +++ b/Documentation/doc-guide/sphinx.rst > @@ -131,6 +131,24 @@ It supports two optional parameters: > ``--no-virtualenv`` > Use OS packaging for Sphinx instead of Python virtual environment. > > +macOS uses a case-insensitive APFS volume by default, but the kernel tree > +contains file names that differ only in case. Before cloning the tree, use > +``diskutil apfs list`` to find the APFS container identifier, replace > +``diskX`` below with that identifier, and create an additional case-sensitive > +volume with:: > + > + diskutil apfs addVolume diskX APFSX Linux > + > +On macOS, the script uses Homebrew for system dependencies. Homebrew > +commands are printed without ``sudo``. The PDF toolchain is provided by the > +``mactex-no-gui`` cask, while the required DejaVu and Noto CJK fonts are > +installed from Homebrew font casks; use ``--no-pdf`` when only building HTML > +documentation. After installing MacTeX, restart the terminal or run > +``eval "$(/usr/libexec/path_helper)"`` so its command-line tools are visible. > +The default virtualenv mode is recommended on macOS because PyYAML is > +installed from ``Documentation/sphinx/requirements.txt`` rather than from a > +Homebrew formula. > + > Installing Sphinx Minimal Version > --------------------------------- > > diff --git a/tools/docs/sphinx-pre-install b/tools/docs/sphinx-pre-install > index 965c9b093..1956f1369 100755 > --- a/tools/docs/sphinx-pre-install > +++ b/tools/docs/sphinx-pre-install > @@ -518,6 +518,24 @@ class MissingCheckers(AncillaryMethods): > a decent coverage. > """ > > + if sys.platform == "darwin": > + sw_vers = self.which("sw_vers") > + if sw_vers: > + try: > + result = self.run( > + [sw_vers, "-productVersion"], > + capture_output=True, > + text=True, > + check=True, > + ) > + version = result.stdout.strip() > + if version: > + return f"macOS {version}" > + except (subprocess.CalledProcessError, FileNotFoundError): > + pass > + > + return "macOS" > + > system_release = "" > > if self.which("lsb_release"): > @@ -716,6 +734,93 @@ class SphinxDependencyChecker(MissingCheckers): > > return self.get_install_progs(progs, "apt-get install") > > + def give_macos_hints(self): > + """Provide package installation hints for macOS using Homebrew.""" > + progs = { > + "Pod::Usage": "perl", > + "convert": "imagemagick", > + "dot": "graphviz", > + "ensurepip": "python", > + "python-sphinx": "sphinx-doc", > + "rsvg-convert": "librsvg", > + "xelatex": "mactex-no-gui", > + "latexmk": "mactex-no-gui", > + } > + > + if self.pdf: > + font_dirs = [ > + os.path.expanduser("~/Library/Fonts"), > + "/Library/Fonts", > + "/System/Library/Fonts", > + ] > + pdf_fonts = { > + "font-dejavu": ["DejaVuSans.ttf"], > + "font-noto-sans-cjk": ["NotoSansCJK.ttc"], > + } > + > + for package, names in pdf_fonts.items(): > + files = [ > + os.path.join(font_dir, name) > + for font_dir in font_dirs > + for name in names > + ] > + self.check_missing_file(files, package, DepManager.PDF_MANDATORY) > + > + install = self.deps.check_missing(progs) > + > + if self.verbose_warn_install: > + self.deps.warn_install() > + > + if not install: > + return None > + > + formulae = set() > + casks = set() > + notes = [] > + for package in install.split(): > + if package == "yaml": > + notes.append( > + "PyYAML is not provided as a Homebrew formula. Use the " > + "default virtualenv mode so it is installed from " > + "Documentation/sphinx/requirements.txt." > + ) > + continue > + > + if package == "mactex-no-gui" or package.startswith("font-"): > + casks.add(package) > + else: > + formulae.add(package) > + > + commands = [] > + if formulae: > + commands.append("\tbrew install " + " ".join(sorted(formulae))) > + if casks: > + commands.append("\tbrew install --cask " + " ".join(sorted(casks))) > + > + if not commands: > + self.distro_msg = "\n".join(notes) > + return None > + > + if not self.which("brew"): > + notes.append( > + "Homebrew is needed to install the missing dependencies. " > + "Install it from https://brew.sh/ and re-run this script." > + ) > + self.distro_msg = "\n".join(notes) > + return None > + > + if "mactex-no-gui" in casks: > + notes.append( > + "After installing MacTeX, restart the terminal or run:\n" > + "\teval \"$(/usr/libexec/path_helper)\"\n" > + "before re-running this script." > + ) > + > + if notes: > + self.distro_msg = "\n".join(notes) > + > + return "\nYou should run:\n" + "\n".join(commands) > + > def give_redhat_hints(self): > """ > Provide package installation hints for RedHat-based distros > @@ -1138,6 +1243,8 @@ class SphinxDependencyChecker(MissingCheckers): > re.compile("Kali"): self.give_debian_hints, > re.compile("Mint"): self.give_debian_hints, > > + re.compile("macOS"): self.give_macos_hints, > + > re.compile("openSUSE"): self.give_opensuse_hints, > > re.compile("Mageia"): self.give_mageia_hints, > @@ -1458,6 +1565,9 @@ class SphinxDependencyChecker(MissingCheckers): > self.check_program("dot", DepManager.SYSTEM_OPTIONAL) > self.check_program("convert", DepManager.SYSTEM_OPTIONAL) > > + # PyYAML is required by Documentation/sphinx/parser_yaml.py. The > + # macOS installation hints explain that it is installed from the > + # virtualenv requirements, rather than from a Homebrew formula. > self.check_python_module("yaml") > > if self.pdf: Thanks, Mauro