diff mbox series

[libgpiod,3/3] doc: integrate rust docs into the sphinx build

Message ID 20250604-rust-docs-v1-3-8ff23924a917@linaro.org
State Superseded
Headers show
Series doc: add rust docs | expand

Commit Message

Bartosz Golaszewski June 4, 2025, 9:53 a.m. UTC
From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

Follow the pattern we established with GLib bindings: generate a separate
set of docs for the rust bindings, make them part of the generated doc
bundle and point to the rust index.html from the dedicated sphinx page.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
 .readthedocs.yaml |  3 +++
 docs/conf.py      | 38 +++++++++++++++++++++++++++++++-------
 docs/rust_api.rst | 22 ++++++++++++++--------
 3 files changed, 48 insertions(+), 15 deletions(-)

Comments

Erik Schilling June 5, 2025, 7:09 a.m. UTC | #1
On Wed Jun 4, 2025 at 11:53 AM CEST, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
>
> Follow the pattern we established with GLib bindings: generate a separate
> set of docs for the rust bindings, make them part of the generated doc
> bundle and point to the rust index.html from the dedicated sphinx page.
>
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> ---
>  .readthedocs.yaml |  3 +++
>  docs/conf.py      | 38 +++++++++++++++++++++++++++++++-------
>  docs/rust_api.rst | 22 ++++++++++++++--------
>  3 files changed, 48 insertions(+), 15 deletions(-)
>
> diff --git a/.readthedocs.yaml b/.readthedocs.yaml
> index 5f4f5ac4954de70e060f1a7b2eafe3a731620c16..d81900c9ad9a60d8530b58e38add3a3a353da718 100644
> --- a/.readthedocs.yaml
> +++ b/.readthedocs.yaml
> @@ -14,6 +14,7 @@ build:
>    os: ubuntu-24.04
>    tools:
>      python: "3.12"
> +    rust: "1.86"
>    apt_packages:
>        - autoconf
>        - autoconf-archive
> @@ -24,6 +25,8 @@ build:
>        - gir1.2-glib-2.0-dev
>        - gobject-introspection
>        - graphviz
> +      # Needed for stdbool.h in rust build
> +      - libclang-dev

Mostly it is needed for bindgen, right?

