Linux Documentation
 help / color / mirror / Atom feed
From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
To: Chen Miao <chenmiao.ku@gmail.com>
Cc: corbet@lwn.net, alexs@kernel.org, si.yanteng@linux.dev,
	skhan@linuxfoundation.org, dzm91@hust.edu.cn, mchehab@kernel.org,
	wy@wyuan.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2 1/5] docs: sphinx-pre-install: add macOS Homebrew support
Date: Mon, 10 Aug 2026 21:56:38 +0200	[thread overview]
Message-ID: <20260810215251.3a25758a@foz.lan> (raw)
In-Reply-To: <20260810143311.57775-2-chenmiao.ku@gmail.com>

On Mon, 10 Aug 2026 22:33:05 +0800
Chen Miao <chenmiao.ku@gmail.com> 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
> actually 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 virtual environment requirements because Homebrew
> does not provide a PyYAML formula. Document the macOS setup, the
> --no-pdf option, and how to create a case-sensitive APFS volume before
> cloning the kernel tree.
> 
> Signed-off-by: Chen Miao <chenmiao.ku@gmail.com>
> ---
>  Documentation/doc-guide/sphinx.rst |  18 +++++
>  tools/docs/sphinx-pre-install      | 113 ++++++++++++++++++++++++++++-
>  2 files changed, 130 insertions(+), 1 deletion(-)
> 
> 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..1b9d77ec3 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,7 +1565,11 @@ class SphinxDependencyChecker(MissingCheckers):
>          self.check_program("dot", DepManager.SYSTEM_OPTIONAL)
>          self.check_program("convert", DepManager.SYSTEM_OPTIONAL)
>  
> -        self.check_python_module("yaml")
> +        # PyYAML is installed from Documentation/sphinx/requirements.txt in
> +        # the virtualenv recommended on macOS. Homebrew does not provide a
> +        # PyYAML formula, so do not ask for a nonexistent brew package here.
> +        if not (sys.platform == "darwin" and self.virtualenv and self.need_pip):
> +            self.check_python_module("yaml")

This is not right: yaml is needed even outside venv/pip, as
it is required to build some docs - See Documentation/sphinx/parser_yaml.py
extension.

So, basically:

if python on macOS is *always* shipped with python3-yaml package (or
whatever name it has there), the code would be something like:

	# For whatever weird reason, macOS added a non-builtin module
	# on its python package, so no need to check as yaml is always
	# there.
	if sys.platform != "darwin":
		self.check_python_module("yaml")

Otherwise, this hunk is wrong.

>  
>          if self.pdf:
>              self.check_program("xelatex", DepManager.PDF_MANDATORY)



Thanks,
Mauro

  reply	other threads:[~2026-08-10 19:56 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-10 14:33 [PATCH v2 0/5] docs: sphinx-pre-install: improve dependency checks Chen Miao
2026-08-10 14:33 ` [PATCH v2 1/5] docs: sphinx-pre-install: add macOS Homebrew support Chen Miao
2026-08-10 19:56   ` Mauro Carvalho Chehab [this message]
2026-08-10 14:33 ` [PATCH v2 2/5] docs: sphinx-pre-install: check GNU Make version Chen Miao
2026-08-11  4:43   ` Mauro Carvalho Chehab
2026-08-10 14:33 ` [PATCH v2 3/5] docs: sphinx-build-wrapper: prefer gmake Chen Miao
2026-08-11  4:51   ` Mauro Carvalho Chehab
2026-08-10 14:33 ` [PATCH v2 4/5] docs/zh_CN: doc-guide: document macOS Sphinx setup Chen Miao
2026-08-10 14:33 ` [PATCH v2 5/5] docs/zh_CN: how-to: document case-sensitive APFS setup Chen Miao

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260810215251.3a25758a@foz.lan \
    --to=mchehab+huawei@kernel.org \
    --cc=alexs@kernel.org \
    --cc=chenmiao.ku@gmail.com \
    --cc=corbet@lwn.net \
    --cc=dzm91@hust.edu.cn \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mchehab@kernel.org \
    --cc=si.yanteng@linux.dev \
    --cc=skhan@linuxfoundation.org \
    --cc=wy@wyuan.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox