bazelbuild / rules_python

Bazel Python Rules
https://rules-python.readthedocs.io
Apache License 2.0
531 stars 541 forks source link

Support directory sources in sphinx_docs_library #2374

Open kaycebasques opened 2 hours ago

kaycebasques commented 2 hours ago

🚀 feature request

Relevant Rules

sphinx_docs_library

Description

pigweed.dev is a Sphinx site. We use Breathe to integrate Doxygen-generated API references directly in the Sphinx site. Doxygen generates XML, and then that XML is used as sources of the Sphinx build. The Breathe extension uses the XML to generate the API references during the Sphinx build.

We expose some headers as docs inputs:

# in //pw_analog/BUILD.bazel
filegroup(
    name = "doxygen",
    srcs = [
        "public/pw_analog/analog_input.h",
        "public/pw_analog/microvolt_input.h",
    ],
)

We use TendTo/rules_doxygen to generate the XML:

doxygen(
    name = "doxygen",
    srcs = [
        "//pw_analog:doxygen",
    ],
    outs = [
        "xml",
    ],
    configurations = [
        "GENERATE_XML = YES",
    ],
    target_compatible_with = incompatible_with_mcu(),
)

And then we're trying to feed the XML into sphinx_docs_library (this is the step that's not working):

sphinx_docs_library(
    name = "doxygen_xml",
    srcs = [":doxygen"],  # this label resolves to a directory whereas sphinx_docs_library expects only files
    target_compatible_with = incompatible_with_mcu(),
)

And then we make the XML available during the Sphinx build:

sphinx_docs(
    name = "docs",
    srcs = [
        "index.rst",
        "modules.rst",
    ],
    config = "conf.py",
    formats = [
        "html",
    ],
    sphinx = ":sphinx-build",
    strip_prefix = "docs/",
    target_compatible_with = incompatible_with_mcu(),
    deps = [
        "//pw_analog:docs",
        "//pw_async2:docs",
        "//pw_boot:docs",
        ":doxygen_xml",  # This is how we're trying to make the XML available
    ],
)

(For completeness) Within our reStructuredText files we use Breathe directives like this to insert the API references into our Sphinx docs:

=======================
.. doxygenclass:: pw::analog::AnalogInput
   :members:

Describe the solution you'd like

we would like sphinx_docs_library to accept labels like shown above:

sphinx_docs_library(
    name = "doxygen_xml",
    srcs = [":doxygen"],  # this label resolves to a directory whereas sphinx_docs_library expects only files
    target_compatible_with = incompatible_with_mcu(),
)

Minimal repro

  1. git clone https://pigweed.googlesource.com/pigweed/pigweed
  2. cd pigweed
  3. git fetch https://pigweed.googlesource.com/pigweed/pigweed refs/changes/92/247192/7 && git checkout -b change-247192 FETCH_HEAD
  4. bazelisk build //docs/...

results in this error:

ERROR: /tmp/pigweed/docs/BUILD.bazel:49:12: in _sphinx_source_tree rule //docs:_docs/_sources: 
Traceback (most recent call last):
    File "/home/kayce/.cache/bazel/_bazel_kayce/21e3877f2b248a7c83c104fd731f99f4/external/rules_python+/sphinxdocs/private/sphinx.bzl", line 369, column 26, in _sphinx_source_tree_impl
        _relocate(original, new_path)
    File "/home/kayce/.cache/bazel/_bazel_kayce/21e3877f2b248a7c83c104fd731f99f4/external/rules_python+/sphinxdocs/private/sphinx.bzl", line 329, column 28, in _relocate
        ctx.actions.symlink(
Error in symlink: symlink() with "target_file" directory param requires that "output" be declared as a directory (did you mean to use declare_directory() instead of declare_file()?)
ERROR: /tmp/pigweed/docs/BUILD.bazel:49:12: Analysis of target '//docs:_docs/_sources' failed
ERROR: Analysis of target '//docs:_docs/_sources' failed; build aborted
INFO: Elapsed time: 114.815s, Critical Path: 0.05s
INFO: 1 process: 1 internal.
ERROR: Build did NOT complete successfully

Describe alternatives you've considered

There is also a path where Breathe kicks off the Doxygen XML generation, but we expect that path to be unacceptably slow.

kaycebasques commented 2 hours ago

@rickeylev