>        - libglib2.0-dev-bin
>        - libgudev-1.0-dev
>        - libtool
> diff --git a/docs/conf.py b/docs/conf.py
> index 04d1cea2a2175166555993c3e936e7cf1ebd0fe6..8c7bed234c98990f01adaec6ca3d6db2c3171c65 100644
> --- a/docs/conf.py
> +++ b/docs/conf.py
> @@ -54,15 +54,16 @@ except ImportError:
>  
>  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 "./"
> +
>  
> -# We need to know where to put docs generated by gi-docgen but app.outdir is
> -# only set once the builder is initialized. Let's delay running gi-docgen
> -# until we're notified.
>  def make_glib_docs(app):
> -    # 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 "./"
> -
>      subprocess.run(
>          [
>              "gi-docgen",
> @@ -77,8 +78,31 @@ def make_glib_docs(app):
>      )
>  
>  
> +def make_rust_docs(app):
> +    subprocess.run(
> +        [
> +            "cargo",
> +            "doc",
> +            "--manifest-path",
> +            f"{prefix}/bindings/rust/libgpiod/Cargo.toml",
> +            "--target-dir",
> +            f"{app.outdir}/rust/",
> +        ],

This would narrow it down to only the libraries that actually matter:

diff --git a/docs/conf.py b/docs/conf.py
index 8c7bed2..e5baeb2 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -82,8 +82,11 @@ def make_rust_docs(app):
     subprocess.run(
         [
             "cargo",
             "doc",
+            "--no-deps",
+            "--package=libgpiod",
+            "--package=libgpiod-sys",
             "--manifest-path",
             f"{prefix}/bindings/rust/libgpiod/Cargo.toml",
             "--target-dir",
             f"{app.outdir}/rust/",

As the other stuff is just build dependencies, we probably do not need
to include it in the output? But not having a strong opinion here.

- Erik
Bartosz Golaszewski June 5, 2025, 7:51 a.m. UTC | #2
On Thu, Jun 5, 2025 at 9:09 AM Erik Schilling <erik@riscstar.com> wrote:
>
> On Wed Jun 4, 2025 at 11:53 AM CEST, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> >
> > Follow the pattern we established with GLib bindings: generate a separate
> > set of docs for the rust bindings, make them part of the generated doc
> > bundle and point to the rust index.html from the dedicated sphinx page.
> >
> > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> > ---
> >  .readthedocs.yaml |  3 +++
> >  docs/conf.py      | 38 +++++++++++++++++++++++++++++++-------
> >  docs/rust_api.rst | 22 ++++++++++++++--------
> >  3 files changed, 48 insertions(+), 15 deletions(-)
> >
> > diff --git a/.readthedocs.yaml b/.readthedocs.yaml
> > index 5f4f5ac4954de70e060f1a7b2eafe3a731620c16..d81900c9ad9a60d8530b58e38add3a3a353da718 100644
> > --- a/.readthedocs.yaml
> > +++ b/.readthedocs.yaml
> > @@ -14,6 +14,7 @@ build:
> >    os: ubuntu-24.04
> >    tools:
> >      python: "3.12"
> > +    rust: "1.86"
> >    apt_packages:
> >        - autoconf
> >        - autoconf-archive
> > @@ -24,6 +25,8 @@ build:
> >        - gir1.2-glib-2.0-dev
> >        - gobject-introspection
> >        - graphviz
> > +      # Needed for stdbool.h in rust build
> > +      - libclang-dev
>
> Mostly it is needed for bindgen, right?
>

Yes, I'll change the comment here.

> >        - libglib2.0-dev-bin
> >        - libgudev-1.0-dev
> >        - libtool
> > diff --git a/docs/conf.py b/docs/conf.py
> > index 04d1cea2a2175166555993c3e936e7cf1ebd0fe6..8c7bed234c98990f01adaec6ca3d6db2c3171c65 100644
> > --- a/docs/conf.py
> > +++ b/docs/conf.py
> > @@ -54,15 +54,16 @@ except ImportError:
> >
> >  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 "./"
> > +
> >
> > -# We need to know where to put docs generated by gi-docgen but app.outdir is
> > -# only set once the builder is initialized. Let's delay running gi-docgen
> > -# until we're notified.
> >  def make_glib_docs(app):
> > -    # 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 "./"
> > -
> >      subprocess.run(
> >          [
> >              "gi-docgen",
> > @@ -77,8 +78,31 @@ def make_glib_docs(app):
> >      )
> >
> >
> > +def make_rust_docs(app):
> > +    subprocess.run(
> > +        [
> > +            "cargo",
> > +            "doc",
> > +            "--manifest-path",
> > +            f"{prefix}/bindings/rust/libgpiod/Cargo.toml",
> > +            "--target-dir",
> > +            f"{app.outdir}/rust/",
> > +        ],
>
> This would narrow it down to only the libraries that actually matter:
>
> diff --git a/docs/conf.py b/docs/conf.py
> index 8c7bed2..e5baeb2 100644
> --- a/docs/conf.py
> +++ b/docs/conf.py
> @@ -82,8 +82,11 @@ def make_rust_docs(app):
>      subprocess.run(
>          [
>              "cargo",
>              "doc",
> +            "--no-deps",
> +            "--package=libgpiod",
> +            "--package=libgpiod-sys",
>              "--manifest-path",
>              f"{prefix}/bindings/rust/libgpiod/Cargo.toml",
>              "--target-dir",
>              f"{app.outdir}/rust/",
>
> As the other stuff is just build dependencies, we probably do not need
> to include it in the output? But not having a strong opinion here.
>

Thanks, it looks much cleaner with this. In fact: I only want to
include libgpiod and not the -sys create as the former is the only
official user-facing API.

I also dropped some environment variables which turned out to not be
needed at build-time - LD_LIBRARY_PATH and
SYSTEM_DEPS_LIBGPIOD_SEARCH_NATIVE.

I'll send a v2 shortly.

Bartosz
diff mbox series

Patch

diff --git a/.readthedocs.yaml b/.readthedocs.yaml
index 5f4f5ac4954de70e060f1a7b2eafe3a731620c16..d81900c9ad9a60d8530b58e38add3a3a353da718 100644
--- a/.readthedocs.yaml
+++ b/.readthedocs.yaml
@@ -14,6 +14,7 @@  build:
   os: ubuntu-24.04
   tools:
     python: "3.12"
+    rust: "1.86"
   apt_packages:
       - autoconf
       - autoconf-archive
@@ -24,6 +25,8 @@  build:
       - gir1.2-glib-2.0-dev
       - gobject-introspection
       - graphviz
+      # Needed for stdbool.h in rust build
+      - libclang-dev
       - libglib2.0-dev-bin
       - libgudev-1.0-dev
       - libtool
diff --git a/docs/conf.py b/docs/conf.py
index 04d1cea2a2175166555993c3e936e7cf1ebd0fe6..8c7bed234c98990f01adaec6ca3d6db2c3171c65 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -54,15 +54,16 @@  except ImportError:
 
 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 "./"
+
 
-# We need to know where to put docs generated by gi-docgen but app.outdir is
-# only set once the builder is initialized. Let's delay running gi-docgen
-# until we're notified.
 def make_glib_docs(app):
-    # 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 "./"
-
     subprocess.run(
         [
             "gi-docgen",
@@ -77,8 +78,31 @@  def make_glib_docs(app):
     )
 
 
+def make_rust_docs(app):
+    subprocess.run(
+        [
+            "cargo",
+            "doc",
+            "--manifest-path",
+            f"{prefix}/bindings/rust/libgpiod/Cargo.toml",
+            "--target-dir",
+            f"{app.outdir}/rust/",
+        ],
+        check=True,
+        env=dict(
+            os.environ,
+            LD_LIBRARY_PATH="../../../lib/.libs/",
+            SYSTEM_DEPS_LIBGPIOD_LIB="gpiod",
+            SYSTEM_DEPS_LIBGPIOD_NO_PKG_CONFIG="1",
+            SYSTEM_DEPS_LIBGPIOD_SEARCH_NATIVE="../../../lib/.libs/",
+            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"])
diff --git a/docs/rust_api.rst b/docs/rust_api.rst
index 1408b5c2457309938e314d1c289b81d583d9cc09..dda20d0baadcf8d97832cd60a60a5d00f99affc9 100644
--- a/docs/rust_api.rst
+++ b/docs/rust_api.rst
@@ -5,19 +5,25 @@ 
 ..
    This file is part of libgpiod.
 
-Where are the Rust bindings?
-=============================
+   libgpiod Rust bindings documentation
 
-.. warning::
-   There's currently no good way of integrating rust documentation with sphinx.
-   Rust bindings should be documented on https://docs.rs/ but due to a yet
-   unsolved build problem, this is currently not the case. Please refer to the
-   in-source comments for now.
+libgpiod Rust bindings API
+==========================
 
-Rust bindings are available on https://crates.io/ as the ``libgpiod`` package.
+Rust bindings for libgpiod aim to provide a memory-safe interface to the
+low-level C API. They are available on https://crates.io/ as the ``libgpiod``
+package.
 
 .. note::
    When building the Rust bindings along the C library using make, they will
    be automatically configured to build against the build results of the
    C library. Building rust bindings requires cargo to be available on the
    system.
+
+.. warning::
+   The documentation for Rust bindings is generated using ``cargo doc`` and
+   cannot be easily integrated with sphinx documentation. Please navigate to
+   a separate section dedicated exclusively to the Rust part of the API.
+
+
+`Navigate to Rust bindings documentation <rust/doc/libgpiod/index.html>`_