Files
external_libcamera/Documentation/meson.build
Laurent Pinchart 0382d215db Documentation: Use Sphinx doxylink to generate links to doxygen
The libcamera Sphinx documentation needs to link to the API
documentation generated by Doxygen. The links currently point to the
documentation hosted on the official https://libcamera.org/ website.
This causes multiple issues:

- Doxygen generates URLs with MD5 hashes of function signatures, making
  the link targets unstable.

- When testing documentation builds that include API changes, links to
  new API elements will be broken.

- The generated documentation can't be browsed offline.

Fix this by using the Sphinx doxylink extension. This allows specifying
link targets as class and function names, with the link being
automatically generated using the same MD5 hashing as Doxygen. The root
of the link target is configured in a central location, which defaults
to the build directory and can be overridden to point to the libcamera
website when pushing the documentation.

This commit only introduces the infrastructure to use doxylink. Manual
links will be replaced separately.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2025-07-30 18:54:26 +03:00

192 lines
7.1 KiB
Meson

# SPDX-License-Identifier: CC0-1.0
doc_install_dir = get_option('datadir') / 'doc' / 'libcamera-@0@'.format(libcamera_version)
#
# Doxygen
#
doxygen = find_program('doxygen', required : get_option('documentation'))
dot = find_program('dot', required : get_option('documentation'))
if doxygen.found() and dot.found()
cdata = configuration_data()
cdata.set('VERSION', 'v@0@'.format(libcamera_git_version))
cdata.set('TOP_SRCDIR', meson.project_source_root())
cdata.set('TOP_BUILDDIR', meson.project_build_root())
cdata.set('OUTPUT_DIR', meson.current_build_dir())
cdata.set('WARN_AS_ERROR', get_option('doc_werror') ? 'YES' : 'NO')
doxygen_predefined = []
foreach key : config_h.keys()
doxygen_predefined += '@0@=@1@'.format(key, config_h.get(key))
endforeach
cdata.set('PREDEFINED', ' \\\n\t\t\t '.join(doxygen_predefined))
doxyfile_common = configure_file(input : 'Doxyfile-common.in',
output : 'Doxyfile-common',
configuration : cdata)
doxygen_public_input = [
libcamera_base_public_headers,
libcamera_base_public_sources,
libcamera_public_headers,
libcamera_public_sources,
]
doxygen_internal_input = [
libcamera_base_private_headers,
libcamera_base_internal_sources,
libcamera_internal_headers,
libcamera_internal_sources,
libcamera_ipa_headers,
libcamera_ipa_interfaces,
libipa_headers,
libipa_sources,
]
if is_variable('ipu3_ipa_sources')
doxygen_internal_input += [ipu3_ipa_sources]
endif
# We run doxygen twice - the first run excludes internal API objects as it
# is intended to document the public API only. A second run covers all of
# the library's objects for libcamera developers. Common configuration is
# set in an initially generated Doxyfile, which is then included by the two
# final Doxyfiles.
# This is the "public" run of doxygen generating an abridged version of the
# API's documentation.
doxyfile_tmpl = configure_file(input : 'Doxyfile-public.in',
output : 'Doxyfile-public.tmpl',
configuration : cdata)
# The set of public input files stored in the doxygen_public_input array
# needs to be set in Doxyfile public. We can't pass them through cdata
# cdata, as some of the array members are custom_tgt instances, which
# configuration_data.set() doesn't support. Using a separate script invoked
# through custom_target(), which supports custom_tgt instances as inputs.
doxyfile = custom_target('doxyfile-public',
input : [
doxygen_public_input,
],
output : 'Doxyfile-public',
command : [
'gen-doxyfile.py',
'-o', '@OUTPUT@',
doxyfile_tmpl,
'@INPUT@',
])
doxygen_public = custom_target('doxygen-public',
input : [
doxyfile,
doxyfile_common,
],
output : 'api-html',
command : [doxygen, doxyfile],
install : true,
install_dir : doc_install_dir,
install_tag : 'doc')
# This is the internal documentation, which hard-codes a list of directories
# to parse in its doxyfile.
doxyfile = configure_file(input : 'Doxyfile-internal.in',
output : 'Doxyfile-internal',
configuration : cdata)
doxygen_internal = custom_target('doxygen-internal',
input : [
doxyfile,
doxyfile_common,
doxygen_public_input,
doxygen_internal_input,
],
output : 'internal-api-html',
command : [doxygen, doxyfile],
install : true,
install_dir : doc_install_dir,
install_tag : 'doc-internal')
endif
#
# Sphinx
#
sphinx = find_program('sphinx-build-3', 'sphinx-build',
required : get_option('documentation'))
if sphinx.found()
# Many distributions do not provide a recent-enough version of the doxylink
# module. This results in a build error with a cryptic message. Check the
# version manually and print clear error messages.
py_mod = import('python')
py3 = py_mod.find_installation('python3')
mod = 'sphinxcontrib.doxylink'
min_version = '>=1.6.1'
version = run_command(py3, '-c',
'import @0@ ; print(@0@.__version__)'.format(mod),
check : false).stdout().strip()
if version == ''
error('@0@ module not found'.format(mod))
endif
if not version.version_compare(min_version)
error('@0@ module v@1@ is too old, @2@ is needed'
.format(mod, version, min_version))
endif
docs_sources = [
'camera-sensor-model.rst',
'code-of-conduct.rst',
'coding-style.rst',
'conf.py',
'contributing.rst',
'design/ae.rst',
'documentation-contents.rst',
'environment_variables.rst',
'feature_requirements.rst',
'guides/application-developer.rst',
'guides/ipa.rst',
'guides/pipeline-handler.rst',
'guides/tracing.rst',
'index.rst',
'introduction.rst',
'lens_driver_requirements.rst',
'libcamera_architecture.rst',
'mali-c55.dot',
'python-bindings.rst',
'sensor_driver_requirements.rst',
'software-isp-benchmarking.rst',
'../README.rst',
]
release = 'release=v' + libcamera_git_version
custom_target('documentation',
command : [sphinx, '-D', release, '-q', '-W', '-b', 'html',
meson.current_source_dir(), '@OUTPUT@'],
input : docs_sources,
output : 'html',
build_by_default : true,
depends : [
doxygen_public,
doxygen_internal,
],
install : true,
install_dir : doc_install_dir,
install_tag : 'doc')
custom_target('documentation-linkcheck',
command : [sphinx, '-W', '-b', 'linkcheck', meson.current_source_dir(), '@OUTPUT@'],
build_always_stale : true,
input : docs_sources,
output : 'linkcheck')
endif