# SPDX-License-Identifier: GPL-2.0-or-later # SPDX-FileCopyrightText: 2024-2025 Bartosz Golaszewski # This file is part of libgpiod. # # Configuration file for the Sphinx documentation builder. import os import re import subprocess import sys from pathlib import Path project = "libgpiod" copyright = "2017-2025, Bartosz Golaszewski" author = "Bartosz Golaszewski" master_doc = "index" source_suffix = ".rst" # Extract the full version from meson.build (including -devel, -rc and other # tags). with open("../meson.build", "r") as fd: version = "" extra = "" for line in fd.readlines(): match = re.search(r"version:\s*'(.*?)'", line) if match and not version: version = match.group(1) continue match = re.search(r"extra_version\s*=\s*'(.*?)'", line) if match: extra = match.group(1) release = f"{version}{extra}" extensions = ["breathe", "sphinx.ext.autodoc"] breathe_projects = {"libgpiod": "./doxygen-output/xml"} breathe_default_project = "libgpiod" sys.path.insert(0, str(Path("../bindings/python").resolve())) autodoc_mock_imports = ["gpiod._ext"] # Use the RTD theme if available sphinx_rtd_theme = None try: import sphinx_rtd_theme extensions.append("sphinx_rtd_theme") except ImportError: pass html_theme = "sphinx_rtd_theme" if sphinx_rtd_theme else "default" # We need to know where to put docs generated by gi-docgen and cargo but # app.outdir is only set once the builder is initialized. Let's delay running # gi-docgen until we're notified. # # For some reason on RTD we're in the docs/ directory while during a local # build, we're still in the top source directory. prefix = "../" if os.getenv("READTHEDOCS") == "True" else "./" builddir_prefix = ( "../sphinx-builddir" if os.getenv("READTHEDOCS") == "True" else "./sphinx-builddir" ) def make_glib_docs(app): subprocess.run( [ "gi-docgen", "generate", "--config", f"{builddir_prefix}/bindings/glib/gi-docgen.toml", f"{builddir_prefix}/bindings/glib/Gpiodglib-1.0.gir", "--output-dir", f"{app.outdir}", ], check=True, ) def make_rust_docs(app): subprocess.run( [ "cargo", "doc", "--manifest-path", f"{prefix}/bindings/rust/libgpiod/Cargo.toml", "--target-dir", f"{app.outdir}/rust/", "--no-deps", "--package=libgpiod", ], check=True, env=dict( os.environ, SYSTEM_DEPS_LIBGPIOD_LIB="gpiod", SYSTEM_DEPS_LIBGPIOD_NO_PKG_CONFIG="1", SYSTEM_DEPS_LIBGPIOD_INCLUDE="../../../include/", ), ) def setup(app): app.connect("builder-inited", make_glib_docs) app.connect("builder-inited", make_rust_docs) subprocess.run(["doxygen", "Doxyfile"]) cwd = os.getcwd() os.chdir("..") sphinx_builddir = "sphinx-builddir" meson_cmd = [ "meson", "setup", sphinx_builddir, "-Dtools=enabled", "-Dbindings-glib=enabled", "-Dintrospection=enabled", "-Ddbus=enabled", "--auto-features=disabled", ] if os.path.exists(sphinx_builddir): meson_cmd.append("--reconfigure") subprocess.run(meson_cmd, check=True) subprocess.run(["ninja", "-C", sphinx_builddir], check=True) os.chdir(cwd) for page in [ "gpiodetect", "gpioinfo", "gpioget", "gpioset", "gpiomon", "gpionotify", "gpio-manager", "gpiocli", "gpiocli-detect", "gpiocli-find", "gpiocli-info", "gpiocli-get", "gpiocli-monitor", "gpiocli-notify", "gpiocli-reconfigure", "gpiocli-release", "gpiocli-request", "gpiocli-requests", "gpiocli-set", "gpiocli-wait", ]: subprocess.run( [ "pandoc", "--from=man", "--to=rst", "--standalone", "--wrap=none", f"--output={page}.rst", f"../sphinx-builddir/man/{page}.1", ], check=True, ) subprocess.run(["gdbus-codegen", "--generate-rst", "dbus", "../dbus/lib/io.gpiod1.xml"])